Browse Source

Working on Views integration with Tripal fields

Stephen Ficklin 8 years ago
parent
commit
65fa5dfa58

+ 0 - 2
tripal/includes/TripalEntityViewsController.inc

@@ -25,7 +25,6 @@ class TripalEntityViewsController extends EntityDefaultViewsController {
     $data['tripal_entity']['id']['title'] = 'tid';
     $data['tripal_entity']['id']['help'] = 'The unique numeric ID for the content';
 
-
     $data['tripal_entity']['title']['help'] = 'The content\'s title.';
     $data['tripal_entity']['title']['field']['handler'] = 'tripal_views_handler_field_entity';
 
@@ -34,7 +33,6 @@ class TripalEntityViewsController extends EntityDefaultViewsController {
     $data['tripal_entity']['status']['help'] = 'The publish status.';
     $data['tripal_entity']['status']['field']['handler'] = 'tripal_views_handler_field_entity_status';
 
-
     // We want to use our own query plugin.
     $data['tripal_entity']['table']['base']['query class'] = 'tripal_views_query';
 

+ 39 - 7
tripal/includes/TripalFields/TripalField.inc

@@ -268,17 +268,49 @@ class TripalField {
   }
 
   /**
-   * Describes this fields "data tables" to Views.
+   * Describes this field to Views.
    *
-   * This function is the equivalent of the hook_views_data() function of
-   * the Drupal Views API.  It provides the necessary details to allow
-   * Views to integrate the field.
+   * An array of views data, in the same format as the return value of
+   * hook_views_data().
    *
-   * @return
-   *   An associative array describing the data structure of the field.
    */
-  public function viewsDataAlter(&$data, $entity_info) {
+  public function viewsData() {
+    $data = array();
+
+
+
+    return $data;
+  }
 
+  /**
+   * Allows the view data for this field to be altered.
+   *
+   * This function is the equivalent of the hook_field_views_data_alter()
+   * function of the Drupal Field API.  It provides the necessary details to
+   * allow views to integrate the field.
+   *
+   * @param $data
+   *   An array of views table data provided for a single field. This has the
+   *   same format as the return value of hook_views_data().
+   */
+  public function viewsDataAlter(&$data) {
+
+    $bundle_name = $this->instance['bundle'];
+    $field_name = $this->field['field_name'];
+    $data[$bundle_name][$field_name] = array(
+      'title' => $this->instance['label'],
+      'help' => $this->instance['description'],
+      'field' => array(
+        'handler' => 'views_handler_field',
+        'click sortable' => TRUE,
+      ),
+      'filter' => array(
+        'handler' => 'views_handler_filter_string',
+      ),
+      'sort' => array(
+        'handler' => 'views_handler_sort',
+      ),
+    );
   }
 
   /**

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

@@ -82,6 +82,64 @@ function tripal_field_widget_info_alter(&$info) {
 
 }
 
+/**
+ * Implements hook_field_views_data();
+ */
+function tripal_field_views_data($field) {
+  $data = array();
+
+  $field_name = $field['field_name'];
+  $field_type = $field['type'];
+
+  // Iterate through the bundles to which this field is attached and
+  // if it is a TripalField field then we'll call the viewsDataAlater function.
+  $bundles = $field['bundles']['TripalEntity'];
+  foreach ($bundles as $bundle_name) {
+    $instance = field_info_instance('TripalEntity', $field['field_name'], $bundle_name);
+    $data[$bundle_name][$field_name] = array(
+      'title' => $instance['label'],
+      'help' => $instance['description'],
+      'field' => array(
+        'handler' => 'views_handler_field',
+        'click sortable' => TRUE,
+      ),
+      'filter' => array(
+        'handler' => 'views_handler_filter_string',
+      ),
+      'sort' => array(
+        'handler' => 'views_handler_sort',
+      ),
+    );
+  }
+  return $data;
+}
+
+/**
+ * Implements hook_field_views_data_alter();
+ */
+function tripal_field_views_data_alter(&$result, $field, $module) {
+  // Skip fields that aren't TripalEntity fields.
+  if (!array_key_exists('TripalEntity', $field['bundles'])) {
+    return;
+  }
+
+  // Get the list of our Tripal field types for reference.
+  $tripal_field_types = tripal_get_field_types();
+
+  // Iterate through the bundles to which this field is attached and
+  // if it is a TripalField field then we'll call the viewsDataAlater function.
+  $bundles = $field['bundles']['TripalEntity'];
+  foreach ($bundles as $bundle_name) {
+
+    $field_type = $field['type'];
+    if (in_array($field_type, $tripal_field_types)) {
+      $instance = field_info_instance('TripalEntity', $field['field_name'], $bundle_name);
+      $tfield = new $field_type($field, $instance);
+      return $tfield->viewsDataAlter($result);
+    }
+  }
+}
+
 /**
  * Implements hook_field_formatter_info().
  */

+ 100 - 49
tripal/tripal.views.inc

@@ -29,75 +29,126 @@ function tripal_views_plugins() {
 function tripal_views_data() {
   $data = array();
   // Job Management System
-  $data = tripal_views_data_jobs($data);
-
-  $data += tripal_entity_views_data();
+  tripal_views_data_jobs($data);
+  tripal_entity_views_data($data);
+  tripal_views_data_fields($data);
 
   return $data;
 }
 
 /**
- * Integrates the TripalEntity entities with Drupal Views.
+ * Integreates the Tripal fields with Views.
  */
-function tripal_entity_views_data() {
-  $data = array();
+function tripal_views_data_fields(&$data) {
 
-  // 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 fields.
+  $fields = field_info_fields();
+  foreach ($fields as $field) {
 
-  // Iterate through the bundles.
-  while ($bundle = $bundles->fetchObject()) {
+    // Skip fields that aren't attached to TripalEntity fields.
+    if (!array_key_exists('TripalEntity', $field['bundles'])) {
+      continue;
+    }
 
-    // Each bundle gets it's own "table".
-//     $data['tripal_entity']['table']['group'] = t($bundle->label);
-//     $data[$bundle->name]['table']['base'] = array(
-//       'query class' => 'tripal_views_query',
-//       'title' => t($bundle->label),
-//       'help' => t('Tripal ' . $bundle->label . ' pages'),
-//     );
-
-    // Now add the fields to the bundle.
-    $instances = field_info_instances('TripalEntity', $bundle->name);
-    foreach ($instances as $instance) {
-
-      // TODO: how to determine which handler to use for each field? Perhaps
-      // fields should set their type and here we use that type to determine
-      // which handler to use. If not handler is specified then we use
-      // a default string handler.
-      $field_handler = 'tripal_views_handler_field_entity_default_formatter';
-      $filter_handler = 'tripal_views_handler_filter_entity_string';
-      $sort_handler = 'tripal_views_handler_sort_entity_string';
-      $click_sortable = TRUE;
-
-      $field_name = $instance['field_name'];
-
-      if ($field_name == 'content_type') {
-        $field_handler = 'views_handler_field';
-      }
-
-      $data['tripal_entity'][$field_name] = array(
-        'group' => $bundle->label,
+    // Call the hook_field_views_data() hooks.
+    // $module = $field['module'];
+    //$result = (array) module_invoke($module, 'field_views_data', $field);
+
+    // Iterate through the bundles to which this field is attached and
+    // add the fields that are attached to the bundle.
+    $bundles = $field['bundles']['TripalEntity'];
+    $field_name = $field['field_name'];
+    $field_type = $field['type'];
+    foreach ($bundles as $bundle_name) {
+      $instance = field_info_instance('TripalEntity', $field['field_name'], $bundle_name);
+      $data[$bundle_name][$field_name] = array(
         'title' => $instance['label'],
-        'help' => t(' Appears in: @bundles.', array('@bundles' => $bundle->label)) . $instance['description'],
-        'handler' => '',
+        'help' => $instance['description'],
         'field' => array(
-          'handler' => $field_handler,
-          'click sortable' => $click_sortable,
+          'handler' => 'views_handler_field',
+          'click sortable' => TRUE,
         ),
         'filter' => array(
-          'handler' => $filter_handler,
+          'handler' => 'views_handler_filter_string',
         ),
         'sort' => array(
-          'handler' => $sort_handler,
+          'handler' => 'views_handler_sort',
         ),
       );
     }
+
+    // Set defaults for the fielf if no data array was returned.
+    //if (empty($result)) {
+      //$result = tripal_views_default_views_data($field);
+    //}
+
+    // Call the hook_field_views_data_alter() hook.
+    //drupal_alter('field_views_data', $result, $field, $module);
+
+    //if (is_array($result)) {
+      //$data = drupal_array_merge_deep($result, $data);
+    //}
   }
+}
+/**
+ * Integrates the TripalEntity entities with Drupal Views.
+ */
+function tripal_entity_views_data(&$data) {
 
-  return $data;
+  // 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()) {
+
+    // Each bundle gets it's own "table".
+     $data[$bundle->name]['table']['group'] = t($bundle->label);
+     $data[$bundle->name]['table']['base'] = array(
+       'query class' => 'tripal_views_query',
+       'title' => t($bundle->label),
+       'help' => t('Tripal ' . $bundle->label . ' pages'),
+     );
+
+//     // Now add the fields to the bundle.
+//     $instances = field_info_instances('TripalEntity', $bundle->name);
+//     foreach ($instances as $instance) {
+
+//       // TODO: how to determine which handler to use for each field? Perhaps
+//       // fields should set their type and here we use that type to determine
+//       // which handler to use. If not handler is specified then we use
+//       // a default string handler.
+//       $field_handler = 'tripal_views_handler_field_entity_default_formatter';
+//       $filter_handler = 'tripal_views_handler_filter_entity_string';
+//       $sort_handler = 'tripal_views_handler_sort_entity_string';
+//       $click_sortable = TRUE;
+
+//       $field_name = $instance['field_name'];
+
+//       if ($field_name == 'content_type') {
+//         $field_handler = 'views_handler_field';
+//       }
+
+//       $data['tripal_entity'][$field_name] = array(
+//         'group' => $bundle->label,
+//         'title' => $instance['label'],
+//         'help' => t(' Appears in: @bundles.', array('@bundles' => $bundle->label)) . $instance['description'],
+//         'handler' => '',
+//         'field' => array(
+//           'handler' => $field_handler,
+//           'click sortable' => $click_sortable,
+//         ),
+//         'filter' => array(
+//           'handler' => $filter_handler,
+//         ),
+//         'sort' => array(
+//           'handler' => $sort_handler,
+//         ),
+//       );
+//     }
+  }
 }
 
 /**

+ 10 - 100
tripal/tripal_views_query.inc

@@ -1,8 +1,11 @@
 <?php
 
-class tripal_views_query extends views_plugin_query_default {
+class tripal_views_query extends views_plugin_query {
 
-  private $attach_fields = array();
+  // The EntityFieldQuery object.
+  var $query;
+
+  var $fields;
 
   /**
    *
@@ -10,24 +13,16 @@ class tripal_views_query extends views_plugin_query_default {
   public function init($base_table = 'tripal_entity', $base_field = 'id', $options) {
     parent::init($base_table, $base_field, $options);
 
-    // Always add the TripaEntity id and the bundle name so we can keep
-    // track of which rows are in the SQL results
-    $this->add_field('tripal_entity', 'id', 'tripal_entity_id');
-    $this->add_field('tripal_bundle', 'name', 'tripal_bundle_name');
+    $this->fields = array();
 
+    $this->query = new EntityFieldQuery;
+    $this->query->entityCondition('entity_type', 'TripalEntity');
   }
   /**
    *
    */
   public function add_field($table_alias, $field, $alias = '', $params = array()) {
-    // If this is not a TripalField then allow the add_field to work as usual.
-    $f = field_info_field($field);
-    if (!$f) {
-      return parent::add_field($table_alias, $field, $alias, $params);
-    }
-    else {
-      $this->attach_fields[] = $f;
-    }
+    $this->fields[] = $field;
   }
 
   /**
@@ -35,91 +30,6 @@ class tripal_views_query extends views_plugin_query_default {
    * @param  $view
    */
   function execute(&$view) {
-
-    // First execute any SQL that needs to run.
-    parent::execute($view);
-
-    // Add in the entity object to the results and any additional fields
-    // that have been requested.
-    for ($i = 0; $i < count($view->result); $i++) {
-
-      // Build a simple entity stub (it's faster than trying to load the
-      // whole things!).
-      $entity_id = $view->result[$i]->tripal_entity_id;
-      $bundle_name = $view->result[$i]->tripal_bundle_name;
-      $ids = array($entity_id, 0, $bundle_name);
-      $entity = entity_create_stub_entity('TripalEntity', $ids);
-
-      // Iterate through the field and attach only those that have been
-      // requested.
-      foreach ($this->attach_fields as $field) {
-        // Don't load this field if it doesn't belong to the selected bundle
-        if (in_array($bundle_name, $field['bundles']['TripalEntity'])) {
-          $entities = array($entity_id => $entity);
-          module_invoke($field['storage']['module'], 'field_storage_load', 'TripalEntity',
-            $entities, FIELD_LOAD_CURRENT, array($field['id'] => array($entity_id)));
-        }
-      }
-      $view->result[$i]->entity = $entity;
-    }
-    return;
-
-    // The base table indicates our content type.
-    $base_table = $view->base_table;
-
-    // Get the bundle that the view base table represents.
-//    $bundle = tripal_load_bundle_entity(array('name' => $view->base_table));
-
-    // The base table for the view is a bundle therefore the first condition
-    // must be with the content_type field.
-    $query = new TripalFieldQuery();
-//    $query->entityCondition('entity_type', 'TripalEntity');
-    $query->entityCondition('bundle', $bundle->name);
-
-    // Apply filters
-    foreach ($view->filter as $field_name => $handler) {
-      if (trim($handler->value)) {
-        $query->fieldCondition($field_name, $field_name, $handler->value, $handler->operator);
-      }
-    }
-    // Apply sorting
-    foreach ($view->sort as $field_name => $sort) {
-      $options = $sort->options;
-      $query->fieldOrderBy($field_name, $options['order']);
-    }
-
-    $results = $query->execute();
-
-    if (count($results) > 0) {
-      foreach ($results['TripalEntity'] as $entity_id => $stub) {
-        // Begin a new row for Views output.
-        $row = new stdClass;
-
-        // Get the entity object.
-        $entity = tripal_load_entity('TripalEntity', array('id' => $entity_id));
-        $entity = reset($entity);
-
-        // Iterate through the fields that are added to the view and attach those
-        // to the entity.  After attaching we can get the value and include
-        // it in the output results.
-        foreach($view->field as $field_name => $handler) {
-          $field = field_info_field($field_name);
-          field_attach_load($entity->type, array($entity->id => $entity), FIELD_LOAD_CURRENT,
-              array('field_id' => $field['id']));
-          $items = field_get_items('TripalEntity', $entity, $field_name);
-          $value = $items[0]['value'];
-
-          $row->entity = $entity;
-          $row->$field_name = $value;
-        }
-
-        // Add the row to the results list.
-        $view->result[] = $row;
-
-      }
-    }
-
-    $view->total_rows = count($view->result);
-    $view->pager['current_page'] = 0;
+    dpm($view);
   }
 }

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

@@ -127,4 +127,5 @@ class ChadoField extends TripalField {
     );
     return $element;
   }
+
 }