Browse Source

Unified the way DrupalViews and WebServices handles TripalField sub elements

Stephen Ficklin 7 years ago
parent
commit
0db17d9419
29 changed files with 1057 additions and 239 deletions
  1. 320 54
      tripal/includes/TripalFields/TripalField.inc
  2. 0 21
      tripal_chado/includes/TripalFields/ChadoField.inc
  3. 56 22
      tripal_chado/includes/TripalFields/chado_linker__contact/chado_linker__contact.inc
  4. 1 0
      tripal_chado/includes/TripalFields/chado_linker__cvterm/chado_linker__cvterm.inc
  5. 2 0
      tripal_chado/includes/TripalFields/data__accession/data__accession.inc
  6. 13 0
      tripal_chado/includes/TripalFields/data__protein_sequence/data__protein_sequence.inc
  7. 15 0
      tripal_chado/includes/TripalFields/data__sequence/data__sequence.inc
  8. 13 0
      tripal_chado/includes/TripalFields/data__sequence_checksum/data__sequence_checksum.inc
  9. 50 0
      tripal_chado/includes/TripalFields/data__sequence_coordinates/data__sequence_coordinates.inc
  10. 15 0
      tripal_chado/includes/TripalFields/data__sequence_length/data__sequence_length.inc
  11. 14 0
      tripal_chado/includes/TripalFields/go__gene_expression/go__gene_expression.inc
  12. 46 6
      tripal_chado/includes/TripalFields/local__source_data/local__source_data.inc
  13. 65 104
      tripal_chado/includes/TripalFields/obi__organism/obi__organism.inc
  14. 55 4
      tripal_chado/includes/TripalFields/ogi__location_on_map/ogi__location_on_map.inc
  15. 36 0
      tripal_chado/includes/TripalFields/sbo__database_cross_reference/sbo__database_cross_reference.inc
  16. 14 1
      tripal_chado/includes/TripalFields/sbo__phenotype/sbo__phenotype.inc
  17. 89 6
      tripal_chado/includes/TripalFields/sbo__relationship/sbo__relationship.inc
  18. 0 1
      tripal_chado/includes/TripalFields/schema__additional_type/schema__additional_type.inc
  19. 1 0
      tripal_chado/includes/TripalFields/schema__alternate_name/schema__alternate_name.inc
  20. 13 1
      tripal_chado/includes/TripalFields/schema__publication/schema__publication.inc
  21. 38 0
      tripal_chado/includes/TripalFields/sio__references/sio__references.inc
  22. 14 0
      tripal_chado/includes/TripalFields/so__cds/so__cds.inc
  23. 37 4
      tripal_chado/includes/TripalFields/so__genotype/so__genotype.inc
  24. 43 1
      tripal_chado/includes/TripalFields/so__transcript/so__transcript.inc
  25. 14 0
      tripal_chado/includes/TripalFields/taxrank__infraspecific_taxon/taxrank__infraspecific_taxon.inc
  26. 12 4
      tripal_chado/includes/tripal_chado.entity.inc
  27. 4 0
      tripal_chado/includes/tripal_chado.semweb.inc
  28. 43 0
      tripal_chado/tripal_chado.install
  29. 34 10
      tripal_ws/includes/TripalWebService/TripalEntityService_v0_1.inc

+ 320 - 54
tripal/includes/TripalFields/TripalField.inc

@@ -91,6 +91,9 @@ class TripalField {
   // when using the widgetForm, formatterSettingsForm, etc.) it should be set.
   protected $instance;
 
+  // The term array that provides all the details about the controlled
+  // vocabulary term that this field maps to.
+  protected $term;
 
   // --------------------------------------------------------------------------
   //                     CONSTRUCTOR
@@ -110,6 +113,8 @@ class TripalField {
 
     $class = get_called_class();
 
+    $this->term = tripal_get_term_details($this->instance['settings']['term_vocabulary'], $this->instance['settings']['term_accession']);
+
     if (!$instance) {
       tripal_set_message(t('Missing instance of field "%field"', array('%field' => $field['field_name'])), TRIPAL_ERROR);
     }
@@ -146,7 +151,7 @@ class TripalField {
 
 
   // --------------------------------------------------------------------------
-  //                 GETTERS AND SETTERS -- DO NOT OVERRIDE
+  //                 DO NOT OVERRIDE THESE FUNCTIONS
   // --------------------------------------------------------------------------
 
   /**
@@ -174,6 +179,200 @@ class TripalField {
     return $this->field['id'];
   }
 
+  public function getFieldTerm(){
+    return $this->term;
+  }
+
+  protected function getFieldTermID() {
+    $class = get_called_class();
+    return $this->instance['settings']['term_vocabulary'] . ':' . $this->instance['settings']['term_accession'];
+  }
+
+  /**
+   * Describes this field to Tripal web services.
+   *
+   * The child class need not implement this function has all of the details
+   * provided for elements by the elementInfo() function are used to generate
+   * the details needed for Views.
+   *
+   * @return
+   *   An associative array with the keys available for searching. The value
+   *   is the term array for the element.
+   */
+  public function webServicesData() {
+    $elements = $this->elementInfo();
+
+    $field_term = $this->getFieldTermID();
+    $field_term_name = strtolower(preg_replace('/[^\w]/', '_', $this->term['name']));
+    $field_details = $elements[$field_term];
+
+    $searchable_keys = array();
+    if (array_key_exists('searchable', $field_details) and $field_details['searchable']) {
+      $searchable_keys[$field_term_name] = $field_term;
+    }
+
+    // Now add any entries for child elements.
+    if (array_key_exists('elements', $field_details)) {
+      $elements = $field_details['elements'];
+      foreach ($elements as $element_name => $element_details) {
+        $this->_addWebServiceElement($searchable_keys, $field_term_name, $field_term, $element_name, $element_details);
+      }
+    }
+
+    return $searchable_keys;
+  }
+
+  /**
+   *
+   * @param $searchabe_keys
+   * @param $field_name
+   * @param $element_name
+   * @param $element_details
+   */
+  protected function _addWebServiceElement(&$searchable_keys, $parent_term_name, $parent_term, $element_name, $element_details) {
+    // Skip the 'entity' element, as we'll never make this searchable or
+    // viewable. It's meant for linking.
+    if ($element_name == 'entity') {
+      return;
+    }
+
+    list($vocabulary, $accession) = explode(':', $element_name);
+    $term = tripal_get_term_details($vocabulary, $accession);
+    $field_term = $parent_term . ',' . $term['vocabulary']['short_name'] . ':' . $term['accession'];
+    $field_term_name = $parent_term_name . '.' . strtolower(preg_replace('/[^\w]/', '_', $term['name']));
+
+    // Is the field searchable?
+    if (array_key_exists('searchable', $element_details) and $element_details['searchable']) {
+      $searchable_keys[$field_term_name] =  $field_term;
+    }
+
+    // Now add any entries for child elements.
+    if (array_key_exists('elements', $element_details)) {
+      $elements = $element_details['elements'];
+      foreach ($elements as $element_name => $element_details) {
+        $this->_addWebServiceElement($searchable_keys, $field_term_name, $field_term, $element_name, $element_details);
+      }
+    }
+  }
+
+  /**
+   * Describes this field to Views.
+   *
+   * The child class need not implement this function has all of the details
+   * provided for elements by the elementInfo() function are used to generate
+   * the details needed for Views.
+   *
+   * @param $view_base_id
+   *   Views was originally designed to integrate with SQL tables. And
+   *   each field is associated with a table.  Because these are TripalFields
+   *   and views is not directly querying the tables it doesn't make sense to
+   *   associate fields with a table, but we must associate the fields with
+   *   the bundle.  Each bundle is uniquely identified with the $view_base_id
+   *   that is passed here.
+   *
+   * @return
+   *   An associative array describing the data structure. Primary key is the
+   *   name used internally by Views for the bundle that is provided by
+   *   the $view_base_id. The returned array should be compatible with the
+   *   instructions provided by the hook_views_data() function.
+   */
+  public function viewsData($view_base_id) {
+    $data = array();
+    $field_name = $this->field['field_name'];
+    $field_term = $this->getFieldTermID();
+
+    $elements = $this->elementInfo();
+    $field_details = $elements[$field_term];
+
+    // Build the entry for the field.
+    $data[$view_base_id][$field_name] = array(
+      'title' => $this->instance['label'],
+      'help' => $this->instance['description'],
+      'field' => array(
+        'handler' => 'tripal_views_handler_field',
+        'click sortable' => TRUE,
+      ),
+    );
+    // Is the field sortable?
+    if (array_key_exists('sortable', $field_details) and $field_details['sortable']) {
+      $data[$view_base_id][$field_name]['sort']['click handler'] = 'views_handler_sort';
+      $data[$view_base_id][$field_name]['field']['click sortable'] = TRUE;
+    }
+
+    // Is the field searchable?
+    if (array_key_exists('searchable', $field_details) and $field_details['searchable']) {
+      $filter_handler = 'tripal_views_handler_filter_string';
+      if (array_key_exists('type', $field_details) and $field_details['type'] == 'numeric') {
+        $filter_handler = 'tripal_views_handler_filter';
+      }
+      $data[$view_base_id][$field_name]['filter'] = array(
+        'handler' => $filter_handler,
+      );
+    }
+
+    // Now add any entries for child elements.
+    if (array_key_exists('elements', $field_details)) {
+      $elements = $field_details['elements'];
+      foreach ($elements as $element_name => $element_details) {
+        $this->_addViewsDataElement($data, $view_base_id, $field_name, $element_name, $element_details);
+      }
+    }
+
+    return $data;
+  }
+
+  /**
+   *
+   * @param unknown $data
+   * @param unknown $view_base_id
+   * @param unknown $parent
+   * @param unknown $element_name
+   * @param unknown $element_details
+   */
+  protected function _addViewsDataElement(&$data, $view_base_id, $parent, $element_name, $element_details) {
+    // Skip the 'entity' element, as we'll never make this searchable or
+    // viewable. It's meant for linking.
+    if ($element_name == 'entity') {
+      return;
+    }
+    $field_name = $parent . '.' . $element_name;
+    list($vocabulary, $accession) = explode(':', $element_name);
+    $term = tripal_get_term_details($vocabulary, $accession);
+
+    // Build the entry for the field.
+    $data[$view_base_id][$field_name] = array(
+      'title' => ucfirst($term['name']),
+      'help' => $term['definition'],
+      'field' => array(
+        'handler' => 'tripal_views_handler_field_element',
+      ),
+    );
+    // Is the field sortable?
+    if (array_key_exists('sortable', $element_details) and $element_details['sortable']) {
+      $data[$view_base_id][$field_name]['sort']['click handler'] = 'views_handler_sort';
+      $data[$view_base_id][$field_name]['field']['click sortable'] = TRUE;
+    }
+
+    // Is the field searchable?
+    if (array_key_exists('searchable', $element_details) and $element_details['searchable']) {
+      $filter_handler = 'tripal_views_handler_filter_element_string';
+      if (array_key_exists('type', $element_details) and $element_details['type'] == 'numeric') {
+        $filter_handler = 'tripal_views_handler_filter';
+      }
+      $data[$view_base_id][$field_name]['filter'] = array(
+        'handler' => $filter_handler,
+      );
+    }
+
+    // Recusrively add any entries for child elements.
+    if (array_key_exists('elements', $element_details)) {
+      $elements = $element_details['elements'];
+      foreach ($elements as $element_name => $element_details) {
+        $this->_addViewsDataElement($data, $view_base_id, $field_name, $element_name, $element_details);
+      }
+    }
+  }
+
   // --------------------------------------------------------------------------
   //                            OVERRIDEABLE FUNCTIONS
   // --------------------------------------------------------------------------
@@ -242,6 +441,108 @@ class TripalField {
 
   }
 
+  /**
+   * Provides the list of elements returned by the 'value' of the field. \
+   *
+   * The elements provided by this function are used to integrate with
+   * Drupal Views and Web services.  The return value is an associative array
+   * that contains all of the elements that will be returned by the
+   * 'value' of this field. If the value field returns an element which
+   * is not defined here a warning will be generated.
+   *
+   * The array structure should contain at the top-level a key of the form
+   * {db}:{accession}. This represents the term that this field belongs to.
+   * The value of this top-level key is an array with the following keys:
+   *   -name: this key is not actually used but is availble to improve
+   *     readability of the array.  Because the key is a vocabulary term
+   *     conaining only the accession it's not always clear what it means.
+   *     Providing a 'name' key helps other's know what the term is.
+   *   -searchable:  TRUE if the element can be used for filtering the content
+   *     type to which tis field is attached.  FALSE if not.
+   *   -operations:  an array of filtering operations that can be used for this
+   *     field.  These include: 'eq', 'ne', 'contains', 'starts', 'gt', 'lt',
+   *     'gte', 'lte'.  These opertaions are applicable to strings: 'eq', 'ne',
+   *     'contains', and 'starts'.  These operations are applicable for numeric
+   *     values: 'gt', 'lt', 'gte', 'lte'.
+   *   -sortable: TRUE if the element can be sorted.  FALSE if not.
+   *   -elements:  If this field value is a simple scalar (i.e. string or
+   *     number) then this key is not needed. But, if the 'value' of the
+   *     field is an array with sub keys then those subkeys must be defined
+   *     using this key.  The members of the element array follows the same
+   *     format as the top-level key and the above subkeys can be used as well.
+   *
+   * The following code provides an example for describing the value elements
+   * of this field.  The Tripal Chado module provides an obi__organism field
+   * that attaches organism details to content types such as genes, mRNA,
+   * stocks, etc.  It provides a label containing the full scientific name of
+   * the organism as well as the genus, species, infraspecific name,
+   * and infraspecific type. If the organism to which the field belong is
+   * published then an entity ID is provided.  The following array describes
+   * all of these.
+   * @code
+    $field_term = $this->getFieldTermID();
+    return array(
+      $field_term => array(
+        'operations' => array('eq', 'contains', 'starts'),
+        'sortable' => TRUE,
+        'searchable' => TRUE,
+        'elements' => array(
+          'rdfs:label' => array(
+            'searchable' => TRUE,
+            'name' => 'scientfic_name',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          'TAXRANK:0000005' => array(
+            'searchable' => TRUE,
+            'name' => 'genus',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          'TAXRANK:0000006' => array(
+            'searchable' => TRUE,
+            'name' => 'species',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          'TAXRANK:0000045' => array(
+            'searchable' => TRUE,
+            'name' => 'infraspecies',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          'local:infraspecific_type' => array(
+            'searchable' => TRUE,
+            'name' => 'infraspecific_type',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          'entity' => array(
+            'searchable' => FALSE,
+          ),
+        ),
+      )
+    );
+   * @endcode
+   *
+   * If a field does not have a complex nested set of values, but simply returns
+   * a scalar then the default elementInfo provides default string-based
+   * searchabilty.
+   *
+   * @return
+   *   An associative array of the value elements provided by this field.
+   */
+  protected function elementInfo() {
+    $field_term = $this->getFieldTermID();
+    return array(
+      $field_term => array(
+        'operations' => array('eq', 'ne', 'contains', 'starts'),
+        'sortable' => TRUE,
+        'searchable' => TRUE,
+      ),
+    );
+  }
+
   /**
    * Provides a form for the 'Field Settings' of the field management page.
    *
@@ -270,47 +571,6 @@ class TripalField {
 
   }
 
-  /**
-   * Describes this field to Views.
-   *
-   * An array of views data, in the same format as the return value of
-   * hook_views_data().
-   *
-   * @param $view_base_id
-   *   Views was originally designed to integrate with SQL tables. And
-   *   each field is associated with a table.  Because these are TripalFields
-   *   and views is not directly querying the tables it doesn't make sense to
-   *   associate fields with a table, but we must associate the fields with
-   *   the bundle.  Each bundle is uniquely identified with the $view_base_id
-   *   that is passed here.
-   *
-   * @return
-   *   An associative array describing the data structure. Primary key is the
-   *   name used internally by Views for the bundle that is provided by
-   *   the $view_base_id. The returned array should be compatible with the
-   *   instructions provided by the hook_views_data() function.
-   */
-  public function viewsData($view_base_id) {
-    $data = array();
-    $field_name = $this->field['field_name'];
-
-    $data[$view_base_id][$field_name] = array(
-      'title' => $this->instance['label'],
-      'help' => $this->instance['description'],
-      'field' => array(
-        'handler' => 'tripal_views_handler_field',
-        'click sortable' => TRUE,
-      ),
-      'filter' => array(
-        'handler' => 'tripal_views_handler_filter_string',
-      ),
-      'sort' => array(
-        'handler' => 'views_handler_sort',
-      )
-    );
-    return $data;
-  }
-
   /**
    * Provides a form for the 'Field Settings' of an instance of this field.
    *
@@ -371,18 +631,24 @@ class TripalField {
   /**
    * Used to filter records that match a given condition.
    *
-   * Entities can be filtered using the fields.  This function should be
-   * implemented if the field  supports filtering.  To provide filtering,
-   * the $query object should be updated to including any joins and
-   * conditions necessary. The following rules should be followed when
-   * implementing this function:
-   * - Any keys from the value array that support filtering should be set
-   *   in the $default_settings['searchable_keys'] array of this class file.
-   * - Implement support for every key in the
-   *   $default_settings['searchable_keys'] array.
-   * - However, avoid making filteres for non-indexed database columns.
-   * - This function should never set the fields that should be returned
-   *   nor ordering or group by.
+   * Records that belong to a content type can be filtered using the fields.
+   * This function should be implemented if the field  supports filtering as
+   * specified in the elementInfo() function.  With this function, the query
+   * object appropriate for the storage back-end is passed into the function.
+   *
+   * The condition array passesd in will have three values:
+   *   - column:  the key indicating how the filter should occur.
+   *   - op: the operation to perform (e.g. equals, contains, starts with etc.
+   *   - value:  the value for filtering.
+   *
+   * The column used for filtering will be a comma-speperated list of
+   * controlled vocabulary IDs. This comma-separate list corresponds directly
+   * to the heirarchy of elements provided by the elementInfo() function.
+   * For example, if a field provides organism information then it may use
+   * the OBI:0100026 term for the field, and the term TAXRANK:0000005 for the
+   * term to indicate the 'Genus'.  If these fields are properly organized in
+   * the elementInfo() function then the "column" of the condition when
+   * a user wants to search by genus will be: OBI:0100026,TAXRANK:0000005.
    *
    * @param $query
    *   A query object appropriate for the data storage backend. For example,

+ 0 - 21
tripal_chado/includes/TripalFields/ChadoField.inc

@@ -109,25 +109,4 @@ class ChadoField extends TripalField {
     );
     return $element;
   }
-
-  /**
-   * @see TripalField::viewsData()
-   */
-  public function viewsData($view_base_id) {
-    $data = array();
-    $field_name = $this->field['field_name'];
-
-    $data[$view_base_id][$field_name] = array(
-      'title' => $this->instance['label'],
-      'help' => $this->instance['description'],
-      // By default our Chado fields are complicated and we only want to support
-      // viewing them, and not filtering by them.  Each field cand override as
-      // needed.
-      'field' => array(
-        'handler' => 'tripal_views_handler_field',
-        'click sortable' => FALSE,
-      )
-    );
-    return $data;
-  }
 }

+ 56 - 22
tripal_chado/includes/TripalFields/chado_linker__contact/chado_linker__contact.inc

@@ -57,7 +57,48 @@ class chado_linker__contact extends ChadoField {
   protected $instance;
 
 
-
+  /**
+   * @see TripalField::elements()
+   */
+  public function elementInfo() {
+    $field_term = $this->getFieldTermID();
+
+    $type_term = tripal_get_chado_semweb_term('contact', 'type_id');
+    $name_term = tripal_get_chado_semweb_term('contact', 'name');
+    $description_term = tripal_get_chado_semweb_term('contact', 'description');
+
+    return array(
+      $field_term => array(
+        'operations' => array('eq', 'contains', 'starts'),
+        'sortable' => TRUE,
+        'searchable' => TRUE,
+        'type' => 'string',
+        'elements' => array(
+          $type_term => array(
+            'searchable' => TRUE,
+            'name' => 'type',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          $name_term => array(
+            'searchable' => TRUE,
+            'name' => 'name',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          $description_term => array(
+            'searchable' => TRUE,
+            'name' => 'description',
+            'operations' => array('contains'),
+            'sortable' => FALSE,
+          ),
+          'entity' => array(
+            'searchable' => FALSE,
+          ),
+        ),
+      )
+    );
+  }
   /**
    *
    * @see TripalField::load()
@@ -70,6 +111,10 @@ class chado_linker__contact extends ChadoField {
     $field_table = $this->instance['settings']['chado_table'];
     $field_column = $this->instance['settings']['chado_column'];
 
+    $type_term = tripal_get_chado_semweb_term('contact', 'type');
+    $name_term = tripal_get_chado_semweb_term('contact', 'name');
+    $description_term = tripal_get_chado_semweb_term('contact', 'description');
+
     // Get the FK that links to the base record.
     $schema = chado_get_schema($field_table);
     $base_table = $entity->chado_table;
@@ -111,27 +156,12 @@ class chado_linker__contact extends ChadoField {
         $contact = $contact_linker->contact_id;
         $entity->{$field_name}['und'][$i] = array(
           'value' => array(
-            'type' => $contact->type_id ? $contact->type_id->name : '',
-            'name' => $contact->name,
-            'description' => $contact->description,
-          ),
-          // Add in the semantic web settings.  This array is expected by
-          // other Tripal modules that handle semantic web for fields.
-          'semantic_web' => array(
-            'type' => $contact->type_id ? $contact->type_id->dbxref_id->db_id->name . ':' . $contact->type_id->dbxref_id->accession : '',
-            'name' => tripal_get_chado_semweb_term('contact', 'name'),
-            'description' => tripal_get_chado_semweb_term('contact', 'description'),
-          ),
-          // Add in subfield mapping to Chado tables. This is used by the
-          // chado_field_storage for performing queries on sub element values.
-          // It should be a comma-separated list (no spacing) of the field names
-          // as foreign keys are followed starting from the Chado table to which
-          // this field maps.
-          'chado_mapping' => array(
-            'type' => 'type_id,name',
-            'name' => 'contact_id,name',
-            'description' => 'contact_id,name'
+            $type_term => $contact->type_id ? $contact->type_id->name : '',
+            $name_term => $contact->name,
+            $description_term => $contact->description,
           ),
+          // Add elements that are not part of the values but used by
+          // the chado storage back-end for saving values.
           'chado-' . $field_table . '__' . $pkey => $contact_linker->$pkey,
           'chado-' . $field_table . '__' . $fkey_lcolumn => $contact_linker->$fkey_lcolumn->$fkey_lcolumn,
           'chado-' . $field_table . '__' . 'contact_id' => $contact->contact_id
@@ -155,7 +185,11 @@ class chado_linker__contact extends ChadoField {
     $alias = 'contact_linker';
     $operator = $condition['operator'];
 
-    if ($condition['column'] == 'contact.name') {
+    $type_term = tripal_get_chado_semweb_term('contact', 'type');
+    $name_term = tripal_get_chado_semweb_term('contact', 'name');
+    $description_term = tripal_get_chado_semweb_term('contact', 'description');
+
+    if ($condition['column'] == $name_term) {
       $query->join($contact_linker, $alias, "base.$bpkey = $alias.$bpkey");
       $query->join('contact', 'C', "C.contact_id = $alias.contact_id");
       $query->condition("C.name", $condition['value'], $operator);

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

@@ -51,6 +51,7 @@ class chado_linker__cvterm extends ChadoField {
   public static $no_ui = FALSE;
 
 
+
   /**
    *
    * @see TripalField::load()

+ 2 - 0
tripal_chado/includes/TripalFields/data__accession/data__accession.inc

@@ -114,6 +114,8 @@ class data__accession extends ChadoField {
     $alias = 'dbx_linker';
     $operator = $condition['operator'];
 
+    // We don't offer any sub elements so the value coming in should
+    // always be the field_name.
     if ($condition['column'] == 'data__accession') {
       $query->join('dbxref', 'DBX', "DBX.dbxref_id = base.dbxref_id");
       $query->condition("DBX.accession", $condition['value'], $operator);

+ 13 - 0
tripal_chado/includes/TripalFields/data__protein_sequence/data__protein_sequence.inc

@@ -44,6 +44,19 @@ class data__protein_sequence extends ChadoField {
   public static $default_formatter = 'data__protein_sequence_formatter';
 
 
+  /**
+   * @see TripalField::elementInfo()
+   */
+  protected function elementInfo() {
+    $field_term = $this->getFieldTermID();
+    return array(
+      $field_term => array(
+        'operations' => array(),
+        'sortable' => FALSE,
+        'searchable' => FALSE,
+      ),
+    );
+  }
   /**
    * @see TripalField::load()
    */

+ 15 - 0
tripal_chado/includes/TripalFields/data__sequence/data__sequence.inc

@@ -43,6 +43,21 @@ class data__sequence extends ChadoField {
   // The default formatter for this field.
   public static $default_formatter = 'data__sequence_formatter';
 
+
+  /**
+   * @see TripalField::elementInfo()
+   */
+  protected function elementInfo() {
+    $field_term = $this->getFieldTermID();
+    return array(
+      $field_term => array(
+        'operations' => array(),
+        'sortable' => FALSE,
+        'searchable' => FALSE,
+      ),
+    );
+  }
+
   /**
    * @see TripalField::load()
    */

+ 13 - 0
tripal_chado/includes/TripalFields/data__sequence_checksum/data__sequence_checksum.inc

@@ -54,5 +54,18 @@ class data__sequence_checksum extends ChadoField {
   // when using the widgetForm, formatterSettingsForm, etc.) it should be set.
   protected $instance;
 
+  /**
+   * @see TripalField::elementInfo()
+   */
+  protected function elementInfo() {
+    $field_term = $this->getFieldTermID();
+    return array(
+      $field_term => array(
+        'operations' => array(),
+        'sortable' => FALSE,
+        'searchable' => FALSE,
+      ),
+    );
+  }
 
 }

+ 50 - 0
tripal_chado/includes/TripalFields/data__sequence_coordinates/data__sequence_coordinates.inc

@@ -55,6 +55,56 @@ class data__sequence_coordinates extends ChadoField {
   protected $instance;
 
 
+  /**
+   * @see TripalField::elementInfo()
+   */
+  protected function elementInfo() {
+    $field_term = $this->getFieldTermID();
+    return array(
+      $field_term => array(
+        'operations' => array(),
+        'sortable' => FALSE,
+        'searchable' => FALSE,
+        'elements' => array(
+          'data:3002' => array(
+            'searchable' => TRUE,
+            'name' => 'source_feature',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          'local:fmin' => array(
+            'searchable' => TRUE,
+            'name' => 'feature min',
+            'type' => 'numeric',
+            'operations' => array('eq', 'gt', 'lt', 'gte' ,'lte'),
+            'sortable' => TRUE,
+          ),
+          'local:fmax' => array(
+            'searchable' => TRUE,
+            'name' => 'feature max',
+            'type' => 'numeric',
+            'operations' => array('eq', 'gt', 'lt', 'gte' ,'lte'),
+            'sortable' => TRUE,
+          ),
+          'data:2336' => array(
+            'searchable' => TRUE,
+            'name' => 'phase',
+            'type' => 'numeric',
+            'operations' => array('eq', 'gt', 'lt', 'gte' ,'lte'),
+            'sortable' => TRUE,
+          ),
+          'data:0853' => array(
+            'searchable' => TRUE,
+            'name' => 'strand',
+            'type' => 'numeric',
+            'operations' => array('eq', 'gt', 'lt', 'gte' ,'lte'),
+            'sortable' => TRUE,
+          ),
+        ),
+      ),
+    );
+  }
+
   /**
    *
    * @see TripalField::load()

+ 15 - 0
tripal_chado/includes/TripalFields/data__sequence_length/data__sequence_length.inc

@@ -55,4 +55,19 @@ class data__sequence_length extends ChadoField {
   // when using the widgetForm, formatterSettingsForm, etc.) it should be set.
   protected $instance;
 
+  /**
+   * @see TripalField::elementInfo()
+   */
+  protected function elementInfo() {
+    $field_term = $this->getFieldTermID();
+    return array(
+      $field_term => array(
+        'operations' => array('eq', 'gt', 'lt', 'gte', 'lte'),
+        'sortable' => TRUE,
+        'searchable' => TRUE,
+        'type' => 'numeric',
+      ),
+    );
+  }
+
 }

+ 14 - 0
tripal_chado/includes/TripalFields/go__gene_expression/go__gene_expression.inc

@@ -60,6 +60,20 @@ class go__gene_expression extends ChadoField {
   protected $instance;
 
 
+  /**
+   * @see TripalField::elementInfo()
+   */
+  protected function elementInfo() {
+    $field_term = $this->getFieldTermID();
+    return array(
+      $field_term => array(
+        'operations' => array(),
+        'sortable' => FALSE,
+        'searchable' => FALSE,
+      ),
+    );
+  }
+
   /**
    *
    * @see TripalField::load()

+ 46 - 6
tripal_chado/includes/TripalFields/local__source_data/local__source_data.inc

@@ -55,6 +55,45 @@ class local__source_data extends ChadoField {
   protected $instance;
 
 
+  /**
+   * @see TripalField::elementInfo()
+   */
+  protected function elementInfo() {
+    $field_term = $this->getFieldTermID();
+
+    $sourcename_term = tripal_get_chado_semweb_term('analysis', 'sourcename');
+    $sourceversion_term = tripal_get_chado_semweb_term('analysis', 'sourceversion');
+    $sourceuri_term = tripal_get_chado_semweb_term('analysis', 'sourceuri');
+
+    return array(
+      $field_term => array(
+        'operations' => array(),
+        'sortable' => FALSE,
+        'searchable' => FALSE,
+        'elements' => array(
+          $sourcename_term => array(
+            'searchable' => TRUE,
+            'name' => 'sourcename',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          $sourceversion_term => array(
+            'searchable' => FALSE,
+            'name' => 'sourceversion',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => FALSE,
+          ),
+          $sourceuri_term => array(
+            'searchable' => FALSE,
+            'name' => 'sourceuri',
+            'operations' => array(),
+            'sortable' => FALSE,
+          ),
+        ),
+      ),
+    );
+  }
+
   /**
    *
    * @see TripalField::load()
@@ -66,14 +105,15 @@ class local__source_data extends ChadoField {
     $field_table = $this->instance['settings']['chado_table'];
     $field_column = $this->instance['settings']['chado_column'];
 
+    $sourcename_term = tripal_get_chado_semweb_term('analysis', 'sourcename');
+    $sourceversion_term = tripal_get_chado_semweb_term('analysis', 'sourceversion');
+    $sourceuri_term = tripal_get_chado_semweb_term('analysis', 'sourceuri');
+
     $entity->{$field_name}['und'][0] = array(
       'value' => array(
-        // The name of the data source.
-        'schema:name' => $analysis->sourcename,
-        // The version of the data source.
-        'IAO:0000129' => $analysis->sourceversion,
-        // The URI of the data source.
-        'data:1047' => $analysis->sourceuri,
+        $sourcename_term => $analysis->sourcename,
+        $sourceversion_term => $analysis->sourceversion,
+        $sourceuri_term => $analysis->sourceuri,
       ),
       'chado-analysis__sourcename' => $analysis->sourcename,
       'chado-analysis__sourceversion' => $analysis->sourceversion,

+ 65 - 104
tripal_chado/includes/TripalFields/obi__organism/obi__organism.inc

@@ -210,108 +210,59 @@ class obi__organism extends ChadoField {
   }
 
   /**
-   * @see ChadoField::viewsData()
+   * @see TripalField::elementInfo()
    */
-  public function viewsData($view_base_id) {
-    $data = array();
-    $options = array('return_object' => TRUE);
+  public function elementInfo() {
+    $field_term = $this->getFieldTermID();
 
-    // Add a views field for the field.
-    $field_name = $this->field['field_name'];
-    $data[$view_base_id][$field_name] = array(
-      'title' => $this->instance['label'],
-      'help' => $this->instance['description'],
-      'field' => array(
-        'handler' => 'tripal_views_handler_field',
-        'click sortable' => TRUE,
-      ),
-      'filter' => array(
-        'handler' => 'tripal_views_handler_filter_string',
-      ),
-      'sort' => array(
-        'handler' => 'views_handler_sort',
-      )
-    );
-
-    // Add a views field for the genus.
-    $cvterm = tripal_get_chado_semweb_term('organism', 'genus', $options);
-    $term = tripal_get_term_details($cvterm->dbxref_id->db_id->name, $cvterm->dbxref_id->accession);
-    $element_name = tripal_format_views_field_element($field_name, $term);
-    $data[$view_base_id][$element_name] = array(
-      'title' => ucfirst($term['name']),
-      'help' => $term['definition'],
-      'field' => array(
-        'handler' => 'tripal_views_handler_field_element',
-        'click sortable' => TRUE,
-      ),
-      'filter' => array(
-        'handler' => 'tripal_views_handler_filter_element_string',
-      ),
-      'sort' => array(
-        'handler' => 'views_handler_sort',
-      )
-    );
+    $genus_term = tripal_get_chado_semweb_term('organism', 'genus');
+    $species_term = tripal_get_chado_semweb_term('organism', 'species');
+    $infraspecific_name_term = tripal_get_chado_semweb_term('organism', 'infraspecific_name');
+    $infraspecific_type_term = tripal_get_chado_semweb_term('organism', 'type_id');
 
-    // Add a views field for the species.
-    $cvterm = tripal_get_chado_semweb_term('organism', 'species', $options);
-    $term = tripal_get_term_details($cvterm->dbxref_id->db_id->name, $cvterm->dbxref_id->accession);
-    $element_name = tripal_format_views_field_element($field_name, $term);
-    $data[$view_base_id][$element_name] = array(
-      'title' => ucfirst($term['name']),
-      'help' => $term['definition'],
-      'field' => array(
-        'handler' => 'tripal_views_handler_field_element',
-        'click sortable' => TRUE,
-      ),
-      'filter' => array(
-        'handler' => 'tripal_views_handler_filter_element_string',
-      ),
-      'sort' => array(
-        'handler' => 'views_handler_sort',
+    return array(
+      $field_term => array(
+        'operations' => array('eq', 'contains', 'starts'),
+        'sortable' => TRUE,
+        'searchable' => TRUE,
+        'type' => 'string',
+        'elements' => array(
+          'rdfs:label' => array(
+            'searchable' => TRUE,
+            'name' => 'scientfic_name',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          $genus_term => array(
+            'searchable' => TRUE,
+            'name' => 'genus',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          $species_term => array(
+            'searchable' => TRUE,
+            'name' => 'species',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          $infraspecific_name_term => array(
+            'searchable' => TRUE,
+            'name' => 'infraspecies',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          $infraspecific_type_term => array(
+            'searchable' => TRUE,
+            'name' => 'infraspecific_type',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          'entity' => array(
+            'searchable' => FALSE,
+          ),
+        ),
       )
     );
-
-    // Suppor the Chado v1.3 fields.
-    if(chado_get_version() >= '1.3') {
-      // Add a views field for the infraspecific name.
-      $cvterm = tripal_get_chado_semweb_term('organism', 'infraspecific_name', $options);
-      $term = tripal_get_term_details($cvterm->dbxref_id->db_id->name, $cvterm->dbxref_id->accession);
-      $element_name = tripal_format_views_field_element($field_name, $term);
-      $data[$view_base_id][$element_name] = array(
-        'title' => ucfirst($term['name']),
-        'help' => $term['definition'],
-        'field' => array(
-          'handler' => 'tripal_views_handler_field_element',
-          'click sortable' => TRUE,
-        ),
-        'filter' => array(
-          'handler' => 'tripal_views_handler_filter_element_string',
-        ),
-        'sort' => array(
-          'handler' => 'views_handler_sort',
-        )
-      );
-
-      // Add a views field for the infraspecific type.
-      $cvterm = tripal_get_chado_semweb_term('organism', 'type_id', $options);
-      $term = tripal_get_term_details($cvterm->dbxref_id->db_id->name, $cvterm->dbxref_id->accession);
-      $element_name = tripal_format_views_field_element($field_name, $term);
-      $data[$view_base_id][$element_name] = array(
-        'title' => ucfirst($term['name']),
-        'help' => $term['definition'],
-        'field' => array(
-          'handler' => 'tripal_views_handler_field_element',
-          'click sortable' => TRUE,
-        ),
-        'filter' => array(
-          'handler' => 'tripal_views_handler_filter_element_string',
-        ),
-        'sort' => array(
-          'handler' => 'views_handler_sort',
-        )
-      );
-    }
-    return $data;
   }
 
   /**
@@ -321,16 +272,26 @@ class obi__organism extends ChadoField {
     $alias = $this->field['field_name'];
     $operator = $condition['operator'];
 
-    $genus_term = tripal_get_chado_semweb_term('organism', 'genus');
-    $species_term = tripal_get_chado_semweb_term('organism', 'species');
-    $infraspecific_name_term = tripal_get_chado_semweb_term('organism', 'infraspecific_name');
-    $infraspecific_type_term = tripal_get_chado_semweb_term('organism', 'type_id');
+    dpm($condition);
 
+    $field_term_id = $this->getFieldTermID();
+    $genus_term = $field_term_id . ',' . tripal_get_chado_semweb_term('organism', 'genus');
+    $species_term = $field_term_id . ',' . tripal_get_chado_semweb_term('organism', 'species');
+    $infraspecific_name_term = $field_term_id . ',' . tripal_get_chado_semweb_term('organism', 'infraspecific_name');
+    $infraspecific_type_term = $field_term_id . ',' . tripal_get_chado_semweb_term('organism', 'type_id');
     $query->join('organism', $alias, "base.organism_id = $alias.organism_id");
 
-    // If the column is the field name.
-    if ($condition['column'] == 'obi__organism') {
-      $query->where("CONCAT($alias.genus, ' ', $alias.species) $operator :full_name",  array(':full_name' => $condition['value']));
+    // If the column is the field name then we're during a search on the full
+    // scientific name.
+    if ($condition['column'] == $field_term_id or
+        $condition['column'] == $field_term_id . ',rdfs:label') {
+      if (chado_get_version() <= 1.3) {
+        $query->where("CONCAT($alias.genus, ' ', $alias.species) $operator :full_name",  array(':full_name' => $condition['value']));
+      }
+      else {
+        $query->leftJoin('cvterm', $alias . '_cvterm', 'base.infraspecific_type = ' . $alias . '_cvterm.type_id');
+        $query->where("CONCAT($alias.genus, ' ', $alias.species, ' ', " . $alias . "'_cvterm.name', ' ', $alias.infraspecific_name) $operator :full_name",  array(':full_name' => $condition['value']));
+      }
     }
 
     // If the column is a subfield.

+ 55 - 4
tripal_chado/includes/TripalFields/ogi__location_on_map/ogi__location_on_map.inc

@@ -54,7 +54,54 @@ class ogi__location_on_map extends ChadoField {
   // when using the widgetForm, formatterSettingsForm, etc.) it should be set.
   protected $instance;
 
-
+  /**
+   * @see TripalField::elementInfo()
+   */
+  protected function elementInfo() {
+    $field_term = $this->getFieldTermID();
+
+    $name_term = tripal_get_chado_semweb_term('featuremap', 'name');
+    $description_term = tripal_get_chado_semweb_term('featuremap', 'description');
+    $mappos_term = tripal_get_chado_semweb_term('featurepos', 'mappos');
+
+    return array(
+      $field_term => array(
+        'sortable' => FALSE,
+        'searchable' => FALSE,
+        'elements' => array(
+          'data:1274' => array(
+            'name' => 'Map',
+            'searchable' => FALSE,
+            'sortable' => FALSE,
+            'elements' => array(
+              $name_term => array(
+                'name' => 'map_name',
+                'searchable' => TRUE,
+                'operations' => array('eq', 'ne', 'contains', 'starts'),
+                'sortable' => FALSE,
+              ),
+              $description_term => array(
+                'name' => 'map_description',
+                'searchable' => TRUE,
+                'operations' => array('eq', 'ne', 'contains', 'starts'),
+                'sortable' => FALSE,
+              ),
+            ),
+          ),
+          $mappos_term => array(
+            'name' => 'Map',
+            'searchable' => TRUE,
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => FALSE,
+          ),
+          'entity' => array(
+            'searchable' => FALSE,
+            'sortable' => FALSE,
+          ),
+        ),
+      ),
+    );
+  }
   /**
    *
    * @see TripalField::load()
@@ -66,6 +113,10 @@ class ogi__location_on_map extends ChadoField {
     $field_name = $this->field['field_name'];
     $field_type = $this->field['type'];
 
+    $name_term = tripal_get_chado_semweb_term('featuremap', 'name');
+    $description_term = tripal_get_chado_semweb_term('featuremap', 'description');
+    $mappos_term = tripal_get_chado_semweb_term('featurepos', 'mappos');
+
     // Set some defaults for the empty record.
     $entity->{$field_name}['und'][0] = array(
       'value' => array(),
@@ -94,10 +145,10 @@ class ogi__location_on_map extends ChadoField {
         $value = array (
           // Map.
           'data:1274' => array(
-            'schema:name' => $featuremap->name,
-            'schema:description' => $featuremap->description,
+            $name_term => $featuremap->name,
+            $description_term => $featuremap->description,
           ),
-          'SIO:000056' => $featurepos->mappos
+          $mappos_term => $featurepos->mappos
         );
         if (property_exists($featuremap, 'entity_id')) {
           $value['data:1274']['entity'] = 'TripalEntity:' . $featuremap->entity_id;

+ 36 - 0
tripal_chado/includes/TripalFields/sbo__database_cross_reference/sbo__database_cross_reference.inc

@@ -57,6 +57,42 @@ class sbo__database_cross_reference extends ChadoField {
   protected $instance;
 
 
+  /**
+   * @see TripalField::elementInfo()
+   */
+  protected function elementInfo() {
+
+    $dbname_term = tripal_get_chado_semweb_term('db', 'name');
+    $accession_term = tripal_get_chado_semweb_term('dbxref', 'accession');
+
+    $field_term = $this->getFieldTermID();
+    return array(
+      $field_term => array(
+        'operations' => array(),
+        'sortable' => FALSE,
+        'searchable' => FALSE,
+        'elements' => array(
+          $dbname_term => array(
+            'searchable' => TRUE,
+            'name' => 'db_name',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          $accession_term => array(
+            'searchable' => TRUE,
+            'name' => 'accession',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          'schema:url' => array(
+            'searchable' => FALSE,
+            'name' => 'URL',
+            'sortable' => FALSE,
+          ),
+        ),
+      ),
+    );
+  }
   /**
    *
    * @see TripalField::load()

+ 14 - 1
tripal_chado/includes/TripalFields/sbo__phenotype/sbo__phenotype.inc

@@ -57,6 +57,19 @@ class sbo__phenotype extends ChadoField {
   protected $instance;
 
 
+  /**
+   * @see TripalField::elementInfo()
+   */
+  protected function elementInfo() {
+    $field_term = $this->getFieldTermID();
+    return array(
+      $field_term => array(
+        'operations' => array('eq', 'ne', 'contains', 'starts'),
+        'sortable' => TRUE,
+        'searchable' => TRUE,
+      ),
+    );
+  }
   /**
    *
    * @see TripalField::load()
@@ -112,7 +125,7 @@ class sbo__phenotype extends ChadoField {
         else {
           $entity->{$field_name}['und'][$i]['value']['value'] =  $phenotype->value;
         }
-        
+
         $entity->{$field_name}['und'][$i][$field_table . '__' . $pkey] = $phenotype_linker->$pkey;
         $entity->{$field_name}['und'][$i][$field_table . '__' . $fkey_lcolumn] = $phenotype_linker->$fkey_lcolumn->$fkey_lcolumn;
         $entity->{$field_name}['und'][$i][$field_table . '__' . 'phenotype_id'] = $phenotype->phenotype_id;

+ 89 - 6
tripal_chado/includes/TripalFields/sbo__relationship/sbo__relationship.inc

@@ -71,6 +71,77 @@ class sbo__relationship extends ChadoField {
   protected $instance;
 
 
+  /**
+   * @see TripalField::elements()
+   */
+  public function elementInfo() {
+    $field_term = $this->getFieldTermID();
+
+    return array(
+      $field_term => array(
+        'operations' => array('eq', 'contains', 'starts'),
+        'sortable' => TRUE,
+        'searchable' => TRUE,
+        'type' => 'string',
+        'elements' => array(
+          'local:relationship_subject' => array(
+            'searchable' => FALSE,
+            'name' => 'scientfic_name',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => FALSE,
+            'elements' => array(
+              'rdfs:type' => array(
+                'searchable' => TRUE,
+                'name' => 'subject_type',
+                'operations' => array('eq', 'ne', 'contains', 'starts'),
+                'sortable' => TRUE,
+              ),
+              'schema:name' => array(
+                'searchable' => TRUE,
+                'name' => 'subject_name',
+                'operations' => array('eq', 'ne', 'contains', 'starts'),
+                'sortable' => TRUE,
+              ),
+              'entity' => array(
+                'searchable' => FALSE,
+                'sortable' => FALSE,
+              )
+            ),
+          ),
+          'local:relationship_type' => array(
+            'searchable' => TRUE,
+            'name' => 'genus',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          'local:relationship_object' => array(
+            'searchable' => TRUE,
+            'name' => 'species',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+            'elements' => array(
+              'rdfs:type' => array(
+                'searchable' => TRUE,
+                'name' => 'object_type',
+                'operations' => array('eq', 'ne', 'contains', 'starts'),
+                'sortable' => TRUE,
+              ),
+              'schema:name' => array(
+                'searchable' => TRUE,
+                'name' => 'object_name',
+                'operations' => array('eq', 'ne', 'contains', 'starts'),
+                'sortable' => TRUE,
+              ),
+              'entity' => array(
+                'searchable' => FALSE,
+                'sortable' => FALSE,
+              )
+            ),
+          ),
+        ),
+      )
+    );
+  }
   /**
    *
    * @see TripalField::load()
@@ -445,38 +516,50 @@ class sbo__relationship extends ChadoField {
     $bpkey = $bschema['primary key'][0];
     $operator = $condition['operator'];
 
+    // Bulid the list of expected elements that will be provided.
+    $field_term_id = $this->getFieldTermID();
+    $rel_subject = $field_term_id . ',local:relationship_subject';
+    $rel_subject_type =  $rel_subject . ',' . 'rdfs:type';
+    $rel_subject_name =  $rel_subject . ',' . 'schema:name';
+    $rel_subject_identifier = $rel_subject . ',' . 'data:0842';
+    $rel_type = $field_term_id . ',local:relationship_type';
+    $rel_object = $field_term_id . ',local:relationship_object';
+    $rel_object_type = $rel_object . ',' . 'rdfs:type';
+    $rel_object_name = $rel_object . ',' . 'schema:name';
+    $rel_object_identifier = $rel_object . ',' . 'data:0842';
+
     // Filter by the name of the subject or object.
-    if ($condition['column'] == 'relationship.clause_subject.name') {
+    if ($condition['column'] == $rel_subject_name) {
       $query->join($chado_table, $alias, "base.$bpkey = $alias.object_id");
       $query->join($base_table, 'base2', "base2.$bpkey = $alias.subject_id");
       $query->condition("base2.name", $condition['value'], $operator);
     }
-    if ($condition['column'] == 'relationship.clause_predicate.name') {
+    if ($condition['column'] == $rel_object_name) {
       $query->join($chado_table, $alias, "base.$bpkey = $alias.subject_id");
       $query->join($base_table, 'base2', "base2.$bpkey = $alias.object_id");
       $query->condition("base2.name", $condition['value'], $operator);
     }
 
     // Filter by unique name of the subject or object.
-    if ($condition['column'] == 'relationship.clause_subject.identifier') {
+    if ($condition['column'] == $rel_subject_identifier) {
       $query->join($chado_table, $alias, "base.$bpkey = $alias.object_id");
       $query->join($base_table, 'base2', "base2.$bpkey = $alias.subject_id");
       $query->condition("base2.uniquename", $condition['value'], $operator);
     }
-    if ($condition['column'] == 'relationship.clause_predicate.identifier') {
+    if ($condition['column'] == $rel_object_identifier) {
       $query->join($chado_table, $alias, "base.$bpkey = $alias.subject_id");
       $query->join($base_table, 'base2', "base2.$bpkey = $alias.object_id");
       $query->condition("base2.uniquename", $condition['value'], $operator);
     }
 
     // Filter by the type of the subject or object
-    if ($condition['column'] == 'relationship.clause_subject.type') {
+    if ($condition['column'] == $rel_subject_type) {
       $query->join($chado_table, $alias, "base.$bpkey = $alias.object_id");
       $query->join($base_table, 'base2', "base2.$bpkey = $alias.subject_id");
       $query->join('cvterm', 'SubjectCVT', "SubjectCVT.cvterm_id = base2.type_id");
       $query->condition("SubjectCVT.name", $condition['value'], $operator);
     }
-    if ($condition['column'] == 'relationship.clause_predicate.type') {
+    if ($condition['column'] == $rel_object_type) {
       $query->join($chado_table, $alias, "base.$bpkey = $alias.subject_id");
       $query->join($base_table, 'base2', "base2.$bpkey = $alias.object_id");
       $query->join('cvterm', 'ObjectCVT', "ObjectCVT.cvterm_id = base2.type_id");

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

@@ -44,7 +44,6 @@ class schema__additional_type extends ChadoField {
   public static $default_formatter = 'schema__additional_type_formatter';
 
 
-
   /**
    *
    * @see TripalField::load()

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

@@ -43,6 +43,7 @@ class schema__alternate_name extends ChadoField {
   // The default formatter for this field.
   public static $default_formatter = 'schema__alternate_name_formatter';
 
+
   /**
    *
    * @see TripalField::load()

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

@@ -56,7 +56,19 @@ class schema__publication extends ChadoField {
   // when using the widgetForm, formatterSettingsForm, etc.) it should be set.
   protected $instance;
 
-
+  /**
+   * @see TripalField::elementInfo()
+   */
+  protected function elementInfo() {
+    $field_term = $this->getFieldTermID();
+    return array(
+      $field_term => array(
+        'operations' => array(),
+        'sortable' => FALSE,
+        'searchable' => FALSE,
+      ),
+    );
+  }
   /**
    *
    * @see TripalField::load()

+ 38 - 0
tripal_chado/includes/TripalFields/sio__references/sio__references.inc

@@ -55,6 +55,44 @@ class sio__references extends ChadoField {
   // and field_create_instance().
   public static $no_ui = FALSE;
 
+
+  /**
+   * @see TripalField::elementInfo()
+   */
+  protected function elementInfo() {
+    $field_term = $this->getFieldTermID();
+    return array(
+      $field_term => array(
+        'operations' => array(),
+        'sortable' => FALSE,
+        'searchable' => FALSE,
+        'elements' => array(
+          'rdfs:type' => array(
+            'searchable' => TRUE,
+            'name' => 'type',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          'schema:name' => array(
+            'searchable' => TRUE,
+            'name' => 'name',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          'data:0842'=> array(
+            'searchable' => TRUE,
+            'name' => 'identifier',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          'entity'=> array(
+            'searchable' => FALSE,
+            'sortable' => FALSE,
+          ),
+        ),
+      ),
+    );
+  }
   /**
    *
    * @see TripalField::load()

+ 14 - 0
tripal_chado/includes/TripalFields/so__cds/so__cds.inc

@@ -43,6 +43,20 @@ class so__cds extends ChadoField {
   // The default formatter for this field.
   public static $default_formatter = 'so__cds_formatter';
 
+
+  /**
+   * @see TripalField::elementInfo()
+   */
+  protected function elementInfo() {
+    $field_term = $this->getFieldTermID();
+    return array(
+      $field_term => array(
+        'sortable' => FALSE,
+        'searchable' => FALSE,
+      ),
+    );
+  }
+
   /**
    * @see TripalField::load()
    */

+ 37 - 4
tripal_chado/includes/TripalFields/so__genotype/so__genotype.inc

@@ -56,6 +56,40 @@ class so__genotype extends ChadoField {
   protected $instance;
 
 
+  /**
+   * @see TripalField::elementInfo()
+   */
+  protected function elementInfo() {
+    $field_term = $this->getFieldTermID();
+    return array(
+      $field_term => array(
+        'operations' => array(),
+        'sortable' => FALSE,
+        'searchable' => FALSE,
+        'elements' => array(
+          'rdfs:type' => array(
+            'searchable' => FALSE,
+            'name' => 'genotype_type_name',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => FALSE,
+          ),
+          'schema:name' => array(
+            'name' => 'genotype_name',
+            'searchable' => FALSE,
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => FALSE,
+          ),
+          'schema:description' => array(
+            'name' => 'genotype_description',
+            'searchable' => FALSE,
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => FALSE,
+          ),
+        )
+      ),
+    );
+  }
+
   /**
    *
    * @see TripalField::load()
@@ -105,10 +139,9 @@ class so__genotype extends ChadoField {
         $genotype = $genotype_linker->genotype_id;
         $entity->{$field_name}['und'][$i] = array(
           'value' => array(
-            '@type' => $genotype->type_id->dbxref_id->db_id->name . ':' . $genotype->type_id->dbxref_id->accession,
-            'type' => $genotype->type_id->name,
-            'name' => $genotype->name,
-            'description' => $genotype->description,
+            'rdfs:type' => $genotype->type_id->name,
+            'schema:name' => $genotype->name,
+            'schema:description' => $genotype->description,
           ),
           $field_table . '__' . $pkey => $genotype_linker->$pkey,
           $field_table . '__' . $fkey_lcolumn => $genotype_linker->$fkey_lcolumn->$fkey_lcolumn,

+ 43 - 1
tripal_chado/includes/TripalFields/so__transcript/so__transcript.inc

@@ -54,7 +54,49 @@ class so__transcript extends ChadoField {
   // when using the widgetForm, formatterSettingsForm, etc.) it should be set.
   protected $instance;
 
-
+  /**
+   * @see TripalField::elementInfo()
+   */
+  protected function elementInfo() {
+    $field_term = $this->getFieldTermID();
+    return array(
+      $field_term => array(
+        'operations' => array(),
+        'sortable' => FALSE,
+        'searchable' => FALSE,
+        'elements' => array(
+          'rdfs:type' => array(
+            'name' => 'transcript_type',
+            'searchable' => FALSE,
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => FALSE,
+          ),
+          'schema:name' => array(
+            'name' => 'transcript_name',
+            'searchable' => FALSE,
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => FALSE,
+          ),
+          'data:0842' => array(
+            'name' => 'transcript_uniquename',
+            'searchable' => FALSE,
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => FALSE,
+          ),
+          'SO:0000735' => array(
+            'name' => 'loc',
+            'searchable' => FALSE,
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => FALSE,
+          ),
+          'entity' => array(
+            'searchable' => FALSE,
+            'sortable' => FALSE,
+          ),
+        ),
+      ),
+    );
+  }
   /**
    *
    * @see TripalField::load()

+ 14 - 0
tripal_chado/includes/TripalFields/taxrank__infraspecific_taxon/taxrank__infraspecific_taxon.inc

@@ -54,6 +54,20 @@ class taxrank__infraspecific_taxon extends ChadoField {
   // when using the widgetForm, formatterSettingsForm, etc.) it should be set.
   protected $instance;
 
+  /**
+   * @see TripalField::elementInfo()
+   */
+  protected function elementInfo() {
+    $field_term = $this->getFieldTermID();
+    return array(
+      $field_term => array(
+        'operations' => array(),
+        'sortable' => FALSE,
+        'searchable' => FALSE,
+      ),
+    );
+  }
+
   /**
    *
    * @see TripalField::load()

+ 12 - 4
tripal_chado/includes/tripal_chado.entity.inc

@@ -144,10 +144,18 @@ function tripal_chado_tripal_default_title_format($bundle, $available_tokens) {
   $table = $bundle->data_table;
 
   if ($table == 'organism') {
-    $format[] = array(
-      'format' => '[taxrank__genus] [taxrank__species]',
-      'weight' => -5
-    );
+    if (chado_get_version() <= '1.2') {
+      $format[] = array(
+        'format' => '[taxrank__genus] [taxrank__species]',
+        'weight' => -5
+      );
+    }
+    else {
+      $format[] = array(
+        'format' => '[taxrank__genus] [taxrank__species] [taxrank__infraspecies]',
+        'weight' => -5
+      );
+    }
   }
   if ($table == 'analysis') {
     $format[] = array(

+ 4 - 0
tripal_chado/includes/tripal_chado.semweb.inc

@@ -161,6 +161,7 @@ function tripal_chado_populate_vocab_SCHEMA() {
     'definition' => 'The name of the item.',
   ));
   tripal_associate_chado_semweb_term(NULL, 'name', $term);
+  tripal_associate_chado_semweb_term('analysis', 'sourcename', $term);
 
   $term = tripal_insert_cvterm(array(
     'id' => 'schema:alternateName',
@@ -376,6 +377,7 @@ function tripal_chado_populate_vocab_EDAM() {
     'definition' => 'A persistent (stable) and unique identifier, typically identifying an object (entry) from a database.',
   ));
   tripal_associate_chado_semweb_term(NULL, 'dbxref_id', $term);
+  tripal_associate_chado_semweb_term('dbxref', 'accession', $term);
 
   $term = tripal_insert_cvterm(array(
     'id' => 'data:2044',
@@ -597,6 +599,8 @@ function tripal_chado_populate_vocab_IAO() {
     'having the same name.',
   ));
   tripal_associate_chado_semweb_term('analysis', 'programversion', $term);
+  tripal_associate_chado_semweb_term('analysis', 'sourceversion', $term);
+  tripal_associate_chado_semweb_term(NULL, 'version', $term);
 
   $term = tripal_insert_cvterm(array(
     'id' => 'IAO:0000064',

+ 43 - 0
tripal_chado/tripal_chado.install

@@ -1029,3 +1029,46 @@ function tripal_chado_update_7307() {
     throw new DrupalUpdateException('Could not perform update: '. $error);
   }
 }
+
+/**
+ * Add cvterm mapping for the analysis.sourcversion and analysis.sourcename.
+ */
+function tripal_chado_update_7308() {
+  try {
+    $term = tripal_insert_cvterm(array(
+      'id' => 'IAO:0000129',
+      'name' => 'version number',
+      'cv_name' => 'IAO',
+      'definition' => 'A version number is an ' .
+      'information content entity which is a sequence of characters ' .
+      'borne by part of each of a class of manufactured products or its ' .
+      'packaging and indicates its order within a set of other products ' .
+      'having the same name.',
+    ));
+    tripal_associate_chado_semweb_term('analysis', 'sourceversion', $term);
+    tripal_associate_chado_semweb_term(NULL, 'version', $term);
+
+    $term = tripal_insert_cvterm(array(
+      'id' => 'schema:name',
+      'name' => 'name',
+      'cv_name' => 'schema',
+      'definition' => 'The name of the item.',
+    ));
+    tripal_associate_chado_semweb_term('analysis', 'sourcename', $term);
+
+    $term = tripal_insert_cvterm(array(
+      'id' => 'data:2091',
+      'name' => 'Accession',
+      'cv_name' => 'EDAM',
+      'definition' => 'A persistent (stable) and unique identifier, typically identifying an object (entry) from a database.',
+    ));
+    tripal_associate_chado_semweb_term('dbxref', 'accession', $term);
+
+  }
+  catch (\PDOException $e) {
+    $error = $e->getMessage();
+    throw new DrupalUpdateException('Could not perform update: '. $error);
+  }
+}
+
+

+ 34 - 10
tripal_ws/includes/TripalWebService/TripalEntityService_v0_1.inc

@@ -75,7 +75,7 @@ class TripalEntityService_v0_1 extends TripalWebService {
 
     // If we couldn't match this field argument to a field and entity then return
     if (!$entity) {
-      throw new Exception("Canno find this entity.");
+      throw new Exception("Cannot find this entity.");
     }
 
     list($field, $instance, $term) = $this->findField($bundle, $expfield);
@@ -485,22 +485,46 @@ class TripalEntityService_v0_1 extends TripalWebService {
         $op = $matches[2];
       }
 
-      // Break apart any subkeys and pull the first one out for the term name key.
+      // Break apart any subkeys and pull the first one as this is the parent
+      // field.
       $subkeys = explode(',', $key);
       if (count($subkeys) > 0) {
-        $key = array_shift($subkeys);
+        $key = $subkeys[0];
       }
-      $column_name = $key;
 
       // Map the values in the filters to their appropriate field names.
       if (array_key_exists($key, $field_mapping)) {
-        $field_name = $field_mapping[$key];
-        if (count($subkeys) > 0) {
-          $column_name .= '.' . implode('.', $subkeys);
+        $key_field_name = $field_mapping[$key];
+        $key_field = field_info_field($key_field_name);
+        $key_instance = field_info_instance('TripalEntity', $key_field_name, $bundle->name);
+
+        // Complex fields provied by the TripalField class may have sub
+        // elements that support filtering.  We need to see if the user
+        // wants to filter on those.
+        if (tripal_load_include_field_class($key_field_name)) {
+          // To find out which fields are searchable we'll call the wsData()
+          // function.
+          $key_field = new $key_field_name($key_field, $key_instance);
+          $searchable_keys = $key_field->webServicesData();
+          $criteria = implode('.', $subkeys);
+          if (array_key_exists($criteria, $searchable_keys)) {
+            $new_params[$key_field_name]['value'] = $value;
+            $new_params[$key_field_name]['op'] = $op;
+            $new_params[$key_field_name]['column'] = $searchable_keys[$criteria];
+          }
+          else {
+            throw new Exception("The filter term, '$criteria', is not available for use.");
+          }
+        }
+        // If this field is not a TripalField then it should just have
+        // a simple value and we can query for that.
+        else {
+          $key_field_id = $key_instance['settings']['term_vocabulary'] . ':' . $key_instance['settings']['term_accession'];
+
+          $new_params[$key_field_name]['value'] = $value;
+          $new_params[$key_field_name]['op'] = $op;
+          $new_params[$key_field_name]['column'] = $key_field_id;
         }
-        $new_params[$field_name]['value'] = $value;
-        $new_params[$field_name]['op'] = $op;
-        $new_params[$field_name]['column'] = $column_name;
       }
       else {
         throw new Exception("The filter term, '$key', is not available for use.");