Browse Source

Merge branch '7.x-3.x' of github.com:tripal/tripal into 7.x-3.x

Stephen Ficklin 9 years ago
parent
commit
ee345f9020
36 changed files with 1138 additions and 3 deletions
  1. 0 0
      legacy/tripal_views/api/tripal_views.DEPRECATED.inc
  2. 0 0
      legacy/tripal_views/api/tripal_views.api.inc
  3. 0 0
      legacy/tripal_views/includes/tripal_views_integration.inc
  4. 0 0
      legacy/tripal_views/includes/tripal_views_integration_UI.inc
  5. 0 0
      legacy/tripal_views/includes/tripal_views_integration_port.inc
  6. 0 0
      legacy/tripal_views/theme/css/tripal_views_admin_views.css
  7. 0 0
      legacy/tripal_views/theme/tripal_views_help.tpl.php
  8. 0 0
      legacy/tripal_views/theme/tripal_views_search_biological_content.tpl.php
  9. 0 0
      legacy/tripal_views/tripal_views.coder_ignores.txt
  10. 1 1
      legacy/tripal_views/tripal_views.info
  11. 0 0
      legacy/tripal_views/tripal_views.install
  12. 0 0
      legacy/tripal_views/tripal_views.module
  13. 0 0
      legacy/tripal_views/tripal_views.views.inc
  14. 0 0
      legacy/tripal_views/tripal_views.views_default.inc
  15. 0 0
      legacy/tripal_views/tripal_views_integration_fields_form.tpl.php
  16. 0 0
      legacy/tripal_views/views-sql-compliant-three-tier-naming-1971160-22.patch
  17. 0 0
      legacy/tripal_views/views/handlers/tripal_views_handler_area_action_links.inc
  18. 0 0
      legacy/tripal_views/views/handlers/tripal_views_handler_field_sequence.inc
  19. 0 0
      legacy/tripal_views/views/handlers/tripal_views_handler_filter_file_upload.inc
  20. 0 0
      legacy/tripal_views/views/handlers/tripal_views_handler_filter_no_results.inc
  21. 0 0
      legacy/tripal_views/views/handlers/tripal_views_handler_filter_select_cvterm.inc
  22. 0 0
      legacy/tripal_views/views/handlers/tripal_views_handler_filter_select_id.inc
  23. 0 0
      legacy/tripal_views/views/handlers/tripal_views_handler_filter_select_string.inc
  24. 0 0
      legacy/tripal_views/views/handlers/tripal_views_handler_filter_sequence.inc
  25. 0 0
      legacy/tripal_views/views/handlers/tripal_views_handler_filter_textarea.inc
  26. 26 0
      tripal/includes/TripalEntityViewsController.inc
  27. 35 0
      tripal/includes/TripalTermViewsController.inc
  28. 34 0
      tripal/includes/TripalVocabViewsController.inc
  29. 246 0
      tripal/includes/tripal.views_default.inc
  30. 14 1
      tripal/tripal.module
  31. 198 0
      tripal_chado/includes/chado_views_handler_field.inc
  32. 435 0
      tripal_chado/includes/chado_views_handler_filter.inc
  33. 22 0
      tripal_chado/includes/chado_views_handler_sort.inc
  34. 4 0
      tripal_chado/tripal_chado.info
  35. 0 1
      tripal_chado/tripal_chado.module
  36. 123 0
      tripal_chado/tripal_chado.views.inc

+ 0 - 0
tripal_views/api/tripal_views.DEPRECATED.inc → legacy/tripal_views/api/tripal_views.DEPRECATED.inc


+ 0 - 0
tripal_views/api/tripal_views.api.inc → legacy/tripal_views/api/tripal_views.api.inc


+ 0 - 0
tripal_views/includes/tripal_views_integration.inc → legacy/tripal_views/includes/tripal_views_integration.inc


+ 0 - 0
tripal_views/includes/tripal_views_integration_UI.inc → legacy/tripal_views/includes/tripal_views_integration_UI.inc


+ 0 - 0
tripal_views/includes/tripal_views_integration_port.inc → legacy/tripal_views/includes/tripal_views_integration_port.inc


+ 0 - 0
tripal_views/theme/css/tripal_views_admin_views.css → legacy/tripal_views/theme/css/tripal_views_admin_views.css


+ 0 - 0
tripal_views/theme/tripal_views_help.tpl.php → legacy/tripal_views/theme/tripal_views_help.tpl.php


+ 0 - 0
tripal_views/theme/tripal_views_search_biological_content.tpl.php → legacy/tripal_views/theme/tripal_views_search_biological_content.tpl.php


+ 0 - 0
tripal_views/tripal_views.coder_ignores.txt → legacy/tripal_views/tripal_views.coder_ignores.txt


+ 1 - 1
tripal_views/tripal_views.info → legacy/tripal_views/tripal_views.info

@@ -2,7 +2,7 @@ name = Tripal Views
 description = Integrates all Chado tables with Drupal Views and provides basic searching for administrators and site visitors and provides a range of flexibility for creating custom pages without the need for programming.
 core = 7.x
 project = tripal
-package = Tripal
+package = Tripal v2 Legacy
 version = 7.x-2.0
 configure = admin/tripal/views-integration
 

+ 0 - 0
tripal_views/tripal_views.install → legacy/tripal_views/tripal_views.install


+ 0 - 0
tripal_views/tripal_views.module → legacy/tripal_views/tripal_views.module


+ 0 - 0
tripal_views/tripal_views.views.inc → legacy/tripal_views/tripal_views.views.inc


+ 0 - 0
tripal_views/tripal_views.views_default.inc → legacy/tripal_views/tripal_views.views_default.inc


+ 0 - 0
tripal_views/tripal_views_integration_fields_form.tpl.php → legacy/tripal_views/tripal_views_integration_fields_form.tpl.php


+ 0 - 0
tripal_views/views-sql-compliant-three-tier-naming-1971160-22.patch → legacy/tripal_views/views-sql-compliant-three-tier-naming-1971160-22.patch


+ 0 - 0
tripal_views/views/handlers/tripal_views_handler_area_action_links.inc → legacy/tripal_views/views/handlers/tripal_views_handler_area_action_links.inc


+ 0 - 0
tripal_views/views/handlers/tripal_views_handler_field_sequence.inc → legacy/tripal_views/views/handlers/tripal_views_handler_field_sequence.inc


+ 0 - 0
tripal_views/views/handlers/tripal_views_handler_filter_file_upload.inc → legacy/tripal_views/views/handlers/tripal_views_handler_filter_file_upload.inc


+ 0 - 0
tripal_views/views/handlers/tripal_views_handler_filter_no_results.inc → legacy/tripal_views/views/handlers/tripal_views_handler_filter_no_results.inc


+ 0 - 0
tripal_views/views/handlers/tripal_views_handler_filter_select_cvterm.inc → legacy/tripal_views/views/handlers/tripal_views_handler_filter_select_cvterm.inc


+ 0 - 0
tripal_views/views/handlers/tripal_views_handler_filter_select_id.inc → legacy/tripal_views/views/handlers/tripal_views_handler_filter_select_id.inc


+ 0 - 0
tripal_views/views/handlers/tripal_views_handler_filter_select_string.inc → legacy/tripal_views/views/handlers/tripal_views_handler_filter_select_string.inc


+ 0 - 0
tripal_views/views/handlers/tripal_views_handler_filter_sequence.inc → legacy/tripal_views/views/handlers/tripal_views_handler_filter_sequence.inc


+ 0 - 0
tripal_views/views/handlers/tripal_views_handler_filter_textarea.inc → legacy/tripal_views/views/handlers/tripal_views_handler_filter_textarea.inc


+ 26 - 0
tripal/includes/TripalEntityViewsController.inc

@@ -0,0 +1,26 @@
+<?php
+/**
+ *
+ */
+class TripalEntityViewsController extends EntityDefaultViewsController {
+
+  /**
+   * Edit or add extra fields to views_data().
+   */
+  public function views_data() {
+    $data = parent::views_data();
+
+    // Change handlers for Date Timestamps.
+    // Date Created.
+    $data['tripal_entity']['created']['field']['handler'] = 'views_handler_field_date';
+    $data['tripal_entity']['created']['sort']['handler'] = 'views_handler_sort_date';
+    $data['tripal_entity']['created']['filter']['handler'] = 'views_handler_filter_date';
+    // Date Changed/Updated.
+    $data['tripal_entity']['changed']['field']['handler'] = 'views_handler_field_date';
+    $data['tripal_entity']['changed']['sort']['handler'] = 'views_handler_sort_date';
+    $data['tripal_entity']['changed']['filter']['handler'] = 'views_handler_filter_date';
+
+    return $data;
+  }
+
+}

+ 35 - 0
tripal/includes/TripalTermViewsController.inc

@@ -0,0 +1,35 @@
+<?php
+/**
+ *
+ */
+class TripalTermViewsController extends EntityDefaultViewsController {
+
+  /**
+   * Edit or add extra fields to views_data().
+   */
+  public function views_data() {
+    $data = parent::views_data();
+
+    // Change handlers for Date Timestamps.
+    // Date Created.
+    $data['tripal_term']['created']['field']['handler'] = 'views_handler_field_date';
+    $data['tripal_term']['created']['sort']['handler'] = 'views_handler_sort_date';
+    $data['tripal_term']['created']['filter']['handler'] = 'views_handler_filter_date';
+    // Date Changed/Updated.
+    $data['tripal_term']['changed']['field']['handler'] = 'views_handler_field_date';
+    $data['tripal_term']['changed']['sort']['handler'] = 'views_handler_sort_date';
+    $data['tripal_term']['changed']['filter']['handler'] = 'views_handler_filter_date';
+
+    $data['tripal_term']['table']['join'] = array();
+
+    // Join the term to it's entity type.
+    $data['tripal_term']['table']['join']['tripal_entity'] = array(
+      'handler' => 'views_join',
+      'left_field' => 'term_id',
+      'field' => 'id',
+    );
+
+    return $data;
+  }
+
+}

+ 34 - 0
tripal/includes/TripalVocabViewsController.inc

@@ -0,0 +1,34 @@
+<?php
+/**
+ *
+ */
+class TripalVocabViewsController extends EntityDefaultViewsController {
+
+  /**
+   * Edit or add extra fields to views_data().
+   */
+  public function views_data() {
+    $data = parent::views_data();
+
+    // Change handlers for Date Timestamps.
+    // Date Created.
+    $data['tripal_vocab']['created']['field']['handler'] = 'views_handler_field_date';
+    $data['tripal_vocab']['created']['sort']['handler'] = 'views_handler_sort_date';
+    $data['tripal_vocab']['created']['filter']['handler'] = 'views_handler_filter_date';
+    // Date Changed/Updated.
+    $data['tripal_vocab']['changed']['field']['handler'] = 'views_handler_field_date';
+    $data['tripal_vocab']['changed']['sort']['handler'] = 'views_handler_sort_date';
+    $data['tripal_vocab']['changed']['filter']['handler'] = 'views_handler_filter_date';
+
+    // Join the term to it's vocabulary so we know it's namespace.
+    $data['tripal_vocab']['table']['join'] = array();
+    $data['tripal_vocab']['table']['join']['tripal_term'] = array(
+      'handler' => 'views_join',
+      'left_field' => 'vocab_id',
+      'field' => 'id',
+    );
+
+    return $data;
+  }
+
+}

+ 246 - 0
tripal/includes/tripal.views_default.inc

@@ -0,0 +1,246 @@
+<?php
+
+/**
+ * Implements hook_views_default_views().
+ * Define default views related primarily to tripal entities.
+ */
+function tripal_views_default_views() {
+  $views = array();
+
+// Vocabulary Search.
+$view = new view();
+$view->name = 'tripal_vocabularies';
+$view->description = '';
+$view->tag = 'default';
+$view->base_table = 'tripal_vocab';
+$view->human_name = 'Search Vocabularies';
+$view->core = 7;
+$view->api_version = '3.0';
+$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
+
+/* Display: Master */
+$handler = $view->new_display('default', 'Master', 'default');
+$handler->display->display_options['title'] = 'Search Vocabularies';
+$handler->display->display_options['use_more_always'] = FALSE;
+$handler->display->display_options['access']['type'] = 'none';
+$handler->display->display_options['cache']['type'] = 'none';
+$handler->display->display_options['query']['type'] = 'views_query';
+$handler->display->display_options['exposed_form']['type'] = 'input_required';
+$handler->display->display_options['exposed_form']['options']['submit_button'] = 'Search';
+$handler->display->display_options['exposed_form']['options']['text_input_required'] = 'Use the namespace to search for specific vocabularies or leave it blank to see all vocabularies currently in use on your site.';
+$handler->display->display_options['exposed_form']['options']['text_input_required_format'] = 'filtered_html';
+$handler->display->display_options['pager']['type'] = 'full';
+$handler->display->display_options['pager']['options']['items_per_page'] = '50';
+$handler->display->display_options['pager']['options']['offset'] = '0';
+$handler->display->display_options['pager']['options']['id'] = '0';
+$handler->display->display_options['pager']['options']['quantity'] = '9';
+$handler->display->display_options['style_plugin'] = 'table';
+/* Field: Controlled Vocabulary: Namespace */
+$handler->display->display_options['fields']['namespace']['id'] = 'namespace';
+$handler->display->display_options['fields']['namespace']['table'] = 'tripal_vocab';
+$handler->display->display_options['fields']['namespace']['field'] = 'namespace';
+/* Field: Controlled Vocabulary: Created */
+$handler->display->display_options['fields']['created']['id'] = 'created';
+$handler->display->display_options['fields']['created']['table'] = 'tripal_vocab';
+$handler->display->display_options['fields']['created']['field'] = 'created';
+/* Field: Controlled Vocabulary: Changed */
+$handler->display->display_options['fields']['changed']['id'] = 'changed';
+$handler->display->display_options['fields']['changed']['table'] = 'tripal_vocab';
+$handler->display->display_options['fields']['changed']['field'] = 'changed';
+/* Filter criterion: Controlled Vocabulary: Namespace */
+$handler->display->display_options['filters']['namespace']['id'] = 'namespace';
+$handler->display->display_options['filters']['namespace']['table'] = 'tripal_vocab';
+$handler->display->display_options['filters']['namespace']['field'] = 'namespace';
+$handler->display->display_options['filters']['namespace']['operator'] = 'contains';
+$handler->display->display_options['filters']['namespace']['exposed'] = TRUE;
+$handler->display->display_options['filters']['namespace']['expose']['operator_id'] = 'namespace_op';
+$handler->display->display_options['filters']['namespace']['expose']['label'] = 'Namespace';
+$handler->display->display_options['filters']['namespace']['expose']['description'] = 'The vocabulary namespace (partial names accepted).';
+$handler->display->display_options['filters']['namespace']['expose']['operator'] = 'namespace_op';
+$handler->display->display_options['filters']['namespace']['expose']['identifier'] = 'namespace';
+$handler->display->display_options['filters']['namespace']['expose']['remember_roles'] = array(
+  2 => '2',
+  1 => 0,
+  3 => 0,
+);
+
+/* Display: Page */
+$handler = $view->new_display('page', 'Page', 'page');
+$handler->display->display_options['path'] = 'admin/tripal/terms/vocabulary-search';
+$handler->display->display_options['menu']['type'] = 'normal';
+$handler->display->display_options['menu']['title'] = 'Search Vocabularies';
+$handler->display->display_options['menu']['description'] = 'Search the vocabularies currently in use.';
+$handler->display->display_options['menu']['weight'] = '0';
+$handler->display->display_options['menu']['name'] = 'management';
+$handler->display->display_options['menu']['context'] = 0;
+$handler->display->display_options['menu']['context_only_inline'] = 0;
+
+$views[$view->name] = $view;
+
+// Term Search.
+$view = new view();
+$view->name = 'tripal_terms';
+$view->description = '';
+$view->tag = 'default';
+$view->base_table = 'tripal_term';
+$view->human_name = 'Search Terms';
+$view->core = 7;
+$view->api_version = '3.0';
+$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
+
+/* Display: Master */
+$handler = $view->new_display('default', 'Master', 'default');
+$handler->display->display_options['title'] = 'Search Terms';
+$handler->display->display_options['use_more_always'] = FALSE;
+$handler->display->display_options['access']['type'] = 'none';
+$handler->display->display_options['cache']['type'] = 'none';
+$handler->display->display_options['query']['type'] = 'views_query';
+$handler->display->display_options['exposed_form']['type'] = 'input_required';
+$handler->display->display_options['exposed_form']['options']['submit_button'] = 'Search';
+$handler->display->display_options['exposed_form']['options']['text_input_required'] = 'Use the filters to search for the term you are interested in or leave them blank to see all terms defining Tripal Content Types.';
+$handler->display->display_options['exposed_form']['options']['text_input_required_format'] = 'filtered_html';
+$handler->display->display_options['pager']['type'] = 'full';
+$handler->display->display_options['pager']['options']['items_per_page'] = '50';
+$handler->display->display_options['style_plugin'] = 'table';
+$handler->display->display_options['style_options']['columns'] = array(
+  'namespace' => 'namespace',
+  'name' => 'name',
+  'accession' => 'accession',
+  'created' => 'created',
+  'changed' => 'changed',
+);
+$handler->display->display_options['style_options']['default'] = '-1';
+$handler->display->display_options['style_options']['info'] = array(
+  'namespace' => array(
+    'sortable' => 1,
+    'default_sort_order' => 'asc',
+    'align' => '',
+    'separator' => '',
+    'empty_column' => 0,
+  ),
+  'name' => array(
+    'sortable' => 1,
+    'default_sort_order' => 'asc',
+    'align' => '',
+    'separator' => '',
+    'empty_column' => 0,
+  ),
+  'accession' => array(
+    'sortable' => 1,
+    'default_sort_order' => 'asc',
+    'align' => '',
+    'separator' => '',
+    'empty_column' => 0,
+  ),
+  'created' => array(
+    'sortable' => 1,
+    'default_sort_order' => 'asc',
+    'align' => '',
+    'separator' => '',
+    'empty_column' => 0,
+  ),
+  'changed' => array(
+    'sortable' => 1,
+    'default_sort_order' => 'asc',
+    'align' => '',
+    'separator' => '',
+    'empty_column' => 0,
+  ),
+);
+/* Field: Controlled Vocabulary: Namespace */
+$handler->display->display_options['fields']['namespace']['id'] = 'namespace';
+$handler->display->display_options['fields']['namespace']['table'] = 'tripal_vocab';
+$handler->display->display_options['fields']['namespace']['field'] = 'namespace';
+/* Field: Controlled Vocabulary Term: Name */
+$handler->display->display_options['fields']['name']['id'] = 'name';
+$handler->display->display_options['fields']['name']['table'] = 'tripal_term';
+$handler->display->display_options['fields']['name']['field'] = 'name';
+/* Field: Controlled Vocabulary Term: Accession */
+$handler->display->display_options['fields']['accession']['id'] = 'accession';
+$handler->display->display_options['fields']['accession']['table'] = 'tripal_term';
+$handler->display->display_options['fields']['accession']['field'] = 'accession';
+/* Field: Controlled Vocabulary Term: Created */
+$handler->display->display_options['fields']['created']['id'] = 'created';
+$handler->display->display_options['fields']['created']['table'] = 'tripal_term';
+$handler->display->display_options['fields']['created']['field'] = 'created';
+$handler->display->display_options['fields']['created']['date_format'] = 'short';
+$handler->display->display_options['fields']['created']['second_date_format'] = 'long';
+/* Field: Controlled Vocabulary Term: Changed */
+$handler->display->display_options['fields']['changed']['id'] = 'changed';
+$handler->display->display_options['fields']['changed']['table'] = 'tripal_term';
+$handler->display->display_options['fields']['changed']['field'] = 'changed';
+$handler->display->display_options['fields']['changed']['date_format'] = 'short';
+$handler->display->display_options['fields']['changed']['second_date_format'] = 'long';
+/* Sort criterion: Controlled Vocabulary: Namespace */
+$handler->display->display_options['sorts']['namespace']['id'] = 'namespace';
+$handler->display->display_options['sorts']['namespace']['table'] = 'tripal_vocab';
+$handler->display->display_options['sorts']['namespace']['field'] = 'namespace';
+/* Sort criterion: Controlled Vocabulary Term: Name */
+$handler->display->display_options['sorts']['name']['id'] = 'name';
+$handler->display->display_options['sorts']['name']['table'] = 'tripal_term';
+$handler->display->display_options['sorts']['name']['field'] = 'name';
+/* Filter criterion: Controlled Vocabulary: Namespace */
+$handler->display->display_options['filters']['namespace']['id'] = 'namespace';
+$handler->display->display_options['filters']['namespace']['table'] = 'tripal_vocab';
+$handler->display->display_options['filters']['namespace']['field'] = 'namespace';
+$handler->display->display_options['filters']['namespace']['operator'] = 'contains';
+$handler->display->display_options['filters']['namespace']['exposed'] = TRUE;
+$handler->display->display_options['filters']['namespace']['expose']['operator_id'] = 'namespace_op';
+$handler->display->display_options['filters']['namespace']['expose']['label'] = 'Vocabulary Namespace';
+$handler->display->display_options['filters']['namespace']['expose']['description'] = 'The vocabulary namespace (partial names accepted).';
+$handler->display->display_options['filters']['namespace']['expose']['operator'] = 'namespace_op';
+$handler->display->display_options['filters']['namespace']['expose']['identifier'] = 'namespace';
+$handler->display->display_options['filters']['namespace']['expose']['remember_roles'] = array(
+  2 => '2',
+  1 => 0,
+  3 => 0,
+);
+/* Filter criterion: Controlled Vocabulary Term: Accession */
+$handler->display->display_options['filters']['accession']['id'] = 'accession';
+$handler->display->display_options['filters']['accession']['table'] = 'tripal_term';
+$handler->display->display_options['filters']['accession']['field'] = 'accession';
+$handler->display->display_options['filters']['accession']['operator'] = 'contains';
+$handler->display->display_options['filters']['accession']['exposed'] = TRUE;
+$handler->display->display_options['filters']['accession']['expose']['operator_id'] = 'accession_op';
+$handler->display->display_options['filters']['accession']['expose']['label'] = 'Accession';
+$handler->display->display_options['filters']['accession']['expose']['description'] = 'The accession of the term (partial accessions accepted).';
+$handler->display->display_options['filters']['accession']['expose']['operator'] = 'accession_op';
+$handler->display->display_options['filters']['accession']['expose']['identifier'] = 'accession';
+$handler->display->display_options['filters']['accession']['expose']['remember_roles'] = array(
+  2 => '2',
+  1 => 0,
+  3 => 0,
+);
+/* Filter criterion: Controlled Vocabulary Term: Name */
+$handler->display->display_options['filters']['name']['id'] = 'name';
+$handler->display->display_options['filters']['name']['table'] = 'tripal_term';
+$handler->display->display_options['filters']['name']['field'] = 'name';
+$handler->display->display_options['filters']['name']['operator'] = 'contains';
+$handler->display->display_options['filters']['name']['exposed'] = TRUE;
+$handler->display->display_options['filters']['name']['expose']['operator_id'] = 'name_op';
+$handler->display->display_options['filters']['name']['expose']['label'] = 'Name';
+$handler->display->display_options['filters']['name']['expose']['description'] = 'The name of the term (partial names accepted).';
+$handler->display->display_options['filters']['name']['expose']['operator'] = 'name_op';
+$handler->display->display_options['filters']['name']['expose']['identifier'] = 'name';
+$handler->display->display_options['filters']['name']['expose']['remember_roles'] = array(
+  2 => '2',
+  1 => 0,
+  3 => 0,
+);
+
+/* Display: Page */
+$handler = $view->new_display('page', 'Page', 'page');
+$handler->display->display_options['path'] = 'admin/tripal/terms/term-search';
+$handler->display->display_options['menu']['type'] = 'normal';
+$handler->display->display_options['menu']['title'] = 'Search Terms';
+$handler->display->display_options['menu']['description'] = 'Search the terms currently defining Tripal Content Types.';
+$handler->display->display_options['menu']['weight'] = '0';
+$handler->display->display_options['menu']['name'] = 'management';
+$handler->display->display_options['menu']['context'] = 0;
+$handler->display->display_options['menu']['context_only_inline'] = 0;
+
+$views[$view->name] = $view;
+
+  return $views;
+}
+

+ 14 - 1
tripal/tripal.module

@@ -13,11 +13,14 @@ require_once "api/tripal.variables.api.inc";
 
 require_once "includes/TripalVocab.inc";
 require_once "includes/TripalVocabController.inc";
+require_once "includes/TripalVocabViewsController.inc";
 require_once "includes/TripalTerm.inc";
 require_once "includes/TripalTermController.inc";
+require_once "includes/TripalTermViewsController.inc";
 require_once "includes/TripalEntity.inc";
 require_once "includes/TripalEntityController.inc";
 require_once "includes/TripalEntityUIController.inc";
+require_once "includes/TripalEntityViewsController.inc";
 require_once "includes/TripalBundle.inc";
 require_once "includes/TripalBundleController.inc";
 require_once "includes/TripalBundleUIController.inc";
@@ -44,6 +47,7 @@ require_once "includes/TripalBundleUIController.inc";
 function tripal_views_api() {
   return array(
     'api' => 3.0,
+    'path' => drupal_get_path('module', 'tripal') . '/includes',
   );
 }
 
@@ -450,6 +454,9 @@ function tripal_entity_info() {
     'entity class' => 'TripalVocab',
     'controller class' => 'TripalVocabController',
 
+    // Adds Views integration for this entity.
+    'views controller class' => 'TripalVocabViewsController',
+
     // The table for this entity defined in hook_schema()
     'base table' => 'tripal_vocab',
 
@@ -499,6 +506,9 @@ function tripal_entity_info() {
     'entity class' => 'TripalTerm',
     'controller class' => 'TripalTermController',
 
+    // Adds Views integration for this entity.
+    'views controller class' => 'TripalTermViewsController',
+
     // The table for this entity defined in hook_schema()
     'base table' => 'tripal_term',
 
@@ -547,6 +557,9 @@ function tripal_entity_info() {
     'entity class' => 'TripalEntity',
     'controller class' => 'TripalEntityController',
 
+    // Adds Views integration for this entity.
+    'views controller class' => 'TripalEntityViewsController',
+
     // The table for this entity defined in hook_schema()
     'base table' => 'tripal_entity',
 
@@ -715,4 +728,4 @@ function TripalBundle_load($bundle_type, $reset = FALSE) {
 function TripalEntity_load($id, $reset = FALSE) {
   $entity = entity_load('TripalEntity', array($id), array(), $reset);
   return reset($entity);
-}
+}

+ 198 - 0
tripal_chado/includes/chado_views_handler_field.inc

@@ -0,0 +1,198 @@
+<?php
+
+// We need to include the views_handler_field_field file since it 
+// includes _field_view_formatter_options() which we need.
+require_once drupal_get_path('module','views') . '/modules/field/views_handler_field_field.inc';
+
+/**
+ * Views Field Handler for chado fields.
+ * Uses the same approach as the field api views_handler_field_field.
+ */
+class chado_views_handler_field extends views_handler_field {
+
+  /**
+   * Alter the views query to provide information for this field.
+   *
+   * We are going to take the same approach as the field api and simply load
+   * the entities in order to get the values of the chado fields. The hope is
+   * that a small number of cached simple queries will be more efficient than
+   * the crazy joins that occur when using chado. *fingers crossed*
+   */
+  function query ($use_groupby = FALSE) {
+
+    $this->base_table = $this->definition['entity_table'];
+    $this->base_table_alias = $this->base_table;
+    $this->ensure_my_table();
+
+    // Because we are just loading entities, we need the entity id and type only.
+    $this->entity = $entity_info = entity_get_info($this->definition['entity_type']);
+    $alias_stub = 'chado_field_' . $this->definition['chado_table'] . '_' . $this->definition['chado_field'];
+
+    $this->id_alias = $this->field_alias = $this->query->add_field($this->base_table_alias, $entity_info['entity keys']['id'], $alias_stub . '_entity_id');
+    $this->type_alias = $this->query->add_field(NULL, "'" . $this->definition['entity_type'] . "'", $alias_stub . '_entity_type');
+
+  }
+
+  /**
+   * Load the entities for all fields that are about to be displayed.
+   * 
+   * Notice that, although we load the entities for each chado field, 
+   * Drupal caches entities to ensure we don't get a performance hit per field,
+   * just per row.
+   */
+  function post_execute(&$values) {
+    if (!empty($values) AND isset($this->id_alias) AND isset($this->type_alias)) {
+
+      // Foreach row in the view we want to grab the appropriate entity_id/type.
+      $entity_ids = array();
+      $keys = array();
+      foreach ($values as $key => $object) {
+        // Only load the entity if we can access the entity_id.
+        if (isset($this->id_alias) AND isset($object->{$this->id_alias})) {
+          $entity_ids[$object->{$this->type_alias}][] = $object->{$this->id_alias};
+          $keys[$key] = $object->{$this->id_alias};
+        }
+      }
+
+      // Now load the entities.
+      foreach($entity_ids as $type => $ids) {
+        $entities[$type] = entity_load($type, $ids);
+      } 
+  
+      // Finally add the loaded entities and values back into the resultset for easy access.
+      foreach ($keys as $row_id => $entity_id) {
+
+        // First set the entities.
+        foreach($entities as $type => $objects) {
+          $values[$row_id]->_chado_field_data[$type] = array(
+            'entity_type' => $type,
+            'entity' => $objects[$entity_id],
+          );
+        }
+
+        // Then set the value of this field.
+        $values[$row_id]->{$this->field_alias} = $this->render_field($objects[$entity_id], $this->definition['field_name'], $row_id);
+      }
+    }
+  }
+
+  /**
+   * Render the field for display in the view.
+   *
+   * @param TripalEntity $entity
+   *   The entity containing the field to be rendered.
+   * @param string $field_name
+   *   The name of the field to render.
+   * @param integer $row_id
+   *   The id of the row this field will be displayed in.
+   *
+   * @return string
+   *   The rendered field.
+   */
+  function render_field($entity, $field_name, $row_id) {
+
+    $display = array(
+      'type' => $this->options['type'],
+      'settings' => (isset($this->options['settings'])) ? $this->options['settings'] : array(),
+      'label' => 'hidden',
+      // Pass the View object in the display so that fields can act on it.
+      'views_view' => $this->view,
+      'views_field' => $this,
+      'views_row_id' => $row_id,
+    );
+
+    $langcode = LANGUAGE_NONE;
+    $items = field_get_items($entity->type, $entity, $field_name);
+    if (count($items) == 1) {
+      $render_array = field_view_value($entity->type, $entity, $field_name, $items[0], $display, $langcode);
+    }
+    // @todo: handle fields with multiple values.
+    else {
+      $render_array = field_view_value($entity->type, $entity, $field_name, $items[0], $display, $langcode);
+      drupal_set_message('Tripal Chado currently only supports views integration for single value fields. The first value has been shown.', 'warning');
+    }
+
+    return $render_array;
+  }
+  
+  /**
+   * @{inheritdoc}
+   */
+  function render($values) {
+  
+    $value = $this->get_value($values);
+    
+    if (is_array($value)) {
+      return drupal_render($value);
+    }
+    else {
+      return $this->sanitize_value($value);
+    }
+  }
+
+  /**
+   * Provide options for views ui admin specific to fields.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $field = field_info_field($this->definition['field_name']);
+    $formatters = _field_view_formatter_options($field['type']);
+    
+    $form['type'] = array(
+      '#type' => 'select',
+      '#title' => t('Formatter'),
+      '#options' => $formatters,
+      '#default_value' => $this->options['type'],
+      '#ajax' => array(
+        'path' => views_ui_build_form_url($form_state),
+      ),
+      '#submit' => array('views_ui_config_item_form_submit_temporary'),
+      '#executes_submit_callback' => TRUE,
+    );
+
+    // Get the currently selected formatter.
+    $format = $this->options['type'];
+
+    $formatter = field_info_formatter_types($format);
+    if (!isset($this->options['settings'])) $this->options['settings'] = array();
+    $settings = $this->options['settings'] + field_info_formatter_settings($format);
+
+    // Provide an instance array for hook_field_formatter_settings_form().
+    ctools_include('fields');
+    $this->instance = ctools_fields_fake_field_instance($this->definition['field_name'], '_custom', $formatter, $settings);
+
+    // Store the settings in a '_custom' view mode.
+    $this->instance['display']['_custom'] = array(
+      'type' => $format,
+      'settings' => $settings,
+    );
+
+    // Get the settings form.
+    $settings_form = array('#value' => array());
+    $function = $formatter['module'] . '_field_formatter_settings_form';
+    if (function_exists($function)) {
+      $settings_form = $function($field, $this->instance, '_custom', $form, $form_state);
+    }
+    $form['settings'] = $settings_form;
+  }
+
+  /**
+   * Define the options we are going to provide.
+   */
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $field = field_info_field($this->definition['field_name']);
+    $field_type = field_info_field_types($field['type']);
+
+    $options['type'] = array(
+      'default' => $field_type['default_formatter'],
+    );
+    $options['settings'] = array(
+      'default' => array(),
+    );
+
+    return $options;
+  }
+}

+ 435 - 0
tripal_chado/includes/chado_views_handler_filter.inc

@@ -0,0 +1,435 @@
+<?php
+/**
+ * @file
+ * Contains views filter handlers that provide chado support.
+ */
+
+/**
+ * Adds support for chado boolean filters.
+ */
+class chado_views_handler_filter_boolean extends views_handler_filter_boolean_operator {
+
+  /**
+   * {@inheritdoc}
+   */
+  function value_form(&$form, &$form_state) {
+    parent::value_form($form, $form_state);
+
+    // change the keys of the options so that this filter can be optional.
+    $form['value']['#options']['f'] = $form['value']['#options'][0];
+    $form['value']['#options']['t'] = $form['value']['#options'][1];
+    unset($form['value']['#options'][0], $form['value']['#options'][1]);
+ 
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function query() {
+
+    // Adds joins to chado_entity and the chado table this field is from.
+    $alias = _chado_views_add_table_joins($this);
+
+    // Booleans in chado are stored t/f.
+    $field = $alias .'.'. $this->definition['chado_field'];
+    if ($this->value) {
+      $this->query->add_where($this->options['group'], $field, $this->value, '=');
+    }
+  }
+}
+
+/**
+ * Adds support for chado datetime filters.
+ */
+class chado_views_handler_filter_date extends views_handler_filter_date {
+
+  /**
+   * {@inheritdoc}
+   */
+  function query() {
+
+    // Adds joins to chado_entity and the chado table this field is from.
+    $alias = _chado_views_add_table_joins($this);
+   
+    // Then allow the parent handler to add the where.
+    $field = $alias .'.'. $this->definition['chado_field'];
+    $info = $this->operators();
+    if (!empty($info[$this->operator]['method'])) {
+      $this->{$info[$this->operator]['method']}($field);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function op_between($field) {
+    // Use the substitutions to ensure a consistent timestamp.
+    $query_substitutions = views_views_query_substitutions($this->view);
+    $a = intval(strtotime($this->value['min'], $query_substitutions['***CURRENT_TIME***']));
+    $b = intval(strtotime($this->value['max'], $query_substitutions['***CURRENT_TIME***']));
+
+    // This is safe because we are manually scrubbing the values.
+    // It is necessary to do it this way because $a and $b are formulas when using an offset.
+    $operator = strtoupper($this->operator);
+    $this->query->add_where_expression($this->options['group'], "$field $operator to_timestamp($a) AND to_timestamp($b)");
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function op_simple($field) {
+    // Use the substitutions to ensure a consistent timestamp.
+    $query_substitutions = views_views_query_substitutions($this->view);
+    $value = intval(strtotime($this->value['value'], $query_substitutions['***CURRENT_TIME***']));
+
+    // This is safe because we are manually scrubbing the value.
+    // It is necessary to do it this way because $value is a formula when using an offset.
+    $this->query->add_where_expression($this->options['group'], "$field $this->operator to_timestamp($value)");
+  }
+
+}
+
+/**
+ * Adds support for chado foreign key filters.
+ */
+class chado_views_handler_filter_fk extends views_handler_filter {
+  
+  /**
+   * {@inheritdoc}
+   */
+  function query() {
+
+    // Adds joins to chado_entity and the chado table this field is from.
+    $alias = _chado_views_add_table_joins($this);
+
+    // We need to do a quick fix for multiple values selected.
+    if (is_array($this->value[0]) AND sizeof($this->value) == 1) {
+      $this->value = $this->value[0];
+    }
+    
+    // Now add the restriction to the chado table as specified by user input.
+    if (sizeof($this->value) == 1) {
+      $value = current($this->value);
+      $field = $alias .'.'. $this->definition['chado_field'];
+      $this->query->add_where($this->options['group'], $field, $value, '=');
+    }
+    elseif (sizeof($this->value) > 1) {
+      $field = $alias .'.'. $this->definition['chado_field'];
+      $this->query->add_where($this->options['group'], $field, $this->value, 'IN');
+    }
+
+
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function value_form(&$form, &$form_state) {
+    parent::value_form($form, $form_state);
+
+    $this->options['values_form_type'] = (isset($this->options['values_form_type'])) ? $this->options['values_form_type'] : 'textfield';
+
+    if (preg_match('/select/', $this->options['values_form_type'])) {
+
+      //Select List
+      $form['value'] = array(
+        '#type' => 'select',
+        '#title' => t('%label', array('%label' => $this->options['expose']['label'])),
+        '#options' => $this->get_select_options(),
+        '#default_value' => $this->value,
+      );
+
+      if ($this->options['select_multiple']) {
+        $form['value']['#multiple'] = TRUE;
+      }
+    }
+    else {
+
+      $form['value'] = array(
+        '#type' => 'textfield',
+        '#title' => t('%label', array('%label' => $this->options['expose']['label'])),
+        '#default_value' => $this->value,
+      );
+
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function exposed_form(&$form, &$form_state) {
+    parent::exposed_form($form, $form_state);
+
+    if (isset($this->options['select_multiple'])) {
+      if ($this->options['select_multiple']) {
+
+        if (isset($this->options['expose']['identifier'])) {
+          $id = $this->options['expose']['identifier'];
+        }
+        else {
+          $id = $this->options['id'];
+        }
+        $form[$id]['#multiple'] = TRUE;
+      }
+    }
+  }
+  
+  function get_select_options() {
+
+    if (isset($this->options['display_column'])) {
+      $name_field = $this->options['display_column'];
+    } 
+    else {
+      $name_field = 'name';
+    }
+    
+    // If the admin has selected to show all the values then just select all
+    // records from the table referenced by the foreign key.
+    if ($this->options['show_all']) {
+      $sql = 'SELECT !id_field as id, !name_field as name
+                FROM {!foreign_table}';
+      $sql = format_string($sql, array(
+        '!foreign_table' => $this->definition['foreign_key']['right_table'],
+        '!id_field' => $this->definition['chado_field'],
+        '!name_field' => $name_field
+      ));
+    }
+    // Otherwise, only return the values from the foreign table that were referenced
+    // in the foreign key column.
+    else {
+      // Using a "Loose Index Scan" to get a list of all the unique values for
+      // the name in the table referenced by the foreign key constraint.
+      // See https://wiki.postgresql.org/wiki/Loose_indexscan
+      $sql = "WITH RECURSIVE t AS (
+            SELECT MIN(filter_table.!id_field) AS col
+              FROM {!filter_table} filter_table
+              LEFT JOIN {!foreign_table} foreign_table ON filter_table.!id_field=foreign_table.!id_field
+            UNION ALL
+            SELECT (
+                SELECT MIN(filter_table.!id_field)
+                FROM {!filter_table} filter_table
+                LEFT JOIN {!foreign_table} foreign_table ON filter_table.!id_field=foreign_table.!id_field
+                WHERE filter_table.!id_field > col
+              )
+              FROM t WHERE col IS NOT NULL
+          )
+          SELECT !id_field as id, !name_field as name
+            FROM {!foreign_table}
+            WHERE !id_field IN (SELECT col FROM t where col IS NOT NULL)
+            ORDER BY !name_field ASC";
+      $sql = format_string($sql, array(
+        '!filter_table' => $this->definition['chado_table'],
+        '!foreign_table' => $this->definition['foreign_key']['right_table'],
+        '!id_field' => $this->definition['chado_field'],
+        '!name_field' => $name_field
+      ));
+    }
+    
+    $resource = chado_query($sql);
+    $options = array();
+
+    if ($this->options['select_optional']) {
+      $options['All'] = '- Any -';
+    }
+
+    foreach ($resource as $r) {
+      $options[$r->id] = $r->name;
+    }
+
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function has_extra_options() {
+    return TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function extra_options_form(&$form, &$form_state) {
+    parent::extra_options_form($form, $form_state);
+
+    $form['values_form_type'] = array(
+      '#type' => 'radios',
+      '#title' => t('Filter Type'),
+      '#options' => array(
+        'textfield' => 'Text Field',
+        'select' => 'Drop-Down Box',
+      ),
+      '#default_value' => $this->options['values_form_type'],
+    );
+    
+    $form['show_all'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Show All'),
+      '#description' => t('When selected all records from the parent table will be shown in the drop-down rather than just those used in the current table.'),
+      '#default_value' => $this->options['show_all'],
+    );
+ 
+    $form['select_multiple'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Select Multiple'),
+      '#description' => t('Allows more then one option to be selected.'),
+      '#default_value' => $this->options['select_multiple'],
+    );
+
+    $form['select_optional'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Optional'),
+      '#description' => t('Adds --Any-- to the available options.'),
+      '#default_value' => $this->options['select_optional'],
+    );
+
+    // Allow the user to select which column to display to the user.
+    // For example, if the foreign key points to the organism table you might want to
+    // display the abbreviation or common name to the user.
+    $table_defn = chado_get_schema($this->definition['foreign_key']['right_table']);
+    $options = array();
+    foreach ($table_defn['fields'] as $name => $details) {
+      $options[$name] = $name;
+    }
+    $form['display_column'] = array(
+      '#type' => 'select',
+      '#title' => 'Display Column',
+      '#description' => t('Specify which column from the parent table you would like to
+        display to the user.'),
+      '#options' => $options,
+      '#default_value' => $this->options['display_column'],
+    );
+    
+    $form['max_length'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Max Width'),
+      '#description' => t('Specify the maximum width of the select box'),
+      '#default_value' => $this->options['max_length'],
+    );
+
+    return $form;
+
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function extra_options_submit($form, &$form_state) {
+    $this->options['values_form_type'] = $form_state['values']['options']['values_form_type'];
+    $this->options['select_multiple'] = $form_state['values']['options']['select_multiple'];
+    $this->options['select_optional'] = $form_state['values']['options']['select_optional'];
+    $this->options['display_column'] = $form_state['values']['options']['display_column'];
+    $this->options['max_length'] = $form_state['values']['options']['max_length'];
+    $this->options['show_all'] = $form_state['values']['options']['show_all'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function admin_summary() {
+    if (is_array($this->value)) {
+      return check_plain((string) $this->operator) . ' ' . check_plain((string) implode(',',$this->value));
+    }
+    else {
+      return check_plain((string) $this->operator) . ' ' . check_plain((string) $this->value);
+    }
+  }
+  
+  /**
+   * {@inheritdoc}
+   */
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['values_form_type'] = array(
+      'default' => 'textfield',
+      'export' => TRUE,
+    );
+    $options['select_multiple'] = array(
+      'default' => FALSE,
+      'bool' => TRUE,
+      'export' => TRUE,
+    );
+    $options['select_optional'] = array(
+      'default' => FALSE,
+      'bool' => TRUE,
+      'export' => TRUE,
+    );
+    $options['show_all'] = array(
+      'default' => FALSE,
+      'bool' => TRUE,
+      'export' => TRUE,
+    );
+    
+    // display column.
+    $table_defn = chado_get_schema($this->definition['foreign_key']['right_table']);
+    $fields = array_keys($table_defn['fields']);
+    $name_fields = preg_grep('/name/', $fields);
+    if ($name_fields) {
+      $default = array_pop($name_fields);
+    }
+    else {
+      $default = array_pop($fields);
+    }
+    $options['display_column'] = array(
+      'export' => TRUE,
+      'default' => $default,
+    );
+    $options['max_length'] = array(
+      'default' => 40,
+      'export' => TRUE,
+    );
+
+    return $options;
+  }
+}
+
+/**
+ * Adds chado support to the string filter.
+ */
+class chado_views_handler_filter_string extends views_handler_filter_string {
+
+  function query() {
+    
+    // Adds joins to chado_entity and the chado table this field is from.
+    $alias = _chado_views_add_table_joins($this);
+
+    // Finally add the restriction on the chado table including the value entered by the filter.
+    // Notice that we don't call $query->add_where directly. This is so that the options
+    // specified for the comparison operator are used (ie: contains).
+    $info = $this->operators();
+    $field = $alias .'.'. $this->definition['chado_field'];
+    if (!empty($info[$this->operator]['method'])) {
+      $this->{$info[$this->operator]['method']}($field);
+    }
+  }
+}
+
+/**
+ * A helper function for adding joins in the views_handler::query() method
+ * to connect a TripalEntity with it's chado tables.
+ *
+ * @param object $views_handler
+ *   $this from within the views_handler::query() method.
+ */
+function _chado_views_add_table_joins(&$handler) {
+
+  // First we need to join to the chado_entity table where the link between an 
+  // entity and it's chado record is stored.
+  $join = new views_join();
+  $join->construct('chado_entity', $handler->table, 'id', 'chado_entity_id');
+  $alias = $handler->query->add_relationship('chado_entity', $join, $handler->table_alias, $handler->relationship);
+
+  // Restrict the chado_entity join to only return the table this field is from.
+  $handler->query->add_where(0, $alias .'.data_table', $handler->definition['chado_table'], '=');
+  
+  // Now, we need to join from chado_entity to the chado table needed by this field.
+  // This only works if the field is from the base table.
+  // @todo: fix handler to work with non-base tables.
+  $join = new views_join();
+  $chado_table = 'chado.'.$handler->definition['chado_table'];
+  $join->construct($chado_table, 'chado_entity', 'record_id', $handler->definition['chado_table'].'_id');
+  $alias = $handler->query->add_relationship('chado_'.$handler->definition['chado_table'], $join, $handler->table_alias, $handler->relationship);
+
+  return $alias;
+}

+ 22 - 0
tripal_chado/includes/chado_views_handler_sort.inc

@@ -0,0 +1,22 @@
+<?php
+/**
+ * Views handlers providing sort support for chado fields.
+ */
+
+/**
+ * Adds support for generic sorting.
+ */
+class chado_views_handler_sort extends views_handler_sort {
+
+  /**
+   * {@inheritdoc}
+   */
+  function query() {
+
+    // Adds joins to chado_entity and the chado table this field is from.
+    $alias = _chado_views_add_table_joins($this);
+    
+    // Add the sort.
+    $this->query->add_orderby($alias, $this->definition['chado_field'], $this->options['order']);
+  }
+}

+ 4 - 0
tripal_chado/tripal_chado.info

@@ -5,6 +5,10 @@ project = tripal
 package = Tripal
 version = 7.x-2.0
 
+files[] = includes/chado_views_handler_field.inc
+files[] = includes/chado_views_handler_filter.inc
+files[] = includes/chado_views_handler_sort.inc
+
 stylesheets[all][] = theme/css/tripal_chado.css
 
 dependencies[] = tripal

+ 0 - 1
tripal_chado/tripal_chado.module

@@ -822,7 +822,6 @@ function tripal_chado_set_field_form_values($field_name, &$form_state, $newvalue
   return TRUE;
 }
 
-
 /**
  * Implements hook_theme().
  */

+ 123 - 0
tripal_chado/tripal_chado.views.inc

@@ -22,6 +22,129 @@ function tripal_chado_views_data() {
   return $data;
 }
 
+/**
+ * Implements hook_views_data_alter().
+ */
+function tripal_chado_views_data_alter(&$data) {
+
+  // Adds integration for chado-based fields.
+  tripal_chado_add_field_views_data($data);
+
+  return $data;
+}
+
+/** 
+ * Adds integration for chado-based fields.
+ *
+ * We can't use hook_field_view_data since this only works when the
+ * storage engine is of type 'field_sql_storage' and of course,
+ * ours is not. Thus we create our own implementation of field_views_data()
+ * for our storage engine.
+ */
+function tripal_chado_add_field_views_data(&$data) {
+
+  foreach (field_info_fields() as $field) {
+    if ($field['storage']['type'] != 'field_chado_storage') {
+      continue;
+    }
+
+    // Currently, we only handle integration of chado fields with TripalEntity.
+    // @todo: extend this to work with other entities in the future.
+    if (isset($field['bundles']['TripalEntity']) AND isset($field['settings']['chado_column'])) {
+
+      // We currently don't support prop tables for views integration due
+      // in part to the multiple values but also b/c we can't indicate which
+      // type of property to show. Thus, instead of warning the user,
+      // we just won't integrate it at this time.
+      // @todo: Handle property fields.
+      if (preg_match('/prop$/', $field['settings']['chado_table'])) {
+        continue;
+      }
+      
+      // Get some information about the chado table in order to make good
+      // choices for handlers.
+      $table_desc = chado_get_schema($field['settings']['chado_table']);
+      $field_defn = $table_desc['fields'][ $field['settings']['chado_column'] ];
+      
+      // We also need to know if this field is a foreign key.
+      $fk_defn = FALSE;
+      foreach ($table_desc['foreign keys'] as $details) {
+        foreach ($details['columns'] as $left_field => $right_field) {
+          if ($left_field == $field['settings']['chado_column']) {
+            $fk_defn = array(
+              'left_table' => $field['settings']['chado_table'],
+              'left_field' => $left_field,
+              'right_table' => $details['table'],
+              'right_field' => $right_field,
+            );
+          }
+        }
+      }
+      
+
+      // Unfortunatly we can't use the field label since that is set at the 
+      // instance level and fields are integrated at the field level (independant of bundle).
+      // Thus we will simply make the most readable and informative field name we can.
+      $data['tripal_entity'][ $field['field_name'] ]['title'] = ucfirst(str_replace('_',' ',$field['settings']['chado_table']))
+        . ' ' .ucfirst(str_replace('_',' ',$field['settings']['chado_column']));
+
+      // The help should be 'Appears in: TripalEntity: gene, organism'
+      // so that users know where they can use it. This requires a little extra work since all
+      // we have access to at this point is bio-data_2, bio-data_4 but since that's not very
+      // informative, extra work is worth it ;-).
+      $entity_info = entity_get_info('TripalEntity');
+      $bundle_labels = array();
+      foreach ($field['bundles']['TripalEntity'] as $bundle_id) {
+        $bundle_labels[] = $entity_info['bundles'][$bundle_id]['label'];
+      }
+      $data['tripal_entity'][ $field['field_name'] ]['help'] = 'Appears in: TripalEntity:' . implode(', ', $bundle_labels);
+
+      // Define the field.
+      $data['tripal_entity'][ $field['field_name'] ]['field']['chado_field'] = $field['settings']['chado_column'];
+      $data['tripal_entity'][ $field['field_name'] ]['field']['chado_table'] = $field['settings']['chado_table'];
+      $data['tripal_entity'][ $field['field_name'] ]['field']['field_name'] = $field['field_name'];
+      $data['tripal_entity'][ $field['field_name'] ]['field']['entity_table'] = 'tripal_entity';
+      $data['tripal_entity'][ $field['field_name'] ]['field']['entity_type'] = 'TripalEntity';
+      $data['tripal_entity'][ $field['field_name'] ]['field']['bundles'] = $field['bundles']['TripalEntity'];
+      $data['tripal_entity'][ $field['field_name'] ]['field']['handler'] = 'chado_views_handler_field';
+      $data['tripal_entity'][ $field['field_name'] ]['field']['click sortable'] = FALSE;
+
+      // Define the Filter.
+      $data['tripal_entity'][ $field['field_name'] ]['filter']['chado_field'] = $field['settings']['chado_column'];
+      $data['tripal_entity'][ $field['field_name'] ]['filter']['chado_table'] = $field['settings']['chado_table'];
+      $data['tripal_entity'][ $field['field_name'] ]['filter']['field_name'] = $field['field_name'];
+      $data['tripal_entity'][ $field['field_name'] ]['filter']['entity_table'] = 'tripal_entity';
+      $data['tripal_entity'][ $field['field_name'] ]['filter']['entity_type'] = 'TripalEntity';
+      $data['tripal_entity'][ $field['field_name'] ]['filter']['bundles'] = $field['bundles']['TripalEntity'];
+      $data['tripal_entity'][ $field['field_name'] ]['filter']['handler'] = 'chado_views_handler_filter_string';
+
+      // Define sorting.
+      $data['tripal_entity'][ $field['field_name'] ]['sort']['chado_field'] = $field['settings']['chado_column'];
+      $data['tripal_entity'][ $field['field_name'] ]['sort']['chado_table'] = $field['settings']['chado_table'];
+      $data['tripal_entity'][ $field['field_name'] ]['sort']['field_name'] = $field['field_name'];
+      $data['tripal_entity'][ $field['field_name'] ]['sort']['entity_table'] = 'tripal_entity';
+      $data['tripal_entity'][ $field['field_name'] ]['sort']['entity_type'] = 'TripalEntity';
+      $data['tripal_entity'][ $field['field_name'] ]['sort']['bundles'] = $field['bundles']['TripalEntity'];
+      $data['tripal_entity'][ $field['field_name'] ]['sort']['handler'] = 'chado_views_handler_sort';
+      
+      // Specify special handlers.
+      if ($fk_defn) {
+        $data['tripal_entity'][ $field['field_name'] ]['filter']['handler'] = 'chado_views_handler_filter_fk';
+        $data['tripal_entity'][ $field['field_name'] ]['filter']['foreign_key'] = $fk_defn;
+      }
+      if ($field_defn['type'] == 'boolean') {
+        $data['tripal_entity'][ $field['field_name'] ]['filter']['handler'] = 'chado_views_handler_filter_boolean';
+        $data['tripal_entity'][ $field['field_name'] ]['filter']['label'] = $field['settings']['chado_column'];
+        $data['tripal_entity'][ $field['field_name'] ]['filter']['type'] = 'yes-no'; 
+      }
+      elseif ($field_defn['type'] == 'datetime') {
+        $data['tripal_entity'][ $field['field_name'] ]['filter']['handler'] = 'chado_views_handler_filter_date';
+      }
+
+    }    
+  }
+}
+
 /**
  * Provides the data array for the tripal custom tables management
  *