Parcourir la source

Fixed merge conflict

Stephen Ficklin il y a 4 ans
Parent
commit
3b2de6fd43
28 fichiers modifiés avec 350 ajouts et 189 suppressions
  1. 4 4
      docs/dev_guide/custom_field/manual_field_creation.rst
  2. 0 8
      docs/extensions/in_development.rst
  3. 8 0
      docs/extensions/visualization.rst
  4. 1 1
      docs/user_guide/install_tripal/custom_theme.rst
  5. 2 2
      legacy/tripal_core/api/tripal_core.chado_nodes.properties.api.inc
  6. 2 2
      legacy/tripal_core/api/tripal_core.chado_nodes.relationships.api.inc
  7. 2 2
      legacy/tripal_phylogeny/tripal_phylogeny.drush.inc
  8. 8 2
      tripal/api/tripal.entities.api.inc
  9. 40 0
      tripal/api/tripal.fields.api.inc
  10. 10 3
      tripal/includes/tripal.admin_blocks.inc
  11. 1 1
      tripal/tripal.module
  12. 2 2
      tripal_chado/api/modules/tripal_chado.cv.api.inc
  13. 1 1
      tripal_chado/api/modules/tripal_chado.db.api.inc
  14. 37 18
      tripal_chado/api/modules/tripal_chado.organism.api.inc
  15. 1 1
      tripal_chado/api/modules/tripal_chado.phylotree.api.inc
  16. 58 58
      tripal_chado/api/tripal_chado.variables.api.inc
  17. 6 1
      tripal_chado/includes/TripalFields/chado_linker__prop/chado_linker__prop_formatter.inc
  18. 1 1
      tripal_chado/includes/TripalFields/sbo__relationship/sbo__relationship_formatter.inc
  19. 91 28
      tripal_chado/includes/TripalFields/sio__references/sio__references.inc
  20. 25 6
      tripal_chado/includes/TripalFields/sio__references/sio__references_formatter.inc
  21. 36 37
      tripal_chado/includes/TripalImporter/OBOImporter.inc
  22. 3 3
      tripal_chado/includes/tripal_chado.fields.inc
  23. 1 1
      tripal_chado/includes/tripal_chado.phylotree.inc
  24. 1 1
      tripal_daemon/theme/tripal_daemon.log_block.css
  25. 1 1
      tripal_ws/includes/TripalFields/remote__data/remote__data_formatter.inc
  26. 1 1
      tripal_ws/includes/TripalWebService.inc
  27. 6 3
      tripal_ws/includes/TripalWebService/TripalContentService_v0_1.inc
  28. 1 1
      tripal_ws/includes/TripalWebServiceCollection.inc

+ 4 - 4
docs/dev_guide/custom_field/manual_field_creation.rst

@@ -122,7 +122,7 @@ Sometimes a field is meant to provide a visualization or some other functionalit
 
 
 .. note::
-  Be sure to only set this to TRUE when you are absolutely certain the contents would not be needed in web services.  Tripal was designed so that what appears on the page will always appear in web services.  Aside form the formatting we see on the website, the content should be the same.
+  Be sure to only set this to TRUE when you are absolutely certain the contents would not be needed in web services.  Tripal was designed so that what appears on the page will always appear in web services.  Aside from the formatting we see on the website, the content should be the same.
 
 Finally, the last item in our Class variables is the **download_formatters**.  Tripal provides an API that allows tools to group entities into data collections.  Data collections are like "baskets" or "shopping carts".   Entities that are in data collections can be downloaded into files.  If your field is compatible with specific file downloaders you can specify those here.  A file downloader is a special TripalFieldDownloader class that "speaks" certain file formats.  Tripal, by default, provides the TripalTabDownloader (for tab-delimited files), the TripalCSVDownloader (for CSV files), a TripalNucFASTADownloader for creating nucleotide FASTA files and a TripalProteinFASTADownloader for protein FASTA files.   If your field is compatible with any of these formatters you can specify them in the following array:
 
@@ -198,7 +198,7 @@ Next, let's initialize our field's value to be empty.  When setting a field valu
     );
 
 
-Notice that our field has some sub elements. The first is 'und'.  This element corresponds to the "language" of the text.  Drupal supports multiple spoken languages and wants to know the language of text we provide.  For Tripal fields we always use 'und' meaning 'undefined'.   The next element is the delta index number.  Field have a cardinality, or in other words they can have multiple values.  For every value we add we increment that index, always starting at zero.  The last element is our 'value' element and it is here where we put our element. You may notice that our **delta** index is hard coded to 0.  This is because an entity can only always have one organism that it is associated with.  We will never have more than one.
+Notice that our field has some sub elements. The first is 'und'.  This element corresponds to the "language" of the text.  Drupal supports multiple spoken languages and wants to know the language of text we provide.  For Tripal fields we always use 'und' meaning 'undefined'.   The next element is the delta index number.  Fields have a cardinality, or in other words they can have multiple values.  For every value we add we increment that index, always starting at zero.  The last element is our 'value' element and it is here where we put our element. You may notice that our **delta** index is hard coded to 0.  This is because an entity can only always have one organism that it is associated with.  We will never have more than one.
 
 Now that we've got some preliminary values and we've initialized our value array we can start adding values!  Before we do though, let's double check that we have a record.  If we don't have a record for this entity, we can't get a value.
 
@@ -222,7 +222,7 @@ We can easily get all of the values we need from this organism object.   We can
 
 .. code-block:: php 
 
-      $label = tripal_replace_chado_tokens($string, $organism);
+      $label = chado_replace_tokens($string, $organism);
       $entity->{$field_name}['und'][0]['value'] = array(
         $label_term => $label,
         $genus_term => $organism->genus,
@@ -278,7 +278,7 @@ We do this because anything in the 'value' element is intended for the end-user.
 
   1.  Does the user need this value?  If yes, put it in the 'value' element.
   2.  Does Tripal need the value when writing back to the Chado table?  If yes, put it as a hidden element.
-  3.  Does the user need to see the value an will this same value need to be written to the table?  If yes, then you have to put the value in both places.
+  3.  Does the user need to see the value and will this same value need to be written to the table?  If yes, then you have to put the value in both places.
 
 For our **obi__organism** field it is for entities with records in the **feature, stock, library**, etc. tables. Those tables only have an **organism_id** to represent the organism.  So, that's the database column this field is supporting.  We therefore, need to put that field as a hidden field, and all the others are just helpful to the user and don't get saved in the feature, stock or library tables. So, those go in the values array.
 

+ 0 - 8
docs/extensions/in_development.rst

@@ -5,14 +5,6 @@ In Development
 The following modules are not yet ready for production or not fully Tripal 3 compatible.
 
 
-TripalMap
------------
-
-TripalMap MapViewer module displays map data stored in Chado. MapViewer provides interfaces to view all linkage groups of a map, choose a linkage group and zoom in to a specific region of a linkage group, compare maps that share the same markers and change colors of markers/QTL. The interface can be integrated into Tripal map page and hyperlinked to/from any Tripal page that are displayed in maps (marker, QTL, heritable morphological marker and/or gene). The admin page allows site developers some flexibility in the display pattern.
-
-`Documentation <https://gitlab.com/mainlabwsu/tripal_map/blob/master/README.md>`__
-`Repository <https://gitlab.com/mainlabwsu/tripal_map>`__
-
 Tripal Apollo
 --------------
 

+ 8 - 0
docs/extensions/visualization.rst

@@ -59,3 +59,11 @@ This module provides additional fields for use with Tripal 3. The current versio
 
 `Documentation <https://github.com/tripal/trpfancy_fields/blob/master/README.md>`__
 `Repository <https://github.com/tripal/trpfancy_fields>`__
+
+TripalMap
+-----------
+
+TripalMap MapViewer module displays map data stored in Chado. MapViewer provides interfaces to view all linkage groups of a map, choose a linkage group and zoom in to a specific region of a linkage group, compare maps that share the same markers and change colors of markers/QTL. The interface can be integrated into Tripal map page and hyperlinked to/from any Tripal page that are displayed in maps (marker, QTL, heritable morphological marker and/or gene). The admin page allows site developers some flexibility in the display pattern.
+
+`Documentation <https://gitlab.com/mainlabwsu/tripal_map/blob/master/README.md>`__
+`Repository <https://gitlab.com/mainlabwsu/tripal_map>`__

+ 1 - 1
docs/user_guide/install_tripal/custom_theme.rst

@@ -7,7 +7,7 @@ Drupal makes it easy to change the look-and-feel of your site by providing Theme
 
 Customizing a Theme
 -------------------
-If you want to make customizations to the theme you should create your own sub theme.  A sub theme borrows from an existing **base theme** (e.g. Bartik) and allows you to make your customizations.  Thus, when updates for a theme are released you can easily upgrade your base theme without losing your changes.   To create a sub theme, follow the instructions on the `Creating a sub-theme page <https://www.drupal.org/docs/7/theming/creating-a-sub-theme>`_ on the Drupal website.  Alternatively, completely custom themes do not borrow from any other theme, you can create your own full-blown theme by following the `Themeing instructions <https://www.drupal.org/docs/7/theming>`_ at the Drupal website.
+If you want to make customizations to the theme you should create your own sub theme.  A sub theme borrows from an existing **base theme** (e.g. Bartik) and allows you to make your customizations.  Thus, when updates for a theme are released you can easily upgrade your base theme without losing your changes.   To create a sub theme, follow the instructions on the `Creating a sub-theme page <https://www.drupal.org/docs/7/theming/creating-a-sub-theme>`_ on the Drupal website.  Alternatively, completely custom themes do not borrow from any other theme, you can create your own full-blown theme by following the `Theming instructions <https://www.drupal.org/docs/7/theming>`_ at the Drupal website.
 
 .. note::
 

+ 2 - 2
legacy/tripal_core/api/tripal_core.chado_nodes.properties.api.inc

@@ -178,7 +178,7 @@ function chado_add_node_form_properties(&$form, &$form_state, $details) {
   // make sure the property table exists before proceeding.
   if (!chado_table_exists($details['property_table'])) {
     drupal_set_message("Cannot add property elements to the form. The property table, '" .
-      $details['property_table'] . "', does not exists", "error");
+      $details['property_table'] . "', does not exist", "error");
     tripal_report_error('tcprops_form', TRIPAL_ERROR,
       "Cannot add property elements to the form. The property table, '%name', cannot be found.",
       ['%name' => $details['property_table']]);
@@ -203,7 +203,7 @@ function chado_add_node_form_properties(&$form, &$form_state, $details) {
     $result = chado_select_record('cv', ['cv_id'], ['name' => $details['cv_name']]);
     if (count($result) == 0) {
       drupal_set_message("Cannot add property elements to the form. The CV name, '" .
-        $details['cv_name'] . "', does not exists", "error");
+        $details['cv_name'] . "', does not exist", "error");
       tripal_report_error('tcprops_form', TRIPAL_ERROR,
         "Cannot add property elements to the form. The CV named, '%name', cannot be found.",
         ['%name' => $details['cv_name']]);

+ 2 - 2
legacy/tripal_core/api/tripal_core.chado_nodes.relationships.api.inc

@@ -155,7 +155,7 @@ function chado_add_node_form_relationships(&$form, &$form_state, $details) {
   // make sure the relationship table exists before proceeding.
   if (!chado_table_exists($details['relationship_table'])) {
     drupal_set_message("Cannot add relationship elements to the form. The relationship table, '" .
-      $details['relationship_table'] . "', does not exists", "error");
+      $details['relationship_table'] . "', does not exist", "error");
     tripal_report_error('tcrel_form', TRIPAL_ERROR, "Cannot add relationship elements to the form.
       The relationship table, '%name', cannot be found.", ['%name' => $details['relationship_table']]);
     return;
@@ -167,7 +167,7 @@ function chado_add_node_form_relationships(&$form, &$form_state, $details) {
     $result = chado_select_record('cv', ['cv_id'], ['name' => $details['cv_name']]);
     if (count($result) == 0) {
       drupal_set_message("Cannot add relationship elements to the form. The CV name, '" .
-        $details['cv_name'] . "', does not exists", "error");
+        $details['cv_name'] . "', does not exist", "error");
       tripal_report_error('tcrel_form', TRIPAL_ERROR, "Cannot add relationship elements to the form.
         The CV named, '%name', cannot be found.", ['%name' => $details['cv_name']]);
       return;

+ 2 - 2
legacy/tripal_phylogeny/tripal_phylogeny.drush.inc

@@ -184,7 +184,7 @@ function drush_tripal_phylogeny_trp_update_phylotree() {
       $options['phylotree_id'] = $phylotree[0]->phylotree_id;
     }
     else {
-      drush_print('A phylotree record with this name does not exists.');
+      drush_print('A phylotree record with this name does not exist.');
     }
   }
 
@@ -234,7 +234,7 @@ function drush_tripal_phylogeny_trp_delete_phylotree() {
       $options['phylotree_id'] = $phylotree[0]->phylotree_id;
     }
     else {
-      drush_print('A phylotree record with this name does not exists.');
+      drush_print('A phylotree record with this name does not exist.');
     }
   }
 

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

@@ -641,11 +641,15 @@ function tripal_tripal_cron_notification() {
         ['%bundle' => $bundle_name]);
       return FALSE;
     }
+    $term = tripal_load_term_entity(['term_id' => $bundle->term_id]);
+
     // Allow modules to add fields to the new bundle.
     $modules = module_implements('bundle_fields_info');
     foreach ($modules as $module) {
       $function = $module . '_bundle_fields_info';
-      $info = $function('TripalEntity', $bundle);
+      $entity_type = 'TripalEntity';
+      $info = $function($entity_type, $bundle);
+      drupal_alter('bundle_fields_info', $info, $bundle, $term);
       foreach ($info as $field_name => $details) {
 
         // If the field already exists then skip it.
@@ -670,7 +674,9 @@ function tripal_tripal_cron_notification() {
     $modules = module_implements('bundle_instances_info');
     foreach ($modules as $module) {
       $function = $module . '_bundle_instances_info';
-      $info = $function('TripalEntity', $bundle);
+      $entity_type = 'TripalEntity';
+      $info = $function($entity_type, $bundle);
+      drupal_alter('bundle_instances_info', $info, $bundle, $term);
       foreach ($info as $field_name => $details) {
 
         // If the field is already attached to this bundle then skip it.

+ 40 - 0
tripal/api/tripal.fields.api.inc

@@ -94,6 +94,26 @@ function hook_bundle_fields_info($entity_type, $bundle) {
 
 }
 
+/**
+ * Allows a module to adjust a field's info settings.
+ *
+ * Modules should only adjust the info array for fields that
+ * they manage and not fields that were created by other modules. For example,
+ * if a field corresponds to a column in a custom table of Chado, then the
+ * tripal_chado module will automatically create a field for it. This function
+ * can be used to override the default settings created by Chado.
+ *
+ * @param $info
+ *  The fields info array for all fields.
+ * @param $bundle
+ *  The bundle content type object that the field belongs to.
+ * @param $term
+ *  The bundle type term.
+ */
+function hook_bundle_fields_info_alter(&$info, $bundle, $term) {
+
+}
+
 /**
  * Allows a module to return the field instances of a bundle.
  *
@@ -108,6 +128,26 @@ function hook_bundle_instances_info($entity_type, $bundle) {
 
 }
 
+
+/**
+ * Allows a module to adjust field instances info settings.
+ *
+ * Modules should only adjust the info array for field instances that
+ * they manage and not fields that were created by other modules. For example,
+ * if a field corresponds to a column in a custom table of Chado, then the
+ * tripal_chado module will automatically create a field for it. This function
+ * can be used to override the default settings created by Chado.
+ *
+ * @param $info
+ *  The field instance info array for all fields.
+ * @param $bundle
+ *  The bundle content type object that the field belongs to.
+ * @param $term
+ *  The bundle type term.
+ */
+function hook_bundle_instances_info_alter(&$info, $bundle, $term) {
+
+}
 /**
  * Indicate if a field has an empty value.
  *

+ 10 - 3
tripal/includes/tripal.admin_blocks.inc

@@ -23,10 +23,15 @@ function tripal_admin_notification_import_field($field_name_note, $bundle_id, $m
     drupal_goto("admin/dashboard");
     return FALSE;
   }
+  $term = tripal_load_term_entity(['term_id' => $bundle->term_id]);
 
+
+  $instance = NULL;
   if ($field_or_instance == 'field') {
     $function = $module . '_bundle_fields_info';
-    $info = $function('TripalEntity', $bundle);
+    $entity_type = 'TripalEntity';
+    $info = $function($entity_type, $bundle);
+    drupal_alter('bundle_fields_info', $info, $bundle, $term);
     foreach ($info as $field_name => $details) {
       $field = field_info_field($field_name);
       if ($details['field_name'] == $field_name_note) {
@@ -44,7 +49,9 @@ function tripal_admin_notification_import_field($field_name_note, $bundle_id, $m
   else {
     if ($field_or_instance == 'instance') {
       $function = $module . '_bundle_instances_info';
-      $info = $function('TripalEntity', $bundle);
+      $entity_type = 'TripalEntity';
+      $info = $function($entity_type, $bundle);
+      drupal_alter('bundle_instances_info', $info, $bundle, $term);
       foreach ($info as $field_name => $details) {
         if ($details['field_name'] == $field_name_note) {
           // Create the field instance.
@@ -68,7 +75,7 @@ function tripal_admin_notification_import_field($field_name_note, $bundle_id, $m
       ->execute();
   }
   else {
-    drupal_set_message(t("There was a problem creating: %field", ['%field' => $info[$field_name]['label']]));
+    drupal_set_message(t("There was a problem creating field."), 'error');
   }
 
   drupal_goto("admin/dashboard");

+ 1 - 1
tripal/tripal.module

@@ -812,7 +812,7 @@ function tripal_theme($existing, $type, $theme, $path) {
     'tripal_add_list' => array(
       'variables' => array('content' => NULL),
     ),
-    // Themeing for all fields.
+    // Theming for all fields.
     'tripal_field_default' => array(
       'render element' => 'element',
       'file' => 'includes/tripal.fields.inc',

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

@@ -702,7 +702,7 @@ function chado_insert_cv($name, $definition) {
   $sel_values = ['name' => $name];
   $results = chado_select_record('cv', ['*'], $sel_values);
 
-  // If it does not exists then add it.
+  // If it does not exist then add it.
   if (count($results) == 0) {
     $success = chado_insert_record('cv', $ins_values);
     if (!$success) {
@@ -963,7 +963,7 @@ function chado_insert_cvterm($term, $options = []) {
         'is_for_definition' => 1,
       ];
       $result = chado_select_record('cvterm_dbxref', ['*'], $values);
-      // if the cvterm_dbxref record does not exists then add it
+      // if the cvterm_dbxref record does not exist then add it
       if (count($result) == 0) {
         $options = [
           'return_record' => FALSE,

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

@@ -375,7 +375,7 @@ function chado_insert_db($values, $options = []) {
   $sel_values = ['name' => $dbname];
   $result = chado_select_record('db', ['*'], $sel_values);
 
-  // If it does not exists then add it.
+  // If it does not exist then add it.
   if (count($result) == 0) {
     $ins_options = ['statement_name' => 'ins_db_nadeurur'];
     $success = chado_insert_record('db', $ins_values, $ins_options);

+ 37 - 18
tripal_chado/api/modules/tripal_chado.organism.api.inc

@@ -1,7 +1,7 @@
 <?php
 /**
  * @file
- * Provides API functions specifically for managing feature
+ * Provides API functions specificially for managing feature
  * records in Chado.
  */
 
@@ -9,7 +9,7 @@
  * @defgroup tripal_organism_api Chado Organism
  * @ingroup tripal_chado_api
  * @{
- * Provides API functions specifically for managing organism
+ * Provides API functions specificially for managing organism
  * records in Chado.
  * @}
  */
@@ -19,7 +19,7 @@
  *
  * @param $identifier
  *   An array with the key stating what the identifier is. Supported keys (only
- *   on of the following unique keys is required):
+ *   one of the following unique keys is required):
  *    - organism_id: the chado organism.organism_id primary key.
  *    - genus & species: the chado organism.genus field & organism.species
  *   field. There are also some specially handled keys. They are:
@@ -48,7 +48,7 @@ function chado_get_organism($identifiers, $options = []) {
 
   // Set Defaults.
   if (!isset($options['include_fk'])) {
-    // Tells chado_generate_var not to follow any foreign keys.
+    // Tells chado_generate_var to not follow any foreign keys.
     $options['include_fk'] = [];
   }
 
@@ -89,7 +89,7 @@ function chado_get_organism($identifiers, $options = []) {
   }
 
   // Else we have a simple case and we can just use chado_generate_var to get 
-  // the analysis.
+  // the organism.
   else {
 
     // Try to get the organism
@@ -118,7 +118,7 @@ function chado_get_organism($identifiers, $options = []) {
     tripal_report_error(
       'tripal_organism_api',
       TRIPAL_ERROR,
-      "chado_get_organism: chado_generate_var() failed to return a organism based on the identifiers
+      "chado_get_organism: chado_generate_var() failed to return an organism based on the identifiers
         you passed in. You should check that your identifiers are correct, as well as, look
         for a chado_generate_var error for additional clues. You passed in %identifier.",
       [
@@ -150,7 +150,7 @@ function chado_get_organism_scientific_name($organism) {
   // For Chado v1.3 we have a type_id and infraspecific name.
   if (property_exists($organism, 'type_id')) {
     $rank = '';
-    // For organism objects crated using chado_generate_var.
+    // For organism objects created using chado_generate_var.
     if (is_object($organism->type_id)) {
       if ($organism->type_id) {
         $rank = $organism->type_id->name;
@@ -165,13 +165,14 @@ function chado_get_organism_scientific_name($organism) {
 
     if ($rank) {
       $rank = chado_abbreviate_infraspecific_rank($rank);
-      $name .= ' ' . $rank . ' ' . $organism->infraspecific_name;
-    }
-    else {
-      if ($organism->infraspecific_name) {
-        $name .= ' ' . $organism->infraspecific_name;
+      // rank will now be an empty string if it had been the "no_rank" cv term
+      if ($rank) {
+        $name .= ' ' . $rank;
       }
     }
+    if ($organism->infraspecific_name) {
+      $name .= ' ' . $organism->infraspecific_name;
+    }
   }
   return $name;
 }
@@ -201,21 +202,33 @@ function chado_get_organism_select_options($syncd_only = TRUE) {
         INNER JOIN {organism} O ON O.organism_id = CO.organism_id
       ORDER BY O.genus, O.species
     ";
+    // if present in this site's version of chado, include infraspecific nomenclature in sorting
+    if (chado_column_exists('organism', 'infraspecific_name')) {
+      $sql .= ", REPLACE ((SELECT name FROM {cvterm} CVT WHERE CVT.cvterm_id = O.type_id
+                AND CVT.cv_id = (SELECT cv_id FROM {cv} WHERE name='taxonomic_rank')), 'no_rank', ''),
+                O.infraspecific_name";
+    }
     $orgs = chado_query($sql);
 
     // Iterate through the organisms and build an array of those that are synced.
     foreach ($orgs as $org) {
-      $org_list[$org->organism_id] = $org->genus . ' ' . $org->species;
+      $org_list[$org->organism_id] = chado_get_organism_scientific_name($org);
     }
   }
   else {
     // use this SQL statement for getting the organisms
     $csql = "SELECT * FROM {organism} ORDER BY genus, species";
+    // if present in this site's version of chado, include infraspecific nomenclature in sorting
+    if (chado_column_exists('organism', 'infraspecific_name')) {
+      $csql .= ", REPLACE ((SELECT name FROM {cvterm} CVT WHERE CVT.cvterm_id = type_id" .
+               " AND CVT.cv_id = (SELECT cv_id FROM {cv} WHERE name='taxonomic_rank')), 'no_rank', '')," .
+               " infraspecific_name";
+    }
     $orgs = chado_query($csql);
 
     // Iterate through the organisms and build an array of those that are synced.
     foreach ($orgs as $org) {
-      $org_list[$org->organism_id] = $org->genus . ' ' . $org->species;
+      $org_list[$org->organism_id] = chado_get_organism_scientific_name($org);
     }
   }
   return $org_list;
@@ -245,7 +258,7 @@ function chado_get_organism_image_url($organism) {
 
   // Look in the file_usage table of Drupal for the image file. This
   // is the current way for handling uploaded images. It allows the file to
-  // keep it's proper name and extension.
+  // keep its proper name and extension.
   $fid = db_select('file_usage', 'fu')
     ->fields('fu', ['fid'])
     ->condition('module', 'tripal_organism')
@@ -270,7 +283,7 @@ function chado_get_organism_image_url($organism) {
     return $url;
   }
 
-  // If we don't find the file using the genus ans species then look for the
+  // If we don't find the file using the genus and species then look for the
   // image with the node ID in the name. This method was used for Tripal 1.1
   // and 2.x-alpha version.
   $image_name = $nid . ".jpg";
@@ -310,8 +323,14 @@ function chado_autocomplete_organism($text) {
     $sql .= "AND lower(species) like lower(:species) ";
     $args[':species'] = $species . '%';
   }
-  $sql .= "ORDER BY genus, species ";
-  $sql .= "LIMIT 25 OFFSET 0 ";
+  $sql .= "ORDER BY genus, species";
+  // if present in this site's version of chado, include infraspecific nomenclature in sorting
+  if (chado_column_exists('organism', 'infraspecific_name')) {
+    $sql .= ", REPLACE ((SELECT name FROM {cvterm} CVT WHERE CVT.cvterm_id = type_id" .
+            " AND CVT.cv_id = (SELECT cv_id FROM {cv} WHERE name='taxonomic_rank')), 'no_rank', '')," .
+            " infraspecific_name";
+  }
+  $sql .= " LIMIT 25 OFFSET 0";
   $results = chado_query($sql, $args);
   $items = [['args' => [$sql => $args]]];
   foreach ($results as $organism) {

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

@@ -116,7 +116,7 @@ function chado_validate_phylotree($val_type, &$options, &$errors, &$warnings) {
     // If this is a numeric Drupal file then all is good, no need to check.
     if (!is_numeric($options['tree_file'])) {
       if (!file_exists($options['tree_file'])) {
-        $errors['tree_file'] = t('The file provided does not exists.');
+        $errors['tree_file'] = t('The file provided does not exist.');
         return FALSE;
       }
     }

+ 58 - 58
tripal_chado/api/tripal_chado.variables.api.inc

@@ -119,13 +119,13 @@
  *     property table (e.g. featureprop) and you want the CV and accession
  *     but do not want the DB the following array would work:
  *
- *        $table_options =  array(
- *          'include_fk' => array(
- *            'type_id' => array(
+ *        $table_options =  [
+ *          'include_fk' => [
+ *            'type_id' => [
  *              'cv_id' => 1,
  *              'dbxref_id' => 1,
- *            )
- *          )
+ *            ]
+ *          ]
  *        );
  *
  *     The above array will expand the 'type_id' of the property table but only
@@ -198,19 +198,19 @@ function chado_generate_var($table, $values, $base_options = []) {
 
   // This allows modules to specify that some fields should be excluded by default
   // For example, tripal core provides a tripal_chado_exclude_field_from_feature_by_default()
-  // which says that we usually don't want to include the residues field by 
+  // which says that we usually don't want to include the residues field by
   // default since it can be very large and cause performance issues.
 
-  // If a field is excluded by default it can always be expanded at a later 
-  // point by calling chado_expand_var($chado_var, 'field', 
+  // If a field is excluded by default it can always be expanded at a later
+  // point by calling chado_expand_var($chado_var, 'field',
   // <field name as shown in expandable_fields array>);
 
   // First get an array of all the fields to be removed for the current table
-  // module_invoke_all() is drupal's way of invoking all implementations of the 
+  // module_invoke_all() is drupal's way of invoking all implementations of the
   // specified hook and merging all of the results.
 
   // $fields_to_remove should be an array with the keys matching field names
-  // and the values being strings to be executed using php_eval() to determine 
+  // and the values being strings to be executed using php_eval() to determine
   // whether to exclude the field (evaluates to TRUE) or not (evaluates to FALSE)
   $fields_to_remove = module_invoke_all('exclude_field_from_' . $table . '_by_default');
 
@@ -226,7 +226,7 @@ function chado_generate_var($table, $values, $base_options = []) {
     }
 
     // If criteria then remove from query
-    // @coder-ignore: only module designers can populate $criteria -not a 
+    // @coder-ignore: only module designers can populate $criteria -not a
     // security risk.
     $success = php_eval('<?php return ' . $criteria . '; ?>');
     if ($success) {
@@ -239,35 +239,35 @@ function chado_generate_var($table, $values, $base_options = []) {
   // Get fields to be removed by type................................
   // This gets all implementations of hook_exclude_type_by_default().
 
-  // This allows modules to specify that some types of fields should be excluded 
-  // by default For example, tripal core provides a 
-  // tripal_chado_exclude_type_by_default() which says that text fields are 
+  // This allows modules to specify that some types of fields should be excluded
+  // by default For example, tripal core provides a
+  // tripal_chado_exclude_type_by_default() which says that text fields are
   // often very large and if they are longer than 250 characters then
   // we want to exclude them by default
 
-  // If a field is excluded by default it can always be expanded at a later 
-  // point by calling chado_expand_var($chado_var, 'field', 
+  // If a field is excluded by default it can always be expanded at a later
+  // point by calling chado_expand_var($chado_var, 'field',
   //<field name as shown in expandable_fields array>);
 
   // First get an array of all the types of fields to be removed for the current
-  // table module_invoke_all() is drupal's way of invoking all implementations 
+  // table module_invoke_all() is drupal's way of invoking all implementations
   // of the specified hook and merging all of the results.
 
   // $types_to_remove should be an array with the keys matching field names
-  // and the values being strings to be executed using php_eval() to determine 
+  // and the values being strings to be executed using php_eval() to determine
   // whether to exclude the field (evaluates to TRUE) or not (evaluates to FALSE)
   // (ie: array('text' => 'strlen("<field_value> ") > 100');
   $types_to_remove = module_invoke_all('exclude_type_by_default');
 
   // Get a list of all the types of fields
-  // the key is the type of field and the value is an array of fields of this 
+  // the key is the type of field and the value is an array of fields of this
   // type.
   $field_types = [];
   foreach ($table_desc['fields'] as $field_name => $field_array) {
     $field_types[$field_array['type']][] = $field_name;
   }
 
-  // We want to use the types to remove in conjunction with our table field 
+  // We want to use the types to remove in conjunction with our table field
   // descriptions to determine which fields might need to be removed.
   foreach ($types_to_remove as $field_type => $criteria) {
 
@@ -286,8 +286,8 @@ function chado_generate_var($table, $values, $base_options = []) {
         }
 
         // If criteria then remove from query
-        // (as long as <field_value> is not needed for the criteria to be 
-        // evaluated) @coder-ignore: only module designers can populate 
+        // (as long as <field_value> is not needed for the criteria to be
+        // evaluated) @coder-ignore: only module designers can populate
         //$criteria -not a security risk.
         $success = php_eval('<?php return ' . $criteria . '; ?>');
         if ($success) {
@@ -316,7 +316,7 @@ function chado_generate_var($table, $values, $base_options = []) {
 
       // For Tripal v2 compatibility
       // check if the current table maps to a node type-------------------------
-      // If this table is connected to a node there will be a chado_tablename 
+      // If this table is connected to a node there will be a chado_tablename
       // table in drupal.
       $base_tables = chado_get_base_tables();
       if (module_exists('tripal_core') and db_table_exists('chado_' . $table)) {
@@ -344,10 +344,10 @@ function chado_generate_var($table, $values, $base_options = []) {
 
       // Remove any fields where criteria needs to be evalulated----------------
       // The fields to be removed can be populated by implementing either
-      // hook_exclude_field_from_<table>_by_default() where <table> is the 
-      // current table OR hook_exclude_type_by_default() where there are fields 
-      // of the specified type in the current table It only reaches this point 
-      // if the criteria specified for whether or not to exclude the field 
+      // hook_exclude_field_from_<table>_by_default() where <table> is the
+      // current table OR hook_exclude_type_by_default() where there are fields
+      // of the specified type in the current table It only reaches this point
+      // if the criteria specified for whether or not to exclude the field
       // includes <field_value> which means it has to be evaluated after
       // the query has been executed.
       foreach ($fields_to_remove as $field_name => $criteria) {
@@ -358,7 +358,7 @@ function chado_generate_var($table, $values, $base_options = []) {
           break;
         }
 
-        // Replace <field_value> with the actual value of the field from the 
+        // Replace <field_value> with the actual value of the field from the
         // query.
         $field_name_safe = preg_replace('/\'|"|\\\/', '\\1', $object->{$field_name});
         $criteria = preg_replace('/<field_value>/', $field_name_safe, $criteria);
@@ -379,22 +379,22 @@ function chado_generate_var($table, $values, $base_options = []) {
           $foreign_table = $foreign_key_array['table'];
           foreach ($foreign_key_array['columns'] as $foreign_key => $primary_key) {
 
-            // Note: Foreign key is the field in the current table whereas 
-            // primary_key is the field in the table referenced by the foreign 
+            // Note: Foreign key is the field in the current table whereas
+            // primary_key is the field in the table referenced by the foreign
             // key, don't do anything if the foreign key is empty
             if (empty($object->{$foreign_key})) {
               continue;
             }
 
             if (is_array($include_fk)) {
-              // Don't recurse if the callee has supplied an $fk_include list 
+              // Don't recurse if the callee has supplied an $fk_include list
               // and this FK table is not in the list.
               if (is_array($include_fk) and !array_key_exists($foreign_key, $include_fk)) {
                 $object->expandable_foreign_keys[] = $table . '.' . $foreign_key . ' => ' . $foreign_table;
                 continue;
               }
             }
-            // If we have the option but it is not an array then we don't 
+            // If we have the option but it is not an array then we don't
             // recurse any further.
             if ($include_fk === TRUE) {
               $object->expandable_foreign_keys[] = $table . '.' . $foreign_key . ' => ' . $foreign_table;
@@ -713,8 +713,8 @@ function chado_expand_var($object, $type, $to_expand, $table_options = []) {
           // Get the value of the foreign key from the object
           $field_value = $object->{$field_name};
 
-          // Get the name of the field in the foreign table using the table 
-          // description For example, with the 
+          // Get the name of the field in the foreign table using the table
+          // description For example, with the
           // feature.type_id => cvterm.cvterm_id we need cvterm_id
           $foreign_field_name = FALSE;
           foreach ($table_desc['foreign keys'][$foreign_table]['columns'] as $left => $right) {
@@ -729,7 +729,7 @@ function chado_expand_var($object, $type, $to_expand, $table_options = []) {
 
             // Generate a chado variable of the foreign key
             // For example, if the foreign key to expand is feature.type_id
-            // then we want to generate a chado cvterm variable that matches the 
+            // then we want to generate a chado cvterm variable that matches the
             // feature.type_id.
             $foreign_var = chado_generate_var(
               $foreign_table, // thus in the example above, generate a cvterm var
@@ -740,7 +740,7 @@ function chado_expand_var($object, $type, $to_expand, $table_options = []) {
             // Check that the foreign object was returned.
             if ($foreign_var) {
 
-              // It was so now we can add this chado variable to our current 
+              // It was so now we can add this chado variable to our current
               // object in place of the key value.
               $object->{$field_name} = $foreign_var;
               $object->expanded = $to_expand;
@@ -778,7 +778,7 @@ function chado_expand_var($object, $type, $to_expand, $table_options = []) {
 
         }
       }
-      // Otherwise we weren't able to extract the parts of the foreign key to 
+      // Otherwise we weren't able to extract the parts of the foreign key to
       // expand thus we will warn the administrator.
       else {
         tripal_report_error('tripal_chado', TRIPAL_ERROR,
@@ -796,8 +796,8 @@ function chado_expand_var($object, $type, $to_expand, $table_options = []) {
       }
       $foreign_table_desc = chado_get_schema($foreign_table);
 
-      // If we don't get a foreign_table (which could happen of a custom 
-      // table is not correctly defined or the table name is mispelled then we 
+      // If we don't get a foreign_table (which could happen of a custom
+      // table is not correctly defined or the table name is mispelled then we
       // should return gracefully.
       if (!is_array($foreign_table_desc)) {
         return $object;
@@ -837,16 +837,16 @@ function chado_expand_var($object, $type, $to_expand, $table_options = []) {
             $filter_criteria = [$left => $object->{$right}];
           }
 
-          // Generate a new object for this table using the FK values in the 
+          // Generate a new object for this table using the FK values in the
           // base table.
           $new_options = $table_options;
           $foreign_object = chado_generate_var($foreign_table, $filter_criteria, $new_options);
 
-          // If the generation of the object was successful, update the base 
+          // If the generation of the object was successful, update the base
           // object to include it.
           if ($foreign_object) {
             // In the case where the foreign key relationship exists more
-            // than once with the same table we want to alter the array 
+            // than once with the same table we want to alter the array
             // structure to include the field name.
             if (count($foreign_table_desc['foreign keys'][$base_table]['columns']) > 1) {
               if (!property_exists($object, $foreign_table)) {
@@ -867,7 +867,7 @@ function chado_expand_var($object, $type, $to_expand, $table_options = []) {
           // If the object returned is NULL then handle that.
           else {
             // In the case where the foreign key relationship exists more
-            // than once with the same table we want to alter the array 
+            // than once with the same table we want to alter the array
             // structure to include the field name.
             if (count($foreign_table_desc['foreign keys'][$base_table]['columns']) > 1) {
               if (!property_exists($object, $foreign_table)) {
@@ -881,18 +881,18 @@ function chado_expand_var($object, $type, $to_expand, $table_options = []) {
           }
         }
       }
-      // RECURSIVE CASE: if the table is not connected directly to the current 
-      // base table through a foreign key relationship, then maybe it has a 
+      // RECURSIVE CASE: if the table is not connected directly to the current
+      // base table through a foreign key relationship, then maybe it has a
       // relationship to one of the nested objects.
       else {
 
         // We need to recurse -the table has a relationship to one of the nested
-        // objects. We assume it's a nested object if the value of the field is 
+        // objects. We assume it's a nested object if the value of the field is
         // an object.
         $did_expansion = 0;
         foreach ((array) $object as $field_name => $field_value) {
 
-          // CASE #1: This field is an already expanded foreign key and the 
+          // CASE #1: This field is an already expanded foreign key and the
           // table to be expanded is in the table referenced by the foreign key.
 
           // First of all it can only be expanded if it's an object
@@ -902,10 +902,10 @@ function chado_expand_var($object, $type, $to_expand, $table_options = []) {
           }
 
           // CASE #2: This field is an already expanded object (ie: the field is
-          // actually the expanded table name) and the table to be expanded is 
+          // actually the expanded table name) and the table to be expanded is
           // related to it.
 
-          // Check to see if the $field_name is a valid chado table, we don't 
+          // Check to see if the $field_name is a valid chado table, we don't
           // need to call chado_expand_var on fields that aren't tables.
           $check = chado_get_schema($field_name);
           if ($check) {
@@ -914,7 +914,7 @@ function chado_expand_var($object, $type, $to_expand, $table_options = []) {
           }
         }
 
-        // If we did not expand this table we should return a message that the 
+        // If we did not expand this table we should return a message that the
         // foreign tabl could not be expanded.
         if (!$did_expansion) {
           tripal_report_error('tripal_chado', TRIPAL_ERROR, 'chado_expand_var: Could not expand %table. ' .
@@ -929,7 +929,7 @@ function chado_expand_var($object, $type, $to_expand, $table_options = []) {
 
     case "node": //-------------------------------------------------------------
 
-      // BASE CASE: if the node to be expanded is for our base table, then just 
+      // BASE CASE: if the node to be expanded is for our base table, then just
       // expand it.
       if ($object->tablename == $to_expand) {
 
@@ -940,7 +940,7 @@ function chado_expand_var($object, $type, $to_expand, $table_options = []) {
         }
         // Try to get the nid based on the tablename.
         else {
-          // Invoke all hook_node_info to avoid hard-coding the chado_$table 
+          // Invoke all hook_node_info to avoid hard-coding the chado_$table
           // assumption..
           foreach (module_invoke_all('node_info') as $node_info) {
             if (array_key_exists('chado_node_api', $node_info)) {
@@ -973,7 +973,7 @@ function chado_expand_var($object, $type, $to_expand, $table_options = []) {
           unset($object->expandable_nodes);
 
           // The node becomes the base object with the obejct added to it.
-          // For example, we may start with a feature object with a name, 
+          // For example, we may start with a feature object with a name,
           // uniquename , type, etc. After expanding we will return the node and
           // at $node->feature you will find the original object.
           $node->{$base_table} = $object;
@@ -993,7 +993,7 @@ function chado_expand_var($object, $type, $to_expand, $table_options = []) {
           }
         } //End of if node.
       }
-      // RECURSIVE CASE: check to see if the node to be expanded associates with 
+      // RECURSIVE CASE: check to see if the node to be expanded associates with
       // a chado table within one of the nested objects.
       else {
 
@@ -1019,7 +1019,7 @@ function chado_expand_var($object, $type, $to_expand, $table_options = []) {
   }
 
   // Move expandable arrays downwards -------------------------------
-  // If the type was either table or foreign key then a new chado variable was 
+  // If the type was either table or foreign key then a new chado variable was
   // generated this variable will have it's own expandable array's which need to
   // be moved down and merged with the base objects expandable arrays.
 
@@ -1054,7 +1054,7 @@ function chado_expand_var($object, $type, $to_expand, $table_options = []) {
         // Move expandable foreign keys downwards.
         if (isset($field_value->expandable_foreign_keys) and is_array($field_value->expandable_foreign_keys)) {
 
-          // If the current object has it's own expandable foreign keys then 
+          // If the current object has it's own expandable foreign keys then
           // merge them.
           if (isset($object->expandable_foreign_keys)) {
             $object->expandable_foreign_keys = array_merge(
@@ -1116,7 +1116,7 @@ function chado_expand_var($object, $type, $to_expand, $table_options = []) {
   // This tells us what we have expanded (ie: that we succeeded)
   // and is needed to remove the entry from the expandable array.
 
-  // If there is no expanded field in the current object then check any of the 
+  // If there is no expanded field in the current object then check any of the
   // nested objects and move it down.
   if (!property_exists($object, 'expanded')) {
 
@@ -1139,7 +1139,7 @@ function chado_expand_var($object, $type, $to_expand, $table_options = []) {
   // We check again because it might have been moved downwards above.
   if (property_exists($object, 'expanded')) {
 
-    // If so, then remove the expanded identifier from the correct expandable 
+    // If so, then remove the expanded identifier from the correct expandable
     // array..
     $expandable_name = 'expandable_' . $type . 's';
     if (property_exists($object, $expandable_name) and $object->{$expandable_name}) {

+ 6 - 1
tripal_chado/includes/TripalFields/chado_linker__prop/chado_linker__prop_formatter.inc

@@ -27,7 +27,12 @@ class chado_linker__prop_formatter extends ChadoFieldFormatter {
 
     $list = [];
     foreach ($items as $index => $item) {
-      $list[$index] = $item['value'];
+      $value = $item['value'];
+      // any URLs are made into clickable links
+      if ( preg_match('/^https?:/i', $value) ) {
+        $value = l($value, $value, ['external' => 'TRUE', 'attributes' => ['target' => '_blank']]);
+      }
+      $list[$index] = $value;
     }
 
     // Also need to make sure to not return markup if the field is empty.

+ 1 - 1
tripal_chado/includes/TripalFields/sbo__relationship/sbo__relationship_formatter.inc

@@ -89,7 +89,7 @@ class sbo__relationship_formatter extends ChadoFieldFormatter {
 
       // Add bold font to the object and subject names.
       // @todo add back in bolding...
-      // @todo Fix Current Bug: if type name is in the object name, wierd bolding happens.
+      // @todo Fix Current Bug: if type name is in the object name, weird bolding happens.
       // $phrase = preg_replace("/$subject_type/", "<b>$subject_type</b>", $phrase);
       // $phrase = preg_replace("/$object_type/", "<b>$object_type</b>", $phrase);
 

+ 91 - 28
tripal_chado/includes/TripalFields/sio__references/sio__references.inc

@@ -41,6 +41,8 @@ class sio__references extends ChadoField {
     'chado_column' => 'pub_id',
     // The base table.
     'base_table' => 'pub',
+    // The number of items to show on a page.
+    'items_per_page' => 10,
   ];
 
   // The default widget for this field.
@@ -97,75 +99,136 @@ class sio__references extends ChadoField {
     foreach ($chado_tables as $chado_table) {
       $matches = [];
       if (preg_match('/^(.+?)_pub$/', $chado_table, $matches)) {
+
         $reference_table = $matches[1];
 
-        // Find the base table this links to and get the fk columns that map it.
+        // Get the schema for the pub linker table table.
         $schema = chado_get_schema($chado_table);
+
+        // Skip tables that don't have a foreign key definition.
+        if (!array_key_exists('foreign keys', $schema)) {
+          continue;
+        }
+
+        // Get information about the linking table.
         $fkeys = $schema['foreign keys'];
+        $fkleft = NULL;
+        $fkright = NULL;
+        $islinked = FALSE;
         foreach ($fkeys as $linked_table => $fk_details) {
+          if ($linked_table == 'pub') {
+            $islinked = TRUE;
+          }
           if ($linked_table == $reference_table) {
             $fkleft = array_keys($fk_details['columns'])[0];
             $fkright = $fk_details['columns'][$fkleft];
           }
+        }
+        // If this table doesn't have an FK to a reference table
+        // then it's just a table with a _pub in the name.
+        if (!$fkleft) {
+          continue;
+        }
+        // If this table does not have a FK to the pub table then
+        // we don't want to search it.
+        if (!$islinked) {
+          continue;
+        }
+
 
+        // Build the SQL to find records assocaited with this publication.
+        $ref_schema = chado_get_schema($reference_table);
+        $ref_pkey = $ref_schema['primary key'][0];
+        $select = "SELECT REF.* ";
+        $from = "FROM {" . $chado_table . "} LINK
+            INNER JOIN {" . $reference_table . "} REF on LINK.$fkleft = REF.$fkright
+        ";
+        if (array_key_exists('type_id', $ref_schema['fields'])) {
+          $select .= ", CVT.name as type_name";
+          $from .= "INNER JOIN {cvterm} CVT on REF.type_id = CVT.cvterm_id ";
         }
+
+        // Get the mapping of the refrence table to a CV term in case the
+        // records in the table don't have a type_id.
+        $ref_mapping = db_select('chado_cvterm_mapping', 'CVM')
+          ->fields('CVM')
+          ->condition('chado_table', $reference_table)
+          ->execute()
+          ->fetchObject();
+        $ref_type = NULL;
+        if ($ref_mapping) {
+          $ref_type = chado_get_cvterm(['cvterm_id' => $ref_mapping->cvterm_id]);
+        }
+
+        // Are the records in this table associated with a content type?
+        // if so, we want to get those types so we can find the entity ID.
+        $bundles = db_select('chado_bundle', 'CB')
+          ->fields('CB', ['bundle_id'])
+          ->condition('CB.data_table', $reference_table)
+          ->execute();
+        $entity_sql = '';
+        while ($bundle_id = $bundles->fetchField()) {
+          $entity_sql .= "SELECT entity_id FROM [chado_bio_data_" . $bundle_id . "] CBD" . $bundle_id . " WHERE record_id = LINK.$ref_pkey UNION ";
+        }
+        if (!empty($entity_sql)) {
+          $entity_sql = rtrim($entity_sql, " UNION ");
+          $entity_sql = ", (" . $entity_sql . " LIMIT 1) as entity_id";
+        }
+
+
         // Iterate through all of the records in the linker table that
         // match the given pub ID.
-        $records = chado_generate_var($chado_table, ['pub_id' => $chado_record->pub_id], ['return_array' => TRUE]);
-        foreach ($records as $record) {
+        $sql = "$select $entity_sql $from WHERE LINK.pub_id = :pub_id";
+        $args = [':pub_id' => $chado_record->pub_id];
+        $records = chado_query($sql, $args);
+        while($record = $records->fetchObject()) {
+        //foreach ($records as $record) {
+
           // We want to add a 'type' and 'name' element to the values (at a
           // minimum) for each of the records.  Unfortunately, every base table
-          // is different and their may not be an easy to identify name,
+          // is different and there may not be an easy to identify name,
           // so... we'll do the best we can.
           $entity->{$field_name}['und'][$delta]['value'] = [];
 
           // First get the type of record.
-          if (property_exists($record->$fkleft, 'type_id') and $record->$fkleft->type_id) {
-            $entity->{$field_name}['und'][$delta]['value']['rdfs:type'] = $record->$fkleft->type_id->name;
+          if (property_exists($record, 'type_name')) {
+            $entity->{$field_name}['und'][$delta]['value']['rdfs:type'] = $record->type_name;
           }
           else {
-            // If there's not a type_id column then see if the table is mapped
-            // to a type.
-            $mapping = db_select('chado_cvterm_mapping', 'CVM')
-              ->fields('CVM')
-              ->condition('chado_table', $reference_table)
-              ->execute()
-              ->fetchObject();
-            if ($mapping) {
-              $cvterm = chado_get_cvterm(['cvterm_id' => $mapping->cvterm_id]);
-              $entity->{$field_name}['und'][$delta]['value']['rdfs:type'] = $cvterm->name;
+            if ($ref_type) {
+              $entity->{$field_name}['und'][$delta]['value']['rdfs:type'] = $ref_type->name;
             }
           }
 
           // Add in the name and uniquename (identifier) if those fields exist.
-          if (property_exists($record->$fkleft, 'name')) {
-            $entity->{$field_name}['und'][$delta]['value']['schema:name'] = $record->$fkleft->name;
+          if (property_exists($record, 'name')) {
+            $entity->{$field_name}['und'][$delta]['value']['schema:name'] = $record->name;
           }
-          if (property_exists($record->$fkleft, 'uniquename')) {
-            $entity->{$field_name}['und'][$delta]['value']['data:0842'] = $record->$fkleft->name;
+          if (property_exists($record, 'uniquename')) {
+            $entity->{$field_name}['und'][$delta]['value']['data:0842'] = $record->name;
           }
 
           // If this records is also a published entity then include that.
-          if (property_exists($record->$fkleft, 'entity_id')) {
-            $entity->{$field_name}['und'][$delta]['value']['entity'] = 'TripalEntity:' . $record->$fkleft->entity_id;
+          if (property_exists($record, 'entity_id') and !empty($record->entity_id)) {
+            $entity->{$field_name}['und'][$delta]['value']['entity'] = 'TripalEntity:' . $record->entity_id;
           }
 
           // If this is the organism table then we will create the name
           // specially.
-          if (property_exists($record->$fkleft, 'genus')) {
-            $name = '<i>' . $record->$fkleft->genus . ' ' . $record->$fkleft->species . '</i>';
-            if (property_exists($record->$fkleft, 'infraspecific_name')) {
+          if (property_exists($record, 'genus')) {
+            $name = '<i>' . $record->genus . ' ' . $record->species . '</i>';
+            if (property_exists($record, 'infraspecific_name')) {
               if ($record->$fkleft->type_id) {
-                $name .= ' ' . $record->$fkleft->type_id->name;
+                $name .= ' ' . $record->type_name;
               }
-              $name .= ' ' . $record->$fkleft->infraspecific_name;
+              $name .= ' ' . $record->infraspecific_name;
             }
             $entity->{$field_name}['und'][$delta]['value']['schema:name'] = $name;
+            $entity->{$field_name}['und'][$delta]['value']['rdfs:type'] = $ref_type->name;
           }
           $delta++;
         }
       }
     }
   }
-
 }

+ 25 - 6
tripal_chado/includes/TripalFields/sio__references/sio__references_formatter.inc

@@ -25,22 +25,39 @@ class sio__references_formatter extends ChadoFieldFormatter {
     $ordered_items = [];
     foreach ($items as $delta => $item) {
       $type = isset($item['value']['rdfs:type']) ? $item['value']['rdfs:type'] : '';
-      $entity = isset($item['value']['entity']) ? $item['value']['entity'] : '';
+      $ientity = isset($item['value']['entity']) ? $item['value']['entity'] : '';
       $name = isset($item['value']['schema:name']) ? $item['value']['schema:name'] : '';
       $identifier = isset($item['value']['data:0842']) ? $item['value']['data:0842'] : '';
-      if ($entity) {
-        list($entity_type, $entity_id) = explode(':', $entity);
+      if ($ientity) {
+        list($entity_type, $entity_id) = explode(':', $ientity);
         $name = l(strip_tags($name), 'bio_data/' . $entity_id);
       }
       $ordered_items[ucfirst($type)][] = $name;
     }
 
     // Reorder the list so it's compatible with theming a list.
+    ksort($ordered_items);
+
+    // Generate the pagers for each type.
     $list_items = [];
     $headers = [];
     $rows = [];
-    ksort($ordered_items);
     foreach ($ordered_items as $type => $children) {
+      $items_per_page = array_key_exists('items_per_page', $this->instance['settings']) ? $this->instance['settings']['items_per_page'] : 10;
+      $total_records = count($children);
+      $total_pages = (int) ($total_records / $items_per_page) + 1;
+      $pelement = 0;
+      $current_page = pager_default_initialize($total_records, $items_per_page, $pelement);
+      $pager = theme('pager', [
+        'tags' => [],
+        'element' => $pelement,
+        'parameters' => [],
+        'quantity' => 5,
+      ]);
+      $pager = $this->ajaxifyPager($pager, $entity);
+      $page_items = array_chunk($children, $items_per_page);
+
+
       $rows[] = [
         [
           'data' => ucfirst($type) . '(s)',
@@ -48,14 +65,16 @@ class sio__references_formatter extends ChadoFieldFormatter {
           'width' => '20%',
         ],
         theme_item_list([
-          'items' => $children,
+          'items' => $page_items[$current_page],
           'title' => '',
           'type' => 'ul',
           'attributes' => [],
-        ]),
+        ]) . $pager,
       ];
     }
 
+
+
     $table = [
       'header' => [],
       'rows' => $rows,

+ 36 - 37
tripal_chado/includes/TripalImporter/OBOImporter.inc

@@ -178,7 +178,7 @@ class OBOImporter extends TripalImporter {
 
 
   /**
-   * An array of used cvterm objects so that we don't have to lookup them
+   * An array of used cvterm objects so that we don't have to look them
    * up repeatedly.
    */
   private $used_terms = [];
@@ -257,8 +257,8 @@ class OBOImporter extends TripalImporter {
     $form['obo_existing']['existing_instructions'] = [
       '#type' => 'item',
       '#markup' => t('The vocabularies listed in the select box below have been pre-populated
-        upon installation of Tripal or have been previously loaded.  Select one to edit
-        its settings or submit for loading.  You may reload any vocabulary that has
+        upon installation of Tripal or have been previously loaded. Select one to edit
+        its settings or submit for loading. You may reload any vocabulary that has
         already been loaded to retrieve any new updates.'),
     ];
 
@@ -307,7 +307,7 @@ class OBOImporter extends TripalImporter {
       $form['obo_existing']['uobo_name'] = [
         '#type' => 'textfield',
         '#title' => t('Vocabulary Name'),
-        '#description' => t('Please provide a name for this vocabulary.  After upload, this name will appear in the drop down
+        '#description' => t('Please provide a name for this vocabulary. After upload, this name will appear in the drop down
                              list above for use again later.'),
         '#default_value' => $uobo_name,
       ];
@@ -315,8 +315,8 @@ class OBOImporter extends TripalImporter {
       $form['obo_existing']['uobo_url'] = [
         '#type' => 'textfield',
         '#title' => t('Remote URL'),
-        '#description' => t('Please enter a URL for the online OBO file.  The file will be downloaded and parsed.
-                             (e.g. http://www.obofoundry.org/ro/ro.obo)'),
+        '#description' => t('Please enter a URL for the online OBO file. The file will be downloaded and parsed.
+                             (e.g. https://raw.githubusercontent.com/oborel/obo-relations/master/ro.obo)'),
         '#default_value' => $uobo_url,
       ];
 
@@ -327,8 +327,8 @@ class OBOImporter extends TripalImporter {
           definition file. If entering a path relative to
           the Drupal installation you may use a relative path that excludes the
           Drupal installation directory (e.g. sites/default/files/xyz.obo). Note
-          that Drupal relative paths have no preceding slash.
-          Otherwise, please provide the full path on the filesystem.  The path
+          that Drupal relative paths have no preceeding slash.
+          Otherwise, please provide the full path on the filesystem. The path
           must be accessible to the web server on which this Drupal instance is running.'),
         '#default_value' => $uobo_file,
       ];
@@ -347,24 +347,24 @@ class OBOImporter extends TripalImporter {
     ];
 
     $form['obo_new']['path_instructions'] = [
-      '#value' => t('Provide the name and path for the OBO file.  If the vocabulary OBO file
+      '#value' => t('Provide the name and path for the OBO file. If the vocabulary OBO file
                      is stored local to the server provide a file name. If the vocabulary is stored remotely,
-                     provide a URL.  Only provide a URL or a local file, not both.'),
+                     provide a URL. Only provide a URL or a local file, not both.'),
     ];
 
     $form['obo_new']['obo_name'] = [
       '#type' => 'textfield',
       '#title' => t('New Vocabulary Name'),
-      '#description' => t('Please provide a name for this vocabulary.  After upload, this name will appear in the drop down
-                             list above for use again later. Additionally, if a default namespace is not provided in the OBO
-                             header this name will be used as the default_namespace.'),
+      '#description' => t('Please provide a name for this vocabulary. After upload, this name will appear in the drop down
+                           list above for use again later. Additionally, if a default namespace is not provided in the OBO
+                           header this name will be used as the default_namespace.'),
     ];
 
     $form['obo_new']['obo_url'] = [
       '#type' => 'textfield',
       '#title' => t('Remote URL'),
       '#description' => t('Please enter a URL for the online OBO file.  The file will be downloaded and parsed.
-                             (e.g. http://www.obofoundry.org/ro/ro.obo)'),
+                           (e.g. https://raw.githubusercontent.com/oborel/obo-relations/master/ro.obo)'),
     ];
 
     $form['obo_new']['obo_file'] = [
@@ -374,7 +374,7 @@ class OBOImporter extends TripalImporter {
           definition file. If entering a path relative to
           the Drupal installation you may use a relative path that excludes the
           Drupal installation directory (e.g. sites/default/files/xyz.obo). Note
-          that Drupal relative paths have no preceding slash.
+          that Drupal relative paths have no preceeding slash.
           Otherwise, please provide the full path on the filesystem.  The path
           must be accessible to the web server on which this Drupal instance is running.'),
     ];
@@ -604,7 +604,7 @@ class OBOImporter extends TripalImporter {
     tripal_populate_mview($mview_id);
 
     // Update the cvtermpath table for each newly added CV.
-    $this->logMessage("Updating cvtermpath table.  This may take a while...");
+    $this->logMessage("Updating cvtermpath table. This may take a while...");
     foreach ($this->obo_namespaces as $namespace => $cv_id) {
       $this->logMessage("- Loading paths for vocabulary: @vocab", ['@vocab' => $namespace]);
       chado_update_cvtermpath($cv_id, $this->job);
@@ -614,7 +614,7 @@ class OBOImporter extends TripalImporter {
   /**
    * A wrapper function for importing the user specified OBO file into Chado by
    * specifying the obo_id of the OBO. It requires that the file be in OBO v1.2
-   * compatible format.  This function is typically executed via the Tripal
+   * compatible format. This function is typically executed via the Tripal
    * jobs
    * management after a user submits a job via the Load Ontologies form.
    *
@@ -662,7 +662,7 @@ class OBOImporter extends TripalImporter {
   /**
    * A wrapper function for importing the user specified OBO file into Chado by
    * specifying the filename and path of the OBO. It requires that the file be
-   * in OBO v1.2 compatible format.  This function is typically executed via
+   * in OBO v1.2 compatible format. This function is typically executed via
    * the Tripal jobs management after a user submits a job via the Load
    * Ontologies form.
    *
@@ -673,7 +673,7 @@ class OBOImporter extends TripalImporter {
    *   The path on the file system where the ontology can be found
    * @param $is_new
    *   Set to TRUE if this is a new ontology that does not yet exist in the
-   *   tripal_cv_obo table.  If TRUE the OBO will be added to the table.
+   *   tripal_cv_obo table. If TRUE the OBO will be added to the table.
    *
    * @ingroup tripal_obo_loader
    */
@@ -855,18 +855,7 @@ class OBOImporter extends TripalImporter {
     // Get the 'ontology' and 'default-namespace' headers.  Unfortunately,
     // not all OBO files contain these.
     if (array_key_exists('ontology', $header)) {
-      $ontology = strtoupper($header['ontology'][0]);
-      // Unfortunately, not all OBO files use the headers in the same way.
-      // GO uses 'ontology' correctly to set the default short name (or idspace)
-      // of the controlled vocabulary but EDAM uses a URL.
-      // So we'll hard code a fix for EDAM.
-      if (preg_match('/^\w+$/', $ontology)) {
-        $short_name = $ontology;
-      }
-      if (preg_match('/edamontology\.org/i', $ontology)) {
-        $namespace = 'EDAM';
-        $short_name = 'EDAM';
-      }
+      $short_name = strtoupper($header['ontology'][0]);
     }
     if (array_key_exists('default-namespace', $header)) {
       $namespace = $header['default-namespace'][0];
@@ -921,6 +910,17 @@ class OBOImporter extends TripalImporter {
       }
     }
 
+    // If we still don't have a namespace defined, use the one from the form
+    // in the "New Vocabulary Name" field
+    if (!$namespace and array_key_exists('run_args', $this->arguments)
+        and array_key_exists('obo_name', $this->arguments['run_args'])) {
+      $namespace = $this->arguments['run_args']['obo_name'];
+    }
+    if (!$namespace and array_key_exists('run_args', $this->arguments)
+        and array_key_exists('uobo_name', $this->arguments['run_args'])) {
+      $namespace = $this->arguments['run_args']['uobo_name'];
+    }
+
     // If we can't find the namespace or the short_name then bust.
     if (!$namespace and !$short_name) {
       throw new ErrorException('Cannot determine the namespace or ontology prefix from this OBO file. It is missing both the "default-namespace" or a compatible "ontology" header.');
@@ -953,13 +953,13 @@ class OBOImporter extends TripalImporter {
     // Check if the EBI ontology search has this ontology:
     try {
       $results = $this->oboEbiLookup($ontology, 'ontology');
-      if (array_key_exists('default-namespace', $results['config']['annotations'])) {
+      if ($results and array_key_exists('config', $results) and array_key_exists('default-namespace', $results['config']['annotations'])) {
         $namespace = $results['config']['annotations']['default-namespace'];
         if (is_array($namespace)) {
           $namespace = $namespace[0];
         }
       }
-      elseif (array_key_exists('namespace', $results['config'])) {
+      elseif ($results and array_key_exists('config', $results) and array_key_exists('namespace', $results['config'])) {
         $namespace = $results['config']['namespace'];
       }
       // If we can't find the namespace at EBI, then just default to using the
@@ -1020,7 +1020,7 @@ class OBOImporter extends TripalImporter {
         "Lookup Service to retrieve the information for this term. " .
         "Please note, that vocabularies with many non-local terms " .
         "require remote lookups and these lookups can dramatically " .
-        "decrease loading time. ",
+        "increase loading time. ",
         ['!vocab' => $this->default_namespace], TRIPAL_WARNING);
       $this->ebi_warned = TRUE;
 
@@ -1090,7 +1090,7 @@ class OBOImporter extends TripalImporter {
     // If EBI sent an error message then throw an error.
     if ($results['error']) {
       $this->logMessage('Cannot find the term via an EBI OLS lookup: !term. ' .
-        'We tried to access: !url' .
+        'We tried to access: "!url" ' .
         'EBI Reported: !message. Consider finding the OBO file for this ontology and manually loading it first.',
         [
           '!message' => $results['message'],
@@ -2122,7 +2122,7 @@ class OBOImporter extends TripalImporter {
           // add the ID to the name to ensure it doesn't.
           if (array_key_exists($stanza['name'][0], $this->term_names)) {
             $new_name = $stanza['name'][0] . '(' . $stanza['id'][0] . ')';
-            $stanza['name'][0] = $stanza['name'][0];
+            $stanza['name'][0] = $new_name;
           }
 
           $this->cacheTermStanza($stanza, $type);
@@ -2388,7 +2388,6 @@ class OBOImporter extends TripalImporter {
     if (!$accession) {
       $this->logMessage("Cannot add an Alt ID without an accession: '!alt_id'", ['!alt_id' => $alt_id]);
       return;
-      //throw new Exception("Cannot add an Alt ID without an accession: '$alt_id'");
     }
 
     // Add the database if it doesn't exist.

+ 3 - 3
tripal_chado/includes/tripal_chado.fields.inc

@@ -813,7 +813,7 @@ function tripal_chado_bundle_fields_info_linker(&$info, $details, $entity_type,
   }
 
   // RELATIONSHIPS
-  // If the linker table does not exists then we don't want to add attach.
+  // If the linker table does not exist then we don't want to add attach.
   $rel_table = $table_name . '_relationship';
   if (chado_table_exists($rel_table)) {
     $field_name = 'sbo__relationship';
@@ -1110,7 +1110,7 @@ function tripal_chado_bundle_instances_info_base(&$info, $entity_type, $bundle,
       if ($column_name == 'uniquename') {
         $base_info['label'] = 'Unique Local Identifier';
         $base_info['required'] = TRUE;
-        $base_info['description'] = 'This publication is housed in Chado whic requires a unique identifer (or name) be provided for every publication. This identifier need not be shown to end-users but it is required. Each site must decide on a format for this unique name.';
+        $base_info['description'] = 'This publication is housed in Chado which requires a unique identifer (or name) be provided for every publication. This identifier need not be shown to end-users but it is required. Each site must decide on a format for this unique name.';
       }
       if ($column_name == 'title') {
         $base_info['description'] = 'The title of the published work.';
@@ -2676,7 +2676,7 @@ function tripal_chado_bundle_instances_info_linker(&$info, $entity_type, $bundle
   }
 
   // RELATIONSHIPS
-  // If the linker table does not exists then we don't want to add attach.
+  // If the linker table does not exist then we don't want to add attach.
   $rel_table = $table_name . '_relationship';
   if (chado_table_exists($rel_table)) {
     $field_name = 'sbo__relationship';

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

@@ -113,7 +113,7 @@ function tripal_phylogeny_ajax_get_tree_json($phylotree_id)
     // features and organisms with which it is associated.  Each phylonode
     // can be associated with an organism in one of two ways: 1) via a
     // feature linked by the phylonode.feature_id field or 2) via a
-    // a record in the phylonde_organism table.  Therefore both types of
+    // a record in the phylonode_organism table.  Therefore both types of
     // organism records are returned in the query below, but those
     // retrieved via a FK link on features are prefixed with 'fo_'.
     $sql = "

+ 1 - 1
tripal_daemon/theme/tripal_daemon.log_block.css

@@ -1,5 +1,5 @@
 /**
- * Themeing for the Tripal Daemon Log Block.
+ * Theming for the Tripal Daemon Log Block.
  */
 
 #trpdaemon-display-log-form {

+ 1 - 1
tripal_ws/includes/TripalFields/remote__data/remote__data_formatter.inc

@@ -24,7 +24,7 @@ class remote__data_formatter extends WebServicesFieldFormatter {
     $field_name = $this->field['field_name'];
 
     // Get any subfields and the header label.  Shift the array because the
-    // results should already be the value of the fisrt entry.
+    // results should already be the value of the first entry.
     $rd_field_name = $this->instance['settings']['data_info']['rd_field_name'];
     $subfields = explode(',', $rd_field_name);
     $header_label = $this->getHeaderLabel($subfields);

+ 1 - 1
tripal_ws/includes/TripalWebService.inc

@@ -295,7 +295,7 @@ class TripalWebService {
    *   An implementation of a TripalWebServiceResource.
    */
   public function setResource($resource) {
-    // Make sure the $service provides is a TripalWebServcie class.
+    // Make sure the $service provides is a TripalWebService class.
     if (!is_a($resource, 'TripalWebServiceResource')) {
       throw new Exception("Cannot add a new resource to this web service as it is not a TripalWebServiceResource.");
     }

+ 6 - 3
tripal_ws/includes/TripalWebService/TripalContentService_v0_1.inc

@@ -520,6 +520,9 @@ class TripalContentService_v0_1 extends TripalWebService {
           // Index number (0, 1, 2...) of a hydra:member array.
           $temp[$k] = $this->sanitizeFieldKeys($resource, $v, $bundle, $service_path);
         }
+        elseif ($k == 'entity') {
+          $temp[$k] = $v;
+        }
         else {
           // TODO: this is an error, if we get here then we have
           // a key that isn't using the proper format... what to do?
@@ -879,13 +882,13 @@ class TripalContentService_v0_1 extends TripalWebService {
 
     // Get the TripalBundle, TripalTerm and TripalVocab type for this type.
     $bundle = tripal_load_bundle_entity(['label' => $ctype]);
-    
+
     // Check that the user has access to this bundle.  If not then the
     // function call will throw an error.
     if (!user_access('view ' . $bundle->name)) {
       throw new Exception("Permission Denied.");
     }
-        
+
     $term = entity_load('TripalTerm', ['id' => $bundle->term_id]);
     $term = reset($term);
 
@@ -1058,7 +1061,7 @@ class TripalContentService_v0_1 extends TripalWebService {
         // Show only content types users have access to and skip the rest.
         continue;
       }
-      
+
       $entity = entity_load('TripalTerm', ['id' => $bundle->term_id]);
       $term = reset($entity);
       $vocab = $term->vocab;

+ 1 - 1
tripal_ws/includes/TripalWebServiceCollection.inc

@@ -91,7 +91,7 @@ class TripalWebServiceCollection extends TripalWebServiceResource {
    *   resource
    */
   public function addMember($member) {
-    // Make sure the $service provides is a TripalWebServcie class.
+    // Make sure the $service provides is a TripalWebService class.
     if (!is_a($member, 'TripalWebServiceResource')) {
       throw new Exception("Cannot add a new member to this resource collection as it is not a TripalWebServiceResource.");
     }