Browse Source

Added dbxref_id field/widget/formatter

Stephen Ficklin 8 years ago
parent
commit
b279f7c64c

+ 3 - 3
tripal/api/tripal.fields.api.inc

@@ -55,7 +55,7 @@ function tripal_get_field_types() {
     foreach ($field_files as $file) {
       $field_type = $file->name;
       module_load_include('inc', $module, 'includes/TripalFields/' . $field_type);
-      if (class_exists($field_type) and get_parent_class($field_type) == 'TripalField') {
+      if (class_exists($field_type) and is_subclass_of($field_type, 'TripalField')) {
         $types[] = $field_type;
       }
     }
@@ -85,7 +85,7 @@ function tripal_get_field_widgets() {
     foreach ($field_files as $file) {
       $field_type = $file->name;
       module_load_include('inc', $module, 'includes/TripalFields/' . $field_type);
-      if (class_exists($field_type) and is_subclass_of($field_type) == 'TripalFieldWidget') {
+      if (class_exists($field_type) and is_subclass_of($field_type, 'TripalFieldWidget')) {
         $widgets[] = $field_type;
       }
     }
@@ -115,7 +115,7 @@ function tripal_get_field_formatters() {
     foreach ($field_files as $file) {
       $field_type = $file->name;
       module_load_include('inc', $module, 'includes/TripalFields/' . $field_type);
-      if (class_exists($field_type) and is_subclass_of($field_type) == 'TripalFieldFormatter') {
+      if (class_exists($field_type) and is_subclass_of($field_type, 'TripalFieldFormatter')) {
         $formatters[] = $field_type;
       }
     }

+ 1 - 1
tripal/includes/TripalField.inc

@@ -19,7 +19,7 @@ class TripalField {
   public static $term = 'schema:Thing';
 
   // The default lable for this field.
-  public static $label = 'Tripal Field.';
+  public static $label = 'Tripal Field';
 
   // The default description for this field.
   public static $description = 'The generic base class for all Tripal fields. ' .

+ 2 - 2
tripal_chado/includes/TripalFields.old/chado_base__dbxref_id.inc

@@ -5,8 +5,8 @@ class chado_base__dbxref_id extends TripalField {
   public static $default_label = 'Accession';
 
   // The default description for this field.
-  public static $default_description = 'This field specifies the unique stable accession (ID) for
-        this record. It requires that this site have a database entry.';
+  public static $default_description = 'The unique stable accession (ID) for
+        this record on this site.';
 
   // Add any default settings elements.  If you override the globalSettingsForm()
   // or the instanceSettingsForm() functions then you need to be sure that

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

@@ -0,0 +1,149 @@
+<?php
+
+class data__accession extends TripalField {
+
+
+  // --------------------------------------------------------------------------
+  //                     EDITABLE STATIC CONSTANTS
+  //
+  // The following constants SHOULD be set for each descendent class.  They are
+  // used by the static functions to provide information to Drupal about
+  // the field and it's default widget and formatter.
+  // --------------------------------------------------------------------------
+
+  // The term that this field maps to.  The format for the term should be:
+  // [vocab]:[accession] where [vocab] is the short name of the vocabulary
+  // and [acession] is the unique accession number for the term.  This term
+  // must already exist in the vocabulary storage backend. This
+  // value should never be changed once fields exist for this type.
+  public static $term = 'data:2091';
+
+  // The default lable for this field.
+  public static $label = 'Accession';
+
+  // The default description for this field.
+  public static $description = 'The unique stable accession (ID) for
+        this record on this site.';
+
+  // Provide a list of global settings. These can be accessed witihn the
+  // globalSettingsForm.  When the globalSettingsForm is submitted then
+  // Drupal will automatically change these settings for all fields.
+  public static $settings = array(
+    'chado_table' => '',
+    'chado_column' => '',
+    'base_table' => '',
+    'semantic_web' => '',
+  );
+
+  // Provide a list of instance specific settings. These can be access within
+  // the instanceSettingsForm.  When the instanceSettingsForm is submitted
+  // then Drupal with automatically change these settings for the instnace.
+  // It is recommended to put settings at the instance level whenever possible.
+  public static $instance_settings  = array();
+
+  // Set this to the name of the storage backend that by default will support
+  // this field.
+  public static $storage = 'field_chado_storage';
+
+  // The default widget for this field.
+  public static $default_widget = 'data__accession_widget';
+
+  // The default formatter for this field.
+  public static $default_formatter = 'data__accession_formatter';
+
+  /**
+   * @see TripalField::load()
+   */
+  public function load($entity, $details = array()) {
+
+    $record = $details['record'];
+
+    $field_name = $this->field['field_name'];
+    $field_type = $this->field['type'];
+    $field_table = $this->field['settings']['chado_table'];
+    $field_column = $this->field['settings']['chado_column'];
+
+
+    // Set some defauls for the empty record
+    $entity->{$field_name}['und'][0] = array(
+      'value' => array(
+        'vocabulary' => '',
+        'accession' => '',
+        'URL' => '',
+      ),
+      'chado-' . $field_table . '__' . $field_column => '',
+      'db_id' => '',
+      'accession' => '',
+      'version' => '',
+      'description' => '',
+    );
+
+    // Get the primary dbxref record (if it's not NULL).  Because we have a
+    // dbxref_id passed in by the base record, we will only have one record.
+    if ($record->$field_column) {
+      $dbxref = $record->$field_column;
+      $value = $dbxref->db_id->name . ':' . $dbxref->accession;
+      $entity->{$field_name}['und'][0] = array(
+        'value' => array(
+          'vocabulary' => $dbxref->db_id->name,
+          'accession' => $dbxref->accession,
+          'URL' => tripal_get_dbxref_url($dbxref),
+        ),
+        'chado-' . $field_table . '__' . $field_column => $record->$field_column->$field_column,
+        'db_id'       => $dbxref->db_id->db_id,
+        'accession'   => $dbxref->accession,
+        'version'     => $dbxref->version,
+        'description' => $dbxref->description,
+      );
+    }
+  }
+
+  /**
+   * @see TripalField::validate()
+   */
+  public function validate($entity_type, $entity, $field, $items, &$errors) {
+
+    $field_name = $this->field['field_name'];
+    $settings = $this->field['settings'];
+    $field_name = $this->field['field_name'];
+    $field_type = $this->field['type'];
+    $field_table = $this->field['settings']['chado_table'];
+    $field_column = $this->field['settings']['chado_column'];
+
+    // Get the field values.
+    foreach ($items as $delta => $values) {
+      $fk_val = $values['chado-' . $field_table . '__' . $field_column];
+      $db_id = $values['db_id'];
+      $accession = $values['accession'];
+      $version = $values['version'];
+      $description = $values['description'];
+
+      // Make sure that if a database ID is provided that an accession is also
+      // provided.  Here we use the form_set_error function rather than the
+      // form_error function because the form_error will add a red_highlight
+      // around all of the fields in the fieldset which is confusing as it's not
+      // clear to the user what field is required and which isn't. Therefore,
+      // we borrow the code from the 'form_error' function and append the field
+      // so that the proper field is highlighted on error.
+      if (!$db_id and $accession) {
+        $errors[$field_name][$delta]['und'][] = array(
+          'message' => t("A database and the accession must both be provided for the primary cross reference."),
+          'error' => 'chado_base__dbxref',
+        );
+      }
+      if ($db_id and !$accession) {
+        $errors[$field_name][$delta]['und'][] = array(
+          'message' => t("A database and the accession must both be provided for the primary cross reference."),
+          'error' => 'chado_base__dbxref',
+        );
+      }
+      if (!$db_id and !$accession and ($version or $description)) {
+        $errors[$field_name][$delta]['und'][] = array(
+          'message' => t("A database and the accession must both be provided for the primary cross reference."),
+          'error' => 'chado_base__dbxref',
+        );
+      }
+    }
+  }
+
+}

+ 28 - 0
tripal_chado/includes/TripalFields/data__accession_formatter.inc

@@ -0,0 +1,28 @@
+<?php
+
+class data__accession_formatter extends TripalFieldFormatter {
+  // The default lable for this field.
+  public static $label = 'Accession';
+
+  // The list of field types for which this formatter is appropriate.
+  public static $field_types = array('data__accession');
+
+  // The list of default settings for this formatter.
+  public static $settings = array();
+
+  /**
+   * @see TripalFieldFormatter::view()
+   */
+  public function view(&$element, $entity_type, $entity, $langcode, $items, $display) {
+
+    foreach ($items as $delta => $item) {
+      if ($item['value']) {
+        $content = $item['value']['vocabulary'] . ':' . $item['value']['accession'];
+        $element[$delta] = array(
+          '#type' => 'markup',
+          '#markup' => $content,
+        );
+      }
+    }
+  }
+}

+ 227 - 0
tripal_chado/includes/TripalFields/data__accession_widget.inc

@@ -0,0 +1,227 @@
+<?php
+class data__accession_widget extends TripalFieldWidget {
+  // The default lable for this field.
+  public static $label = 'Accession';
+
+  // The list of field types for which this formatter is appropriate.
+  public static $field_types = array('data__accession');
+
+  /**
+   * @see TripalFieldWidget::form()
+   */
+  public function form(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) {
+    parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element);
+
+    $field_name = $this->field['field_name'];
+    $field_type = $this->field['type'];
+    $field_table = $this->field['settings']['chado_table'];
+    $field_column = $this->field['settings']['chado_column'];
+
+    // Get the field defaults.
+    $fk_val = '';
+    $db_id = '';
+    $accession = '';
+    $version = '';
+    $description = '';
+
+    // If the field already has a value then it will come through the $items
+    // array.  This happens when editing an existing record.
+    if (count($items) > 0 and array_key_exists($delta, $items)) {
+      $fk_val = $items[$delta]['chado-' . $field_table . '__' . $field_column];
+      $db_id = $items[$delta]['db_id'];
+      $accession = $items[$delta]['accession'];
+      $version = $items[$delta]['version'];
+      $description = $items[$delta]['description'];
+    }
+
+    // Check $form_state['values'] to see if an AJAX call set the values.
+    if (array_key_exists('values', $form_state)) {
+      $fk_val = isset($form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__' . $field_column]) ? $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__' . $field_column] : '';
+      $db_id = isset($form_state['values'][$field_name]['und'][$delta]['db_id']) ? $form_state['values'][$field_name]['und'][$delta]['db_id'] : '';
+      $accession = isset($form_state['values'][$field_name]['und'][$delta]['accession']) ? $form_state['values'][$field_name]['und'][$delta]['accession'] : '';
+      $version = isset($form_state['values'][$field_name]['und'][$delta]['version']) ? $form_state['values'][$field_name]['und'][$delta]['version'] : '';
+      $description = isset($form_state['values'][$field_name]['und'][$delta]['description']) ? $form_state['values'][$field_name]['und'][$delta]['description'] : '';
+    }
+
+    $schema = chado_get_schema('dbxref');
+    $options = tripal_get_db_select_options();
+
+    //$widget['#element_validate'] = array('chado_base__dbxref_id_widget_validate');
+    $widget['#theme'] = 'data__accession_widget';
+    $widget['#prefix'] =  "<span id='$field_name-dbxref--db-id'>";
+    $widget['#suffix'] =  "</span>";
+
+    // A temporary element used for theming the fieldset.
+    $widget['#theme_settings'] = array(
+      '#title' => $element['#title'],
+      '#description' =>  $element['#description'],
+      '#weight' => isset($element['#weight']) ? $element['#weight'] : 0,
+      '#theme' => 'data__accession_widget',
+      //'#collapsible' => TRUE,
+      //'#collapsed' => $collapsed,
+    );
+
+    $widget['value'] = array(
+      '#type' => 'value',
+      '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
+    );
+
+    $widget['chado-' . $field_table . '__' . $field_column] = array(
+      '#type' => 'value',
+      '#default_value' => $fk_val,
+    );
+
+    $widget['db_id'] = array(
+      '#type' => 'select',
+      '#title' => t('Database'),
+      '#options' => $options,
+      '#required' => $element['#required'],
+      '#default_value' => $db_id,
+      '#ajax' => array(
+        'callback' => "data__accession_widget_form_ajax_callback",
+        'wrapper' => "$field_name-dbxref--db-id",
+        'effect' => 'fade',
+        'method' => 'replace'
+      ),
+    );
+    $widget['accession'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Accession'),
+      '#default_value' => $accession,
+      '#required' => $element['#required'],
+      '#maxlength' => array_key_exists('length', $schema['fields']['accession']) ? $schema['fields']['accession']['length'] : 255,
+      '#size' => 15,
+      '#autocomplete_path' => 'admin/tripal/storage/chado/auto_name/dbxref/' . $db_id,
+      '#ajax' => array(
+        'callback' => "tripal_chado_dbxref_widget_form_ajax_callback",
+        'wrapper' => "$field_name-dbxref--db-id",
+        'effect' => 'fade',
+        'method' => 'replace'
+      ),
+      '#disabled' => $db_id ? FALSE : TRUE,
+    );
+    $widget['version'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Version'),
+      '#default_value' => $version,
+      '#maxlength' => array_key_exists('length', $schema['fields']['version']) ? $schema['fields']['version']['length'] : 255,
+      '#size' => 5,
+      '#disabled' => $db_id ? FALSE : TRUE,
+    );
+    $widget['description'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Description'),
+      '#default_value' => $description,
+      '#size' => 20,
+      '#disabled' => $db_id ? FALSE : TRUE,
+    );
+    $widget['links'] = array(
+      '#type' => 'item',
+      '#markup' => l('Add a new database', 'admin/tripal/legacy/tripal_db/add', array('attributes' => array('target' => '_blank')))
+    );
+  }
+
+  /**
+   * @see TripalFieldWidget::submit()
+   */
+  public function submit($form, &$form_state, $entity_type, $entity, $langcode, $delta) {
+    $field_name = $this->field['field_name'];
+    $settings = $this->field['settings'];
+    $field_name = $this->field['field_name'];
+    $field_type = $this->field['type'];
+    $field_table = $this->field['settings']['chado_table'];
+    $field_column = $this->field['settings']['chado_column'];
+
+    $fk_val = isset($form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__' . $field_column]) ? $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__' . $field_column] : '';
+    $db_id = isset($form_state['values'][$field_name][$langcode][$delta]['db_id']) ? $form_state['values'][$field_name][$langcode][$delta]['db_id'] : '';
+    $accession = isset($form_state['values'][$field_name][$langcode][$delta]['accession']) ? $form_state['values'][$field_name][$langcode][$delta]['accession'] : '';
+    $version = isset($form_state['values'][$field_name][$langcode][$delta]['version']) ? $form_state['values'][$field_name][$langcode][$delta]['version'] : '';
+
+    // If user did not select a database, we want to remove dbxref_id from the
+    // field.
+    if (!$db_id) {
+      $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__dbxref_id'] = '__NULL__';
+    }
+    // If the dbxref_id does not match the db_id + accession then the user
+    // has selected a new dbxref record and we need to update the hidden
+    // value accordingly.
+    if ($db_id and $accession) {
+      $dbxref = chado_generate_var('dbxref', array('db_id' => $db_id, 'accession' => $accession));
+      if ($dbxref and $dbxref->dbxref_id != $fk_val) {
+        $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__dbxref_id'] = $dbxref->dbxref_id;
+      }
+    }
+  }
+}
+
+/**
+ * An Ajax callback for the tripal_chado_admin_publish_form..
+ */
+function data__accession_widget_form_ajax_callback($form, $form_state) {
+  $field_name = $form_state['triggering_element']['#parents'][0];
+  $field = field_info_field($field_name);
+  $field_type = $field['type'];
+  $field_table = $field['settings']['chado_table'];
+  $field_column = $field['settings']['chado_column'];
+  $field_prefix = 'chado-' . $field_table . '__' . $field_column;
+
+  //   $db_id = tripal_chado_get_field_form_values($field_name, $form_state, 0, $field_prefix . '--db_id');
+  //   $accession = tripal_chado_get_field_form_values($field_name, $form_state, 0, $field_prefix . '--accession');
+  if ($db_id and $accession) {
+    $values = array(
+      'db_id' => $db_id,
+      'accession' => $accession,
+    );
+    $options = array('is_duplicate' => TRUE);
+    $has_duplicate = chado_select_record('dbxref', array('*'), $values, $options);
+    if (!$has_duplicate) {
+      drupal_set_message('The selected cross reference is new and will be added for future auto completions.', 'warning');
+    }
+  }
+
+  return $form[$field_name];
+}
+
+function theme_data__accession_widget($variables) {
+  $element = $variables['element'];
+  $field_name = $element['#field_name'];
+  $field = field_info_field($field_name);
+  $field_type = $field['type'];
+  $field_table = $field['settings']['chado_table'];
+  $field_column = $field['settings']['chado_column'];
+  $field_prefix = 'chado-' . $field_table . '__' . $field_column;
+
+  $layout = "
+      <div class=\"primary-dbxref-widget\">
+        <div class=\"primary-dbxref-widget-item\">" .
+        drupal_render($element['db_id']) . "
+        </div>
+        <div class=\"primary-dbxref-widget-item\">" .
+        drupal_render($element['accession']) . "
+        </div>
+        <div class=\"primary-dbxref-widget-item\">" .
+        drupal_render($element['version']) . "
+        </div>
+        <div class=\"primary-dbxref-widget-item\">" .
+        drupal_render($element['description']) . "
+        </div>
+        <div class=\"primary-dbxref-widget-links\">" . drupal_render($element['links']) . "</div>
+      </div>
+    ";
+
+  //   $classes = array();
+  //   $classes[] = 'collapsible';
+  //   $theme_settings = $element['#theme_settings'];
+  //   if ($theme_settings['#collapsed'] == FALSE) {
+  //     $classes[] = 'collapsed';
+  //   }
+  $fieldset = array(
+    '#title' => $element['#title'],
+    '#value' => '',
+    '#description' => $element['#description'],
+    '#children' => $layout,
+    //    '#attributes' => array('class' => $classes),
+  );
+
+  return theme('fieldset', array('element' => $fieldset));
+}

+ 6 - 6
tripal_chado/includes/tripal_chado.fields.inc

@@ -237,12 +237,11 @@ function tripal_chado_bundle_create_fields_custom(&$info, $details, $entity_type
       ),
     );
   }
-  return;
 
   // BASE DBXREF
   if (array_key_exists('dbxref_id', $schema['fields'])) {
-    $field_name = $table_name . '__dbxref_id';
-    $field_type = 'chado_base__dbxref_id';
+    $field_name = $bundle->name . '_data__accession';
+    $field_type = 'data__accession';
     $info[$field_name] = array(
       'field_name' => $field_name,
       'type' => $field_type,
@@ -258,7 +257,7 @@ function tripal_chado_bundle_create_fields_custom(&$info, $details, $entity_type
       ),
     );
   }
-
+  return;
 
 
   // FEATURE MD5CHECKSUM
@@ -920,11 +919,10 @@ function tripal_chado_bundle_create_instances_custom(&$info, $entity_type, $bund
       ),
     );
   }
-  return;
 
   // BASE DBXREF
   if (array_key_exists('dbxref_id', $schema['fields'])) {
-    $field_name = $table_name . '__dbxref_id';
+    $field_name = $bundle->name . '_data__accession';
     $info[$field_name] = array(
       'field_name' => $field_name,
       'entity_type' => $entity_type,
@@ -951,6 +949,8 @@ function tripal_chado_bundle_create_instances_custom(&$info, $entity_type, $bund
       ),
     );
   }
+  return;
+
 
   // FEATURE MD5CHECKSUM
   if ($table_name == 'feature') {

+ 4 - 4
tripal_chado/tripal_chado.module

@@ -586,10 +586,10 @@ function tripal_chado_theme($existing, $type, $theme, $path) {
   $themes = array(
 
     // Theme fields.
-//     'chado_base__dbxref_id_widget' => array(
-//       'render element' => 'element',
-//       'file' => 'includes/TripalFields/chado_base__dbxref_id.inc',
-//     ),
+     'data__accession_widget' => array(
+       'render element' => 'element',
+       'file' => 'includes/TripalFields/data__accession_widget.inc',
+     ),
 //     'chado_linker__dbxref_widget' => array(
 //       'render element' => 'element',
 //       'file' => 'includes/TripalFields/chado_linker__dbxref.inc',