Browse Source

Merge branch '7.x-3.x' into 7.x-3.x-dashboard

Stephen Ficklin 7 years ago
parent
commit
2d15c7cd5d
31 changed files with 811 additions and 164 deletions
  1. 21 1
      tripal/api/tripal.fields.api.inc
  2. 3 0
      tripal/api/tripal.importer.api.inc
  3. 4 2
      tripal/includes/TripalEntityController.inc
  4. 6 0
      tripal/includes/TripalFieldQuery.inc
  5. 16 13
      tripal/includes/TripalFields/TripalField.inc
  6. 8 1
      tripal/includes/tripal.fields.inc
  7. 3 1
      tripal/tripal.info
  8. 10 2
      tripal/tripal.views.inc
  9. 192 2
      tripal/tripal.views_default.inc
  10. 154 63
      tripal/tripal_views_query.inc
  11. 13 3
      tripal/views_handlers/tripal_views_handler_field.inc
  12. 73 0
      tripal/views_handlers/tripal_views_handler_field_element.inc
  13. 6 6
      tripal/views_handlers/tripal_views_handler_filter.inc
  14. 0 10
      tripal/views_handlers/tripal_views_handler_filter_boolean_operator.inc
  15. 13 0
      tripal/views_handlers/tripal_views_handler_filter_element_string.inc
  16. 4 2
      tripal/views_handlers/tripal_views_handler_filter_string.inc
  17. 28 10
      tripal_chado/api/tripal_chado.semweb.api.inc
  18. 20 0
      tripal_chado/includes/TripalFields/ChadoField.inc
  19. 22 1
      tripal_chado/includes/TripalFields/data__accession/data__accession.inc
  20. 1 1
      tripal_chado/includes/TripalFields/data__accession/data__accession_formatter.inc
  21. 16 14
      tripal_chado/includes/TripalFields/data__sequence_coordinates/data__sequence_coordinates.inc
  22. 142 4
      tripal_chado/includes/TripalFields/obi__organism/obi__organism.inc
  23. 0 5
      tripal_chado/includes/TripalFields/obi__organism/obi__organism_formatter.inc
  24. 6 0
      tripal_chado/includes/tripal_chado.entity.inc
  25. 8 3
      tripal_chado/includes/tripal_chado.field_storage.inc
  26. 9 4
      tripal_chado/includes/tripal_chado.fields.inc
  27. 9 1
      tripal_chado_views/api/tripal_chado_views.api.inc
  28. 2 2
      tripal_chado_views/includes/tripal_chado_views_integration.inc
  29. 9 9
      tripal_chado_views/tripal_chado_views.module
  30. 2 2
      tripal_chado_views/tripal_chado_views.views.inc
  31. 11 2
      tripal_ds/includes/tripal_ds.ds.inc

+ 21 - 1
tripal/api/tripal.fields.api.inc

@@ -224,4 +224,24 @@ function tripal_get_field_item_keyval($items, $delta, $key, $default='') {
   return $items[$delta][$key];
 }
 
-
+/**
+ * Formats an element of a TripalField for use by Drupal Views.
+ *
+ * Sometimes the value of TripalField can be more than just a single scalar. In
+ * this case the value is an array of key value pairs where each key is a
+ * controlled vocabulary term.  In order to support fields, filtering and
+ * sorting by these sub elements using Drupal Views, the TripalField
+ * implementation must provide some help to Views by describing these elements,
+ * and then implementing a query() function to support them.  However, the
+ * naming of sub elements must follow a set convention. This function
+ * guarantees proper naming for sub elements.
+ *
+ * @param $field_name
+ *   The name of the field to which the element belongs.
+ * @param $term
+ *   The term object as returned by tripal_get_term_details();
+ */
+function tripal_format_views_field_element($field_name, $term) {
+  $element_name = $term['vocabulary']['short_name'] . '__' . $term['accession'];
+  return $field_name . '.' . $element_name;
+}

+ 3 - 0
tripal/api/tripal.importer.api.inc

@@ -123,6 +123,9 @@ function tripal_run_importer($import_id, TripalJob $job = NULL) {
     // Check for new fields and notify the user.
     tripal_tripal_cron_notification();
 
+    // Clear the Drpual chace
+    cache_clear_all();
+
   }
   catch (Exception $e) {
     $transaction->rollback();

+ 4 - 2
tripal/includes/TripalEntityController.inc

@@ -335,8 +335,10 @@ class TripalEntityController extends EntityAPIController {
     $changed_date = time();
     $create_date = $changed_date;
     if (property_exists($entity, 'created')) {
-      $temp = new DateTime($entity->created);
-      $create_date = $temp->getTimestamp();
+      if (!is_numeric($entity->created)) {
+        $temp = new DateTime($entity->created);
+        $create_date = $temp->getTimestamp();
+      }
     }
 
     $status = 1;

+ 6 - 0
tripal/includes/TripalFieldQuery.inc

@@ -34,6 +34,7 @@ class TripalFieldQuery extends EntityFieldQuery {
       foreach ($this->field_storage as $storage_type => $storage_module) {
         // Execute the query using the correct callback.
         $callback = $this->queryStorageCallback($storage_module);
+
         $st_results = call_user_func($callback, $this);
         // If this is the first storage type to be queries then save these
         // as the current results list.
@@ -60,7 +61,11 @@ class TripalFieldQuery extends EntityFieldQuery {
     else {
       $results = call_user_func($this->queryCallback(), $this);
     }
+
     if ($results and $this->count) {
+      if (!is_numeric($results)) {
+        throw new Exception('Query callback function did not provide a numeric value: ' . $this->queryCallback());
+      }
       return $results;
     }
     else {
@@ -95,6 +100,7 @@ class TripalFieldQuery extends EntityFieldQuery {
     if (empty($this->fields)) {
       return array($this, 'propertyQuery');
     }
+
     if ($storage) {
       // Use hook_field_storage_query() from the field storage.
       return $storage . '_field_storage_query';

+ 16 - 13
tripal/includes/TripalFields/TripalField.inc

@@ -79,7 +79,6 @@ class TripalField {
   // the user but otherwise provides no data.
   public static $no_data = FALSE;
 
-
   // --------------------------------------------------------------------------
   //              PROTECTED CLASS MEMBERS -- DO NOT OVERRIDE
   // --------------------------------------------------------------------------
@@ -277,20 +276,25 @@ class TripalField {
    * 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() {
+  public function viewsData($view_base_id) {
     $data = array();
-
-    $bundle_name = $this->instance['bundle'];
     $field_name = $this->field['field_name'];
 
-    // Fields should be associated with the bundle's term identifier
-    // (i.e. [vocab]__[accession].
-    $bundle = tripal_load_bundle_entity(array('name' => $bundle_name));
-    $term = tripal_load_term_entity(array('term_id' => $bundle->term_id));
-    $table = $term->vocab->vocabulary . '__' . $term->accession;
-
-    $data[$table][$field_name] = array(
+    $data[$view_base_id][$field_name] = array(
       'title' => $this->instance['label'],
       'help' => $this->instance['description'],
       'field' => array(
@@ -302,9 +306,8 @@ class TripalField {
       ),
       'sort' => array(
         'handler' => 'views_handler_sort',
-      ),
+      )
     );
-
     return $data;
   }
 

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

@@ -98,7 +98,14 @@ function tripal_field_views_data($field) {
     $instance = field_info_instance('TripalEntity', $field['field_name'], $bundle_name);
     if (in_array($field_type, $field_types)) {
       $tfield = new $field_type($field, $instance);
-      $data += $tfield->viewsData();
+
+      // Fields should be associated with the bundle's term identifier
+      // (i.e. [vocab]__[accession].
+      $bundle = tripal_load_bundle_entity(array('name' => $bundle_name));
+      $term = tripal_load_term_entity(array('term_id' => $bundle->term_id));
+      $view_base_id = $term->vocab->vocabulary . '__' . $term->accession;
+
+      $data += $tfield->viewsData($view_base_id);
     }
   }
   return $data;

+ 3 - 1
tripal/tripal.info

@@ -10,6 +10,7 @@ stylesheets[all][] = theme/css/tripal.css
 scripts[]          = theme/js/tripal.js
 
 files[] = views_handlers/tripal_views_handler_field.inc
+files[] = views_handlers/tripal_views_handler_field_element.inc
 files[] = views_handlers/tripal_views_handler_field_entity.inc
 files[] = views_handlers/tripal_views_handler_field_entity_link.inc
 files[] = views_handlers/tripal_views_handler_field_entity_link_edit.inc
@@ -18,7 +19,8 @@ files[] = views_handlers/tripal_views_handler_field_image.inc
 files[] = views_handlers/tripal_views_handler_field_boolean.inc
 files[] = views_handlers/tripal_views_handler_filter.inc
 files[] = views_handlers/tripal_views_handler_filter_string.inc
-files[] = views_handlers/tripal_views_handler_filter_boolean.inc
+files[] = views_handlers/tripal_views_handler_filter_element_string.inc
+files[] = views_handlers/tripal_views_handler_filter_boolean_operator.inc
 files[] = views_handlers/tripal_views_handler_filter_entity_string.inc
 files[] = views_handlers/tripal_views_handler_filter_string_selectbox.inc
 files[] = views_handlers/tripal_views_handler_sort_entity_string.inc

+ 10 - 2
tripal/tripal.views.inc

@@ -62,9 +62,17 @@ function tripal_views_data_fields(&$data) {
       $bundles = $field['bundles']['TripalEntity'];
       $result = array();
       foreach ($bundles as $bundle_name) {
+        $field_name = $field['field_name'];
+
+        // Fields should be associated with the bundle's term identifier
+        // (i.e. [vocab]__[accession].
+        $bundle = tripal_load_bundle_entity(array('name' => $bundle_name));
+        $term = tripal_load_term_entity(array('term_id' => $bundle->term_id));
+        $view_base_id = $term->vocab->vocabulary . '__' . $term->accession;
+
         $instance = field_info_instance('TripalEntity', $field['field_name'], $bundle_name);
         $tfield = new TripalField($field, $instance);
-        $result += $tfield->viewsData();
+        $result += $tfield->viewsData($view_base_id);
       }
     }
 
@@ -165,7 +173,7 @@ function tripal_views_data_tripal_entity(&$data) {
         ),
       ),
       'filter' => array(
-        'handler' => 'views_handler_filter_boolean_operator',
+        'handler' => 'tripal_views_handler_filter_boolean_operator',
         'label' => t('Published'),
         'type' => 'yes-no',
         'use equal' => TRUE, // Use status = 1 instead of status <> 0 in WHERE statment

+ 192 - 2
tripal/tripal.views_default.inc

@@ -14,11 +14,201 @@ function tripal_views_default_views() {
 
   $view = tripal_admin_defaultview_jobs();
   $views[$view->name] = $view;
-    
+
+  // Add in the views for existing content types.
+  tripal_bundle_default_views($views);
+
   return $views;
-}  
+}
+
+function tripal_bundle_default_views(&$views) {
+  // Get the list of all of the bundles (entity types) and add them
+  // as "base tables" for views.
+  $bundles = db_select('tripal_bundle', 'tb')
+    ->fields('tb')
+    ->execute();
+
+  // Iterate through the bundles.
+  while ($bundle = $bundles->fetchObject()) {
+
+    // The base table for a TripalEntity content type is simply the
+    // vocab and the accession for the term.  It's not really a table
+    // but we use that nomenclature for views.
+    $term = tripal_load_term_entity(array('term_id' => $bundle->term_id));
+    $base_table = $term->vocab->vocabulary . '__' . $term->accession;
+    $view_name = preg_replace('/[^\w]/', '_', $bundle->label) . '_search';
+
+    // Get the fields that are attached to this bundle type.
+    $fields = field_info_instances('TripalEntity', $bundle->name);
+
+    // Initalize the view.
+    $view = new view();
+    $view->name = $view_name;
+    $view->description = 'A search tool for ' . $bundle->label . ' content.';
+    $view->tag = $bundle->label . ' search';
+    $view->base_table = $base_table;
+    $view->human_name = $bundle->label . ' Search';
+    $view->core = 7;
+    $view->api_version = '3.0';
+    $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
+
+
+    /* Display: Defaults */
+    $handler = $view->new_display('default', 'Defaults', 'default');
+    $handler->display->display_options['title'] = $bundle->label . ' Search';
+    $handler->display->display_options['use_more_always'] = FALSE;
+    $handler->display->display_options['access']['type'] = 'perm';
+    $handler->display->display_options['access']['perm'] = 'view ' . $bundle->name;
+    $handler->display->display_options['cache']['type'] = 'none';
+    $handler->display->display_options['query']['type'] = 'views_query';
+    $handler->display->display_options['exposed_form']['type'] = 'basic';
+    $handler->display->display_options['pager']['type'] = 'full';
+    $handler->display->display_options['pager']['options']['items_per_page'] = '25';
+    $handler->display->display_options['pager']['options']['offset'] = '0';
+    $handler->display->display_options['pager']['options']['id'] = '0';
+    $handler->display->display_options['pager']['options']['quantity'] = '9';
+
+    // Start the default display style options.
+    $handler->display->display_options['style_plugin'] = 'table';
+    $handler->display->display_options['style_options']['grouping'] = '';
+
+    // We can't have all fields show up as columns in a table so we have
+    // to be selective and choose those that are most likely to be most
+    // descriptive of a content type.
+    $columns = array();
+    $default_fields = array('data__image', 'data__identifier', 'schema__name',
+      'data__accession', 'rdfs__label', 'taxrank__genus',
+      'taxrank__species', 'obi__organism', 'tpub__title',
+      'schema__alternate_name', 'schema__description', 'tpub__abstract'
+    );
+    $selected_fields = array();
+    foreach ($default_fields as $field_name) {
+      if (in_array($field_name, array_keys($fields))) {
+        $selected_fields[] = $field_name;
+      }
+    }
+    $handler->display->display_options['style_options']['default'] = '-1';
+
+    // Add in the entity_id field.
+    $handler->display->display_options['style_options']['columns']['entity_id'] = 'entity_id';
+    $handler->display->display_options['style_options']['info']['entity_id'] = array(
+      'sortable' => 1,
+      'separator' => '',
+    );
+    $handler->display->display_options['fields']['entity_id']['id'] = 'entity_id';
+    $handler->display->display_options['fields']['entity_id']['table'] = $base_table;
+    $handler->display->display_options['fields']['entity_id']['field'] = 'entity_id';
+    $handler->display->display_options['fields']['entity_id']['exclude'] = TRUE;
+
+    // Add in other selected fields to the view.
+    foreach ($selected_fields as $field_name) {
+      $field = $fields[$field_name];
+
+      // Make sure the table headers are there for this field.
+      $handler->display->display_options['style_options']['columns'][$field_name] = $field_name;
+      $handler->display->display_options['style_options']['info'][$field_name]['separator'] = '';
+
+      // Add in the current field.
+      $handler->display->display_options['fields'][$field_name]['id'] = $field_name;
+      $handler->display->display_options['fields'][$field_name]['table'] = $base_table;
+      $handler->display->display_options['fields'][$field_name]['field'] = $field_name;
+      $handler->display->display_options['fields'][$field_name]['label'] = $field['label'];
+
+      // Only some fields are sortable.
+      if (in_array($field_name, array('data__identifier', 'schema__name',
+          'data__accession', 'rdfs__label', 'taxrank__genus',
+          'taxrank__species', 'obi__organism',
+          'schema__alternate_name', 'tpub__title'))) {
+        $handler->display->display_options['style_options']['info'][$field_name]['sortable'] = 1;
+        $handler->display->display_options['style_options']['info'][$field_name]['default_sort_order'] = 'asc';
+      }
+
+      // The name or identifier fields should link to the record.
+      if ($field_name == 'data__identifier' or $field_name == 'schema__name' or
+          $field_name == 'taxrank__genus' or $field_name == 'taxrank__species' or
+          $field_name == 'tpub__title') {
+        $handler->display->display_options['fields'][$field_name]['alter']['make_link'] = TRUE;
+        $handler->display->display_options['fields'][$field_name]['alter']['path'] = 'bio_data/[entity_id]';
+      }
 
+      // Set a default image width to 100px.
+      if ($field_name == 'data__image') {
+        $handler->display->display_options['fields']['data__image']['image_width'] = '100';
+      }
 
+      // Add a 'read more' link to the description field if it's too big
+      if ($field_name == 'schema__description') {
+        $handler->display->display_options['fields']['schema__description']['alter']['max_length'] = '512';
+        $handler->display->display_options['fields']['schema__description']['alter']['more_link'] = TRUE;
+        $handler->display->display_options['fields']['schema__description']['alter']['more_link_text'] = 'read more';
+        $handler->display->display_options['fields']['schema__description']['alter']['more_link_path'] = 'bio_data/[entity_id]';
+        $handler->display->display_options['fields']['schema__description']['alter']['trim'] = TRUE;
+      }
+
+      // Filter criterion.
+      if (in_array($field_name, array('data__identifier', 'schema__name',
+          'data__accession', 'rdfs__label', 'taxrank__genus',
+          'taxrank__species', 'obi__organism', 'tpub__title'))) {
+        $handler->display->display_options['filters'][$field_name]['id'] = $field_name;
+        $handler->display->display_options['filters'][$field_name]['table'] = $base_table;
+        $handler->display->display_options['filters'][$field_name]['field'] = $field_name;
+        $handler->display->display_options['filters'][$field_name]['operator'] = 'contains';
+        $handler->display->display_options['filters'][$field_name]['group'] = 1;
+        $handler->display->display_options['filters'][$field_name]['exposed'] = TRUE;
+        $handler->display->display_options['filters'][$field_name]['expose']['operator_id'] = $field_name . '_op';
+        $handler->display->display_options['filters'][$field_name]['expose']['label'] = $field['label'];
+        $handler->display->display_options['filters'][$field_name]['expose']['use_operator'] = TRUE;
+        $handler->display->display_options['filters'][$field_name]['expose']['operator'] = $field_name . '_op';
+        $handler->display->display_options['filters'][$field_name]['expose']['identifier'] = $field_name;
+        $handler->display->display_options['filters'][$field_name]['expose']['remember_roles'] = array(
+          2 => '2',
+          1 => 0,
+          3 => 0,
+        );
+        $handler->display->display_options['filters'][$field_name]['select_optional'] = TRUE;
+        $handler->display->display_options['filters'][$field_name]['max_length'] = '40';
+      }
+    }
+
+    // Add the default sorted column.
+    if (in_array('data__identifier', $selected_fields)) {
+      $handler->display->display_options['style_options']['default'] = 'data__identifier';
+    }
+    else if (in_array('schema__name', $selected_fields)) {
+      $handler->display->display_options['style_options']['default'] = 'schema__name';
+    }
+    else if (in_array('obi__organism', $selected_fields)) {
+      $handler->display->display_options['style_options']['default'] = 'obi__organism';
+    }
+    else if (in_array('rdfs_label', $selected_fields)) {
+      $handler->display->display_options['style_options']['default'] = 'rdfs_label';
+    }
+    else if (in_array('taxrank__genus', $selected_fields)) {
+      $handler->display->display_options['style_options']['default'] = 'taxrank__genus';
+    }
+    else if (in_array('taxrank__species', $selected_fields)) {
+      $handler->display->display_options['style_options']['default'] = 'taxrank__species';
+    }
+
+    // No results behavior: Global: Text area.
+    $handler->display->display_options['empty']['text']['id'] = 'text';
+    $handler->display->display_options['empty']['text']['table'] = 'views';
+    $handler->display->display_options['empty']['text']['field'] = 'area';
+    $handler->display->display_options['empty']['text']['empty'] = TRUE;
+    $handler->display->display_options['empty']['text']['content'] = 'No ' . strtolower($bundle->label) . ' records matched the supplied criteria.';
+    $handler->display->display_options['empty']['text']['format'] = 'filtered_html';
+
+    // Add page and menu.
+    $handler = $view->new_display('page', 'Page', 'page_1');
+    $handler->display->display_options['path'] = 'data_search/' . strtolower(preg_replace('/[^\w]/', '_', $bundle->label));
+    $handler->display->display_options['menu']['type'] = 'normal';
+    $handler->display->display_options['menu']['title'] = $bundle->label . ' Search';
+    $handler->display->display_options['menu']['description'] = 'A search form for finding ' . $bundle->label . ' records';
+    $handler->display->display_options['menu']['weight'] = '-10';
+
+    $views[$view_name] = $view;
+  }
+}
 /**
  * Describes the jobs administration view.
  *

+ 154 - 63
tripal/tripal_views_query.inc

@@ -38,10 +38,8 @@ class tripal_views_query extends views_plugin_query {
   /**
    *
    */
-  public function init($base_table = 'tripal_entity', $base_field = 'id', $options) {
-
+  public function init($base_table = 'tripal_entity', $base_field = 'id', $options) {;
     parent::init($base_table, $base_field, $options);
-
     $this->fields = array();
     $this->where = array();
 
@@ -91,91 +89,184 @@ class tripal_views_query extends views_plugin_query {
    *   here.
    */
   public function add_where($group, $field_name, $value = NULL, $operator = NULL) {
-    // Remove the preceeding period from the $field_name
-    $field_name = preg_replace('/^\./', '', $field_name);
-
     $this->filters[] = array(
       'group' => $group,
       'field_name' => $field_name,
       'value' => $value,
       'op' => $operator
     );
+
     if ($value) {
-      $this->query->fieldCondition($field_name, $value, $value, $op);
+      // Handle the bundle properties separate from real fields.
+      if ($field_name == 'entity_id' or $field_name == 'status') {
+        $this->query->propertyCondition($field_name, $value, $operator);
+      }
+      else if ($field_name == 'link' or $field_name == 'edit_link' or $field_name == 'delete_link') {
+        // TODO: not sure how to handle these just yet.
+      }
+      else {
+        // If the field_name comes to us with a period in it then it means that
+        // we need to separate the field name from sub-element names.
+        $matches = array();
+        if (preg_match('/^(.+?)\.(.*)$/', $field_name, $matches)) {
+           $field_name = $matches[1];
+           $element_name = $matches[2];
+           // Remove the double underscore from the $element_name and put
+           // back the colon
+           $element_name = preg_replace('/__/', ':', $element_name);
+          $this->query->fieldCondition($field_name, $element_name, $value, $operator);
+        }
+        else {
+          $this->query->fieldCondition($field_name, $field_name, $value, $operator);
+        }
+      }
     }
   }
 
+  public function add_orderby($table, $field = NULL, $order = 'ASC',
+      $alias = '', $params = array()) {
+
+    $this->orderby[] = array(
+      'field' => $field,
+      'direction' => strtoupper($order)
+    );
+
+  }
+  /**
+   *
+   */
+  function build(&$view) {
+    // Make the query distinct if the option was set.
+    if (!empty($this->options['distinct'])) {
+      $this->set_distinct(TRUE, !empty($this->options['pure_distinct']));
+    }
+
+    // Store the view in the object to be able to use it later.
+    $this->view = $view;
+
+    $view->init_pager();
+
+    // Let the pager modify the query to add limits.
+    $this->pager->query();
+
+    $cquery = clone $this->query;
+    $view->build_info['query'] = $this->query;
+    $view->build_info['count_query'] = $cquery->count();
+  }
   /**
    *
    * @param  $view
    */
   function execute(&$view) {
-    $query = $this->query;
-
-    $start = microtime(TRUE);
-
-    // Execute the count query
-    // TODO: support paging.
-    $cquery = clone $query;
-    $cquery->count();
-    //$views->total_rows = $cquery->execute();
-
-    // Get the IDs
-    $results = $query->execute();
-    $entity_ids = array_keys($results['TripalEntity']);
-
-
-    // Get the fields to attach to the entity
-    $fields = array();
-    $field_ids = array();
-    foreach ($this->fields as $details) {
-      $field_name = $details['field_name'];
-      $field = field_info_field($field_name);
-      if ($field) {
-        $fields[$field_name] = $field;
-        $field_ids[] = $field['id'];
-      }
-    }
+    $query = $view->build_info['query'];
+    $count_query = $view->build_info['count_query'];
+
+    if ($query) {
+      $start = microtime(TRUE);
 
-    $entities = tripal_load_entity('TripalEntity', $entity_ids, FALSE, $field_ids);
-    $i = 0;
-    foreach ($entities as $entity_id => $entity) {
-      $view->result[$i] = new stdClass();
-      foreach ($this->fields as $details) {
-        $field_name = $details['field_name'];
-        // The entity_id and link fields are not true fields. They are
-        // added by the tripal_views_data_tripal_entity() function to provide
-        // useful fields to reference entities. If we see these
-        // we need to support them here by giving them values.
-        if ($field_name == 'entity_id') {
-          $view->result[$i]->$field_name = $entity;
-          continue;
+      try {
+
+        if ($this->pager->use_count_query() || !empty($view->get_total_rows)) {
+          // TODO: The code below was taken from the
+          // views_plugin_pager::execute_count_query($count_query) which would
+          // be called here, but that function expects the query is a
+          // database query rather than a TripalEntityField query.  We
+          // really should create a new tripal_views_plugin_pager class
+          // and call the corresponding function here, but due to time
+          // constraints this is the shortcut.
+          $this->pager->total_items = $count_query->execute();
+          if (!empty($this->pager->options['offset'])) {
+            $this->pager->total_items -= $this->pager->options['offset'];
+          };
+          $this->pager->update_page_info();
         }
-        if ($field_name == 'link') {
-          $view->result[$i]->$field_name = $entity;
-          continue;
+
+        // TODO: we need to implement a new views_plugin_pager class to
+        // override the pre_execute to set the range, instead we'll just do
+        // it manully here until we have the class.
+        $this->pager->pre_execute($query);
+        $num_items_per_page = $this->pager->get_items_per_page();
+        $offset = $this->pager->get_current_page() * $num_items_per_page;
+        $query->range($offset, $num_items_per_page);
+
+        // Get the IDs
+        $results = $query->execute();
+
+        $entity_ids = array_keys($results['TripalEntity']);
+
+        $this->pager->post_execute($view->result);
+
+        if ($this->pager->use_count_query() || !empty($view->get_total_rows)) {
+          $view->total_rows = $this->pager->get_total_items();
         }
-        if ($field_name == 'edit_link') {
-          $view->result[$i]->$field_name = $entity;
-          continue;
+
+        // Get the fields to attach to the entity
+        $fields = array();
+        $field_ids = array();
+        foreach ($this->fields as $details) {
+          $field_name = $details['field_name'];
+          $field = field_info_field($field_name);
+          if ($field) {
+            $fields[$field_name] = $field;
+            $field_ids[] = $field['id'];
+          }
         }
-        if ($field_name == 'delete_link') {
-          $view->result[$i]->$field_name = $entity;
-          continue;
+
+        $entities = tripal_load_entity('TripalEntity', $entity_ids, FALSE, $field_ids);
+        $i = 0;
+        foreach ($entities as $entity_id => $entity) {
+          $view->result[$i] = new stdClass();
+          foreach ($this->fields as $details) {
+            $field_name = $details['field_name'];
+            // The entity_id and link fields are not true fields. They are
+            // added by the tripal_views_data_tripal_entity() function to provide
+            // useful fields to reference entities. If we see these
+            // we need to support them here by giving them values.
+            if ($field_name == 'entity_id') {
+              $view->result[$i]->$field_name = $entity;
+              continue;
+            }
+            if ($field_name == 'link') {
+              $view->result[$i]->$field_name = $entity;
+              continue;
+            }
+            if ($field_name == 'edit_link') {
+              $view->result[$i]->$field_name = $entity;
+              continue;
+            }
+            if ($field_name == 'delete_link') {
+              $view->result[$i]->$field_name = $entity;
+              continue;
+            }
+            if ($field_name == 'status') {
+              $view->result[$i]->$field_name = $entity->status;
+              continue;
+            }
+            if (array_key_exists($field_name, $fields)) {
+              $items = field_get_items('TripalEntity', $entity, $field_name);
+              $view->result[$i]->$field_name = $items;
+            }
+          }
+          // Always add the entity to the results so that handlers
+          // can take advantage of it.
+          $view->result[$i]->entity = $entity;
+          $i++;
         }
-        if ($field_name == 'status') {
-          $view->result[$i]->$field_name = $entity->status;
-          continue;
+      }
+      catch (Exception $e) {
+        $view->result = array();
+        if (!empty($view->live_preview)) {
+          drupal_set_message($e->getMessage(), 'error');
         }
-        if (array_key_exists($field_name, $fields)) {
-          $items = field_get_items('TripalEntity', $entity, $field_name);
-          $view->result[$i]->$field_name = $items;
+        else {
+          vpr('Exception in @human_name[@view_name]: @message', array('@human_name' => $view->human_name, '@view_name' => $view->name, '@message' => $e->getMessage()));
         }
       }
-      $i++;
+    }
+    else {
+      $start = microtime(TRUE);
     }
     $view->execute_time = microtime(TRUE) - $start;
-    $view->current_page = 0;
   }
 
 }

+ 13 - 3
tripal/views_handlers/tripal_views_handler_field.inc

@@ -59,10 +59,20 @@ class tripal_views_handler_field extends views_handler_field {
    */
   function render($values) {
 
-    $value = $this->get_value($values);
+    list ($vocabulary, $accession) = explode('__', $this->table_alias);
+    $term = tripal_load_term_entity(array('vocabulary' => $vocabulary, 'accession' => $accession));
+    $bundle = tripal_load_bundle_entity(array('term_id' => $term->id));
+    $field_name = $this->field_alias;
+    $field = field_info_field($field_name);
+    $instance = field_info_instance('TripalEntity', $field_name, $bundle->name);
+    $entity = $values->entity;
+
+    $items = $this->get_value($values);
+
     // Handle single value fields:
-    if (count($value == 1)) {
-      $value = $this->sanitize_value($value[0]['value'], 'xss');
+    if (count($items == 1)) {
+      $function = $field['module'] . '_field_formatter_view';
+      $value = $function('TripalEntity', $entity, $field, $instance, 'und', $items, $instance['display']['default']);
       return $value;
     }
     return '';

+ 73 - 0
tripal/views_handlers/tripal_views_handler_field_element.inc

@@ -0,0 +1,73 @@
+<?php
+/**
+ * @file
+ *   Views field handler for basic TripalFields fields.
+ */
+
+/**
+ * Views field handler for basic TripalFields fields.
+ */
+class tripal_views_handler_field_element extends tripal_views_handler_field {
+  /**
+   *
+   */
+  function query() {
+    parent::query();
+    // We need to add an alias to our TripalFields so that the
+    // views can find the results.  With SQL it sets the alias for each
+    // field and expects to find that alias in the results array.  Without
+    // setting this alias Views can't find our results from our
+    // tripal_views_query plugin.
+    $this->field_alias = $this->real_field;
+  }
+
+  /**
+   * Get the value that's supposed to be rendered.
+   *
+   * This api exists so that other modules can easy set the values of the field
+   * without having the need to change the render method as well.
+   *
+   * @param $values
+   *   An object containing all retrieved values.
+   * @param $field
+   *   Optional name of the field where the value is stored.
+   */
+  function get_value($values, $field = NULL) {
+
+    $field_name = $this->field_alias;
+
+    if (preg_match('/^(.+?)\.(.*)$/', $field_name, $matches)) {
+      $field_name = $matches[1];
+      $element_name = $matches[2];
+    }
+    if (isset($values->{$field_name})) {
+      return $values->{$field_name};
+    }
+  }
+
+  /**
+   * Render the field.
+   *
+   * @param $values
+   *   The values retrieved from the database.
+   */
+  function render($values) {
+    $field_name = $this->field_alias;
+    $element_name = $field_name;
+
+    if (preg_match('/^(.+?)\.(.*)$/', $field_name, $matches)) {
+      $field_name = $matches[1];
+      $element_name = $matches[2];
+      // Conver the element name back to it's correct format with the colon.
+      $element_name = preg_replace('/__/', ':', $element_name);
+    }
+
+    $value = $this->get_value($values);
+
+    // Handle single value fields:
+    if (count($value == 1)) {
+      return $this->sanitize_value($value[0]['value'][$element_name], 'xss');
+    }
+    return '';
+  }
+}

+ 6 - 6
tripal/views_handlers/tripal_views_handler_filter.inc

@@ -4,14 +4,14 @@ class tripal_views_handler_filter extends views_handler_filter {
 
   /**
    * Add this filter to the query.
-   *
-   * Due to the nature of fapi, the value and the operator have an unintended
-   * level of indirection. You will find them in $this->operator
-   * and $this->value respectively.
    */
   function query() {
     $this->ensure_my_table();
-    $this->query->add_where($this->options['group'], $this->real_field, $this->value, $this->operator);
+    $this->query->add_where(
+      $this->options['group'],
+      $this->real_field,
+      $this->value,
+      $this->operator
+    );
   }
-
 }

+ 0 - 10
tripal/views_handlers/tripal_views_handler_filter_boolean.inc → tripal/views_handlers/tripal_views_handler_filter_boolean_operator.inc

@@ -129,14 +129,4 @@ class tripal_views_handler_filter_boolean_operator extends tripal_views_handler_
     $this->options['expose']['label'] = $this->value_value;
     $this->options['expose']['required'] = TRUE;
   }
-
-  function query() {
-//     $this->ensure_my_table();
-//     $field = $this->real_field;
-
-//     $info = $this->operators();
-//     if (!empty($info[$this->operator]['method'])) {
-//       $this->{$info[$this->operator]['method']}($field);
-//     }
-  }
 }

+ 13 - 0
tripal/views_handlers/tripal_views_handler_filter_element_string.inc

@@ -0,0 +1,13 @@
+<?php
+
+class tripal_views_handler_filter_element_string extends tripal_views_handler_filter_string {
+
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+
+    // Fix identifier names that don't match what will be in the form state.
+    $this->options['expose']['identifier'] = preg_replace('/\./', '_', $this->options['expose']['identifier']);
+    $this->options['expose']['operator'] = preg_replace('/\./', '_', $this->options['expose']['operator']);
+    $this->options['expose']['operator_id'] = preg_replace('/\./', '_', $this->options['expose']['operator_id']);
+  }
+}

+ 4 - 2
tripal/views_handlers/tripal_views_handler_filter_string.inc

@@ -169,6 +169,7 @@ class tripal_views_handler_filter_string extends tripal_views_handler_filter {
    * Provide a simple textfield for equality
    */
   function value_form(&$form, &$form_state) {
+
     // We have to make some choices when creating this as an exposed
     // filter form. For example, if the operator is locked and thus
     // not rendered, we can't render dependencies; instead we only
@@ -233,12 +234,13 @@ class tripal_views_handler_filter_string extends tripal_views_handler_filter {
 
     $info = $this->operators();
     if (!empty($info[$this->operator]['method'])) {
-      $this->{$info[$this->operator]['method']}($field);
+      $op_function = $info[$this->operator]['method'];
+      $this->{$op_function}($field);
     }
   }
 
   function op_equal($field) {
-    $this->query->add_where($this->options['group'], $field, $this->value, $this->operator());
+    $this->query->add_where($this->options['group'], $field, $this->value, $this->operator);
   }
 
   function op_contains($field) {

+ 28 - 10
tripal_chado/api/tripal_chado.semweb.api.inc

@@ -189,9 +189,21 @@ function tripal_get_chado_semweb_term($chado_table, $chado_column, $options = ar
       return $cvterm;
     }
 
-    return $cvterm->dbxref_id->db_id->name . ':' . $cvterm->dbxref_id->accession;
+    return tripal_format_chado_semweb_term($cvterm);
   }
 }
+
+/**
+ * Formats a controlled vocabulary term from Chado for use with Tripal.
+ *
+ * @param $cvterm
+ *   A cvterm object.
+ * @return
+ *   The semantic web name for the term.
+ */
+function tripal_format_chado_semweb_term($cvterm) {
+  return $cvterm->dbxref_id->db_id->name . ':' . $cvterm->dbxref_id->accession;
+}
 /**
  * Retreive the column name in a Chado table that matches a given term.
  *
@@ -199,7 +211,7 @@ function tripal_get_chado_semweb_term($chado_table, $chado_column, $options = ar
  *   The name of the Chado table.
  * @param $term
  *   The term. This can be a term name or a unique identifer of the form
- *   {db}:{accession}
+ *   {db}:{accession} or of the form {db}__{term_name}.
  *
  * @return
  *   The name of the Chado column that matches the given term or FALSE if the
@@ -212,23 +224,29 @@ function tripal_get_chado_semweb_column($chado_table, $term) {
     ->execute();
   while($column = $columns->fetchObject()) {
     $cvterm_id = $column->cvterm_id;
+
     if ($cvterm_id) {
+
       $cvterm = chado_generate_var('cvterm', array('cvterm_id' => $cvterm_id));
+
+      $full_accession = strtolower($cvterm->dbxref_id->db_id->name . ':' . $cvterm->dbxref_id->accession);
+      $full_accession = preg_replace('/ /', '_', $full_accession);
+      $full_name_uscore = strtolower($cvterm->dbxref_id->db_id->name . '__' . $cvterm->name);
+      $full_name_uscore = preg_replace('/ /', '_', $full_name_uscore);
+
+      $term = preg_replace('/ /', '_', $term);
+      $term = strtolower(preg_replace('/ /', '_', $term));
+
       // Does the term match identically?
       if ($term == $cvterm->name) {
         return $column->chado_column;
       }
       // Is the term a concatenation of the vocab and the accession?
-      else if ($term == $cvterm->dbxref_id->db_id->name . ':' . $cvterm->dbxref_id->accession) {
+      else if ($term == $full_accession) {
         return $column->chado_column;
       }
-      // Does the term have spaces that are renamed to underscores?
-      else if ($term == preg_replace('/ /', '_', $cvterm->name)) {
-        return $column->chado_column;
-      }
-      // Does the term have spaces that are renamed to underscores and
-      // all lowercase.
-      else if (strtolower($term) == strtolower(preg_replace('/ /', '_', $cvterm->name))) {
+      // Is the term a concatenation of the vocab and the accession?
+      else if ($term == $full_name_uscore) {
         return $column->chado_column;
       }
     }

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

@@ -110,4 +110,24 @@ 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;
+  }
 }

+ 22 - 1
tripal_chado/includes/TripalFields/data__accession/data__accession.inc

@@ -37,6 +37,27 @@ class data__accession extends ChadoField {
     'term_fixed' => FALSE,
   );
 
+  // In order for this field to integrate with Drupal Views, a set of
+  // handlers must be specififed.  These include handlers for
+  // the field, for the filter, and the sort.  Within this variable,
+  // the key must be one of: field, filter, sort; and the value
+  // is the settings for those handlers as would be provided by
+  // a hook_views_data().  The following defaults make a field visible
+  // using the default formatter of the field, allow for filtering using
+  // a string value and sortable.  in order for filters to work you
+  // must implement the query() function.
+  public static $default_view_handlers = array(
+    'field' => array(
+      'handler' => 'tripal_views_handler_field',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'tripal_views_handler_filter_string',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+  );
   // The default widget for this field.
   public static $default_widget = 'data__accession_widget';
 
@@ -93,7 +114,7 @@ class data__accession extends ChadoField {
     $alias = 'dbx_linker';
     $operator = $condition['operator'];
 
-    if ($condition['column'] == 'accession') {
+    if ($condition['column'] == 'data__accession') {
       $query->join('dbxref', 'DBX', "DBX.dbxref_id = base.dbxref_id");
       $query->condition("DBX.accession", $condition['value'], $operator);
     }

+ 1 - 1
tripal_chado/includes/TripalFields/data__accession/data__accession_formatter.inc

@@ -13,7 +13,7 @@ class data__accession_formatter extends ChadoFieldFormatter {
    */
   public function view(&$element, $entity_type, $entity, $langcode, $items, $display) {
 
-    $content = 'N/A';
+    $content = '';
     if ($items[0]['value']) {
       $content = $items[0]['value'];
     }

+ 16 - 14
tripal_chado/includes/TripalFields/data__sequence_coordinates/data__sequence_coordinates.inc

@@ -89,20 +89,22 @@ class data__sequence_coordinates extends ChadoField {
 
     // Get the featureloc records that this feature is aligned to.
     $aligned = $feature->featureloc->feature_id;
-    foreach ($aligned as $index => $featureloc) {
-      $srcfeature = $featureloc->srcfeature_id->name;
-      $entity->{$field_name}['und'][0] = array(
-        'value' => array(
-          'data:3002' => $srcfeature,
-          'local:fmin' => $featureloc->fmin + 1,
-          'local:fmax' => $featureloc->fmax,
-          'data:2336' => $featureloc->phase,
-          'data:0853' => $featureloc->strand,
-        ),
-      );
-      $sentity_id = chado_get_record_entity_by_table('feature_id', $featureloc->srcfeature_id->feature_id);
-      if ($sentity_id) {
-        $entity->{$field_name}['und'][0]['value']['entity'] = 'TripalEntity:' . $sentity_id;
+    if ($aligned) {
+      foreach ($aligned as $index => $featureloc) {
+        $srcfeature = $featureloc->srcfeature_id->name;
+        $entity->{$field_name}['und'][0] = array(
+          'value' => array(
+            'data:3002' => $srcfeature,
+            'local:fmin' => $featureloc->fmin + 1,
+            'local:fmax' => $featureloc->fmax,
+            'data:2336' => $featureloc->phase,
+            'data:0853' => $featureloc->strand,
+          ),
+        );
+        $sentity_id = chado_get_record_entity_by_table('feature_id', $featureloc->srcfeature_id->feature_id);
+        if ($sentity_id) {
+          $entity->{$field_name}['und'][0]['value']['entity'] = 'TripalEntity:' . $sentity_id;
+        }
       }
     }
   }

+ 142 - 4
tripal_chado/includes/TripalFields/obi__organism/obi__organism.inc

@@ -30,6 +30,28 @@ class obi__organism extends ChadoField {
     'field_display_string' => '<i>[organism.genus] [organism.species]</i>',
   );
 
+  // In order for this field to integrate with Drupal Views, a set of
+  // handlers must be specififed.  These include handlers for
+  // the field, for the filter, and the sort.  Within this variable,
+  // the key must be one of: field, filter, sort; and the value
+  // is the settings for those handlers as would be provided by
+  // a hook_views_data().  The following defaults make a field visible
+  // using the default formatter of the field, allow for filtering using
+  // a string value and sortable.  in order for filters to work you
+  // must implement the query() function.
+  public static $default_view_handlers = array(
+    'field' => array(
+      'handler' => 'tripal_views_handler_field',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'tripal_views_handler_filter_string',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+  );
+
   // The default widget for this field.
   public static $default_widget = 'OBI__organism_widget';
 
@@ -187,6 +209,111 @@ class obi__organism extends ChadoField {
     return $element;
   }
 
+  /**
+   * @see ChadoField::viewsData()
+   */
+  public function viewsData($view_base_id) {
+    $data = array();
+    $options = array('return_object' => TRUE);
+
+    // 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',
+      )
+    );
+
+    // 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',
+      )
+    );
+
+    // 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;
+  }
+
   /**
    * @see ChadoField::query()
    */
@@ -194,18 +321,29 @@ 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');
+
     $query->join('organism', $alias, "base.organism_id = $alias.organism_id");
 
-    if ($condition['column'] == 'organism.species') {
+    // 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 a subfield.
+    if ($condition['column'] == $species_term) {
       $query->condition("$alias.species", $condition['value'], $operator);
     }
-    if ($condition['column'] == 'organism.genus') {
+    if ($condition['column'] == $genus_term) {
       $query->condition("$alias.genus", $condition['value'], $operator);
     }
-    if ($condition['column'] == 'organism.infraspecies') {
+    if ($condition['column'] == $infraspecific_name_term) {
       $query->condition("$alias.infraspecific_name", $condition['value'], $operator);
     }
-    if ($condition['column'] == 'organism.infraspecific_taxon') {
+    if ($condition['column'] == $infraspecific_type_term) {
       $query->join('cvterm', 'CVT', "base.type_id = CVT.cvterm_id");
       $query->condition("CVT.name", $condition['value'], $operator);
     }

+ 0 - 5
tripal_chado/includes/TripalFields/obi__organism/obi__organism_formatter.inc

@@ -14,11 +14,6 @@ class obi__organism_formatter extends ChadoFieldFormatter {
   public function view(&$element, $entity_type, $entity, $langcode, $items, $display) {
     if (count($items) > 0) {
       $content = $items[0]['value']['rdfs:label'];
-      $entity = isset($item['value']['entity']) ? $item['value']['entity'] : '';
-      if ($entity) {
-        list($entity_type, $entity_id) = explode(':', $entity);
-        $content = l(content, 'bio_data/' . $entity_id);
-      }
       if (array_key_exists('entity', $items[0]['value'])) {
         list($entity_type, $entity_id) = explode(':', $items[0]['value']['entity']);
         $content = l(strip_tags($items[0]['value']['rdfs:label']), 'bio_data/' . $entity_id);

+ 6 - 0
tripal_chado/includes/tripal_chado.entity.inc

@@ -185,6 +185,12 @@ function tripal_chado_tripal_default_title_format($bundle, $available_tokens) {
       'weight' => -5,
     );
   }
+  if ($table == 'project') {
+    $format[] = array(
+      'format' => '[schema__name]',
+      'weight' => -5,
+    );
+  }
   return $format;
 }
 

+ 8 - 3
tripal_chado/includes/tripal_chado.field_storage.inc

@@ -477,7 +477,6 @@ function tripal_chado_field_storage_query($query) {
   $schema = chado_get_schema($data_table);
   $pkey = $schema['primary key'][0];
 
-
   // Initialize the Query object.
   $cquery = chado_db_select($data_table, 'base');
   $cquery->fields('base', array($pkey));
@@ -620,11 +619,17 @@ function tripal_chado_field_storage_query($query) {
     } // end if ($sort['type'] == 'field') {
   } // end foreach ($query->order as $index => $sort) {
 
-  //print_r($cquery->__toString());
-  //print_r($cquery->getArguments());
+  //dpm($cquery->__toString());
+  //dpm($cquery->getArguments());
 
   $records = $cquery->execute();
 
+  // If the query is a count query then just return the  total count.
+  if ($query->count) {
+    return $records->rowCount();
+  }
+
+  // If this is not a count query then return the results.
   $result = array();
   while ($record = $records->fetchObject()) {
     $ids = array($record->entity_id, 0, $record->bundle);

+ 9 - 4
tripal_chado/includes/tripal_chado.fields.inc

@@ -810,7 +810,12 @@ function tripal_chado_bundle_instances_info_base(&$info, $entity_type, $bundle,
     // Set some default semantic web information
     if ($column_name == 'uniquename') {
       $base_info['label'] = 'Identifier';
-      $base_info['widget_type'] = 'text_textfield';
+      $base_info['widget']['type'] = 'text_textfield';
+      if ($details['type'] == 'text') {
+        unset($base_info['display']['default']['label']);
+        unset($base_info['settings']['text_processing']);
+        unset($base_info['settings']['format']);
+      }
     }
     elseif ($base_info['label'] == 'Timeaccessioned') {
       $base_info['label'] = 'Time Accessioned';
@@ -943,7 +948,7 @@ function tripal_chado_bundle_instances_info_custom(&$info, $entity_type, $bundle
       'entity_type' => $entity_type,
       'bundle' => $bundle->name,
       'label' => 'Organism',
-      'description' => 'Select an organism.',
+      'description' => 'The full scientific name for a species..',
       'required' => $is_required,
       'settings' => array(
         'auto_attach' => TRUE,
@@ -967,7 +972,7 @@ function tripal_chado_bundle_instances_info_custom(&$info, $entity_type, $bundle
     );
   }
 
-  // BASE ORGANISM_ID
+  // BASE CVTERM
   if ($table_name == 'cvterm') {
     $field_name = 'sio__vocabulary';
     $is_required = TRUE;
@@ -976,7 +981,7 @@ function tripal_chado_bundle_instances_info_custom(&$info, $entity_type, $bundle
       'entity_type' => $entity_type,
       'bundle' => $bundle->name,
       'label' => 'Vocabulary',
-      'description' => 'Select a vocabulary.',
+      'description' => 'A controlled vocabulary.',
       'required' => $is_required,
       'settings' => array(
         'auto_attach' => TRUE,

+ 9 - 1
tripal_chado_views/api/tripal_chado_views.api.inc

@@ -697,7 +697,15 @@ function tripal_add_views_integration($defn_array, $setup_id = FALSE) {
     );
 
     // Insert Field Definitions
-    foreach ($defn_array['fields'] as $field) {
+    foreach ($defn_array['fields'] as $key => $field) {
+      // Set some defaults.
+      $field['name'] = (isset($field['name'])) ? $field['name'] : $key;
+      $field['title'] = (isset($field['title'])) ? $field['title'] : $field['name'];
+      $field['type'] = (isset($field['type'])) ? $field['type'] : 'text';
+      $field['description'] = (isset($field['description'])) ? $field['description'] : $field['name'];
+      $field['handlers'] = (isset($field['handlers'])) ? $field['handlers'] : array('field' => array('name' => 'views_handler_field'));
+
+      // Build the field record.
       $field_record = array(
         'setup_id' => $view_record['setup_id'],
         'column_name' => $field['name'],

+ 2 - 2
tripal_chado_views/includes/tripal_chado_views_integration.inc

@@ -119,11 +119,11 @@ function tripal_chado_views_get_integration_array_for_chado_table($table_name, $
   foreach ($schema['fields'] as $field_name => $field_schema) {
 
     // Base field definition
-    if (!empty($field_name) && !empty($field_schema['type'])) {
+    if (!empty($field_name)) {
       $defn_array['fields'][$field_name] = array(
         'name' => $field_name,
         'title' => ucwords(str_replace('_', ' ', $field_name)),
-        'type' => $field_schema['type'],
+        'type' => (isset($field_schema['type'])) ? $field_schema['type'] : 'text',
         'description' => (!empty($field_schema['description'])) ? $field_schema['description'] : ucwords(str_replace('_', ' ', $field_name)),
         'handlers' => array(),
         'joins' => array()

+ 9 - 9
tripal_chado_views/tripal_chado_views.module

@@ -30,15 +30,15 @@ require_once 'includes/tripal_chado_views_integration_port.inc';
 function tripal_chado_views_menu() {
   $items = array();
 
-  $items['chado'] = array(
-    'title' => 'Search Data',
-    'description' => 'Listings of the various biological data available categorized by type.',
-    'page callback' => 'theme',
-    'page arguments' => array('tripal_chado_views_search_biological_content'),
-    'access arguments' => array('access content'),
-    'expanded' => TRUE,
-    'type' => MENU_NORMAL_ITEM,
-  );
+//   $items['chado'] = array(
+//     'title' => 'Search Data',
+//     'description' => 'Listings of the various biological data available categorized by type.',
+//     'page callback' => 'theme',
+//     'page arguments' => array('tripal_chado_views_search_biological_content'),
+//     'access arguments' => array('access content'),
+//     'expanded' => TRUE,
+//     'type' => MENU_NORMAL_ITEM,
+//   );
 
   // TODO: should the views integration be moved into the tripal_chado module?
   $items['admin/tripal/storage/chado/views-integration'] = array(

+ 2 - 2
tripal_chado_views/tripal_chado_views.views.inc

@@ -218,7 +218,7 @@ function tripal_chado_views_views_data() {
       foreach ($fields as $column => $attrs) {
         $base_fields[$column] = array(
           'column_name' => $column,
-          'type' => $attrs['type'],
+          'type' => (isset($attrs['type'])) ? $attrs['type'] : 'text',
         );
       }
 
@@ -663,4 +663,4 @@ function tripal_chado_views_views_data_alter(&$data) {
  */
 function tripal_chado_views_views_pre_view(&$view, &$display_id, &$args) {
   $_GET = array_merge($_GET, $_POST);
-}
+}

+ 11 - 2
tripal_ds/includes/tripal_ds.ds.inc

@@ -136,11 +136,15 @@ function _ds_layout_settings_info($bundle_name, $instances) {
     $right_fields = array();
     $all_field_groups = field_group_info_groups('TripalEntity', $bundle_name);
     if (is_array($all_field_groups)) {
-      if (!isset($all_field_groups['default'])) { $all_field_groups['default'] = array(); }
+      if (!isset($all_field_groups['default'])) {
+        $all_field_groups['default'] = array();
+      }
       foreach ($all_field_groups['default'] as $key => $field_name) {
         $right_fields[$key] = $field_name;
       }
       usort($right_fields, sort_object('label'));
+      watchdog('debug', '<pre>$right_fields: '. print_r($right_fields, TRUE) .'</pre>');
+
     }
 
     // Now build the $region_right array and the fields array.
@@ -175,8 +179,11 @@ function _ds_layout_settings_info($bundle_name, $instances) {
     }
     // Add blocks to $region_left and build the toc field that is placed within.
     _ds_fields_info_write($bundle_name);
-    $region_left += [ 'toc' ];
+    $region_left = [ 'toc' ];
     $fields_with_regions += [ 'toc' => 'left' ];
+    watchdog('debug', '<pre>$fields_with_regions: '. print_r($fields_with_regions, TRUE) .'</pre>');
+    watchdog('debug', '<pre>$region_right: '. print_r($region_right, TRUE) .'</pre>');
+
     // Build the ds layout.
     $record = new stdClass;
     $record->id ='TripalEntity|' . $bundle_name . '|default';
@@ -207,6 +214,8 @@ function _ds_layout_settings_info($bundle_name, $instances) {
     );
     $record->settings = $settings;
     drupal_write_record('ds_layout_settings', $record);
+    // Clear the Drpual chace
+    cache_clear_all();
   }
   catch (Exception $e) {
     watchdog_exception('tripal_ds', $e);