Forráskód Böngészése

mergeing in the most recent changes to the master branch and fixing a merge conflict

Shawna Spoor 7 éve
szülő
commit
f10f50c8b4
48 módosított fájl, 1388 hozzáadás és 240 törlés
  1. 2 2
      tripal/api/tripal.entities.api.inc
  2. 202 0
      tripal/api/tripal.terms.api.inc
  3. 2 2
      tripal/includes/TripalBundleUIController.inc
  4. 2 2
      tripal/includes/TripalFields/TripalField.inc
  5. 18 20
      tripal/includes/tripal.bulk_update.inc
  6. 1 0
      tripal/includes/tripal.fields.inc
  7. 2 2
      tripal/includes/tripal.importer.inc
  8. 5 1
      tripal/includes/tripal.upload.inc
  9. 1 1
      tripal/theme/js/TripalUploadFile.js
  10. 1 1
      tripal_bulk_loader/includes/tripal_bulk_loader.loader.inc
  11. 1 1
      tripal_chado/api/modules/tripal_chado.analysis.api.inc
  12. 37 9
      tripal_chado/api/modules/tripal_chado.cv.api.inc
  13. 3 3
      tripal_chado/api/modules/tripal_chado.organism.api.inc
  14. 0 4
      tripal_chado/api/modules/tripal_chado.phylotree.api.inc
  15. 2 2
      tripal_chado/api/tripal_chado.api.inc
  16. 1 1
      tripal_chado/api/tripal_chado.entity.api.inc
  17. 41 0
      tripal_chado/api/tripal_chado.migrate.api.inc
  18. 1 1
      tripal_chado/api/tripal_chado.query.api.inc
  19. 1 1
      tripal_chado/api/tripal_chado.schema.api.inc
  20. 6 3
      tripal_chado/api/tripal_chado.variables.api.inc
  21. 1 1
      tripal_chado/includes/TripalFields/ChadoField.inc
  22. 0 1
      tripal_chado/includes/TripalFields/chado_linker__contact/chado_linker__contact.inc
  23. 19 18
      tripal_chado/includes/TripalFields/chado_linker__contact/chado_linker__contact_formatter.inc
  24. 3 0
      tripal_chado/includes/TripalFields/chado_linker__contact/chado_linker__contact_widget.inc
  25. 12 10
      tripal_chado/includes/TripalFields/local__contact/local__contact.inc
  26. 3 3
      tripal_chado/includes/TripalFields/local__source_data/local__source_data_formatter.inc
  27. 1 1
      tripal_chado/includes/TripalFields/obi__organism/obi__organism.inc
  28. 80 2
      tripal_chado/includes/TripalFields/schema__additional_type/schema__additional_type.inc
  29. 42 14
      tripal_chado/includes/TripalFields/schema__additional_type/schema__additional_type_widget.inc
  30. 1 1
      tripal_chado/includes/TripalFields/schema__publication/schema__publication_formatter.inc
  31. 149 0
      tripal_chado/includes/TripalFields/sep__protocol/sep__protocol.inc
  32. 133 0
      tripal_chado/includes/TripalFields/sep__protocol/sep__protocol_formatter.inc
  33. 153 0
      tripal_chado/includes/TripalFields/sep__protocol/sep__protocol_widget.inc
  34. 1 1
      tripal_chado/includes/TripalFields/sio__annotation/sio__annotation_formatter.inc
  35. 2 2
      tripal_chado/includes/TripalFields/taxrank__infraspecific_taxon/taxrank__infraspecific_taxon.inc
  36. 5 5
      tripal_chado/includes/TripalFields/taxrank__infraspecific_taxon/taxrank__infraspecific_taxon_widget.inc
  37. 234 0
      tripal_chado/includes/TripalImporter/NewickImporter.inc
  38. 4 4
      tripal_chado/includes/TripalImporter/TaxonomyImporter.inc
  39. 44 62
      tripal_chado/includes/tripal_chado.cv.inc
  40. 1 1
      tripal_chado/includes/tripal_chado.entity.inc
  41. 2 1
      tripal_chado/includes/tripal_chado.field_storage.inc
  42. 117 20
      tripal_chado/includes/tripal_chado.fields.inc
  43. 17 6
      tripal_chado/includes/tripal_chado.migrate.inc
  44. 14 15
      tripal_chado/tripal_chado.module
  45. 8 3
      tripal_chado_views/tripal_chado_views.views.inc
  46. 1 1
      tripal_ws/includes/TripalWebService.inc
  47. 11 11
      tripal_ws/includes/TripalWebService/TripalEntityService_v0_1.inc
  48. 1 1
      tripal_ws/includes/tripal_ws.field_storage.inc

+ 2 - 2
tripal/api/tripal.entities.api.inc

@@ -1048,7 +1048,7 @@ function tripal_replace_entity_tokens($string, &$entity, $bundle_entity = NULL)
 
     if (property_exists($entity, $field_name)) {
       // Note: there is a memory leak in field_get_items() so we can't use it
-      // here or bulk publising will slowly erode memory.
+      // here or bulk publishing will slowly erode memory.
       //$field_value = field_get_items('TripalEntity', $entity, $field_name);
       if (array_key_exists(0, $entity->{$field_name}['und'])) {
         $value = $entity->{$field_name}['und'][0]['value'];
@@ -1286,4 +1286,4 @@ function tripal_insert_entity($bundle_name, $values){
 function tripal_update_entity($bundle_name, $values) {
 
 
-}
+}

+ 202 - 0
tripal/api/tripal.terms.api.inc

@@ -295,3 +295,205 @@ function tripal_get_vocabulary_details($vocabulary) {
     }
   }
 }
+
+
+/**
+ * Provides a term lookup form.
+ *
+ * It may be necessary at times for a form to provide to the user the ability
+ * to lookup and use a controlled vocabulary term.  However, a simple text box
+ * or auto-lookup is not sufficient because a term name may be identical in
+ * multiple vocabularies and the user would need to select the proper term.
+ *
+ * This function will add the form elements necessary to provide a lookup form.
+ * The form elements should work with a flat fortm (no #tree set for the form)
+ * or with a form in a TripalField.
+ *
+ * Use the tripal_get_term_lookup_form_result() function to retreive the
+ * result in a form submit or validate.
+ *
+ * @param $form
+ *   The form (or $widget form).
+ * @param $form_state
+ *   The form state.
+ * @param $title
+ *   The title to give to the field set.
+ * @param $description
+ *   A description for the lookup field element.
+ * @param $is_required
+ *   Indicates if this form element is required.
+ * @param $field_name
+ *   The name of the field, if this form is being added to a field widget.
+ * @param  $delta
+ *   The delta value for the field if this form is being added to a field
+ *   widget.
+ */
+function tripal_get_term_lookup_form(&$form, &$form_state, $default_name = '',
+    $title = 'Vocabulary Term', $description = '', $is_required,
+    $field_name = '', $delta = 0 ) {
+
+  $term_name = $default_name;
+  if (array_key_exists('values', $form_state)) {
+    $term_name = $form_state['values']['term_name'];
+  }
+  if ($field_name and array_key_exists('input', $form_state) and array_key_exists($field_name, $form_state['input'])) {
+    $term_name = $form_state['input'][$field_name]['und'][$delta]['term_match']['term_name'];
+  }
+
+  if (!$description) {
+    $description = t('Enter the name of the term that specifies the type. ' .
+      'The type must be the name of a term in a controlled vocabulary and ' .
+      'the controlled vocabulary should already be loaded into this site.');
+  }
+
+  $form_state['storage']['term_match_field'] = $field_name;
+  $form_state['storage']['term_match_delta'] = $delta;
+
+  $form['term_match'] = array(
+    '#type' => 'fieldset',
+    '#collapsible' => FALSE,
+    '#collapsed' => FALSE,
+    '#title' => t($title),
+    '#prefix' => '<div id = "tripal-vocab-select-form">',
+    '#suffix' => '</div>',
+  );
+  $form['term_match']['term_name'] = array(
+    '#title'  => t('Type'),
+    '#type' => 'textfield',
+    '#description' => $description,
+    '#required' => $is_required,
+    '#default_value' => $term_name,
+    '#autocomplete_path' => "admin/tripal/storage/chado/auto_name/cvterm/",
+  );
+  $form['term_match']['select_button'] = array(
+    '#type' => 'button',
+    '#value' => t('Lookup Term'),
+    '#name' => 'select_cvterm',
+    '#validate' => array(),
+    '#limit_validation_errors' => array(),
+    '#ajax' => array(
+      'callback' => "tripal_get_term_lookup_form_ajax_callback",
+      'wrapper' => "tripal-vocab-select-form",
+      'effect' => 'fade',
+      'method' => 'replace'
+    ),
+  );
+
+  // If the term has been provided by the user then we want to search for
+  // matching terms in the database and let them select among any matches.
+  if ($term_name) {
+    $submit_disabled = TRUE;
+    $form['term_match']['terms_list'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Matching Terms'),
+      '#description' => t('Please select the term the best matches the
+          content type you want to create. If the same term exists in
+          multiple vocabularies you will see more than one option below.')
+    );
+    $match = array(
+      'name' => $term_name,
+    );
+    // TODO: this should not call the chado functions because we're in the
+    // tripal module.
+    $terms = chado_generate_var('cvterm', $match, array('return_array' => TRUE));
+    $terms = chado_expand_var($terms, 'field', 'cvterm.definition');
+    $num_terms = 0;
+    $selected_term = '';
+
+    // Let the user select from any matching terms. Sometimes there may be
+    // more than one that match.
+    foreach ($terms as $term) {
+      // Save the user a click by setting the default value as 1 if there's
+      // only one matching term.
+      $default = FALSE;
+      $attrs = array();
+      if ($num_terms == 0 and count($terms) == 1) {
+        $default = TRUE;
+        $attrs = array('checked' => 'checked');
+      }
+      $term_element_name = 'term-' . $term->cvterm_id;
+      $form['term_match']['terms_list'][$term_element_name] = array(
+        '#type' => 'checkbox',
+        '#title' =>  $term->name,
+        '#default_value' => $default,
+        '#attributes' => $attrs,
+        '#description' => '<b>Vocabulary:</b> ' . $term->cv_id->name . ' (' . $term->dbxref_id->db_id->name . ') ' . $term->cv_id->definition .
+        '<br><b>Term: </b> ' . $term->dbxref_id->db_id->name . ':' . $term->dbxref_id->accession . '.  ' .
+        '<br><b>Definition:</b>  ' . $term->definition,
+        '#ajax' => array(
+          'callback' => "tripal_get_term_lookup_form_ajax_callback",
+          'wrapper' => "tripal-vocab-select-form",
+          'effect' => 'fade',
+          'method' => 'replace'
+        ),
+      );
+
+      if (array_key_exists('values', $form_state) and array_key_exists($term_element_name, $form_state['values']) and
+          $form_state['values'][$term_element_name] == 1) {
+        $selected_term = $term;
+      }
+      $num_terms++;
+    }
+    if ($num_terms == 0) {
+      $form['term_match']['terms_list']['none'] = array(
+        '#type' => 'item',
+        '#markup' => '<i>' . t('There is no term that matches the entered text.') . '</i>'
+      );
+    }
+  }
+}
+
+/**
+ * Returns the terms selected from the tripal_get_term_lookup_form.
+ *
+ * @param $form
+ *   The form (or $widget form).
+ * @param $form_state
+ *   The form state.
+ * @param $field_name
+ *   The name of the field, if this form is being added to a field widget.
+ * @param  $delta
+ *   The delta value for the field if this form is being added to a field
+ *   widget.
+ *
+ * @return
+ *   An array of term objects for each of the user selected terms.
+ */
+function tripal_get_term_lookup_form_result($form, $form_state, $field_name = '', $delta = 0) {
+  $values = array();
+  $selected = array();
+  if ($field_name) {
+    if (array_key_exists('term_match', $form_state['values'][$field_name]['und'][$delta])) {
+      $values = $form_state['values'][$field_name]['und'][$delta]['term_match']['terms_list'];
+    }
+  }
+  else {
+    $values = $form_state['values'];
+  }
+
+  foreach ($values as $key => $value) {
+    $matches = array();
+    if (preg_match("/^term-(\d+)$/", $key, $matches) and $values['term-' . $matches[1]]) {
+      $cvterm_id = $matches[1];
+      $selected[] = chado_generate_var('cvterm', array('cvterm_id' => $cvterm_id));
+    }
+  }
+  return $selected;
+}
+
+/**
+ * Implements an AJAX callback for the tripal_chado_vocab_select_term_form.
+ */
+function tripal_get_term_lookup_form_ajax_callback($form, $form_state) {
+  $field_name = $form_state['storage']['term_match_field'];
+  $delta = $form_state['storage']['term_match_delta'];
+
+  // If this form is in a field then we need to dig a bit deeper to return
+  // the form elements.
+  if ($field_name) {
+    return $form[$field_name]['und'][$delta]['term_match'];
+  }
+  else {
+    return $form['term_match'];
+  }
+}

+ 2 - 2
tripal/includes/TripalBundleUIController.inc

@@ -439,7 +439,7 @@ function tripal_tripal_bundle_form_submit($form, &$form_state) {
       $includes = array(
         module_load_include('inc', 'tripal', 'includes/tripal.bulk_update'),
       );
-      tripal_add_job('Update all aliases', 'tripal', 'tripal_update_all', $args,
+      tripal_add_job('Update all aliases', 'tripal', 'tripal_update_all_urls_and_titles', $args,
         $user->uid, 10, $includes);
     }
     elseif ($trigger == 'Bulk update all aliases'){
@@ -453,7 +453,7 @@ function tripal_tripal_bundle_form_submit($form, &$form_state) {
       $includes = array(
         module_load_include('inc', 'tripal', 'includes/tripal.bulk_update'),
       );
-      tripal_add_job('Update all aliases', 'tripal', 'tripal_update_all', $args,
+      tripal_add_job('Update all aliases', 'tripal', 'tripal_update_all_urls_and_titles', $args,
         $user->uid, 10, $includes);
     }
 

+ 2 - 2
tripal/includes/TripalFields/TripalField.inc

@@ -474,7 +474,7 @@ class TripalField {
    *   An array of the following format:
    *     $entity->{$field_name}['und'][0]['value'] = $value;
    *   where:
-   *     - $entity is the enity object to which this field is attached.
+   *     - $entity is the entity object to which this field is attached.
    *     - $field_name is the name of this field
    *     - 'und' is the language code (in this case 'und' == undefined)
    *     - 0 is the cardinality.  Increment by 1 when more than one item is
@@ -549,7 +549,7 @@ class TripalField {
         'elements' => array(
           'rdfs:label' => array(
             'searchable' => TRUE,
-            'name' => 'scientfic_name',
+            'name' => 'scientific_name',
             'operations' => array('eq', 'ne', 'contains', 'starts'),
             'sortable' => TRUE,
           ),

+ 18 - 20
tripal/includes/tripal.bulk_update.inc

@@ -1,29 +1,23 @@
 <?php
 
 /**
- * Updates all existing url aliases for an entity.
+ * Updates all existing url aliases and titles for an entity.
  *
  * @param $bundle_id
  * @param $update
  * @param $type
  */
-function tripal_update_all($bundle_id, $update, $type) {
+function tripal_update_all_urls_and_titles($bundle_id, $update, $type) {
   // Load all the entity_ids.
   $entity_table = 'chado_'.$bundle_id;
   $entities = db_select($entity_table, 'e')
     ->fields('e', array('entity_id'))
-    ->execute()->fetchAll();
-  $num_entities = count($entities);
+    ->orderBy('entity_id', 'ASC')
+    ->execute();
+  $num_entities = $entities->rowCount();
   // Parse the $update variable for tokens and load those tokens.
   preg_match_all("/\[[^\]]*\]/", $update, $bundle_tokens);
-  // Get the queue so we can add to it.  Use a
-  // descriptive name. It's ok if it doesn't exist yet.
-  $queue = DrupalQueue::get('entityQueue');
-  // Push all the items into the queue, one at a time.
-  // You can push any data in with (arrays, objects, etc).
-  foreach ($entities as $entity) {
-    $queue->createItem($entity);
-  }
+
   $fields = array();
   foreach ($bundle_tokens as $bundle_token) {
     foreach ($bundle_token as $token) {
@@ -32,10 +26,11 @@ function tripal_update_all($bundle_id, $update, $type) {
       $fields[] = $field_array['id'];
     }
   }
-  $i = 0;
+
+  $i = 1;
   // Pull items out one at a time.
-  while ($entity = $queue->claimItem()) {
-    $arg = tripal_load_entity('TripalEntity', [$entity->data->entity_id], FALSE, $fields);
+  while ($entity = $entities->fetchObject()) {
+    $arg = tripal_load_entity('TripalEntity', [$entity->entity_id], FALSE, $fields);
     if ($type == 'alias') {
       if (!empty($arg)) {
         if (is_array($arg)) {
@@ -44,6 +39,7 @@ function tripal_update_all($bundle_id, $update, $type) {
         // Get the entity controller and clear the cache if requested (default).
         $ec = entity_get_controller('TripalEntity');
         $ec->setAlias($ent, $update);
+        $ec->resetCache();
       }
     }
     elseif ($type == 'title') {
@@ -54,14 +50,16 @@ function tripal_update_all($bundle_id, $update, $type) {
 
         $ec = entity_get_controller('TripalEntity');
         $ec->setTitle($ent, $update);
+        $ec->resetCache();
       }
     }
-    $i++;
     // Check if 50 items have been updated, if so print message.
-    if ($i < $num_entities) {
-      print $i . "/" . $num_entities . " entities have been updated.\r";
+    if ($i <= $num_entities) {
+      $mem = number_format(memory_get_usage());
+      print $i . "/" . $num_entities . " entities have been updated. Memory usage: $mem bytes.\r";
     }
-    // Good, we succeeded.  Delete the item as it is no longer needed.
-    $queue->deleteItem($entity);
+    $i++;
   }
+
+  print "\nDone.";
 }

+ 1 - 0
tripal/includes/tripal.fields.inc

@@ -338,6 +338,7 @@ function tripal_form_field_ui_field_overview_form_submit($form, &$form_state) {
       $type = $form_values['_add_new_field']['type'];
       if (tripal_load_include_field_class($type)) {
         $module = $type::$module;
+        dpm($module);
         $function = $module . '_bundle_create_user_field';
         $bundle = tripal_load_bundle_entity(array('name' => $form['#bundle']));
         $field_name = $form_values['_add_new_field']['field_name'];

+ 2 - 2
tripal/includes/tripal.importer.inc

@@ -191,7 +191,7 @@ function tripal_get_importer_form_submit($form, &$form_state) {
   }
   try {
 
-    // Now allow the loader to do it's own submit if needed.
+    // Now allow the loader to do its own submit if needed.
     $importer = new $class();
     $importer->formSubmit($form, $form_state);
     // If the formSubmit made changes to the $form_state we need to update the
@@ -213,4 +213,4 @@ function tripal_get_importer_form_submit($form, &$form_state) {
   catch (Exception $e) {
     drupal_set_message('Cannot submit import: ' . $e->getMessage(), 'error');
   }
-}
+}

+ 5 - 1
tripal/includes/tripal.upload.inc

@@ -118,6 +118,7 @@ function tripal_file_upload_merge($filename, $type, $user_dir) {
       $status = 'failed';
       $message = 'Cannot open merged file: ' . $merge_file . '.';
     }
+    flock($merge_fh, LOCK_UN);
     fclose($merge_fh);
   }
 
@@ -234,6 +235,7 @@ function tripal_file_upload_put($filename, $chunk, $user_dir) {
       while ($data = fread($putdata, 1024)) {
         fwrite($fh, $data);
       }
+      flock($fh, LOCK_UN);
       fclose($fh);
     }
   }
@@ -271,6 +273,7 @@ function tripal_file_upload_read_log($temp_dir) {
       }
       $log = unserialize($contents);
     }
+    flock($fh, LOCK_UN);
     fclose($fh);
   }
   if (!is_array($log)) {
@@ -309,5 +312,6 @@ function tripal_file_upoad_write_log($temp_dir, $log) {
   if ($fh and flock($fh, LOCK_EX)) {
     fwrite($fh, serialize($log));
   }
+  flock($fh, LOCK_UN);
   fclose($fh);
-}
+}

+ 1 - 1
tripal/theme/js/TripalUploadFile.js

@@ -13,7 +13,7 @@
     this.file = file;
     this.options = options;
     this.file_size = file.size;
-    this.chunk_size = (1024 * 2000); // 2024MB
+    this.chunk_size = (1024 * 2000); 
     this.total_chunks = ((this.file.size % this.chunk_size == 0) ? Math.floor(this.file.size / this.chunk_size) : Math.floor(this.file.size / this.chunk_size) + 1); 
     this.curr_chunk = 0;
     this.status = 'pending';

+ 1 - 1
tripal_bulk_loader/includes/tripal_bulk_loader.loader.inc

@@ -194,7 +194,7 @@ function tripal_bulk_loader_load_data($nid, $job_id) {
       $tables[$record_array['table']] = $record_array['table'];
     }
 
-    // iterate through each of the fiels for the current record and
+    // iterate through each of the fields for the current record and
     // set the default_data array
     foreach ($record_array['fields'] as $field_index => $field_array) {
 

+ 1 - 1
tripal_chado/api/modules/tripal_chado.analysis.api.inc

@@ -147,7 +147,7 @@ function tripal_get_analysis_select_options($syncd_only = TRUE) {
         INNER JOIN {analysis} A ON A.analysis_id = CO.analysis_id
       ORDER BY A.name
     ";
-    $orgs = chado_query($sql);
+    $analyses = chado_query($sql);
 
     // iterate through the analyses and build an array of those that are synced
     foreach ($analyses as $analysis) {

+ 37 - 9
tripal_chado/api/modules/tripal_chado.cv.api.inc

@@ -419,7 +419,7 @@ function tripal_update_cvtermpath($cv_id, $job_id = NULL){
  *   The controlled vocabulary ID from the cv table of Chado (i.e. cv.cv_id).
  */
 function tripal_update_cvtermpath_root_loop($rootid, $cvid, &$roots) {
-  
+
   // Get's the cvterm record for this "root".
   $ttype = db_select('cvterm', 'cv')
           ->fields('cv', array('cvterm_id'));
@@ -485,13 +485,13 @@ function tripal_update_cvtermpath_root_loop($rootid, $cvid, &$roots) {
  * @param $possible_loop
  *    A boolean flag.
  * @param $matched_row
- *    An array of rows that are currently in the cvtermpath table that match the 
+ *    An array of rows that are currently in the cvtermpath table that match the
  *    build_id of the current term trying to be written to the table
  * @param $possible_start_of_ loop
- *    The array of the possible loop item between the current child and the origin. 
+ *    The array of the possible loop item between the current child and the origin.
  *    Each element in the array is an associative array with the keys:
  *     - cvid : $cv_id
- *     - subject_id: 
+ *     - subject_id:
  *     - child_id : $child_id,
  *     - type_id : $type_id,
  *     - depth : $depth,
@@ -529,7 +529,7 @@ function tripal_update_cvtermpath_loop(
         array(':cvtermpath_id' => $cvtermpath_id)
       );
       $next_row = $next_row->fetchObject();
-      
+
       // If the next row matches the values passed we can't rule out a loop.
       if (($next_row->type_id === $type_id) &&
           ($next_row->subject_id === $child_id) &&
@@ -641,13 +641,13 @@ function tripal_update_cvtermpath_loop(
  * @param $possible_loop
  *    A boolean flag.
  * @param $matched_row
- *    An array of rows that are currently in the cvtermpath table that match the 
+ *    An array of rows that are currently in the cvtermpath table that match the
  *    build_id of the current term trying to be written to the table
  * @param $possible_start_of_ loop
- *    The array of the possible loop item between the current child and the origin. 
+ *    The array of the possible loop item between the current child and the origin.
  *    Each element in the array is an associative array with the keys:
  *     - cvid : $cv_id
- *     - subject_id: 
+ *     - subject_id:
  *     - child_id : $child_id,
  *     - type_id : $type_id,
  *     - depth : $depth,
@@ -730,7 +730,7 @@ function tripal_update_cvtermpath_loop_increment(
           }
         }
       }
-    
+
       $query = db_insert('cvtermpath')
         ->fields([
           'object_id' => $origin,
@@ -1373,7 +1373,35 @@ function tripal_get_obo($values) {
   }
   return $query->execute()->fetchObject();
 }
+/**
+ * This function is intended to be used in autocomplete forms.
+ *
+ * This function searches for a matching controlled vobulary name.
+ *
+ * @param $string
+ * The string to search for
+ *
+ * @return
+ * A json array of terms that begin with the provided string
+ *
+ * @ingroup tripal_chado_api
+ */
+function tripal_autocomplete_cv($string = '') {
+  $sql = "
+    SELECT CV.cv_id, CV.name
+    FROM {cv} CV
+    WHERE lower(CV.name) like lower(:name)
+    ORDER by CV.name
+    LIMIT 25 OFFSET 0
+  ";
+  $results = chado_query($sql, array(':name' => $string . '%'));
+  $items = array();
+  foreach ($results as $cv) {
+    $items[$cv->name] = $cv->name;
+  }
 
+  drupal_json_output($items);
+}
 /**
  * This function is intended to be used in autocomplete forms
  * for searching for CV terms that begin with the provided string

+ 3 - 3
tripal_chado/api/modules/tripal_chado.organism.api.inc

@@ -154,7 +154,7 @@ function tripal_get_organism_scientific_name($organism) {
     }
 
     if ($rank) {
-      $rank = tripal_abbreviate_infraspeicifc_rank($rank);
+      $rank = tripal_abbreviate_infraspecific_rank($rank);
       $name .= ' ' . $rank . ' ' . $organism->infraspecific_name;
     }
     else if ($organism->infraspecific_name) {
@@ -313,7 +313,7 @@ function tripal_autocomplete_organism($text) {
  * @return
  *   The proper abbreviation for the rank.
  */
-function tripal_abbreviate_infraspeicifc_rank($rank) {
+function tripal_abbreviate_infraspecific_rank($rank) {
   $abb = '';
   switch($rank) {
     case 'no_rank':
@@ -344,4 +344,4 @@ function tripal_abbreviate_infraspeicifc_rank($rank) {
       $abb = $rank;
   }
   return $abb;
-}
+}

+ 0 - 4
tripal_chado/api/modules/tripal_chado.phylotree.api.inc

@@ -66,10 +66,6 @@ function tripal_validate_phylotree($val_type, &$options, &$errors, &$warnings) {
       $errors['description'] = t('Please provide a description for this tree.');
       return FALSE;
     }
-    if (!array_key_exists('analysis', $options) and !array_key_exists('analysis_id', $options)) {
-      $errors['analysis'] = t('Please provide an analysis or analysis_id for this tree.');
-      return FALSE;
-    }
     if (!array_key_exists('tree_file', $options)) {
       $errors['tree_file'] = t('Please provide either the full path to the tree_file or a Drupal managed file ID number.');
       return FALSE;

+ 2 - 2
tripal_chado/api/tripal_chado.api.inc

@@ -180,9 +180,9 @@ function tripal_chado_publish_records($values, $job_id = NULL) {
       "If the load fails or is terminated prematurely then the entire set of \n" .
       "is rolled back with no changes to the database\n\n";
 
+  $i = 0;
   printf("%d of %d records. (%0.2f%%) Memory: %s bytes\r", $i, $count, 0, number_format(memory_get_usage()));
   try {
-    $i = 0;
     while($record = $records->fetchObject()) {
 
       // update the job status every interval
@@ -200,7 +200,7 @@ function tripal_chado_publish_records($values, $job_id = NULL) {
         'bundle' => $bundle_name,
         'term_id' => $bundle->term_id,
         // Add in the Chado details for when the hook_entity_create()
-        // is called and our tripal_cahdo_entity_create() implementation
+        // is called and our tripal_chado_entity_create() implementation
         // can deal with it.
         'chado_record' => chado_generate_var($table, array($pkey_field => $record_id)),
         'chado_record_id' => $record_id,

+ 1 - 1
tripal_chado/api/tripal_chado.entity.api.inc

@@ -3,7 +3,7 @@
  * Retreive the entity_id assigned to a given record_id and bundle.
  *
  * @param $bundle
- *   A bundle object (as retreieved from tripal_load_bundle_entity().
+ *   A bundle object (as retrieved from tripal_load_bundle_entity().
  * @param $record_id
  *   The ID of the record in the Chado table. The record must belong to
  *   the table to which the bundle is associated in chado.

+ 41 - 0
tripal_chado/api/tripal_chado.migrate.api.inc

@@ -0,0 +1,41 @@
+<?php 
+
+/**
+ * Migrate Tripal content types
+ * 
+ * Migrate specified Tripal content type and publish all its content. The content type 
+ * will be created if it does not already exist.
+ * 
+ * @param $type
+ *   A type array specifying the vocabular, accession, term_name, and chado data_table
+ *   e.g.
+ *     $type = array(
+ *       'vocabulary' => 'OBI',
+ *       'accession' => '0100026',
+ *       'term_name' => 'organism',
+ *       'storage_args' => array (
+ *         'data_table' => $table
+ *       )
+ *     )
+ * 
+ */
+function tripal_chado_migrate_tripal_content_type($type = array()) {
+    
+  // Check if the term already exists
+  $term = tripal_load_term_entity($type);
+  // If term doesn't exist, create a new bundle for this term
+  if (!$term) {
+    print("Creating bundle for term '" . $type['term_name'] . "'...\n");
+    $success = tripal_create_bundle($type);
+    $term = tripal_load_term_entity($type);
+  }
+  // Create bundle name
+  $bundle_name = 'bio_data_' . $term->id;
+    
+  // Publish records for the bundle
+  $value = array(
+    'sync_node' => 1,
+    'bundle_name' => $bundle_name
+  );
+  tripal_chado_publish_records($value);
+}

+ 1 - 1
tripal_chado/api/tripal_chado.query.api.inc

@@ -1923,7 +1923,7 @@ function chado_schema_get_foreign_key($table_desc, $field, $values, $options = N
        key referrs to (<foreign table>) and then implement
        hook_chado_chado_schema_v<version>_<foreign table>(). See
        tripal_chado_chado_v1_2_schema_feature for an example. Chado version: $version");
-    tripal_report_error('tripal_chado', $message);
+    tripal_report_error('tripal_chado', TRIPAL_ERROR, $message);
     drupal_set_message(check_plain($message), 'error');
   }
 

+ 1 - 1
tripal_chado/api/tripal_chado.schema.api.inc

@@ -560,7 +560,7 @@ function chado_get_base_tables() {
 
   // Initialize the base tables with those tables that are missing a type.
   // Ideally they should have a type, but that's for a future version of Chado.
-  $base_tables = array('organism', 'project', 'analysis', 'biomaterial');
+  $base_tables = array('organism', 'project', 'analysis', 'biomaterial', 'eimage');
 
   // We'll use the cvterm table to guide which tables are base tables. Typically
   // base tables (with a few exceptions) all have a type.  Iterate through the

+ 6 - 3
tripal_chado/api/tripal_chado.variables.api.inc

@@ -202,7 +202,8 @@ function chado_generate_var($table, $values, $base_options = array()) {
   foreach ($fields_to_remove as $field_name => $criteria) {
 
     //replace <field_name> with the current field name
-    $criteria = preg_replace('/<field_name> /', addslashes($field_name), $criteria);
+    $field_name_safe = preg_replace("/\'\"\\\/", '\\1', $field_name);
+    $criteria = preg_replace('/<field_name> /', $field_name_safe, $criteria);
     // if field_value needed we can't deal with this field yet
     if (preg_match('/<field_value> /', $criteria)) {
       break;
@@ -255,7 +256,8 @@ function chado_generate_var($table, $values, $base_options = array()) {
 
       // Do any processing needed on the php criteria
       //replace <field_name>  with the current field name
-      $criteria = preg_replace('/<field_name> /', addslashes($field_name), $criteria);
+      $field_name_safe = preg_replace('/\'|"|\\\/', '\\1', $field_name);
+      $criteria = preg_replace('/<field_name> /', $field_name_safe, $criteria);
       foreach ($field_types[$field_type] as $field_name) {
         // if field_value needed we can't deal with this field yet
         if (preg_match('/<field_value>/', $criteria)) {
@@ -333,7 +335,8 @@ function chado_generate_var($table, $values, $base_options = array()) {
         }
 
         // replace <field_value> with the actual value of the field from the query
-        $criteria = preg_replace('/<field_value>/', addslashes($object->{$field_name}), $criteria);
+        $field_name_safe = preg_replace('/\'|"|\\\/', '\\1', $object->{$field_name});
+        $criteria = preg_replace('/<field_value>/', $field_name_safe, $criteria);
 
         // evaluate the criteria, if TRUE is returned then exclude the field
         // excluded fields can be expanded later by calling

+ 1 - 1
tripal_chado/includes/TripalFields/ChadoField.inc

@@ -8,7 +8,7 @@ class ChadoField extends TripalField {
   // The default description for this field.
   public static $default_description = 'The generic base class for all Chado fields. Replace this text as appropriate for the child implementation.';
 
-  // A list of global settings. These can be accessed witihn the
+  // A list of global settings. These can be accessed within the
   // globalSettingsForm.  When the globalSettingsForm is submitted then
   // Drupal will automatically change these settings for all fields.
   // Once instances exist for a field type then these settings cannot be

+ 0 - 1
tripal_chado/includes/TripalFields/chado_linker__contact/chado_linker__contact.inc

@@ -138,7 +138,6 @@ class chado_linker__contact extends ChadoField {
     $fkey_lcolumn = key($schema['foreign keys'][$base_table]['columns']);
     $fkey_rcolumn = $schema['foreign keys'][$base_table]['columns'][$fkey_lcolumn];
 
-
     // Set some defaults for the empty record.
     $entity->{$field_name}['und'][0] = array(
       'value' => array(),

+ 19 - 18
tripal_chado/includes/TripalFields/chado_linker__contact/chado_linker__contact_formatter.inc

@@ -49,27 +49,28 @@ class chado_linker__contact_formatter extends ChadoFieldFormatter {
       }
       $rows[] = array($contact_name, $description, $type);
     }
-    $table = array(
-      'header' => $headers,
-      'rows' => $rows,
-      'attributes' => array(
-        'id' => 'tripal_linker-table-contact-object',
-        'class' => 'tripal-data-table'
-      ),
-      'sticky' => FALSE,
-      'caption' => "",
-      'colgroups' => array(),
-      'empty' => 'There are no contacts available.',
-    );
-    $content = theme_table($table);
 
+    $content = '';
     if (count($items) > 0) {
-      // once we have our table array structure defined, we call Drupal's theme_table()
-      // function to generate the table.
-      $element[0] = array(
-        '#type' => 'markup',
-        '#markup' => $content,
+      $table = array(
+        'header' => $headers,
+        'rows' => $rows,
+        'attributes' => array(
+          'id' => 'tripal_linker-table-contact-object',
+          'class' => 'tripal-data-table'
+        ),
+        'sticky' => FALSE,
+        'caption' => "",
+        'colgroups' => array(),
+        'empty' => 'There are no contacts available.',
       );
+      $content = theme_table($table);
     }
+
+    $element[0] = array(
+      // We create a render array to produce the desired markup,
+      '#type' => 'markup',
+      '#markup' => $content,
+    );
   }
 }

+ 3 - 0
tripal_chado/includes/TripalFields/chado_linker__contact/chado_linker__contact_widget.inc

@@ -24,7 +24,10 @@ class chado_linker__contact_widget extends ChadoFieldWidget {
     // Get the FK column that links to the base table.
     $schema = chado_get_schema($field_table);
     $pkey = $schema['primary key'][0];
+
     $fkey_lcolumn = key($schema['foreign keys'][$base_table]['columns']);
+//    $fkey_lcolumn = key($schema['foreign keys']['protocol']['columns']);
+
     $fkey_rcolumn = $schema['foreign keys'][$base_table]['columns'][$fkey_lcolumn];
 
     // Get the field defaults.

+ 12 - 10
tripal_chado/includes/TripalFields/local__contact/local__contact.inc

@@ -137,16 +137,18 @@ class local__contact extends ChadoField {
     if ($field_table == 'biomaterial') {
       if ($record) {
         $contact = $record->biosourceprovider_id;
-        $entity->{$field_name}['und'][0] = array(
-          'value' => array(
-            $type_term => $contact->type_id ? $contact->type_id->name : '',
-            $name_term => $contact->name,
-            $description_term => $contact->description,
-          ),
-          $entity->{$field_name}['und'][0]['chado-biomaterial__biosourceprovider_id'] = $contact->contact_id,
-        );
-        if (property_exists($contact, 'entity_id')) {
-          $entity->{$field_name}['und'][0]['value']['entity'] = 'TripalEntity:' . $contact->entity_id;
+        if ($contact) {
+          $entity->{$field_name}['und'][0] = array(
+            'value' => array(
+              $type_term => $contact->type_id ? $contact->type_id->name : '',
+              $name_term => $contact->name,
+              $description_term => $contact->description,
+            ),
+            $entity->{$field_name}['und'][0]['chado-biomaterial__biosourceprovider_id'] = $contact->contact_id,
+          );
+          if (property_exists($contact, 'entity_id')) {
+            $entity->{$field_name}['und'][0]['value']['entity'] = 'TripalEntity:' . $contact->entity_id;
+          }
         }
       }
     };

+ 3 - 3
tripal_chado/includes/TripalFields/local__source_data/local__source_data_formatter.inc

@@ -21,13 +21,13 @@ class local__source_data_formatter extends ChadoFieldFormatter {
     if ($items[0]['value']) {
       $content = "<dl class=\"tripal-dl\">";
       if (!empty($items[0]['value'][$sourcename_term])) {
-        $content .= "<dt>Source Name</dt><dd>: " . $items[0]['value']['schema:name'] . " </dd>";
+        $content .= "<dt>Source Name</dt><dd>: " . $items[0]['value'][$sourcename_term] . " </dd>";
       }
       if (!empty($items[0]['value'][$sourceversion_term])) {
-        $content .= "<dt>Source Version</dt><dd>: " . $items[0]['value']['IAO:0000129'] . " </dd>";
+        $content .= "<dt>Source Version</dt><dd>: " . $items[0]['value'][$sourceversion_term] . " </dd>";
       }
       if (!empty($items[0]['value'][$sourceuri_term])) {
-        $content .= "<dt>Source URI</dt><dd>: " . l($items[0]['value']['data:1047'], $items[0]['value']['data:1047'], array('attributes' => array('target' => '_blank'))) . " </dd>";
+        $content .= "<dt>Source URI</dt><dd>: " . l($items[0]['value'][$sourceuri_term], $items[0]['value'][$sourceuri_term], array('attributes' => array('target' => '_blank'))) . " </dd>";
       }
       $content .= "</dl>";
     }

+ 1 - 1
tripal_chado/includes/TripalFields/obi__organism/obi__organism.inc

@@ -126,7 +126,7 @@ class obi__organism extends ChadoField {
         $genus_term => $organism->genus,
         $species_term => $organism->species,
       );
-      // The infraspecific fiels were introdcued in Chado v1.3.
+      // The infraspecific fields were introduced in Chado v1.3.
       if (property_exists($organism, 'infraspecific_name')) {
         $entity->{$field_name}['und'][0]['value'][$infraspecific_type_term] = NULL;
         $entity->{$field_name}['und'][0]['value'][$infraspecific_name_term] = $organism->infraspecific_name;

+ 80 - 2
tripal_chado/includes/TripalFields/schema__additional_type/schema__additional_type.inc

@@ -97,9 +97,87 @@ class schema__additional_type extends ChadoField {
 
     // Set some defaults for the empty record.
     $entity->{$field_name}['und'][0] = array(
-      'value' => $record->type_id->name,
-      'chado-' . $field_table . '__type_id' => $record->type_id->cvterm_id,
+      'value' => '',
+      'chado-' . $field_table . '__type_id' => '',
     );
+
+    if ($record->type_id) {
+      $entity->{$field_name}['und'][0] = array(
+        'value' => $record->type_id->name,
+        'chado-' . $field_table . '__type_id' => $record->type_id->cvterm_id,
+      );
+    }
+  }
+
+  /**
+   * @see ChadoField::instanceSettingsForm()
+   */
+  public function instanceSettingsForm(){
+    $element = parent::instanceSettingsForm();
+    $settings = $this->instance['settings'];
+
+    $element['vocabulary']  = array(
+      '#title'  => t('Enforce Vocabulary'),
+      '#type' => 'textfield',
+      '#description' => t('Optional. Enter the name of the vocabulary that must be used when the user selects a term for the additional type. If no value is provided then the user can select from any term available on the site.') ,
+      '#default_value' => $settings['vocabulary'],
+      '#autocomplete_path' => "admin/tripal/storage/chado/auto_name/cv",
+    );
+
+    $element['parent_term']  = array(
+      '#title'  => t('Enforce Parent Term'),
+      '#type' => 'textfield',
+      '#description' => t('Optional. If a vocabulary is heirarchical and if the user should be restricted to a set of terms below a given parent term, then enter the parent term here. The term should be in the form {db}:{accession} where {db} is the short name for the database (e.g. GO, SO, TPUB, TContact) and {accession} is the unique identifier for that term in the vocabulary (e.g. TContact:0000001).') ,
+      '#default_value' => $settings['parent_term'],
+    );
+
+    return $element;
   }
 
+  /**
+   * @see TripalField::settingsFormValidate()
+   */
+  public function settingsFormValidate($form, &$form_state) {
+    $element = parent::settingsFormValidate($form, $form_state);
+
+    $values = $form_state['values']['instance']['settings'];
+
+    // Make sure te vocabulary and parent term exist
+    $vocabulary = $values['vocabulary'];
+    $parent_term = $values['parent_term'];
+
+    $good_vocab = FALSE;
+    if ($vocabulary) {
+      $sql = "SELECT cv_id FROM {cv} WHERE name = :name";
+      $results = chado_query($sql, array(':name' => $vocabulary));
+      $cv_id = $results->fetchField();
+      if (!$cv_id) {
+        form_set_error('instance][settings][vocabulary', 'Invalid vocabulary');
+      }
+      else {
+        $good_vocab =  TRUE;
+      }
+    }
+
+    if ($parent_term and $good_vocab) {
+      $matches = array();
+      if (preg_match('/^(.+):(.+)$/', $parent_term, $matches)) {
+        $db = $matches[1];
+        $accession = $matches[2];
+        $values = array(
+          'db_id' => array(
+            'name' => $db,
+          ),
+          'accession' => $accession,
+        );
+        $records = chado_select_record('dbxref', array('dbxref_id'), $values);
+        if (count($records) == 0) {
+          form_set_error('instance][settings][parent_term', 'The specified parent term does not exist on this site. Please check the entry.');
+        }
+      }
+      else {
+        form_set_error('instance][settings][parent_term', 'Please provide a parent term in the correct format.');
+      }
+    }
+  }
 }

+ 42 - 14
tripal_chado/includes/TripalFields/schema__additional_type/schema__additional_type_widget.inc

@@ -22,7 +22,6 @@ class schema__additional_type_widget extends ChadoFieldWidget {
     $vocabulary = $this->instance['settings']['vocabulary'];
     $parent_term = $this->instance['settings']['parent_term'];
 
-    $record_id = $element['#entity']->chado_record_id;
     $value = '';
     $type_id = '';
 
@@ -40,9 +39,6 @@ class schema__additional_type_widget extends ChadoFieldWidget {
       '#value' => $value,
     );
 
-    If ($field_table == 'pub' && empty($vocabulary)){
-      $vocabulary = 'tripal_pub';
-    };
     // If a parent_term is provided then use that to get the options
     $options = array();
     $options[] = 'Select a type';
@@ -55,10 +51,13 @@ class schema__additional_type_widget extends ChadoFieldWidget {
           FROM {cvtermpath} CVTP
             INNER JOIN {cvterm} CVTS ON CVTP.subject_id = CVTS.cvterm_id
             INNER JOIN {cvterm} CVTO ON CVTP.object_id = CVTO.cvterm_id
+            INNER JOIN {cvterm} CVTT ON CVTP.type_id = CVTT.cvterm_id
             INNER JOIN {dbxref} DBXO ON DBXO.dbxref_id = CVTO.dbxref_id
             INNER JOIN {db} DBO      ON DBO.db_id = DBXO.db_id
           WHERE
             DBO.name = :vocabulary AND DBXO.accession = :accession AND
+            (CVTT.name = 'is a' OR CVTT.name = 'is_a') AND
+            CVTS.name != CVTO.name AND
             NOT CVTS.is_obsolete = 1
           ORDER BY CVTS.name ASC
        ";
@@ -72,15 +71,31 @@ class schema__additional_type_widget extends ChadoFieldWidget {
       $cv = tripal_get_cv(array('name' => $vocabulary));
       $options = tripal_get_cvterm_select_options($cv->cv_id);
     }
-    $widget['chado-' . $field_table . '__type_id'] = array(
-      '#type' => 'select',
-      '#options' => $options,
-      '#title' => $element['#title'],
-      '#description' => $element['#description'],
-      '#weight' => isset($element['#weight']) ? $element['#weight'] : 0,
-      '#default_value' => $type_id,
-      '#delta' => $delta,
-    );
+    // If no vocabulary or parent term are provided then just give a generic
+    // term finder.
+    else {
+      $cvterm = NULL;
+      $default_name = '';
+      if ($type_id) {
+        $cvterm = chado_generate_var('cvterm', array('cvterm_id' => $type_id));
+        $default_name = $cvterm->name;
+      }
+      tripal_get_term_lookup_form($widget, $form_state, $default_name,
+          $element['#title'], $element['#description'], $element['#required'],
+          $field_name, $delta);
+    }
+    if ($vocabulary) {
+      $widget['chado-' . $field_table . '__type_id'] = array(
+        '#type' => 'select',
+        '#options' => $options,
+        '#title' => $element['#title'],
+        '#description' => $element['#description'],
+        '#weight' => isset($element['#weight']) ? $element['#weight'] : 0,
+        '#default_value' => $type_id,
+        '#required' => $element['#required'],
+        '#delta' => $delta,
+      );
+    }
   }
 
   /**
@@ -97,7 +112,20 @@ class schema__additional_type_widget extends ChadoFieldWidget {
     $vocabulary = $this->instance['settings']['vocabulary'];
     $parent_term = $this->instance['settings']['parent_term'];
 
-    $type_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__type_id'];
+    // Get the vocabulary term.
+    $type_id = '';
+    if ($vocabulary) {
+      $type_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__type_id'];
+    }
+    else {
+      $selected = tripal_get_term_lookup_form_result($form, $form_state, $field_name, $delta);
+      if (count($selected) == 1) {
+        $type_id = $selected[0]->cvterm_id;
+      }
+      if (count($selected) > 1) {
+        form_set_error($field_name . '[' . $langcode . '][' . $delta . '][term_match][term_name', 'Please select only one vocabulary term.');
+      }
+    }
 
     if (!$type_id) {
       $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__type_id'] = '__NULL__';

+ 1 - 1
tripal_chado/includes/TripalFields/schema__publication/schema__publication_formatter.inc

@@ -19,7 +19,7 @@ class schema__publication_formatter extends ChadoFieldFormatter {
 
       $title = isset($item['value']['TPUB:0000039']) ? $item['value']['TPUB:0000039'] : '';
       $citation = isset($item['value']['TPUB:0000003']) ? $item['value']['TPUB:0000003'] : '';
-      $entity = array_key_exists('entity', $item['value']) ? $item['value']['entity'] : '';
+      $entity = (is_array($item['value']) && array_key_exists('entity', $item['value'])) ? $item['value']['entity'] : '';
       if ($entity) {
         list($entity_type, $entity_id) = explode(':', $entity);
         $new_title = l($title, 'bio_data/' . $entity_id);

+ 149 - 0
tripal_chado/includes/TripalFields/sep__protocol/sep__protocol.inc

@@ -0,0 +1,149 @@
+<?php
+
+/**
+ * @class
+ * Purpose: Provide a field for Protocol (typically the protocol_id column of a
+ *   Chado table).
+ *
+ * Data:
+ * Assumptions:
+ */
+class sep__protocol extends ChadoField {
+
+  // The default label for this field.
+  public static $default_label = 'Protocol';
+
+  // The default description for this field.
+  public static $default_description = 'The protocol followed to generate this resource.';
+
+  // The default widget for this field.
+  public static $default_widget = 'sep__protocol_widget';
+
+  // The default formatter for this field.
+  public static $default_formatter = 'sep__protocol_formatter';
+
+  // The module that manages this field.
+  public static $module = 'tripal_chado';
+
+  // A list of global settings. These can be accessed within the
+  // globalSettingsForm.  When the globalSettingsForm is submitted then
+  // Drupal will automatically change these settings for all fields.
+  // Once instances exist for a field type then these settings cannot be
+  // changed.
+  public static $default_settings = [
+    'storage' => 'field_chado_storage',
+    // It is expected that all fields set a 'value' in the load() function.
+    // In many cases, the value may be an associative array of key/value pairs.
+    // In order for Tripal to provide context for all data, the keys should
+    // be a controlled vocabulary term (e.g. rdfs:type). Keys in the load()
+    // function that are supported by the query() function should be
+    // listed here.
+    'searchable_keys' => [],
+  ];
+
+  // Provide a list of instance specific settings. These can be access within
+  // the instanceSettingsForm.  When the instanceSettingsForm is submitted
+  // then Drupal with automatically change these settings for the instance.
+  // It is recommended to put settings at the instance level whenever possible.
+  // If you override this variable in a child class be sure to replicate the
+  // term_name, term_vocab, term_accession and term_fixed keys as these are
+  // required for all TripalFields.
+  public static $default_instance_settings = [
+    // The DATABASE name, as it appears in chado.db.  This also builds the link-out url.  In most cases this will simply be the CV name.  In some cases (EDAM) this will be the SUBONTOLOGY.
+    'term_vocabulary' => 'sep',
+    // The name of the term.
+    'term_name' => 'protocol',
+    // The unique ID (i.e. accession) of the term.
+    'term_accession' => '00101',
+    // Set to TRUE if the site admin is not allowed to change the term
+    // type, otherwise the admin can change the term mapped to a field.
+    'term_fixed' => FALSE,
+    // Indicates if this field should be automatically attached to display
+    // or web services or if this field should be loaded separately. This
+    // is convenient for speed.  Fields that are slow should for loading
+    // should have auto_attach set to FALSE so tha their values can be
+    // attached asynchronously.
+    'auto_attach' => FALSE,
+  ];
+
+  // A boolean specifying that users should not be allowed to create
+  // fields and instances of this field type through the UI. Such
+  // fields can only be created programmatically with field_create_field()
+  // and field_create_instance().
+  public static $no_ui = FALSE;
+
+  // A boolean specifying that the field will not contain any data. This
+  // should exclude the field from web services or downloads.  An example
+  // could be a quick search field that appears on the page that redirects
+  // the user but otherwise provides no data.
+  public static $no_data = FALSE;
+
+  /**
+   * Loads the field values from the underlying data store.
+   *
+   * @param $entity
+   *
+   * @return
+   *   An array of the following format:
+   *     $entity->{$field_name}['und'][0]['value'] = $value;
+   *   where:
+   *     - $entity is the entity object to which this field is attached.
+   *     - $field_name is the name of this field
+   *     - 'und' is the language code (in this case 'und' == undefined)
+   *     - 0 is the cardinality.  Increment by 1 when more than one item is
+   *       available.
+   *     - 'value' is the key indicating the value of this field. It should
+   *       always be set.  The value of the 'value' key will be the contents
+   *       used for web services and for downloadable content.  The value
+   *       should be of the follow format types: 1) A single value (text,
+   *       numeric, etc.) 2) An array of key value pair. 3) If multiple entries
+   *       then cardinality should incremented and format types 1 and 2 should
+   *       be used for each item.
+   *   The array may contain as many other keys at the same level as 'value'
+   *   but those keys are for internal field use and are not considered the
+   *   value of the field.
+   *
+   *
+   */
+  public function load($entity) {
+
+    parent::load($entity);
+
+
+    $record = $entity->chado_record;
+    $settings = $this->instance['settings'];
+
+
+    $field_name = $this->field['field_name'];
+    $field_type = $this->field['type'];
+    $field_table = $this->instance['settings']['chado_table'];
+    $field_column = $this->instance['settings']['chado_column'];
+    $linker_field = 'chado-' . $field_table . '__protocol_id';
+
+    // Set some defaults for the empty record.
+    $entity->{$field_name}['und'][0] = [
+      'value' => [],
+    ];
+
+    if (!$record->protocol_id->protocol_id) {
+      return;
+    }
+
+    $protocol_id = $record->protocol_id->protocol_id;
+    $protocol_name = $record->protocol_id->name;
+
+    $entity_id = $record->entity_id;
+
+    $entity->{$field_name}['und'][0]['value'] = [
+      "protocol_id" => $protocol_id,
+      "protocol_name" => $protocol_name,
+      "entity_id" => $entity_id,
+    ];
+
+    // Is there a published entity for this protocol?
+    if (property_exists($record->{$field_column}, 'entity_id')) {
+      $entity->{$field_name}['und'][0]['value']['entity_id'] = 'TripalEntity:' . $record->{$field_column}->entity_id;
+    }
+  }
+
+}

+ 133 - 0
tripal_chado/includes/TripalFields/sep__protocol/sep__protocol_formatter.inc

@@ -0,0 +1,133 @@
+<?php
+
+/**
+ * @class
+ * Purpose:
+ *
+ * Display:
+ * Configuration:
+ */
+class sep__protocol_formatter extends ChadoFieldFormatter {
+
+  // The default label for this field.
+  public static $default_label = 'Protocol';
+
+  // The list of field types for which this formatter is appropriate.
+  public static $field_types = ['sep__protocol'];
+
+  // The list of default settings for this formatter.
+  public static $default_settings = [
+    'setting1' => 'default_value',
+  ];
+
+  /**
+   * Provides the field's setting form.
+   *
+   * This function corresponds to the hook_field_formatter_settings_form()
+   * function of the Drupal Field API.
+   *
+   * The settings form appears on the 'Manage Display' page of the content
+   * type administration page. This function provides the form that will
+   * appear on that page.
+   *
+   * To add a validate function, please create a static function in the
+   * implementing class, and indicate that this function should be used
+   * in the form array that is returned by this function.
+   *
+   * This form will not be displayed if the formatter_settings_summary()
+   * function does not return anything.
+   *
+   * param $field
+   *   The field structure being configured.
+   * param $instance
+   *   The instance structure being configured.
+   * param $view_mode
+   *   The view mode being configured.
+   * param $form
+   *   The (entire) configuration form array, which will usually have no use
+   *   here.  Typically for reference only.
+   * param $form_state
+   *   The form state of the (entire) configuration form.
+   *
+   * @return
+   *   A Drupal Form array containing the settings form for this field.
+   */
+  public function settingsForm($view_mode, $form, &$form_state) {
+
+  }
+
+  /**
+   *  Provides the display for a field
+   *
+   * This function corresponds to the hook_field_formatter_view()
+   * function of the Drupal Field API.
+   *
+   *  This function provides the display for a field when it is viewed on
+   *  the web page.  The content returned by the formatter should only include
+   *  what is present in the $items[$delta]['values] array. This way, the
+   *  contents that are displayed on the page, via webservices and downloaded
+   *  into a CSV file will always be identical.  The view need not show all
+   *  of the data in the 'values' array.
+   *
+   * @param $element
+   * @param $entity_type
+   * @param $entity
+   * @param $langcode
+   * @param $items
+   * @param $display
+   *
+   * @return
+   *    An element array compatible with that returned by the
+   *    hook_field_formatter_view() function.
+   */
+  public function view(&$element, $entity_type, $entity, $langcode, $items, $display) {
+    if (count($items) > 0) {
+      $protocol_id = $items[0]['value']["protocol_id"];
+      $protocol_name = $items[0]['value']["protocol_name"];
+      $content = $protocol_name;
+      list($entity_type, $entity_id) = explode(':', $items[0]['value']['entity_id']);
+      if ($entity_id) {
+        $content = l($protocol_name, 'bio_data/' . $entity_id);
+      }
+    }
+
+    //cardinality for this field is 1
+    $element[0] = [
+      '#type' => 'markup',
+      '#markup' => $content,
+    ];
+  }
+
+
+  /**
+   * Provides a summary of the formatter settings.
+   *
+   * This function corresponds to the hook_field_formatter_settings_summary()
+   * function of the Drupal Field API.
+   *
+   * On the 'Manage Display' page of the content type administration page,
+   * fields are allowed to provide a settings form.  This settings form can
+   * be used to allow the site admin to define how the field should be
+   * formatted.  The settings are then available for the formatter()
+   * function of this class.  This function provides a text-based description
+   * of the settings for the site developer to see.  It appears on the manage
+   * display page inline with the field.  A field must always return a
+   * value in this function if the settings form gear button is to appear.
+   *
+   * See the hook_field_formatter_settings_summary() function for more
+   * information.
+   *
+   * @param $field
+   * @param $instance
+   * @param $view_mode
+   *
+   * @return string
+   *   A string that provides a very brief summary of the field settings
+   *   to the user.
+   *
+   */
+  public function settingsSummary($view_mode) {
+    return '';
+  }
+
+}

+ 153 - 0
tripal_chado/includes/TripalFields/sep__protocol/sep__protocol_widget.inc

@@ -0,0 +1,153 @@
+<?php
+
+/**
+ * @class
+ * Purpose:
+ *
+ * Data:
+ * Assumptions:
+ */
+class sep__protocol_widget extends ChadoFieldWidget {
+
+  // The default label for this field.
+  public static $default_label = 'Protocol';
+
+  // The list of field types for which this formatter is appropriate.
+  public static $field_types = ['sep__protocol'];
+
+  /**
+   * Provides the form for editing of this field.
+   *
+   * This function corresponds to the hook_field_widget_form()
+   * function of the Drupal Field API.
+   *
+   * This form is diplayed when the user creates a new entity or edits an
+   * existing entity.  If the field is attached to the entity then the form
+   * provided by this function will be displayed.
+   *
+   * At a minimum, the form must have a 'value' element.  For Tripal, the
+   * 'value' element of a field always corresponds to the value that is
+   * presented to the end-user either directly on the page (with formatting)
+   * or via web services, or some other mechanism.  However, the 'value' is
+   * sometimes not enough for a field.  For example, the Tripal Chado module
+   * maps fields to table columns and sometimes those columns are foreign keys
+   * therefore, the Tripal Chado modules does not just use the 'value' but adds
+   * additional elements to help link records via FKs.  But even in this case
+   * the 'value' element must always be present in the return form and in such
+   * cases it's value should be set equal to that added in the 'load' function.
+   *
+   * @param $widget
+   * @param $form
+   *   The form structure where widgets are being attached to. This might be a
+   *   full form structure, or a sub-element of a larger form.
+   * @param $form_state
+   *   An associative array containing the current state of the form.
+   * @param $langcode
+   *   The language associated with $items.
+   * @param $items
+   *   Array of default values for this field.
+   * @param $delta
+   *   The order of this item in the array of subelements (0, 1, 2, etc).
+   * @param $element
+   * A form element array containing basic properties for the widget:
+   *  - #entity_type: The name of the entity the field is attached to.
+   *  - #bundle: The name of the field bundle the field is contained in.
+   *  - #field_name: The name of the field.
+   *  - #language: The language the field is being edited in.
+   *  - #field_parents: The 'parents' space for the field in the form. Most
+   *    widgets can simply overlook this property. This identifies the location
+   *    where the field values are placed within $form_state['values'], and is
+   *    used to access processing information for the field through the
+   *    field_form_get_state() and field_form_set_state() functions.
+   *  - #columns: A list of field storage columns of the field.
+   *  - #title: The sanitized element label for the field instance, ready for
+   *    output.
+   *  - #description: The sanitized element description for the field instance,
+   *    ready for output.
+   *  - #required: A Boolean indicating whether the element value is required;
+   *    for required multiple value fields, only the first widget's values are
+   *    required.
+   *  - #delta: The order of this item in the array of subelements; see
+   *    $delta above
+   */
+  public function form(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) {
+    parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element);
+
+
+    $settings = $this->field['settings'];
+    $field_name = $this->field['field_name'];
+    $field_type = $this->field['type'];
+    $field_table = $this->instance['settings']['chado_table'];
+    $field_column = $this->instance['settings']['chado_column'];
+    $linker_field = 'chado-' . $field_table . '__protocol_id';
+
+    $protocols = [];
+    //options are all protocols
+    //It could be argued that options should only be protocols where protocol_type matches the bundle base table.
+
+    $sql = "SELECT * FROM {protocol}";
+    $results = chado_query($sql);
+    foreach ($results as $protocol) {
+      $protocols[$protocol->protocol_id] = $protocol->name;
+    }
+
+    $widget['value'] = [
+      '#type' => 'select',
+      '#title' => $element['#title'],
+      '#description' => $element['#description'],
+      '#options' => $protocols,
+      '#empty_option' => '- Select a Protocol -',
+      '#required' => $element['#required'],
+      '#weight' => isset($element['#weight']) ? $element['#weight'] : 0,
+      '#delta' => $delta,
+    ];
+
+  }
+
+  /**
+   * Performs validation of the widgetForm.
+   *
+   * Use this validate to ensure that form values are entered correctly.
+   * The 'value' key of this field must be set in the $form_state['values']
+   * array anytime data is entered by the user.  It may be the case that there
+   * are other fields for helping select a value. In the end those helper
+   * fields must be used to set the 'value' field.
+   */
+  public function validate($element, $form, &$form_state, $langcode, $delta) {
+
+  }
+
+  /**
+   * Performs extra commands when the entity form is submitted.
+   *
+   * Drupal typically does not provide a submit hook for fields.  The
+   * TripalField provides one to allow for behind-the-scenes actions to
+   * occur.   This function should never be used for updates, deletes or
+   * inserts for the Chado table associated with the field.  Rather, the
+   * storage backend should be allowed to handle inserts, updates deletes.
+   * However, it is permissible to perform inserts, updates or deletions within
+   * Chado using this function.  Those operations can be performed if needed but
+   * on other tables not directly associated with the field.
+   *
+   * An example is the chado.feature_synonym table.  The chado_linker__synonym
+   * field allows the user to provide a brand new synonynm and it must add it
+   * to the chado.synonym table prior to the record in the
+   * chado.feature_synonym table.  This insert occurs in the widgetFormSubmit
+   * function.
+   *
+   * @param $form
+   *    The submitted form array.
+   * @param $form_state .
+   *    The form state array.
+   * @param $entity_type
+   *    The type of $entity.
+   * @param $entity
+   *    The entity for the operation.
+   * @param $langcode
+   *    The language associated with $items.
+   * @param $delta
+   */
+  public function submit($form, &$form_state, $entity_type, $entity, $langcode, $delta) {
+  }
+
+}

+ 1 - 1
tripal_chado/includes/TripalFields/sio__annotation/sio__annotation_formatter.inc

@@ -28,7 +28,7 @@ class sio__annotation_formatter extends ChadoFieldFormatter {
     $chado_table = $this->instance['settings']['chado_table'];
     foreach ($items as $delta => $item) {
 
-      if ($item['chado-' . $chado_table . '__cvterm_id']) {
+      if (!empty($item['chado-' . $chado_table . '__cvterm_id'])) {
         $cvterm = chado_generate_var('cvterm', array('cvterm_id' => $item['chado-' . $chado_table . '__cvterm_id']));
         $dbxref = $cvterm->dbxref_id;
 

+ 2 - 2
tripal_chado/includes/TripalFields/taxrank__infraspecific_taxon/taxrank__infraspecific_taxon.inc

@@ -85,7 +85,7 @@ class taxrank__infraspecific_taxon extends ChadoField {
             'name' => 'infraspecific_name',
             'sortable' => TRUE,
             'searchable' => TRUE,
-            'label' => 'Infrasepcies Name',
+            'label' => 'Infraspecies Name',
             'help' => 'The infraspecific name of the organism below the rank of species.',
             'type' => 'xs:string',
             'readonly' => FALSE,
@@ -192,4 +192,4 @@ class taxrank__infraspecific_taxon extends ChadoField {
       $entity->{$field_name}['und'][0]['chado-organism__type_id'] = $record->type_id->cvterm_id;
     }
   }
-}
+}

+ 5 - 5
tripal_chado/includes/TripalFields/taxrank__infraspecific_taxon/taxrank__infraspecific_taxon_widget.inc

@@ -32,7 +32,7 @@ class taxrank__infraspecific_taxon_widget extends ChadoFieldWidget {
     if (array_key_exists('values', $form_state) and
         array_key_exists($field_name, $form_state['values'])) {
       $type_id = $form_state['values'][$field_name][$langcode][$delta]['infraname']['specific_epithet'];
-      $infra_name = $form_state['values'][$field_name][$langcode][$delta]['infraname']['infrapsecific_epithet'];
+      $infra_name = $form_state['values'][$field_name][$langcode][$delta]['infraname']['infraspecific_epithet'];
     }
 
     $widget['value'] = array(
@@ -52,7 +52,7 @@ class taxrank__infraspecific_taxon_widget extends ChadoFieldWidget {
     $terms = tripal_get_cvterm_select_options($cv->cv_id);
 
     // Unfortunately the taxonomic_rank vocabulary is not properly organized
-    // such that we an only include terms below 'species'. Therefore we will
+    // such that we only include terms below 'species'. Therefore we will
     // just list them here and hope we haven't missed one.
     $valid_terms = array('cultivar', 'subspecies', 'varietas', 'subvariety', 'forma', 'subforma');
     $options = array();
@@ -77,9 +77,9 @@ class taxrank__infraspecific_taxon_widget extends ChadoFieldWidget {
       '#options' => $options,
       '#default_value' => $type_id,
     );
-    $widget['infraname']['infrapsecific_epithet'] = array(
+    $widget['infraname']['infraspecific_epithet'] = array(
       '#type' => 'textfield',
-      '#title' => 'Infrapsecific Epithet',
+      '#title' => 'Infraspecific Epithet',
       '#description' => 'The name below species.',
       '#default_value' => $infra_name,
       '#required' => $element['#required'],
@@ -95,7 +95,7 @@ class taxrank__infraspecific_taxon_widget extends ChadoFieldWidget {
     $field_column = $this->instance['settings']['chado_column'];
 
     $type_id = $form_state['values'][$field_name]['und'][0]['infraname']['specific_epithet'];
-    $infra_name = $form_state['values'][$field_name]['und'][0]['infraname']['infrapsecific_epithet'];
+    $infra_name = $form_state['values'][$field_name]['und'][0]['infraname']['infraspecific_epithet'];
 
     if ($infra_name and $type_id) {
       $form_state['values'][$field_name]['und'][0]['value'] = $infra_name;

+ 234 - 0
tripal_chado/includes/TripalImporter/NewickImporter.inc

@@ -0,0 +1,234 @@
+<?php
+
+class NewickImporter extends TripalImporter {
+
+  /**
+   * The name of this loader.  This name will be presented to the site
+   * user.
+   */
+  public static $name = 'Newick Tree Loader';
+
+  /**
+   * The machine name for this loader. This name will be used to construct
+   * the URL for the loader.
+   */
+  public static $machine_name = 'chado_newick_loader';
+
+  /**
+   * A brief description for this loader.  This description will be
+   * presented to the site user.
+   */
+  public static $description = 'Load Newick formatted phylogenetic trees.';
+
+  /**
+   * An array containing the extensions of allowed file types.
+   */
+  public static $file_types = ['tree', 'txt'];
+
+  /**
+   * Provides information to the user about the file upload.  Typically this
+   * may include a description of the file types allowed.
+   */
+  public static $upload_description = 'Please provide the Newick formatted tree file.  The file must have a .txt or .tree extension.';
+
+  /**
+   * The title that should appear above the file upload section.
+   */
+  public static $upload_title = 'Newick Upload';
+
+  /**
+   * Text that should appear on the button at the bottom of the importer
+   * form.
+   */
+  public static $button_text = 'Import Newick file';
+
+
+  /**
+   * Indicates the methods that the file uploader will support.
+   */
+  public static $methods = [
+    // Allow the user to upload a file to the server.
+    'file_upload' => TRUE,
+    // Allow the user to provide the path on the Tripal server for the file.
+    'file_local' => TRUE,
+    // Allow the user to provide a remote URL for the file.
+    'file_remote' => TRUE,
+  ];
+
+  /**
+   * @see TripalImporter::form()
+   */
+  public function form($form, &$form_state) {
+    // Default values can come in the following ways:
+    //
+    // 1) as elements of the $node object.  This occurs when editing an existing phylotree
+    // 2) in the $form_state['values'] array which occurs on a failed validation or
+    //    ajax callbacks from non submit form elements
+    // 3) in the $form_state['input'[ array which occurs on ajax callbacks from submit
+    //    form elements and the form is being rebuilt
+    //
+    // set form field defaults
+    $phylotree = NULL;
+    $phylotree_id = NULL;
+    $tree_name = '';
+    $leaf_type = '';
+    $analysis_id = '';
+    $dbxref = '';
+    $comment = '';
+    $tree_required = TRUE;
+    $tree_file = '';
+    $name_re = '';
+    $match = '';
+
+    // If we are re constructing the form from a failed validation or ajax callback
+    // then use the $form_state['values'] values.
+    if (array_key_exists('values', $form_state) and isset($form_state['values']['tree_name'])) {
+      $tree_name = $form_state['values']['tree_name'];
+      $leaf_type = $form_state['values']['leaf_type'];
+      $analysis_id = $form_state['values']['analysis_id'];
+      $dbxref = $form_state['values']['dbxref'];
+      $comment = $form_state['values']['description'];
+    }
+    // If we are re building the form from after submission (from ajax call) then
+    // the values are in the $form_state['input'] array.
+    if (array_key_exists('input', $form_state) and !empty($form_state['input'])) {
+      $tree_name = $form_state['input']['tree_name'];
+      $leaf_type = $form_state['input']['leaf_type'];
+      $analysis_id = $form_state['input']['analysis_id'];
+      $comment = $form_state['input']['description'];
+      $dbxref = $form_state['input']['dbxref'];
+    }
+
+    $form['tree_name'] = [
+      '#type' => 'textfield',
+      '#title' => t('Tree Name'),
+      '#required' => TRUE,
+      '#default_value' => $tree_name,
+      '#description' => t('Enter the name used to refer to this phylogenetic tree.'),
+      '#maxlength' => 255,
+    ];
+
+    $type_cv = tripal_get_default_cv('phylotree', 'type_id');
+    $so_cv = tripal_get_cv(['name' => 'sequence']);
+    $cv_id = $so_cv->cv_id;
+    if (!$so_cv) {
+      drupal_set_message('The Sequence Ontolgoy does not appear to be imported.
+        Please import the Sequence Ontology before adding a tree.', 'error');
+    }
+
+    $form['leaf_type'] = [
+      '#title' => t('Tree Type'),
+      '#type' => 'textfield',
+      '#description' => t("Choose the tree type. The type is
+        a valid Sequence Ontology (SO) term. For example, trees derived
+        from protein sequences should use the SO term 'polypeptide'.
+        Alternatively, a phylotree can be used for representing a taxonomic
+        tree. In this case, the word 'taxonomy' should be used."),
+      '#required' => TRUE,
+      '#default_value' => $leaf_type,
+      '#autocomplete_path' => "admin/tripal/legacy/tripal_cv/cvterm/auto_name/$cv_id",
+    ];
+
+    $form['dbxref'] = [
+      '#title' => t('Database Cross-Reference'),
+      '#type' => 'textfield',
+      '#description' => t("Enter a database cross-reference of the form
+        [DB name]:[accession]. The database name must already exist in the
+        database. If the accession does not exist it is automatically added."),
+      '#required' => FALSE,
+      '#default_value' => $dbxref,
+    ];
+
+    $form['description'] = [
+      '#type' => 'textarea',
+      '#title' => t('Description'),
+      '#required' => TRUE,
+      '#default_value' => $comment,
+      '#description' => t('Enter a description for this tree.'),
+    ];
+
+    $form['name_re'] = [
+      '#title' => t('Feature Name Regular Expression'),
+      '#type' => 'textfield',
+      '#description' => t('If this is a phylogenetic (non taxonomic) tree, then
+          the tree nodes will be automatically associated with features. However,
+          if the nodes in the tree file are not exactly as the names of features
+          but have enough information to uniquely identify the feature then you
+          may provide a regular expression that the importer will use to extract
+          the feature names from the node names.'),
+      '#default_value' => $name_re,
+    ];
+    $form['match'] = [
+      '#title' => t('Use Unique Feature Name'),
+      '#type' => 'checkbox',
+      '#description' => t('If this is a phylogenetic (non taxonomic tree) and the nodes ' . 'should match the unique name of the feature rather than the name of the feature ' . 'then select this box. If unselected the loader will try to match the feature ' . 'using the feature name.'),
+      '#default_value' => $match,
+    ];
+
+    return $form;
+  }
+
+  /**
+   * @see TripalImporter::formValidate()
+   */
+  public function formValidate($form, &$form_state) {
+
+    $values = $form_state['values'];
+
+    $options = [
+      'name' => trim($values["tree_name"]),
+      'description' => trim($values["description"]),
+      'analysis_id' => $values["analysis_id"],
+      'leaf_type' => $values["leaf_type"],
+      'tree_file'    => $this->arguments['files'][0]['file_path'],
+      'format' => 'newick',
+      'dbxref' => trim($values["dbxref"]),
+      'match' => $values["match"],
+      'name_re' => $values["name_re"],
+    ];
+
+    $errors = [];
+    $warnings = [];
+
+    tripal_validate_phylotree('insert', $options, $errors, $warnings);
+
+    // Now set form errors if any errors were detected.
+    if (count($errors) > 0) {
+      foreach ($errors as $field => $message) {
+        if ($field == 'name') {
+          $field = 'tree_name';
+        }
+        form_set_error($field, $message);
+      }
+    }
+    // Add any warnings if any were detected
+    if (count($warnings) > 0) {
+      foreach ($warnings as $field => $message) {
+        drupal_set_message($message, 'warning');
+      }
+    }
+  }
+
+  /**
+   * @see TripalImporter::run()
+   */
+  public function run() {
+
+    $arguments = $this->arguments['run_args'];
+
+    $options = array(
+      'name'         => $this->arguments["tree_name"],
+      'description'  => $this->arguments["description"],
+      'analysis_id'  => $this->arguments["analysis_id"],
+      'leaf_type'    => $this->arguments["leaf_type"],
+      'tree_file'    => $this->arguments['files'][0]['file_path'],
+      'format'       => 'newick',
+      'dbxref'       => $this->arguments["dbxref"],
+      'match'        => $this->arguments["match"],
+      'name_re'      => $this->arguments["name_re"],
+    );
+    $errors = array();
+    $warnings = array();
+    tripal_insert_phylotree($options, $errors, $warnings);
+  }
+}

+ 4 - 4
tripal_chado/includes/TripalImporter/TaxonomyImporter.inc

@@ -131,7 +131,7 @@ class TaxonomyImporter extends TripalImporter {
     );
     $form['taxonomy_ids'] = array(
       '#type' => 'textarea',
-      '#title' => 'Taxonomy IDa',
+      '#title' => 'Taxonomy ID',
       '#description' => t('Please provide a list of NCBI taxonomy IDs separated
         by spaces, tabs or new lines.
         The information about these organisms will be downloaded and new organism
@@ -141,7 +141,7 @@ class TaxonomyImporter extends TripalImporter {
     $form['import_existing'] = array(
       '#type' => 'checkbox',
       '#title' => 'Import details for existing species.',
-      '#description' =>  t('The NCBI Taxonmic Importer examines the organisms
+      '#description' =>  t('The NCBI Taxonomic Importer examines the organisms
         currently present in the database and queries NCBI for the
         taxonomic details.  If the importer is able to match the
         genus and species with NCBI the species details will be imported,
@@ -600,7 +600,7 @@ class TaxonomyImporter extends TripalImporter {
       ));
 
       // Remove the rank from the infraspecific name.
-      $abbrev = tripal_abbreviate_infraspeicifc_rank($rank);
+      $abbrev = tripal_abbreviate_infraspecific_rank($rank);
       $infra = preg_replace("/$abbrev/", "", $infra);
       $infra = trim($infra);
 
@@ -914,4 +914,4 @@ class TaxonomyImporter extends TripalImporter {
     );
     chado_insert_record('organism_dbxref', $values);
   }
-}
+}

+ 44 - 62
tripal_chado/includes/tripal_chado.cv.inc

@@ -646,70 +646,52 @@ function tripal_cv_cvterm_edit_form_submit($form, &$form_state) {
   $accession       = array_key_exists('accession', $form_state['values'])       ? trim($form_state['values']['accession']) : '';
   $op              = array_key_exists('op', $form_state['values'])              ? trim($form_state['values']['op']) : '';
 
+  if ($op == 'Update') {
+    // get the original cvterm_id
+    $values = array('name' => $name, 'cv_id' => $cv_id);
+    $results = chado_select_record('cvterm', array('cvterm_id'), $values);
+    $cvterm = $results[0];
 
-  $step = $form_state['storage']['step'];
+    // get the cv
+    $values = array('cv_id' => $cv_id);
+    $results = chado_select_record('cv', array('name'), $values);
+    $cv = $results[0];
+
+    // get the db
+    $values = array('db_id' => $db_id);
+    $results = chado_select_record('db', array('name'), $values);
+    $db = $results[0];
+
+    // now add the term
+    $term = array(
+      'name' => $name,
+      'namespace' => $cv->name,
+      'id' => $accession,
+      'definition' => $definition,
+      'is_obsolete' => $is_obsolete,
+      'cv_name' => $cv->name,
+      'is_relationship' => $is_relationship,
+      'db_name' => $db->name
+    );
 
-  switch ($step) {
-    case 0:  // a cvterm name has been selected
-      $cv_id = array_key_exists('cv_id', $form_state['values']) ? trim($form_state['values']['cv_id']) : '';
-      $name  = array_key_exists('name', $form_state['values'])  ? trim($form_state['values']['name'])  : '';
-
-      // get the original cvterm_id
-      $values = array('name' => $name, 'cv_id' => $cv_id);
-      $results = chado_select_record('cvterm', array('cvterm_id'), $values);
-      $cvterm = $results[0];
-
-      $form_state['storage']['cv_id'] = $cv_id;
-      $form_state['storage']['name'] = $name;
-      $form_state['storage']['step'] = 1;
-      $form_state['storage']['cvterm_id'] = $cvterm->cvterm_id;
-      $form_state['rebuild'] = TRUE;
-      break;
-
-    case 1:  // update/delete button has been clicked
-
-      if ($op == 'Update') {
-        // get the cv
-        $values = array('cv_id' => $cv_id);
-        $results = chado_select_record('cv', array('name'), $values);
-        $cv = $results[0];
-
-        // get the db
-        $values = array('db_id' => $db_id);
-        $results = chado_select_record('db', array('name'), $values);
-        $db = $results[0];
-
-        // now add the term
-        $term = array(
-          'name' => $name,
-          'namespace' => $cv->name,
-          'id' => $accession,
-          'definition' => $definition,
-          'is_obsolete' => $is_obsolete,
-          'cv_name' => $cv->name,
-          'is_relationship' => $is_relationship,
-          'db_name' => $db_name
-        );
-
-        $cvterm = tripal_insert_cvterm($term, array('update_existing' => TRUE));
-        if ($cvterm) {
-          drupal_set_message('Term updated successfully.');
-        }
-        else {
-          drupal_set_message('Could not add term. Check Drupal recent logs for error messages.', 'error');
-        }
-      }
-      if ($op == 'Delete') {
-        $values = array('cvterm_id' => $cvterm_id);
-        $success = chado_delete_record('cvterm', $values);
-        if ($success) {
-          drupal_set_message('Term deleted successfully.');
-        }
-        else {
-          drupal_set_message('Could not delete term term. Check Drupal recent logs for error messages.', 'error');
-        }
-      }
-      break;
+    $cvterm = tripal_insert_cvterm($term, array('update_existing' => TRUE));
+    if ($cvterm) {
+      drupal_set_message('Term updated successfully.');
+      drupal_goto('admin/tripal/loaders/chado_vocabs/chado_cvterms');
+    }
+    else {
+      drupal_set_message('Could not add term. Check Drupal recent logs for error messages.', 'error');
+    }
+  }
+  if ($op == 'Delete') {
+    $values = array('cvterm_id' => $cvterm_id);
+    $success = chado_delete_record('cvterm', $values);
+    if ($success) {
+      drupal_set_message('Term deleted successfully.');
+    }
+    else {
+      drupal_set_message('Could not delete term term. Check Drupal recent logs for error messages.', 'error');
+    }
   }
 }
 

+ 1 - 1
tripal_chado/includes/tripal_chado.entity.inc

@@ -249,7 +249,7 @@ function tripal_chado_entity_view($entity, $type, $view_mode, $langcode) {
       $enabled_templates = variable_get('tripal_chado_enabled_legacy_templates', array());
       $legacy_template = 'legacy_template--chado_' . $chado_table;
 
-      // If the site admin has indicated that thhis entity type should use
+      // If the site admin has indicated that this entity type should use
       // a legacy tmplate then prepare the entity and content to fake a
       // node.
       if (key_exists($legacy_template, $enabled_templates) && $enabled_templates[$legacy_template]) {

+ 2 - 1
tripal_chado/includes/tripal_chado.field_storage.inc

@@ -54,6 +54,8 @@ function tripal_chado_field_storage_write($entity_type, $entity, $op, $fields) {
   elseif ($type_field and !$linker) {
     $values[$type_field] = $cvterm->cvterm_id;
   }
+
+
   $base_record_id = tripal_chado_field_storage_write_table($base_table, $values, $base_table);
 
   // If this is an insert then add the chado_entity record.
@@ -1328,4 +1330,3 @@ function tripal_chado_field_storage_bundle_mapping_form_submit($form,
   }
 }
 
-

+ 117 - 20
tripal_chado/includes/tripal_chado.fields.inc

@@ -115,6 +115,11 @@ function tripal_chado_bundle_fields_info_base(&$info, $details, $entity_type, $b
       continue;
     }
 
+    // Skip the type ID as it will be handled by a custom field.
+    if ($column_name == 'type_id') {
+      continue;
+    }
+
     // Set some defaults for the field.
     $base_info = array(
       'field_name' => $field_name,
@@ -191,7 +196,6 @@ function tripal_chado_bundle_fields_info_base(&$info, $details, $entity_type, $b
       $base_info['type'] = 'text';
       $base_info['settings']['text_processing'] = 0;
     }
-
     $info[$field_name] = $base_info;
   }
 }
@@ -209,8 +213,8 @@ function tripal_chado_bundle_fields_info_custom(&$info, $details, $entity_type,
 
   $schema = chado_get_schema($table_name);
 
-  // An additional type for the publication
-  if ($table_name == 'pub') {
+  // Handle type_id fields that are not the type_column.
+  if (array_key_exists('type_id', $schema['fields']) and 'type_id' != $type_column) {
     $field_name = 'schema__additional_type';
     $field_type = 'schema__additional_type';
     $info[$field_name] = array(
@@ -448,11 +452,27 @@ function tripal_chado_bundle_fields_info_custom(&$info, $details, $entity_type,
       ),
     );
   }
+
+  //protocol
+  if ($table_name == 'protocol' and array_key_exists('protocol_id', $schema['fields'])) {
+    $field_name = 'sep__protocol';
+    $field_type = 'sep__protocol';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'type' => $field_type,
+      'cardinality' => 1,
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+    );
+  }
+
 }
 
 /**
  *
- * @param unknown $details
+ * @param $details
  */
 function tripal_chado_bundle_fields_info_linker(&$info, $details, $entity_type, $bundle) {
 
@@ -776,14 +796,19 @@ function tripal_chado_bundle_instances_info_base(&$info, $entity_type, $bundle,
       continue;
     }
 
-    // Don't create base fields for the primary key and the type_id field.
-    if ($column_name == $pkey or $column_name == $type_column) {
+    // Skip the cvterm.is_relationshptype.
+    if ($table_name == 'cvterm' and $column_name == 'is_relationshiptype') {
       continue;
     }
 
-    // Skip the type field that will always be custom
-    if (($table_name == $type_table and $column_name == $type_column) or
-        $column_name == 'type_id') {
+    // The biosourceprovider_id and taxon_id are handled by custom fields.
+    if ($table_name == 'biomaterial' and (
+        $column_name == 'biosourceprovider_id' or $column_name == 'taxon_id')) {
+      continue;
+    }
+
+    // Don't create base fields for the primary key and the type_id field.
+    if ($column_name == $pkey or $column_name == $type_column) {
       continue;
     }
 
@@ -793,12 +818,6 @@ function tripal_chado_bundle_instances_info_base(&$info, $entity_type, $bundle,
       // don't create another one here.
       continue;
     }
-
-    if ($table_name == 'biomaterial' and (
-        $column_name == 'biosourceprovider_id' or $column_name == 'taxon_id')) {
-      continue;
-    }
-
     $field_name = strtolower($cvterm->dbxref_id->db_id->name . '__' . preg_replace('/[^\w]/', '_', $cvterm->name));
     $field_name = substr($field_name, 0, 32);
 
@@ -813,6 +832,11 @@ function tripal_chado_bundle_instances_info_base(&$info, $entity_type, $bundle,
       continue;
     }
 
+    // Skip the type ID as it will be handled by a custom field.
+    if ($column_name == 'type_id') {
+      continue;
+    }
+
     $base_info =  array(
       'field_name' => $field_name,
       'entity_type' => 'TripalEntity',
@@ -1017,6 +1041,14 @@ function tripal_chado_bundle_instances_info_base(&$info, $entity_type, $bundle,
       $base_info['label'] = 'Short Description';
     }
 
+    //
+    // CONTACT TABLE
+    //
+    if ($table_name == 'contact' and $column_name == 'description') {
+      $base_info['label'] = 'Short Description';
+    }
+
+
     $info[$field_name] = $base_info;
   }
 }
@@ -1040,27 +1072,47 @@ function tripal_chado_bundle_instances_info_custom(&$info, $entity_type, $bundle
   $schema = chado_get_schema($table_name);
 
   // An additional type for publications
-  if ($table_name == 'pub') {
+  if (array_key_exists('type_id', $schema['fields']) and 'type_id' != $type_column) {
     $field_name = 'schema__additional_type';
     $is_required = FALSE;
     if (array_key_exists('not null', $schema['fields']['type_id']) and
         $schema['fields']['type_id']['not null']) {
       $is_required = TRUE;
     }
+    $label = ucwords(preg_replace('/_/', ' ', $table_name)) . ' Type';
+    $default_vocab = '';
+    $parent_term = '';
+    switch($table_name) {
+      case 'pub':
+        $default_vocab = 'tripal_pub';
+        $label = 'Publication Type';
+        $parent_term = 'TPUB:0000015';
+        $description = 'Select the type.';
+        break;
+      case 'contact':
+        $default_vocab = 'tripal_contact';
+        $parent_term = 'TContact:0000001';
+        $description = 'Select the type.';
+        break;
+      default:
+        $description = t('Enter the name of the term that specifies the type. ' .
+            'The type must be the name of a term in a controlled vocabulary and ' .
+            'the controlled vocabulary should already be loaded into this site.');
+    }
     $info[$field_name] =  array(
       'field_name' => $field_name,
       'entity_type' => $entity_type,
       'bundle' => $bundle->name,
-      'label' => 'Publication Type',
-      'description' => 'Select the publication type.',
+      'label' => $label,
+      'description' => $description,
       'required' => $is_required,
       'settings' => array(
         'auto_attach' => TRUE,
         'chado_table' => $table_name,
         'chado_column' => 'type_id',
         'base_table' => $table_name,
-        'vocabulary' => 'tripal_pub',
-        'parent_term' => 'TPUB:0000015',
+        'vocabulary' => $default_vocab,
+        'parent_term' => $parent_term,
       ),
       'widget' => array(
         'type' => 'schema__additional_type_widget',
@@ -1575,6 +1627,51 @@ function tripal_chado_bundle_instances_info_custom(&$info, $entity_type, $bundle
       ),
     );
   }
+
+
+  // PROTOCOL FIELD
+  if ($table_name != 'protocol' and
+    (array_key_exists('protocol_id', $schema['fields']))) {
+
+    $field_name = 'sep__protocol';
+    $is_required = FALSE;
+    $table_column = 'protocol_id';
+    if  (array_key_exists('not null', $schema['fields']['protocol_id']) and
+      $schema['fields']['protocol_id']['not null']) {
+      $is_required = TRUE;
+    }
+    $info[$field_name] =  array(
+      'field_name' => $field_name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Protocol',
+      'description' => 'The parameterizable description of a process',
+      'required' => $is_required,
+      'settings' => array(
+        'auto_attach' => TRUE,
+        'chado_table' => $table_name,
+        'chado_column' => $table_column,
+        'base_table' => $table_name,
+      ),
+      'widget' => array(
+        'type' => 'sep__protocol_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'inline',
+          'type' => 'sep__protocol_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
+
+
+
+
 }
 
 /**

+ 17 - 6
tripal_chado/includes/tripal_chado.migrate.inc

@@ -849,7 +849,7 @@ function tripal_chado_migrate_url_alias_for_selected_types($tv2_content_types =
  * Migrate images for all chado_organism
  *
  */
-function tripal_chado_migrate_organism_images () {
+function tripal_chado_migrate_organism_images ($bundle_name) {
   // Get all organism entities
   $bio_data_table = array_pop(tripal_chado_migrate_get_biodata_tables('organism'));
   $results =
@@ -902,13 +902,13 @@ function tripal_chado_migrate_organism_images () {
           }
         }
         if($file){
-          tripal_chado_migrate_organism_image_add_file($file->fid, $entity_id);
+            tripal_chado_migrate_organism_image_add_file($file->fid, $entity_id, $bundle_name);
         }
       }
     }
     else {
       // If there is an image, add it to the organism entity
-      tripal_chado_migrate_organism_image_add_file ($fid, $entity_id);
+        tripal_chado_migrate_organism_image_add_file ($fid, $entity_id, $bundle_name);
     }
 
   }
@@ -920,15 +920,16 @@ function tripal_chado_migrate_organism_images () {
  *
  * @param unknown $fid
  */
-function tripal_chado_migrate_organism_image_add_file ($fid, $entity_id) {
+function tripal_chado_migrate_organism_image_add_file ($fid, $entity_id, $bundle_name) {
   if ($fid && $entity_id) {
     $file = file_load($fid);
     // Add a record to the file_usage table
     file_usage_add($file, 'file', 'TripalEntity', $entity_id);
+    $image_file = (array) $file;
     // Attached it to the entity
+    /* 
     $entities = entity_load('TripalEntity', array($entity_id));
     $entity = $entities[$entity_id];
-    $image_file = (array) $file;
     $image = array(
       'und' => array(
         0 =>$image_file
@@ -937,8 +938,18 @@ function tripal_chado_migrate_organism_image_add_file ($fid, $entity_id) {
     $entity->data__image = $image;
     field_attach_update('TripalEntity', $entity);
     entity_get_controller('TripalEntity')->resetCache(array($entity_id));
+    */
     // Add a record to the field_data_data__image table
-
+    $values = array(
+        'entity_type' => 'TripalEntity',
+        'bundle' => $bundle_name,
+        'entity_id' => $entity_id,
+        'revision_id' => $entity_id,
+        'language' => 'und',
+        'delta' => 0,
+        'data__image_fid' => $fid,
+    );
+    drupal_write_record('field_data_data__image', $values);
   }
 }
 

+ 14 - 15
tripal_chado/tripal_chado.module

@@ -17,6 +17,7 @@ require_once 'api/tripal_chado.schema_v1.3.api.inc';
 require_once 'api/tripal_chado.schema_v1.2.api.inc';
 require_once 'api/tripal_chado.schema_v1.11.api.inc';
 require_once 'api/tripal_chado.semweb.api.inc';
+require_once 'api/tripal_chado.migrate.api.inc';
 
 // Chado module specific API functions
 require_once 'api/modules/tripal_chado.analysis.api.inc';
@@ -364,16 +365,6 @@ function tripal_chado_menu() {
   //                           Data Loaders
   //////////////////////////////////////////////////////////////////////////////
 
-  // Data Loaders
-  $items['admin/tripal/loaders/newic_phylotree_loader'] = array(
-    'title' => 'Chado Phylogenetic Trees (Newic format)',
-    'description' => 'Loads phylogenetic trees in Newic format.',
-    'page callback' => 'drupal_goto',
-    'page arguments' => array('node/add/chado-phylotree'),
-    'access arguments' => array('load tripal data'),
-    'type' => MENU_NORMAL_ITEM,
-  );
-
   $items['admin/tripal/loaders/pub'] = array(
     'title' => t('Chado Publication Importers'),
     'description' => t('Create and modify importers that can connect to and retreive publications from remote databases.'),
@@ -517,6 +508,14 @@ function tripal_chado_menu() {
     'file path' => drupal_get_path('module', 'tripal_chado'),
     'type' => MENU_CALLBACK,
   );
+  $items['admin/tripal/storage/chado/auto_name/cv/%'] = array(
+    'page callback' => 'tripal_autocomplete_cv',
+    'page arguments' => array(6),
+    'access arguments' => array('access content'),
+    'file' => 'api/modules/tripal_chado.cv.api.inc',
+    'file path' => drupal_get_path('module', 'tripal_chado'),
+    'type' => MENU_CALLBACK,
+  );
   $items['admin/tripal/storage/chado/auto_name/cvterm/%/%'] = array(
     'page callback' => 'tripal_autocomplete_cvterm',
     'page arguments' => array(6, 7),
@@ -583,7 +582,7 @@ function tripal_chado_menu() {
     'title' => 'Edit a Controlled Vocabulary',
     'description' => 'Edit the details such as name and description for an existing controlled vocabulary.',
     'page callback' => 'drupal_get_form',
-    'page arguments' => array('tripal_cv_cv_edit_form', 5),
+    'page arguments' => array('tripal_cv_cv_edit_form', 6),
     'access callback' => 'user_access',
     'access arguments' => array('administer controlled vocabularies'),
     'file' => 'includes/tripal_chado.cv.inc',
@@ -605,7 +604,7 @@ function tripal_chado_menu() {
     'title' => 'Add a Controlled Vocabulary Term',
     'description' => 'Add a new controlled vocabulary term.',
     'page callback' => 'drupal_get_form',
-    'page arguments' => array('tripal_cv_cvterm_add_form', 4),
+    'page arguments' => array('tripal_cv_cvterm_add_form', 5),
     'access arguments' => array('administer controlled vocabularies'),
     'file' => 'includes/tripal_chado.cv.inc',
     'file path' => drupal_get_path('module', 'tripal_chado'),
@@ -625,7 +624,7 @@ function tripal_chado_menu() {
     'title' => 'Edit a Controlled Vocabulary Term',
     'description' => 'Edit an existing controlled vocabulary term.',
     'page callback' => 'drupal_get_form',
-    'page arguments' => array('tripal_cv_cvterm_edit_form', 4, 7),
+    'page arguments' => array('tripal_cv_cvterm_edit_form', 5, 8),
     'access arguments' => array('administer controlled vocabularies'),
     'file' => 'includes/tripal_chado.cv.inc',
     'file path' => drupal_get_path('module', 'tripal_chado'),
@@ -1012,7 +1011,7 @@ function tripal_chado_form_field_ui_field_edit_form_alter(&$form, &$form_state,
   // such that record can't be saved in Chado.
 
   // TODO: we shouldn't check for specific field types here
-  // (e.g. chaod_linker_prop). That should be done via the TripalField
+  // (e.g. chado_linker_prop). That should be done via the TripalField
   // functions.
   if ($form['#instance']['entity_type'] == 'TripalEntity') {
     if ($form['#field']['storage']['type'] == 'field_chado_storage' and
@@ -1141,4 +1140,4 @@ function tripal_feature_match_features_page($id) {
   }
 
 
-}
+}

+ 8 - 3
tripal_chado_views/tripal_chado_views.views.inc

@@ -176,10 +176,15 @@ function tripal_chado_views_views_data() {
       $sql = "SELECT name, mv_specs FROM {tripal_mviews} WHERE mview_id = :id";
       $mview_table = db_query($sql, array(':id' => $mview_id));
       $mview_table = $mview_table->fetchObject();
-      $base_table = $mview_table->name;
+      if ($mview_table) {
+        $base_table = $mview_table->name;
 
-      if (!empty($mview_table->mv_specs)) {
-        $legacy_mview = TRUE;
+        if (!empty($mview_table->mv_specs)) {
+          $legacy_mview = TRUE;
+        }
+      }
+      else {
+        continue;
       }
     }
 

+ 1 - 1
tripal_ws/includes/TripalWebService.inc

@@ -224,7 +224,7 @@ class TripalWebService {
     $cfh = fopen($context_file_path, "w");
     if (flock($cfh, LOCK_EX)) {
       fwrite($cfh, json_encode($context));
-      flock($context_file_path, LOCK_UN);
+      flock($cfh, LOCK_UN);
       fclose($cfh);
     }
     else {

+ 11 - 11
tripal_ws/includes/TripalWebService/TripalEntityService_v0_1.inc

@@ -950,8 +950,8 @@ class TripalEntityService_v0_1 extends TripalWebService {
       'title' => 'Content Collection',
     );
     $vocab = tripal_get_vocabulary_details('hydra');
-    $propeties = array();
-    $propeties[] = array(
+    $properties = array();
+    $properties[] = array(
       'type' => $vocab['sw_url'],
       'title' => 'member',
       'description' => "The list of available content types.",
@@ -959,7 +959,7 @@ class TripalEntityService_v0_1 extends TripalWebService {
       "readonly" => FALSE,
       "writeonly" => FALSE,
     );
-    $propeties[] = array(
+    $properties[] = array(
       "type" => $vocab['sw_url'],
       "title" => "totalItems",
       "description" => "The total number of content types.",
@@ -967,7 +967,7 @@ class TripalEntityService_v0_1 extends TripalWebService {
       "readonly" => FALSE,
       "writeonly" => FALSE
     );
-    $propeties[] = array(
+    $properties[] = array(
       "type" => $vocab['sw_url'],
       "title" => "label",
       "description" => "The type content.",
@@ -983,7 +983,7 @@ class TripalEntityService_v0_1 extends TripalWebService {
       'expects' => NULL,
       'returns' => 'vocab:ContentCollection',
     );
-    $this->addDocClass($details,$operations, $propeties);
+    $this->addDocClass($details,$operations, $properties);
   }
   /**
    * Adds classes for every content type to the documentation for this service.
@@ -1186,8 +1186,8 @@ class TripalEntityService_v0_1 extends TripalWebService {
       'description' => 'A collection (or list) of ' . $bundle->label . ' resources.',
     );
     $vocab = tripal_get_vocabulary_details('hydra');
-    $propeties = array();
-    $propeties[] = array(
+    $properties = array();
+    $properties[] = array(
       'type' => $vocab['sw_url'],
       'title' => 'member',
       'description' => "The list of available " . $bundle->label . '(s).',
@@ -1195,7 +1195,7 @@ class TripalEntityService_v0_1 extends TripalWebService {
       "readonly" => FALSE,
       "writeonly" => FALSE,
     );
-    $propeties[] = array(
+    $properties[] = array(
       "type" => $vocab['sw_url'],
       "title" => "totalItems",
       "description" => "The total number of resources.",
@@ -1203,7 +1203,7 @@ class TripalEntityService_v0_1 extends TripalWebService {
       "readonly" => FALSE,
       "writeonly" => FALSE
     );
-    $propeties[] = array(
+    $properties[] = array(
       "type" => $vocab['sw_url'],
       "title" => "label",
       "description" => "A label or name for the resource.",
@@ -1244,7 +1244,7 @@ class TripalEntityService_v0_1 extends TripalWebService {
 //         ),
 //       );
     }
-    $this->addDocClass($details, $operations, $propeties);
+    $this->addDocClass($details, $operations, $properties);
   }
 
-}
+}

+ 1 - 1
tripal_ws/includes/tripal_ws.field_storage.inc

@@ -7,7 +7,7 @@ function tripal_ws_field_storage_info() {
   return array(
     'field_tripal_ws_storage' => array(
       'label' => t('Tripal Web Services'),
-      'description' => t('Retreives fields data from a remote site using Tripal web services.'),
+      'description' => t('Retrieves fields data from a remote site using Tripal web services.'),
       'settings' => array(),
     ),
   );