Selaa lähdekoodia

Working on Views integration with TripalEntities

Stephen Ficklin 7 vuotta sitten
vanhempi
commit
d346287dc1

+ 34 - 5
tripal/includes/TripalEntityController.inc

@@ -36,6 +36,7 @@ class TripalEntityController extends EntityAPIController {
     $values['title'] = '';
     $values['type'] = 'TripalEntity';
     $values['nid'] = '';
+    $values['status'] = 1;
 
     // Call the parent constructor.
     $entity = parent::create($values);
@@ -144,8 +145,8 @@ class TripalEntityController extends EntityAPIController {
       $alias = tripal_replace_entity_tokens($alias, $entity, $bundle_entity);
     }
 
-    // If there was no defaults supplied by the admins
-    // then we should gneerate our own using the term name and entity id.
+    // If there is still no alias supplied then we should generate one using
+    // the term name and entity id.
     if (!$alias) {
 
       // Load the term for this TripalEntity.
@@ -269,6 +270,26 @@ class TripalEntityController extends EntityAPIController {
     global $user;
     $pkeys = array();
 
+    // Get the author information.
+    $author = $user;
+    if (property_exists($entity, 'uid')) {
+      $author = user_load($entity->uid);
+    }
+
+    $changed_date = time();
+    $create_date = $changed_date;
+    if (property_exists($entity, 'created')) {
+      $temp = new DateTime($entity->created);
+      $create_date = $temp->getTimestamp();
+    }
+
+    $status = 1;
+    if (property_exists($entity, 'status')) {
+      if ($entity->status === 0 or $entity->status === 1) {
+        $status = $entity->status;
+      }
+    }
+
     $transaction  = db_transaction();
     try {
       // If our entity has no id, then we need to give it a
@@ -291,9 +312,10 @@ class TripalEntityController extends EntityAPIController {
         'type'      => $entity->type,
         'bundle'    => $entity->bundle,
         'title'     => $entity->title,
-        'uid'       => $user->uid,
-        'created'   => $entity->created,
-        'changed'   => time(),
+        'uid'       => $author->uid,
+        'created'   => $create_date,
+        'changed'   => $changed_date,
+        'status'    => $status,
       );
       if (property_exists($entity, 'nid') and $entity->nid) {
         $record['nid'] = $entity->nid;
@@ -327,6 +349,11 @@ class TripalEntityController extends EntityAPIController {
       module_invoke_all('entity_postsave', $entity, $entity->type);
       module_invoke_all($invocation, $entity, $entity->type);
 
+      // Clear any cache entries for this entity so it can be reloaded using
+      // the values that were just saved.
+      $cid = 'field:TripalEntity:' . $entity->id;
+      cache_clear_all($cid, 'cache_field', TRUE);
+
       return $entity;
     }
     catch (Exception $e) {
@@ -335,6 +362,8 @@ class TripalEntityController extends EntityAPIController {
       drupal_set_message("Could not save the entity: " . $e->getMessage(), "error");
       return FALSE;
     }
+
+
   }
 
   /**

+ 102 - 0
tripal/includes/TripalEntityUIController.inc

@@ -119,6 +119,9 @@ function tripal_view_entity($entity, $view_mode = 'full') {
    $controller = entity_get_controller($entity->type);
    $content = $controller->view(array($entity->id => $entity));
    drupal_set_title($entity->title);
+   if ($entity->status == 0) {
+     drupal_set_message('This page is currently unpublished', 'warning');
+   }
    return $content;
  }
 
@@ -480,6 +483,81 @@ function tripal_view_entity($entity, $view_mode = 'full') {
        );
      }
    }
+   $form['additional_settings'] = array(
+     '#type' => 'vertical_tabs',
+     '#weight' => 99,
+   );
+
+   // Node author information for administrators
+   $form['author'] = array(
+     '#type' => 'fieldset',
+     '#access' => user_access('administer nodes'),
+     '#title' => t('Authoring information'),
+     '#collapsible' => TRUE,
+     '#collapsed' => TRUE,
+     '#group' => 'additional_settings',
+     '#attributes' => array(
+       'class' => array('TripalEntity-form-author'),
+     ),
+     '#attached' => array(
+       'js' => array(
+         drupal_get_path('module', 'node') . '/node.js',
+         array(
+           'type' => 'setting',
+           'data' => array('anonymous' => variable_get('anonymous', t('Anonymous'))),
+         ),
+       ),
+     ),
+
+     '#weight' => 90,
+   );
+
+   $account = user_load($entity->uid);
+   $form['author']['author_name'] = array(
+     '#type' => 'textfield',
+     '#title' => t('Authored by'),
+     '#maxlength' => 60,
+     '#autocomplete_path' => 'user/autocomplete',
+     '#default_value' => !empty($account->name) ? $account->name : '',
+     '#weight' => -1,
+     '#description' => t('Leave blank for %anonymous.', array('%anonymous' => variable_get('anonymous', t('Anonymous')))),
+   );
+   $form['author']['author_date'] = array(
+     '#type' => 'textfield',
+     '#title' => t('Authored on'),
+     '#maxlength' => 25,
+     '#description' => t('Format: %time. The date format is YYYY-MM-DD and ' .
+       '%timezone is the time zone offset from UTC. Leave blank to use the ' .
+       'time of form submission.',
+       array(
+         '%time' => !empty($entity->created) ? date('Y-m-d H:i:s O', $entity->created) : format_date($entity->created, 'custom', 'Y-m-d H:i:s O'),
+         '%timezone' => !empty($entity->created) ? date('O', $entity->created) : format_date($entity->created, 'custom', 'O'))
+       ),
+     '#default_value' => !empty($entity->created) ? date('Y-m-d H:i:s O', $entity->created) : '',
+   );
+   // Node options for administrators
+   $form['options'] = array(
+     '#type' => 'fieldset',
+     '#access' => user_access('administer nodes'),
+     '#title' => t('Publishing options'),
+     '#collapsible' => TRUE,
+     '#collapsed' => TRUE,
+     '#group' => 'additional_settings',
+     '#attributes' => array(
+       'class' => array('node-form-options'),
+     ),
+     '#attached' => array(
+       'js' => array(drupal_get_path('module', 'node') . '/node.js'),
+     ),
+     '#weight' => 95,
+   );
+   $form['options']['status'] = array(
+     '#type' => 'checkbox',
+     '#title' => t('Published'),
+     '#default_value' => $entity->status,
+   );
+
+
    $form['cancel_button'] = array(
      '#type' => 'submit',
      '#value' => t('Cancel'),
@@ -519,6 +597,19 @@ function tripal_entity_form_ajax_callback($form, $form_state) {
    // For adds and updates, perform validation.
    $entity = $form_state['TripalEntity'];
    field_attach_form_validate('TripalEntity', $entity, $form, $form_state);
+
+   $username = $form_state['values']['author_name'];
+   $user = user_load_by_name($username);
+   if (!$user) {
+     form_set_error('author_name', 'Please provide a valid author name.');
+   }
+
+   try {
+    $create_date = new DateTime($form_state['values']['author_date']);
+   }
+   catch (Exception $e) {
+     form_set_error('author_date', 'Please provide a valid authored on date.');
+   }
  }
 
  /**
@@ -541,6 +632,17 @@ function tripal_entity_form_ajax_callback($form, $form_state) {
      $form_state['redirect'] = 'bio_data/' . $entity->id .'/delete';
      return;
    }
+
+   $username = $form_state['values']['author_name'];
+   $user = user_load_by_name($username);
+   $entity->uid = $user->uid;
+
+   $create_date = $form_state['values']['author_date'];
+   $entity->created = $create_date;
+
+   $published = $form_state['values']['status'];
+   $entity->status = $published;
+
    // Allow the fields to perform actions prior to submit.
    $instances = field_info_instances('TripalEntity', $entity->bundle);
    $langcode = 'und';

+ 1 - 1
tripal/includes/TripalEntityViewsController.inc

@@ -31,7 +31,7 @@ class TripalEntityViewsController extends EntityDefaultViewsController {
     $data['tripal_entity']['uid']['help'] = 'The User\'s unique ID.';
 
     $data['tripal_entity']['status']['help'] = 'The publish status.';
-    $data['tripal_entity']['status']['field']['handler'] = 'tripal_views_handler_field_entity_status';
+    $data['tripal_entity']['status']['field']['handler'] = 'tripal_views_handler_field_boolean';
 
     // We want to use our own query plugin.
     $data['tripal_entity']['table']['base']['query class'] = 'tripal_views_query';

+ 0 - 15
tripal/includes/TripalFields/TripalField.inc

@@ -302,21 +302,6 @@ class TripalField {
     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) {
-
-  }
-
   /**
    * Provides a form for the 'Field Settings' of an instance of this field.
    *

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

@@ -104,32 +104,6 @@ function tripal_field_views_data($field) {
   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().
  */

+ 6 - 2
tripal/tripal.info

@@ -11,10 +11,14 @@ scripts[]          = theme/js/tripal.js
 
 files[] = views_handlers/tripal_views_handler_field.inc
 files[] = views_handlers/tripal_views_handler_field_entity.inc
-files[] = views_handlers/tripal_views_handler_field_entity_status.inc
-files[] = views_handlers/tripal_views_handler_field_entity_default_formatter.inc
+files[] = views_handlers/tripal_views_handler_field_entity_link.inc
+files[] = views_handlers/tripal_views_handler_field_entity_link_edit.inc
+files[] = views_handlers/tripal_views_handler_field_entity_link_delete.inc
+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_entity_string.inc
 files[] = views_handlers/tripal_views_handler_filter_string_selectbox.inc
 files[] = views_handlers/tripal_views_handler_sort_entity_string.inc

+ 61 - 2
tripal/tripal.views.inc

@@ -45,7 +45,7 @@ function tripal_views_data_fields(&$data) {
   $fields = field_info_fields();
   foreach ($fields as $field) {
 
-    // Skip fields that aren't attached to TripalEntity fields.
+    // Skip fields that aren't attached to TripalEntity entities.
     if (!array_key_exists('TripalEntity', $field['bundles'])) {
       continue;
     }
@@ -58,7 +58,7 @@ function tripal_views_data_fields(&$data) {
     // Set defaults for the field if no data array was returned.
     if (empty($result)) {
       // Iterate through the bundles to which this field is attached and
-      // if it is a TripalField field then we'll call the viewsDataAlater function.
+      // if it is a TripalField field then we'll call the viewsData function.
       $bundles = $field['bundles']['TripalEntity'];
       $result = array();
       foreach ($bundles as $bundle_name) {
@@ -109,6 +109,65 @@ function tripal_views_data_tripal_entity(&$data) {
         'handler' => 'views_handler_sort',
       ),
     );
+    $data[$bundle->name]['link'] = array(
+      'title' => t('Link'),
+      'help' => t('Provide a simple link to the content.'),
+      'field' => array(
+        'handler' => 'tripal_views_handler_field_entity_link',
+      ),
+      'filter' => array(
+        'handler' => 'tripal_views_handler_filter',
+      ),
+      'sort' => array(
+        'handler' => 'views_handler_sort',
+      ),
+    );
+    $data[$bundle->name]['edit_link'] = array(
+      'title' => t('Edit Link'),
+      'help' => t('Provide a simple link to edit the content.'),
+      'field' => array(
+        'handler' => 'tripal_views_handler_field_entity_link_edit',
+      ),
+      'filter' => array(
+        'handler' => 'tripal_views_handler_filter',
+      ),
+      'sort' => array(
+        'handler' => 'views_handler_sort',
+      ),
+    );
+    $data[$bundle->name]['delete_link'] = array(
+      'title' => t('Delete Link'),
+      'help' => t('Provide a simple link to delete the content.'),
+      'field' => array(
+        'handler' => 'tripal_views_handler_field_entity_link_delete',
+      ),
+      'filter' => array(
+        'handler' => 'tripal_views_handler_filter',
+      ),
+      'sort' => array(
+        'handler' => 'views_handler_sort',
+      ),
+    );
+    $data[$bundle->name]['status'] = array(
+      'title' => t('Published'),
+      'help' => t('Whether or not the content is published.'),
+      'field' => array(
+        'handler' => 'tripal_views_handler_field_boolean',
+        'click sortable' => TRUE,
+        'output formats' => array(
+          'published-notpublished' => array(t('Published'), t('Not published')),
+        ),
+      ),
+      'filter' => array(
+        'handler' => 'views_handler_filter_boolean_operator',
+        'label' => t('Published'),
+        'type' => 'yes-no',
+        'use equal' => TRUE, // Use status = 1 instead of status <> 0 in WHERE statment
+      ),
+      'sort' => array(
+        'handler' => 'views_handler_sort',
+      ),
+    );
   }
 }
 

+ 47 - 15
tripal/tripal_views_query.inc

@@ -107,35 +107,67 @@ class tripal_views_query extends views_plugin_query {
     $start = microtime(TRUE);
 
     // Execute the count query
+    // TODO: support paging.
     $cquery = clone $query;
     $cquery->count();
-    $num_records = $cquery->execute();
-    $views->total_rows = count($num_records['TripalEntity']);
+    //$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'];
+      }
+    }
 
-    // Iterate through the entities that were returned and get the field
-    // values that are requested.  Those go in the view->result array.
+    $entities = tripal_load_entity('TripalEntity', $entity_ids, FALSE, $field_ids);
     $i = 0;
-    $view->result = array();
-    foreach ($results['TripalEntity'] as $entity_id => $stub) {
-      $entities = array($entity_id => $stub);
+    foreach ($entities as $entity_id => $entity) {
       $view->result[$i] = new stdClass();
-      $view->result[$i]->entity = $stub;
       foreach ($this->fields as $details) {
         $field_name = $details['field_name'];
-        $field = field_info_field($field_name);
-        module_invoke($field['storage']['module'], 'field_storage_load', 'TripalEntity',
-            $entities, FIELD_LOAD_CURRENT, array($field['id'] => array($entity_id)));
-        $view->result[$i]->$field_name = $entities[$entity_id]->$field_name['und'][0]['value'];
+        // 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;
+        }
       }
-      $view->result[$i]->entity_id = $stub->id;
       $i++;
     }
     $view->execute_time = microtime(TRUE) - $start;
     $view->current_page = 0;
-    //dpm($view->query);
-    //dpm($view->result);
   }
 
 }

+ 8 - 1
tripal/views_handlers/tripal_views_handler_field.inc

@@ -34,6 +34,7 @@ class tripal_views_handler_field extends views_handler_field {
    *   Optional name of the field where the value is stored.
    */
   function get_value($values, $field = NULL) {
+
     $alias = isset($field) ? $this->aliases[$field] : $this->field_alias;
 
     // For some reason the alias isn't being added to the $this->aliases
@@ -57,7 +58,13 @@ class tripal_views_handler_field extends views_handler_field {
    *   The values retrieved from the database.
    */
   function render($values) {
+
     $value = $this->get_value($values);
-    return $this->sanitize_value($value);
+    // Handle single value fields:
+    if (count($value == 1)) {
+      $value = $this->sanitize_value($value[0]['value']);
+      return $value;
+    }
+    return '';
   }
 }

+ 88 - 0
tripal/views_handlers/tripal_views_handler_field_boolean.inc

@@ -0,0 +1,88 @@
+<?php
+class tripal_views_handler_field_boolean extends tripal_views_handler_field {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['type'] = array('default' => 'yes-no');
+    $options['type_custom_true'] = array('default' => '', 'translatable' => TRUE);
+    $options['type_custom_false'] = array('default' => '', 'translatable' => TRUE);
+    $options['not'] = array('definition bool' => 'reverse');
+
+    return $options;
+  }
+
+  function init(&$view, &$options) {
+    parent::init($view, $options);
+
+    $default_formats = array(
+      'yes-no' => array(t('Yes'), t('No')),
+      'true-false' => array(t('True'), t('False')),
+      'on-off' => array(t('On'), t('Off')),
+      'enabled-disabled' => array(t('Enabled'), t('Disabled')),
+      'boolean' => array(1, 0),
+      'unicode-yes-no' => array('✔', '✖'),
+    );
+    $output_formats = isset($this->definition['output formats']) ? $this->definition['output formats'] : array();
+    $custom_format = array('custom' => array(t('Custom')));
+    $this->formats = array_merge($default_formats, $output_formats, $custom_format);
+  }
+
+  function options_form(&$form, &$form_state) {
+    foreach ($this->formats as $key => $item) {
+      $options[$key] = implode('/', $item);
+    }
+
+    $form['type'] = array(
+      '#type' => 'select',
+      '#title' => t('Output format'),
+      '#options' => $options,
+      '#default_value' => $this->options['type'],
+    );
+
+    $form['type_custom_true'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Custom output for TRUE'),
+      '#default_value' => $this->options['type_custom_true'],
+      '#states' => array(
+        'visible' => array(
+          'select[name="options[type]"]' => array('value' => 'custom'),
+        ),
+      ),
+    );
+
+    $form['type_custom_false'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Custom output for FALSE'),
+      '#default_value' => $this->options['type_custom_false'],
+      '#states' => array(
+        'visible' => array(
+          'select[name="options[type]"]' => array('value' => 'custom'),
+        ),
+      ),
+    );
+
+    $form['not'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Reverse'),
+      '#description' => t('If checked, true will be displayed as false.'),
+      '#default_value' => $this->options['not'],
+    );
+    parent::options_form($form, $form_state);
+  }
+
+  function render($values) {
+    $value = $this->get_value($values);
+    if (!empty($this->options['not'])) {
+      $value = !$value;
+    }
+
+    if ($this->options['type'] == 'custom') {
+      return $value ? filter_xss_admin($this->options['type_custom_true']) : filter_xss_admin($this->options['type_custom_false']);
+    }
+    else if (isset($this->formats[$this->options['type']])) {
+      return $value ? $this->formats[$this->options['type']][0] : $this->formats[$this->options['type']][1];
+    }
+    else {
+      return $value ? $this->formats['yes-no'][0] : $this->formats['yes-no'][1];
+    }
+  }
+}

+ 42 - 10
tripal/views_handlers/tripal_views_handler_field_entity.inc

@@ -45,6 +45,35 @@ class tripal_views_handler_field_entity extends tripal_views_handler_field {
     parent::options_form($form, $form_state);
   }
 
+  /**
+   * 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) {
+
+    $alias = isset($field) ? $this->aliases[$field] : $this->field_alias;
+
+    // For some reason the alias isn't being added to the $this->aliases
+    // variable when the user clicks the checkbox 'Link this field to the
+    // original piece of content'.  That may need to be investigated and is
+    // probably a side effect of using the  views_handler_field as a parent
+    // class that is expecting something more for SQL. We don't use aliases
+    // for fields so the following if statement will fix the problem.
+    if (!$alias) {
+      $alias = $this->field_alias;
+    }
+    if (isset($values->{$alias})) {
+      return $values->{$alias}->id;
+    }
+  }
+
   /**
    * Render whatever the data is as a link to the entity.
    *
@@ -53,16 +82,19 @@ class tripal_views_handler_field_entity extends tripal_views_handler_field {
   function render_link($data, $values) {
     if (!empty($this->options['link_to_entity']) && !empty($this->additional_fields['id'])) {
       if ($data !== NULL && $data !== '') {
-        $this->options['alter']['make_link'] = TRUE;
-        $this->options['alter']['path'] = "bio_data/" . $this->get_value($values, 'id');
-        if (isset($this->aliases['language'])) {
-          $languages = language_list();
-          $language = $this->get_value($values, 'language');
-          if (isset($languages[$language])) {
-            $this->options['alter']['language'] = $languages[$language];
-          }
-          else {
-            unset($this->options['alter']['language']);
+        $alias = $this->field_alias;
+        if (entity_access('view', 'TripalEntity', $values->{$alias})) {
+          $this->options['alter']['make_link'] = TRUE;
+          $this->options['alter']['path'] = "bio_data/" . $this->get_value($values, 'id');
+          if (isset($this->aliases['language'])) {
+            $languages = language_list();
+            $language = $this->get_value($values, 'language');
+            if (isset($languages[$language])) {
+              $this->options['alter']['language'] = $languages[$language];
+            }
+            else {
+              unset($this->options['alter']['language']);
+            }
           }
         }
       }

+ 0 - 27
tripal/views_handlers/tripal_views_handler_field_entity_default_formatter.inc

@@ -1,27 +0,0 @@
-<?php
-/**
- * @file
-* Contains tripal_views_handler_field_entity_status Filter Handler
-*/
-
-/**
- * This Handler provides a generic select list for any chado field that is a string
-*  The select list includes all distinct values for that field.
-*
-* @ingroup tripal_views
-*/
-class tripal_views_handler_field_entity_default_formatter extends  views_handler_field {
-
-  function render($values) {
-
-    $field_name = $this->field;
-    $row_index = $this->view->row_index;
-    $result = $this->view->result[$row_index];
-    if (property_exists($result, entity)) {
-      $entity = $result->entity;
-      $format = field_view_field('TripalEntity', $entity, $field_name);
-      $format['#label_display'] = 'hidden';
-      return $format;
-    }
-  }
-}

+ 40 - 0
tripal/views_handlers/tripal_views_handler_field_entity_link.inc

@@ -0,0 +1,40 @@
+<?php
+
+
+class tripal_views_handler_field_entity_link extends tripal_views_handler_field {
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['text'] = array('default' => '', 'translatable' => TRUE);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['text'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Text to display'),
+      '#default_value' => $this->options['text'],
+    );
+    parent::options_form($form, $form_state);
+
+    // The path is set by render_link function so don't allow to set it.
+    $form['alter']['path'] = array('#access' => FALSE);
+    $form['alter']['external'] = array('#access' => FALSE);
+  }
+
+  function render($values) {
+    if ($entity = $this->get_value($values)) {
+      return $this->render_link($entity, $values);
+    }
+  }
+
+  function render_link($entity, $values) {
+
+    if (entity_access('view', 'TripalEntity', $entity)) {
+      $this->options['alter']['make_link'] = TRUE;
+      $this->options['alter']['path'] = 'bio_data/' . $entity->id;
+      $text = !empty($this->options['text']) ? $this->options['text'] : t('view');
+      return $text;
+    }
+  }
+}

+ 40 - 0
tripal/views_handlers/tripal_views_handler_field_entity_link_delete.inc

@@ -0,0 +1,40 @@
+<?php
+
+
+class tripal_views_handler_field_entity_link_delete extends tripal_views_handler_field {
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['text'] = array('default' => '', 'translatable' => TRUE);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['text'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Text to display'),
+      '#default_value' => $this->options['text'],
+    );
+    parent::options_form($form, $form_state);
+
+    // The path is set by render_link function so don't allow to set it.
+    $form['alter']['path'] = array('#access' => FALSE);
+    $form['alter']['external'] = array('#access' => FALSE);
+  }
+
+  function render($values) {
+    if ($entity = $this->get_value($values)) {
+      return $this->render_link($entity, $values);
+    }
+  }
+
+  function render_link($entity, $values) {
+
+    if (entity_access('delete', 'TripalEntity', $entity)) {
+      $this->options['alter']['make_link'] = TRUE;
+      $this->options['alter']['path'] = 'bio_data/' . $entity->id . '/delete';
+      $text = !empty($this->options['text']) ? $this->options['text'] : t('view');
+      return $text;
+    }
+  }
+}

+ 40 - 0
tripal/views_handlers/tripal_views_handler_field_entity_link_edit.inc

@@ -0,0 +1,40 @@
+<?php
+
+
+class tripal_views_handler_field_entity_link_edit extends tripal_views_handler_field {
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['text'] = array('default' => '', 'translatable' => TRUE);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['text'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Text to display'),
+      '#default_value' => $this->options['text'],
+    );
+    parent::options_form($form, $form_state);
+
+    // The path is set by render_link function so don't allow to set it.
+    $form['alter']['path'] = array('#access' => FALSE);
+    $form['alter']['external'] = array('#access' => FALSE);
+  }
+
+  function render($values) {
+    if ($entity = $this->get_value($values)) {
+      return $this->render_link($entity, $values);
+    }
+  }
+
+  function render_link($entity, $values) {
+
+    if (entity_access('edit', 'TripalEntity', $entity)) {
+      $this->options['alter']['make_link'] = TRUE;
+      $this->options['alter']['path'] = 'bio_data/' . $entity->id . '/edit';
+      $text = !empty($this->options['text']) ? $this->options['text'] : t('view');
+      return $text;
+    }
+  }
+}

+ 0 - 24
tripal/views_handlers/tripal_views_handler_field_entity_status.inc

@@ -1,24 +0,0 @@
-<?php
-/**
- * @file
-* Contains tripal_views_handler_field_entity_status Filter Handler
-*/
-
-/**
- * This Handler provides a generic select list for any chado field that is a string
-*  The select list includes all distinct values for that field.
-*
-* @ingroup tripal_views
-*/
-class tripal_views_handler_field_entity_status extends  views_handler_field {
-
-  function render($values) {
-    $value = $this->get_value($values);
-    if ($value == 1) {
-      return 'published';
-    }
-    else {
-      return 'unpublished';
-    }
-  }
-}

+ 71 - 0
tripal/views_handlers/tripal_views_handler_field_image.inc

@@ -0,0 +1,71 @@
+<?php
+/**
+ * @file
+ *   Views field handler for basic TripalFields fields.
+ */
+
+/**
+ * Views field handler for basic TripalFields fields.
+ */
+class tripal_views_handler_field_image extends tripal_views_handler_field {
+
+  /**
+   * Overrides option_definition().
+   */
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['image_width'] = array('default' => '');
+    $options['image_height'] = array('default' => '');
+
+    return $options;
+  }
+
+  /**
+   * Overrides options_form().
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['image_width'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Image Width'),
+      '#description' => t('Please provide the width for display of images. Leave blank to accept the width of the image.'),
+      '#size' => '10',
+      '#default_value' => $this->options['image_width'],
+    );
+    $form['image_height'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Image Height'),
+      '#description' => t('Please provide the height for display of images. Leave blank to accept the width of the image.'),
+      '#size' => '10',
+      '#default_value' => $this->options['image_height'],
+    );
+  }
+  /**
+   * Render the field.
+   *
+   * @param $values
+   *   The values retrieved from the database.
+   */
+  function render($values) {
+    $value = $this->get_value($values);
+    // Handle single value fields:
+    if (count($value == 1)) {
+       $fid = $value[0]['fid'];
+       if ($fid) {
+         $file = file_load($fid);
+         $url = file_create_url($file->uri);
+         $width = '';
+         $height = '';
+         if ($this->options['image_width']) {
+           $width = ' width = "' . $this->options['image_width'] . '"';
+         }
+         if ($this->options['image_height']) {
+           $height = ' height = "' . $this->options['image_height'] . '"';
+         }
+         return '<img src="' . $url . '"'. $width . $height .' border="0">';
+
+       }
+    }
+    return '';
+  }
+}

+ 142 - 0
tripal/views_handlers/tripal_views_handler_filter_boolean.inc

@@ -0,0 +1,142 @@
+<?php
+class tripal_views_handler_filter_boolean_operator extends tripal_views_handler_filter {
+  // exposed filter options
+  var $always_multiple = TRUE;
+  // Don't display empty space where the operator would be.
+  var $no_operator = TRUE;
+  // Whether to accept NULL as a false value or not
+  var $accept_null = FALSE;
+
+  function construct() {
+    $this->value_value = t('True');
+    if (isset($this->definition['label'])) {
+      $this->value_value = $this->definition['label'];
+    }
+    if (isset($this->definition['accept null'])) {
+      $this->accept_null = (bool) $this->definition['accept null'];
+    }
+    else if (isset($this->definition['accept_null'])) {
+      $this->accept_null = (bool) $this->definition['accept_null'];
+    }
+    $this->value_options = NULL;
+    parent::construct();
+  }
+
+  /**
+   * Return the possible options for this filter.
+   *
+   * Child classes should override this function to set the possible values
+   * for the filter.  Since this is a boolean filter, the array should have
+   * two possible keys: 1 for "True" and 0 for "False", although the labels
+   * can be whatever makes sense for the filter.  These values are used for
+   * configuring the filter, when the filter is exposed, and in the admin
+   * summary of the filter.  Normally, this should be static data, but if it's
+   * dynamic for some reason, child classes should use a guard to reduce
+   * database hits as much as possible.
+   */
+  function get_value_options() {
+    if (isset($this->definition['type'])) {
+      if ($this->definition['type'] == 'yes-no') {
+        $this->value_options = array(1 => t('Yes'), 0 => t('No'));
+      }
+      if ($this->definition['type'] == 'on-off') {
+        $this->value_options = array(1 => t('On'), 0 => t('Off'));
+      }
+      if ($this->definition['type'] == 'enabled-disabled') {
+        $this->value_options = array(1 => t('Enabled'), 0 => t('Disabled'));
+      }
+    }
+
+    // Provide a fallback if the above didn't set anything.
+    if (!isset($this->value_options)) {
+      $this->value_options = array(1 => t('True'), 0 => t('False'));
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['value']['default'] = FALSE;
+
+    return $options;
+  }
+
+  function operator_form(&$form, &$form_state) {
+    $form['operator'] = array();
+  }
+
+  function value_form(&$form, &$form_state) {
+    if (empty($this->value_options)) {
+      // Initialize the array of possible values for this filter.
+      $this->get_value_options();
+    }
+    if (!empty($form_state['exposed'])) {
+      // Exposed filter: use a select box to save space.
+      $filter_form_type = 'select';
+    }
+    else {
+      // Configuring a filter: use radios for clarity.
+      $filter_form_type = 'radios';
+    }
+    $form['value'] = array(
+      '#type' => $filter_form_type,
+      '#title' => $this->value_value,
+      '#options' => $this->value_options,
+      '#default_value' => $this->value,
+    );
+    if (!empty($this->options['exposed'])) {
+      $identifier = $this->options['expose']['identifier'];
+      if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier])) {
+        $form_state['input'][$identifier] = $this->value;
+      }
+      // If we're configuring an exposed filter, add an <Any> option.
+      if (empty($form_state['exposed']) || empty($this->options['expose']['required'])) {
+        $any_label = variable_get('views_exposed_filter_any_label', 'new_any') == 'old_any' ? '<Any>' : t('- Any -');
+        if ($form['value']['#type'] != 'select') {
+          $any_label = check_plain($any_label);
+        }
+        $form['value']['#options'] = array('All' => $any_label) + $form['value']['#options'];
+      }
+    }
+  }
+
+  function value_validate($form, &$form_state) {
+    if ($form_state['values']['options']['value'] == 'All' && !empty($form_state['values']['options']['expose']['required'])) {
+      form_set_error('value', t('You must select a value unless this is an non-required exposed filter.'));
+    }
+  }
+
+  function admin_summary() {
+    if ($this->is_a_group()) {
+      return t('grouped');
+    }
+    if (!empty($this->options['exposed'])) {
+      return t('exposed');
+    }
+    if (empty($this->value_options)) {
+      $this->get_value_options();
+    }
+    // Now that we have the valid options for this filter, just return the
+    // human-readable label based on the current value.  The value_options
+    // array is keyed with either 0 or 1, so if the current value is not
+    // empty, use the label for 1, and if it's empty, use the label for 0.
+    return $this->value_options[!empty($this->value)];
+  }
+
+  function expose_options() {
+    parent::expose_options();
+    $this->options['expose']['operator_id'] = '';
+    $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);
+//     }
+  }
+}

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

@@ -37,7 +37,7 @@ function tripal_chado_field_storage_write($entity_type, $entity, $op, $fields) {
   $type_field = $entity->chado_column;
   $record     = $entity->chado_record;
   $record_id  = $entity->chado_record_id;
-  $linker     = $entity->chado_linker;
+  $linker     = property_exists($entity, 'chado_linker') ? $entity->chado_linker : '';
   $base_schema = chado_get_schema($base_table);
   $base_pkey = $base_schema['primary key'][0];
 

+ 17 - 0
tripal_chado/includes/tripal_chado.fields.inc

@@ -2148,3 +2148,20 @@ function tripal_chado_form_tripalbundle_form_alter(&$form, $form_state) {
     '#weight' => 0,
   );
 }
+
+/**
+ * Implements hook_field_views_data_alter();
+ */
+function tripal_chado_field_views_data_alter(&$result, $field, $module) {
+
+  // This module creates the data__image field for managing images on
+  // bio_data content types. But we want it to render correctly
+  // so we need to set some handlers.
+  if ($field['field_name'] == 'data__image') {
+    foreach ($result as $key => $fields) {
+      if (preg_match('/^bio_data/', $key)) {
+        $result[$key]['data__image']['field']['handler'] = 'tripal_views_handler_field_image';
+      }
+    }
+  }
+}