Browse Source

Nightly commit... still working on field values and saving to Chado

Stephen Ficklin 9 years ago
parent
commit
eca8d53f70

+ 102 - 58
tripal_chado/includes/fields/chado_base__dbxref_id.inc

@@ -6,10 +6,9 @@ class chado_base__dbxref_id extends TripalField {
    */
   function field_info() {
     return array(
-      'label' => t('Cross reference'),
-      'description' => t('This record can be cross referenced with a record in
-        another online database. This field is intended for the most prominent
-        reference.  At a minimum, the database and accession must be provided.'),
+      'label' => t('Accession'),
+      'description' => t('This field specifies the unique stable accession (ID) for
+        this record. It requires that this site have a database entry.'),
       'default_widget' => 'chado_base__dbxref_id_widget',
       'default_formatter' => 'chado_base__dbxref_id_formatter',
       'settings' => array(),
@@ -45,12 +44,9 @@ class chado_base__dbxref_id extends TripalField {
       'field_name' => $table_name . '__dbxref_id',
       'field_type' => 'chado_base__dbxref_id',
       'widget_type' => 'chado_base__dbxref_id_widget',
-      'description' => 'This record can be cross referenced with a ' .
-        'record in another online database. The primary reference is for the ' .
-        'most prominent reference.  At a minimum, the database and accession ' .
-        'must be provided.  To remove a set reference, change the database ' .
-        'field to "Select a Database".',
-      'label' => 'Cross Reference',
+      'description' => 'This field specifies the unique stable accession (ID) for
+        this record. It requires that this site have a database entry.',
+      'label' => 'Accession',
       'is_required' => 0,
       'storage' => 'field_chado_storage',
       'widget_settings' => array(
@@ -60,10 +56,10 @@ class chado_base__dbxref_id extends TripalField {
         'chado_table' => $table_name,
         'chado_column' => 'dbxref_id',
         'semantic_web' => array(
-          'name' => 'database cross reference',
-          'accession' => '0000554',
-          'ns' => 'SBO',
-          'nsurl' => 'http://www.ebi.ac.uk/sbo/main/',
+          'name' => 'Accession',
+          'accession' => '2091',
+          'ns' => 'data',
+          'nsurl' => ' http://edamontology.org/',
         ),
       ),
     );
@@ -76,12 +72,10 @@ class chado_base__dbxref_id extends TripalField {
    */
   function widget_info() {
     return array(
-      'label' => t('Cross reference'),
+      'label' => t('Accession'),
       'field types' => array('chado_base__dbxref_id'),
-      'description' => t('This record can be cross referenced with a record in
-          another online database. This field is intended for the most
-          prominent reference.  At a minimum, the database and accession
-          must be provided.'),
+      'description' => t('This field specifies the unique stable accession (ID) for
+        this record. It requires that this site have a database entry.'),
     );
   }
   /**
@@ -89,7 +83,7 @@ class chado_base__dbxref_id extends TripalField {
    */
   function formatter_info() {
     return array(
-      'label' => t('Database Cross Reference'),
+      'label' => t('Accession'),
       'field types' => array('chado_base__dbxref_id'),
       'settings' => array(
       ),
@@ -137,21 +131,21 @@ class chado_base__dbxref_id extends TripalField {
     // array.  This happens when editing an existing record.
     if (array_key_exists($delta, $items)) {
       $fk_val = $items[$delta][$field_table . '__' . $field_column];
-      $dbxref_id = $items[$delta]['dbxref__dbxref_id'];
-      $db_id = $items[$delta]['dbxref__db_id'];
-      $accession = $items[$delta]['dbxref__accession'];
-      $version = $items[$delta]['dbxref__version'];
-      $description = $items[$delta]['dbxref__description'];
+      $dbxref_id = $items[$delta][$field_table . '__' . $field_column . '--dbxref_id'];
+      $db_id = $items[$delta][$field_table . '__' . $field_column . '--db_id'];
+      $accession = $items[$delta][$field_table . '__' . $field_column . '--accession'];
+      $version = $items[$delta][$field_table . '__' . $field_column . '--version'];
+      $description = $items[$delta][$field_table . '__' . $field_column . '--description'];
     }
 
     // Check $form_state['values'] to see if an AJAX call set the values.
     if (array_key_exists('values', $form_state)) {
       $fk_val = tripal_chado_get_field_form_values($field_name, $form_state, 0, $field_table . '__' . $field_column);
-      $dbxref_id = tripal_chado_get_field_form_values($field_name, $form_state, 0, 'dbxref__dbxref_id');
-      $db_id = tripal_chado_get_field_form_values($field_name, $form_state, 0, "dbxref__db_id");
-      $accession = tripal_chado_get_field_form_values($field_name, $form_state, 0, "dbxref__accession");
-      $version = tripal_chado_get_field_form_values($field_name, $form_state, 0, "dbxref__version");
-      $description = tripal_chado_get_field_form_values($field_name, $form_state, 0, "dbxref__description");
+      $dbxref_id = tripal_chado_get_field_form_values($field_name, $form_state, 0, $field_table . '__' . $field_column . '--dbxref_id');
+      $db_id = tripal_chado_get_field_form_values($field_name, $form_state, 0, $field_table . '__' . $field_column . '--db_id');
+      $accession = tripal_chado_get_field_form_values($field_name, $form_state, 0, $field_table . '__' . $field_column . '--accession');
+      $version = tripal_chado_get_field_form_values($field_name, $form_state, 0, $field_table . '__' . $field_column . '--version');
+      $description = tripal_chado_get_field_form_values($field_name, $form_state, 0, $field_table . '__' . $field_column . '--description');
     }
 
     // If we are here because our parent was triggered in a form submit
@@ -194,12 +188,12 @@ class chado_base__dbxref_id extends TripalField {
       '#default_value' => $fk_val,
     );
 
-    $widget['dbxref__dbxref_id'] = array(
+    $widget[$field_table . '__' . $field_column . '--dbxref_id'] = array(
       '#type' => 'value',
       '#default_value' => $dbxref_id,
     );
 
-    $widget['dbxref__db_id'] = array(
+    $widget[$field_table . '__' . $field_column . '--db_id'] = array(
       '#type' => 'select',
       '#title' => t('Database'),
       '#options' => $options,
@@ -212,7 +206,7 @@ class chado_base__dbxref_id extends TripalField {
         'method' => 'replace'
       ),
     );
-    $widget['dbxref__accession'] = array(
+    $widget[$field_table . '__' . $field_column . '--accession'] = array(
       '#type' => 'textfield',
       '#title' => t('Accession'),
       '#default_value' => $accession,
@@ -228,7 +222,7 @@ class chado_base__dbxref_id extends TripalField {
       ),
       '#disabled' => $db_id ? FALSE : TRUE,
     );
-    $widget['dbxref__version'] = array(
+    $widget[$field_table . '__' . $field_column . '--version'] = array(
       '#type' => 'textfield',
       '#title' => t('Version'),
       '#default_value' => $version,
@@ -236,17 +230,17 @@ class chado_base__dbxref_id extends TripalField {
       '#size' => 5,
       '#disabled' => $db_id ? FALSE : TRUE,
     );
-    $widget['dbxref__description'] = array(
+    $widget[$field_table . '__' . $field_column . '--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/chado/tripal_db/add', array('attributes' => array('target' => '_blank')))
-//     );
+    $widget['links'] = array(
+      '#type' => 'item',
+      '#markup' => l('Add a new database', 'admin/tripal/chado/tripal_db/add', array('attributes' => array('target' => '_blank')))
+    );
   }
 
   /**
@@ -290,11 +284,11 @@ class chado_base__dbxref_id extends TripalField {
           'URL' => $URL,
         ),
         $field_table . '__' . $field_column => $record->$field_column->$field_column,
-        'dbxref__dbxref_id' => $dbxref->dbxref_id,
-        'dbxref__db_id' => $dbxref->db_id->db_id,
-        'dbxref__accession' => $dbxref->accession,
-        'dbxref__version' => $dbxref->version,
-        'dbxref__description' => $dbxref->description,
+        $field_table . '__' . $field_column . '--dbxref_id'   => $dbxref->dbxref_id,
+        $field_table . '__' . $field_column . '--db_id'       => $dbxref->db_id->db_id,
+        $field_table . '__' . $field_column . '--accession'   => $dbxref->accession,
+        $field_table . '__' . $field_column . '--version'     => $dbxref->version,
+        $field_table . '__' . $field_column . '--description' => $dbxref->description,
       );
     }
   }
@@ -311,6 +305,8 @@ function chado_base__dbxref_id_widget_validate($element, &$form_state) {
   $field_type = $field['type'];
   $field_table = $field['settings']['chado_table'];
   $field_column = $field['settings']['chado_column'];
+  $field_prefix = $field_table . '__' . $field_column;
+
 
   // If the form ID is field_ui_field_edit_form, then the user is editing the
   // field's values in the manage fields form of Drupal.  We don't want
@@ -321,11 +317,11 @@ function chado_base__dbxref_id_widget_validate($element, &$form_state) {
 
   // Get the field values.
   $fk_value = tripal_chado_get_field_form_values($field_name, $form_state, 0, $field_table . '__' . $field_column);
-  $dbxref_id = tripal_chado_get_field_form_values($field_name, $form_state, 0, 'dbxref__dbxref_id');
-  $db_id = tripal_chado_get_field_form_values($field_name, $form_state, 0, "dbxref__db_id");
-  $accession = tripal_chado_get_field_form_values($field_name, $form_state, 0, "dbxref__accession");
-  $version = tripal_chado_get_field_form_values($field_name, $form_state, 0, "dbxref__version");
-  $description = tripal_chado_get_field_form_values($field_name, $form_state, 0, "dbxref__description");
+  $dbxref_id = tripal_chado_get_field_form_values($field_name, $form_state, 0, $field_prefix . '--dbxref_id');
+  $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');
+  $version = tripal_chado_get_field_form_values($field_name, $form_state, 0, $field_prefix . '--version');
+  $description = tripal_chado_get_field_form_values($field_name, $form_state, 0, $field_prefix . '--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
@@ -335,19 +331,19 @@ function chado_base__dbxref_id_widget_validate($element, &$form_state) {
   // 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) {
-    form_set_error(implode('][', $element ['#parents']) . '][dbxref__db_id', t("A database and the accession must both be provided for the primary cross reference."));
+    form_set_error(implode('][', $element ['#parents']) . '][' . $field_prefix . '--db_id', t("A database and the accession must both be provided for the primary cross reference."));
   }
   if ($db_id and !$accession) {
-    form_set_error(implode('][', $element ['#parents']) . '][dbxref__accession', t("A database and the accession must both be provided for the primary cross reference."));
+    form_set_error(implode('][', $element ['#parents']) . '][' . $field_prefix . '--accession', t("A database and the accession must both be provided for the primary cross reference."));
   }
   if (!$db_id and !$accession and ($version or $description)) {
-    form_set_error(implode('][', $element ['#parents']) . '][dbxref__db_id', t("A database and the accession must both be provided for the primary cross reference."));
+    form_set_error(implode('][', $element ['#parents']) . '][' . $field_prefix . '--db_id', t("A database and the accession must both be provided for the primary cross reference."));
   }
 
   // If user did not select a database, we want to remove dbxref_id from the
   // field.
   if (!$db_id) {
-    tripal_chado_set_field_form_values($field_name, $form_state, '__NULL__', 0, 'dbxref__dbxref_id');
+    tripal_chado_set_field_form_values($field_name, $form_state, '__NULL__', 0, $field_prefix . '--dbxref_id');
     tripal_chado_set_field_form_values($field_name, $form_state, '__NULL__', 0, $field_table . '__' . $field_column);
   }
   // If the dbxref_id does not match the db_id + accession then the user
@@ -357,7 +353,7 @@ function chado_base__dbxref_id_widget_validate($element, &$form_state) {
     $dbxref = chado_generate_var('dbxref', array('db_id' => $db_id, 'accession' => $accession));
     if ($dbxref and $dbxref->dbxref_id != $dbxref_id) {
       tripal_chado_set_field_form_values($field_name, $form_state, $dbxref->dbxref_id, 0, $field_table . '__' . $field_column);
-      tripal_chado_set_field_form_values($field_name, $form_state, $dbxref->dbxref_id, 0, 'dbxref__dbxref_id');
+      tripal_chado_set_field_form_values($field_name, $form_state, $dbxref->dbxref_id, 0, $field_prefix . '--dbxref_id');
     }
   }
 }
@@ -367,8 +363,14 @@ function chado_base__dbxref_id_widget_validate($element, &$form_state) {
  */
 function chado_base__dbxref_id_widget_form_ajax_callback($form, $form_state) {
   $field_name = $form_state['triggering_element']['#parents'][0];
-  $db_id = tripal_chado_get_field_form_values($field_name, $form_state, 0, 'dbxref__db_id');
-  $accession = tripal_chado_get_field_form_values($field_name, $form_state, 0, 'dbxref__accession');
+  $field = field_info_field($field_name);
+  $field_type = $field['type'];
+  $field_table = $field['settings']['chado_table'];
+  $field_column = $field['settings']['chado_column'];
+  $field_prefix = $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,
@@ -377,11 +379,53 @@ function chado_base__dbxref_id_widget_form_ajax_callback($form, $form_state) {
     $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.');
+      drupal_set_message('The selected cross reference is new and will be added for future auto completions.', 'warning');
     }
   }
 
   return $form[$field_name];
 }
 
-
+function theme_chado_base__dbxref_id_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 = $field_table . '__' . $field_column;
+
+  $layout = "
+      <div class=\"primary-dbxref-widget\">
+        <div class=\"primary-dbxref-widget-item\">" .
+        drupal_render($element[$field_prefix . '--db_id']) . "
+        </div>
+        <div class=\"primary-dbxref-widget-item\">" .
+        drupal_render($element[$field_prefix . '--accession']) . "
+        </div>
+        <div class=\"primary-dbxref-widget-item\">" .
+        drupal_render($element[$field_prefix . '--version']) . "
+        </div>
+        <div class=\"primary-dbxref-widget-item\">" .
+        drupal_render($element[$field_prefix . '--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));
+}

+ 1 - 1
tripal_chado/includes/fields/chado_base__organism_id.inc

@@ -133,7 +133,7 @@ class chado_base__organism_id extends TripalField {
 
     $widget['value'] = array(
       '#type' => 'value',
-      '#value' => $items[0]['value'],
+      '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
     );
     $options = tripal_get_organism_select_options(FALSE);
     $widget[$field_table . '__organism_id'] = array(

+ 76 - 320
tripal_chado/includes/fields/chado_linker__dbxref.inc

@@ -44,46 +44,29 @@ class chado_linker__dbxref extends TripalField {
     $cv_id      = $settings['cv_id'];
     $cvterm_id  = $settings['cvterm_id'];
 
-    // If the base table has a 'dbxref_id' then we want to attach
-    $attach = FALSE;
-    $cardinality = 1;
-    $field_name = $table_name . '__dbxref_id';
-    $chado_table = $table_name;
-    $chado_column = 'dbxref_id';
-    $schema = chado_get_schema($table_name);
-    if (array_key_exists('dbxref_id', $schema['fields'])){
-      $attach = TRUE;
-    }
-
-    // If the linker table exists then we want to attach.
+    // If the linker table does not exists then we don't want to add attach.
     $dbxref_table = $table_name . '_dbxref';
     if (chado_table_exists($dbxref_table)) {
+
+      // We already have a dbxref_id field.
       $schema = chado_get_schema($dbxref_table);
       $pkey = $schema['primary key'][0];
-      $attach = TRUE;
-      $field_name = $dbxref_table;
-      $cardinality = FIELD_CARDINALITY_UNLIMITED;
-      $chado_table = $dbxref_table;
-      $chado_column = $pkey;
-    }
 
-    if ($attach) {
       // Initialize the field array.
       $field_info = array(
-        'field_name' => $field_name,
+        'field_name' => $dbxref_table,
         'field_type' => 'chado_linker__dbxref',
         'widget_type' => 'chado_linker__dbxref_widget',
-        'widget_settings' => array(
-          'display_label' => 1
-        ),
-        'description' => '',
+        'widget_settings' => array('display_label' => 1),
+        'description' => 'This field specifies the IDs where this
+           record may be available in other external online databases.',
         'label' => 'Cross References',
         'is_required' => 0,
-        'cardinality' => $cardinality,
+        'cardinality' => FIELD_CARDINALITY_UNLIMITED,
         'storage' => 'field_chado_storage',
         'field_settings' => array(
-          'chado_table' => $chado_table,
-          'chado_column' => $chado_column,
+          'chado_table' => $dbxref_table,
+          'chado_column' => $pkey,
           'base_table' => $table_name,
           'semantic_web' => array(
             'name' => 'database cross reference',
@@ -93,6 +76,7 @@ class chado_linker__dbxref extends TripalField {
           ),
         ),
       );
+
     }
 
     return $field_info;
@@ -127,188 +111,27 @@ class chado_linker__dbxref extends TripalField {
   function formatter_view(&$element, $entity_type, $entity, $field,
       $instance, $langcode, $items, $display) {
 
-    dpm($items);
+    $chado_table = $field['settings']['chado_table'];
     foreach ($items as $delta => $item) {
-      if ($item['value']) {
-        $content = $item['value']['namespace'] . ':' . $item['value']['accession'];
-        if ($item['value']['URL']) {
-          $content = l($item['value']['URL'], $item['value']['URL']);
+      $accession = '';
+      if ($item[$chado_table . '__dbxref_id']) {
+        $dbxref = chado_generate_var('dbxref', array('dbxref_id' => $item[$chado_table . '__dbxref_id']));
+        $accession = $dbxref->db_id->name . ':' . $dbxref->accession;
+        if ($dbxref->db_id->urlprefix) {
+          $accession = l($accession, $dbxref->db_id->urlprefix . '/' . $dbxref->accession, array('attributes' => array('target' => '_blank')));
         }
-        $element[$delta] = array(
-          '#type' => 'markup',
-          '#markup' => $content,
-        );
       }
+      $element[$delta] = array(
+        '#type' => 'markup',
+        '#markup' => $accession,
+      );
     }
   }
 
-  function widget_form(&$widget, $form, $form_state, $field, $instance,
-      $langcode, $items, $delta, $element) {
-
-    $field_name = $field['field_name'];
-    $field_type = $field['type'];
-    $field_table = $field['settings']['chado_table'];
-    $field_column = $field['settings']['chado_column'];
-    dpm($items[$delta]);
-
-    $record = $element['#entity']->chado_record;
-    $base_table = $record->tablename;
-
-    // The first form element should be for the local dbxref record.
-    if (property_exists($record, 'dbxref_id') and $delta == 0) {
-      $this->base_widget_form($widget, $form, $form_state, $field, $instance,
-          $langcode, $items, $delta, $element);
-    }
-    else {
-      // The remainindg form elements should be for the linking dbxref table.
-      $this->linker_widget_form($widget, $form, $form_state, $field, $instance,
-          $langcode, $items, $delta, $element);
-    }
-  }
-
-  /**
-   * @see TripalField::widget_form()
-   */
-  private function base_widget_form(&$widget, $form, $form_state, $field, $instance, $langcode, $items, $delta, $element) {
-    $field_name = $field['field_name'];
-    $field_type = $field['type'];
-    $base_table = $element['#entity']->chado_record->tablename;
-    $field_table = $base_table;
-    $field_column = 'dbxref_id';
-
-    // Get the field defaults.
-    $fk_val = '';
-    $dbxref_id = '';
-    $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 (array_key_exists($delta, $items)) {
-      $fk_val = $items[$delta][$field_table .'__' .$field_column];
-      $dbxref_id = $items[$delta]['dbxref__dbxref_id'];
-      $db_id = $items[$delta]['dbxref__db_id'];
-      $accession = $items[$delta]['dbxref__accession'];
-      $version = $items[$delta]['dbxref__version'];
-      $description = $items[$delta]['dbxref__description'];
-    }
-
-    // Check $form_state['values'] to see if an AJAX call set the values.
-    if (array_key_exists('values', $form_state)) {
-      $fk_val = tripal_chado_get_field_form_values($field_name, $form_state, 0, $field_table .'__' .$field_column);
-      $dbxref_id = tripal_chado_get_field_form_values($field_name, $form_state, 0, 'dbxref__dbxref_id');
-      $db_id = tripal_chado_get_field_form_values($field_name, $form_state, 0, "dbxref__db_id");
-      $accession = tripal_chado_get_field_form_values($field_name, $form_state, 0, "dbxref__accession");
-      $version = tripal_chado_get_field_form_values($field_name, $form_state, 0, "dbxref__version");
-      $description = tripal_chado_get_field_form_values($field_name, $form_state, 0, "dbxref__description");
-    }
-
-    // If we are here because our parent was triggered in a form submit
-    // then that means an ajax call was made and we don't want the fieldset to
-    // be closed when it returns from the ajax call.
-    // $collapsed = TRUE;
-    // if (array_key_exists('triggering_element', $form_state) and
-    // $form_state['triggering_element']['#parents'][0] == $field_name) {
-    // $collapsed = FALSE;
-    // }
-    // if ($dbxref_id) {
-    // $collapsed = FALSE;
-    // }
-
-    $schema = chado_get_schema('dbxref');
-    $options = tripal_get_db_select_options();
-
-    $widget['#element_validate'] = array('chado_base__dbxref_id_widget_validate');
-    $widget['#theme'] = 'chado_base__dbxref_id_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' => 'chado_base__dbxref_id_widget'
-      // '#collapsible' => TRUE,
-      // '#collapsed' => $collapsed,
-    );
-
-    $widget['value'] = array(
-      '#type' => 'value',
-      '#value' => $items[0]['value']
-    );
-
-    $widget[$field_table .'__' .$field_column] = array(
-      '#type' => 'value',
-      '#default_value' => $fk_val
-
-    );
-
-    $widget['dbxref__dbxref_id'] = array(
-      '#type' => 'value',
-      '#default_value' => $dbxref_id
-
-    );
-
-    $widget['dbxref__db_id'] = array(
-      '#type' => 'select',
-      '#title' => t('Database'),
-      '#options' => $options,
-      '#required' => $element['#required'],
-      '#default_value' => $db_id,
-      '#ajax' => array(
-        'callback' => "chado_base__dbxref_id_widget_form_ajax_callback",
-        'wrapper' => "$field_name-dbxref--db-id",
-        'effect' => 'fade',
-        'method' => 'replace')
-
-    );
-    $widget['dbxref__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['dbxref__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['dbxref__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/chado/tripal_db/add', array('attributes' => array('target' => '_blank')))
-    // );
-  }
-
   /**
    * @see TripalField::widget_form()
    */
-  private function linker_widget_form(&$widget, $form, $form_state, $field, $instance,
+  function widget_form(&$widget, $form, $form_state, $field, $instance,
       $langcode, $items, $delta, $element) {
 
     $field_name = $field['field_name'];
@@ -336,24 +159,24 @@ class chado_linker__dbxref extends TripalField {
     // If the field already has a value then it will come through the $items
     // array.  This happens when editing an existing record.
     if (array_key_exists($delta, $items)) {
-      $record_id = $items[$delta]['value'];
-      $fkey_value = $items[$delta][$field_name . '__' . $fkey];
-      $dbxref_id = $items[$delta][$field_name . '__dbxref_id'];
-      $db_id = $items[$delta][$field_name . '--dbxref__db_id'];
-      $accession = $items[$delta][$field_name . '--dbxref__accession'];
-      $version = $items[$delta][$field_name . '--dbxref__version'];
-      $description = $items[$delta][$field_name . '--dbxref__description'];
+      $record_id = $items[$delta][$field_table . '__' . $pkey];
+      $fkey_value = $items[$delta][$field_table . '__' . $fkey];
+      $dbxref_id = $items[$delta][$field_table . '__dbxref_id'];
+      $db_id = $items[$delta][$field_table . '__dbxref_id--db_id'];
+      $accession = $items[$delta][$field_table . '__dbxref_id--accession'];
+      $version = $items[$delta][$field_table . '__dbxref_id--version'];
+      $description = $items[$delta][$field_table . '__dbxref_id--description'];
     }
 
     // Check $form_state['values'] to see if an AJAX call set the values.
     if (array_key_exists('values', $form_state) and array_key_exists($delta, $form_state['values'])) {
-      $record_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name);
-      $fkey_value = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '__' . $fkey);
-      $dbxref_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '__dbxref_id');
-      $db_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '--dbxref__db_id');
-      $accession = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '--dbxref__accession');
-      $version = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '--dbxref__version');
-      $description = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_name . '--dbxref__description');
+      $record_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_table . '__' . $pkey);
+      $fkey_value = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_table . '__' . $fkey);
+      $dbxref_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_table . '__dbxref_id');
+      $db_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_table . '__dbxref_id--db_id');
+      $accession = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_table . '__dbxref_id--accession');
+      $version = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_table . '__dbxref_id--version');
+      $description = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_table . '__dbxref_id--description');
     }
 
     $schema = chado_get_schema('dbxref');
@@ -369,26 +192,26 @@ class chado_linker__dbxref extends TripalField {
 
     $widget['value'] = array(
       '#type' => 'value',
-      '#value' => array_key_exists($delta, $items)? $items[$delta]['value'] : '',
+      '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
     );
 
     $widget[$field_table . '__' . $pkey] = array(
       '#type' => 'value',
       '#default_value' => $record_id,
     );
-    $widget[$field_table . '__dbxref_id'] = array(
-      '#type' => 'value',
-      '#default_value' => $dbxref_id,
-    );
     $widget[$field_table . '__' . $fkey] = array(
       '#type' => 'value',
       '#default_value' => $fkey_value,
     );
-    $widget[$field_table . '--dbxref__dbxref_id'] = array(
+    $widget[$field_table . '__dbxref_id'] = array(
       '#type' => 'value',
       '#default_value' => $dbxref_id,
     );
-    $widget[$field_table . '--dbxref__db_id'] = array(
+    $widget[$field_table . '__dbxref_id--dbxref_id'] = array(
+      '#type' => 'value',
+      '#default_value' => $dbxref_id,
+    );
+    $widget[$field_table . '__dbxref_id--db_id'] = array(
       '#type' => 'select',
       '#title' => t('Database'),
       '#options' => $options,
@@ -401,7 +224,7 @@ class chado_linker__dbxref extends TripalField {
         'method' => 'replace'
       ),
     );
-    $widget[$field_table . '--dbxref__accession'] = array(
+    $widget[$field_table . '__dbxref_id--accession'] = array(
       '#type' => 'textfield',
       '#title' => t('Accession'),
       '#default_value' => $accession,
@@ -417,7 +240,7 @@ class chado_linker__dbxref extends TripalField {
       ),
       '#disabled' => $db_id ? FALSE : TRUE,
     );
-    $widget[$field_table . '--dbxref__version'] = array(
+    $widget[$field_table . '__dbxref_id--version'] = array(
       '#type' => 'textfield',
       '#title' => t('Version'),
       '#default_value' => $version,
@@ -425,7 +248,7 @@ class chado_linker__dbxref extends TripalField {
       '#size' => 5,
       '#disabled' => $db_id ? FALSE : TRUE,
     );
-    $widget[$field_table . '--dbxref__description'] = array(
+    $widget[$field_table . '__dbxref_id--description'] = array(
       '#type' => 'textfield',
       '#title' => t('Description'),
       '#default_value' => $description,
@@ -453,72 +276,32 @@ class chado_linker__dbxref extends TripalField {
     $field_column = $field['settings']['chado_column'];
     $base_table = $record->tablename;
 
-    $num_dbxrefs = 0;
-
-    // Set some defauls for the empty record
-    if (property_exists($record, 'dbxref_id')) {
-      $entity->{$field_name}['und'][0] = array(
-        'value' => array(),
-        $base_table . '__dbxref_id' => '',
-        'dbxref__dbxref_id' => '',
-        'dbxref__db_id' => '',
-        'dbxref__accession' => '',
-        'dbxref__version' => '',
-        'dbxref__description' => '',
-      );
-    }
-    else {
-      $entity->{$field_name}['und'][0] = array(
-        'value' => array(),
-        $field_table . '__' . $pkey => '',
-        $field_table . '__' . $fkey => '',
-        $field_table . '__' . 'dbxref_id' => '',
-        $field_table . '--' . 'dbxref__dbxref_id' => '',
-        $field_table . '--' . 'dbxref__db_id' => '',
-        $field_table . '--' . 'dbxref__accession' => '',
-        $field_table . '--' . 'dbxref__version' => '',
-        $field_table . '--' . 'dbxref__description' => '',
-      );
-    }
-
-    // First check to see if a local dbxref_id field has values, if it does
-    // then add it.
-    if (property_exists($record, 'dbxref_id')) {
-      $dbxref = $record->dbxref_id;
-      $value = $dbxref->db_id->name . ':' . $dbxref->accession;
-      $URL = '';
-      if ($dbxref->db_id->urlprefix) {
-        $URL = l($value, $dbxref->db_id->urlprefix . '/' . $dbxref->accession);
-      }
-
-      $entity->{$field_name}['und'][$num_dbxrefs] = array(
-        'value' => array(
-          'namespace' => $dbxref->db_id->name,
-          'accession' => $dbxref->accession,
-          'URL' => $URL,
-        ),
-        $base_table . '__dbxref_id' => $dbxref->dbxref_id,
-        'dbxref__dbxref_id' => $dbxref->dbxref_id,
-        'dbxref__db_id' => $dbxref->db_id->db_id,
-        'dbxref__accession' => $dbxref->accession,
-        'dbxref__version' => $dbxref->version,
-        'dbxref__description' => $dbxref->description,
-      );
-      $num_dbxrefs++;
-    }
-
-    // Second, check in the dbxref linker table for values.
     $schema = chado_get_schema($field_table);
     $pkey = $schema['primary key'][0];
     $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
     $fkey = $fkeys[0];
+
+    // Set some defaults for the empty record.
+    $entity->{$field_name}['und'][0] = array(
+      'value' => array(),
+      $field_table . '__' . $pkey => '',
+      $field_table . '__' . $fkey => '',
+      $field_table . '__dbxref_id' => '',
+      $field_table . '__dbxref_id--dbxref_id' => '',
+      $field_table . '__dbxref_id--db_id' => '',
+      $field_table . '__dbxref_id--accession' => '',
+      $field_table . '__dbxref_id--version' => '',
+      $field_table . '__dbxref_id--description' => '',
+    );
+
     $linker_table = $base_table . '_dbxref';
     $options = array('return_array' => 1);
     $record = chado_expand_var($record, 'table', $linker_table, $options);
     if (count($record->$linker_table) > 0) {
+      $i = 0;
       foreach ($record->$linker_table as $index => $linker) {
         $dbxref = $linker->dbxref_id;
-        $entity->{$field_name}['und'][$num_dbxrefs] = array(
+        $entity->{$field_name}['und'][$i] = array(
           'value' => array(
             'namespace' => $dbxref->db_id->name,
             'accession' => $dbxref->accession,
@@ -526,20 +309,20 @@ class chado_linker__dbxref extends TripalField {
           ),
           $field_table . '__' . $pkey => $linker->$pkey,
           $field_table . '__' . $fkey => $linker->$fkey->$fkey,
-          $field_table . '__' . 'dbxref_id' => $dbxref->dbxref_id,
-          $field_table . '--' . 'dbxref__dbxref_id' => $dbxref->dbxref_id,
-          $field_table . '--' . 'dbxref__db_id' => $dbxref->db_id->db_id,
-          $field_table . '--' . 'dbxref__accession' => $dbxref->accession,
-          $field_table . '--' . 'dbxref__version' => $dbxref->version,
-          $field_table . '--' . 'dbxref__description' => $dbxref->description,
+          $field_table . '__dbxref_id' => $dbxref->dbxref_id,
+          $field_table . '__dbxref_id--dbxref_id' => $dbxref->dbxref_id,
+          $field_table . '__dbxref_id--db_id' => $dbxref->db_id->db_id,
+          $field_table . '__dbxref_id--accession' => $dbxref->accession,
+          $field_table . '__dbxref_id--version' => $dbxref->version,
+          $field_table . '__dbxref_id--description' => $dbxref->description,
         );
-        $num_dbxrefs++;
+        $i++;
       }
     }
   }
 }
 /**
- * Theme function for the linker table dbxrefs.
+ * Theme function for the dbxref_id_widget.
  *
  * @param $variables
  */
@@ -552,18 +335,18 @@ function theme_chado_linker__dbxref_widget($variables) {
   $fkey = $element['#fkey_field'];
 
   $layout = "
-      <div>
+      <div class=\"secondary-dbxref-widget\">
         <div class=\"secondary-dbxref-widget-item\">" .
-        drupal_render($element[$table_name . '--dbxref__db_id']) . "
+        drupal_render($element[$table_name . '__dbxref_id--db_id']) . "
         </div>
         <div class=\"secondary-dbxref-widget-item\">" .
-        drupal_render($element[$table_name . '--dbxref__accession']) . "
+        drupal_render($element[$table_name . '__dbxref_id--accession']) . "
         </div>
         <div class=\"secondary-dbxref-widget-item\">" .
-        drupal_render($element[$table_name . '--dbxref__version']) . "
+        drupal_render($element[$table_name . '__dbxref_id--version']) . "
         </div>
         <div class=\"secondary-dbxref-widget-item\">" .
-        drupal_render($element[$table_name . '--dbxref__description']) . "
+        drupal_render($element[$table_name . '__dbxref_id--description']) . "
         </div>
         <div class=\"secondary-dbxref-widget-links\">" . drupal_render($element['links']) . "</div>
       </div>
@@ -656,31 +439,4 @@ function chado_linker__dbxref_widget_form_ajax_callback($form, $form_state) {
   }
 
   return $form[$field_name]['und'][$delta];
-}
-
-/**
- * Theme function for the local base table dbxrefs.
- */
-function theme_chado_base__dbxref_id_widget($variables) {
-  $element = $variables['element'];
-
-  $layout = "
-      <div>
-        <div class=\"primary-dbxref-widget-item\">" .
-        drupal_render($element['dbxref__db_id']) . "
-        </div>
-        <div class=\"primary-dbxref-widget-item\">" .
-        drupal_render($element['dbxref__accession']) . "
-        </div>
-        <div class=\"primary-dbxref-widget-item\">" .
-        drupal_render($element['dbxref__version']) . "
-        </div>
-        <div class=\"primary-dbxref-widget-item\">" .
-        drupal_render($element['dbxref__description']) . "
-        </div>
-        <div class=\"primary-dbxref-widget-links\">" . drupal_render($element['links']) . "</div>
-      </div>
-    ";
-
-  return $layout;
 }

+ 98 - 41
tripal_chado/includes/tripal_chado.field_storage.inc

@@ -35,12 +35,20 @@ function tripal_chado_field_storage_write($entity_type, $entity, $op, $fields) {
   $record_id  = $entity->chado_record_id;
 
   // Convert the fields into a key/value list of fields and their values.
-  $field_vals = tripal_chado_field_storage_unnest_fields($fields, $entity_type, $entity);
+  $field_vals = tripal_chado_field_storage_merge_fields($fields, $entity_type, $entity);
 dpm($field_vals);
-
-  // Recursively write fields for the base table.
-  $record_id = tripal_chado_field_storage_write_recursive($entity_type, $entity, $term,
-      $op, $field_vals, $base_table, $base_table, $type_field, $record_id);
+return;
+  // Write the record for the base table.
+  $record_id = tripal_chado_field_storage_write_table(array(
+    'entity' => $entity,
+    'term' => $term,
+    'op' => $op,
+    'field_vals' => $field_vals,
+    'base_table' => $base_table,
+    'tablename' => $base_table,
+    'type_field' => $type_field,
+    'record_id' => $record_id,
+  ));
 
   // If this is an insert then add the chado_entity record.
   if ($op == FIELD_STORAGE_INSERT) {
@@ -59,9 +67,7 @@ dpm($field_vals);
     }
   }
 
-
-  // Now that we have handled the base table, we need to handle fields that
-  // are not part of the base table.
+  // Now that we have handled the base table, we need to handle linking tables.
   foreach ($fields as $field_id) {
     // Get the field using the id.
     $field = field_info_field_by_id($field_id);
@@ -77,8 +83,14 @@ dpm($field_vals);
         // Iterate through each record.
         if (array_key_exists($field_name, $field_vals)) {
           foreach ($field_vals[$field_name] as $delta => $fvals) {
-            tripal_chado_field_storage_write_recursive($entity_type, $entity, $term,
-                $op, $fvals, $base_table, $field_table);
+            tripal_chado_field_storage_write_table(array(
+              'entity' => $entity,
+              'term' => $term,
+              'op' => $op,
+              'field_vals' => $fvals,
+              'base_table' => $base_table,
+              'tablename' => $field_table
+            ));
           }
         }
       }
@@ -88,21 +100,17 @@ dpm($field_vals);
 
 /**
  *
- * @param $entity_type
- * @param $entity
- * @param $op
- * @param $field_vals
- * @param $tablename
- * @param $type_field
- * @param $record_id
- * @param $depth
- * @throws Exception
- * @return
- *   The record_id of the table if a matching record exists.
  */
-function tripal_chado_field_storage_write_recursive($entity_type, $entity, $term,
-   $op, $field_vals, $base_table, $tablename, $type_field = NULL,
-   $record_id = NULL, $depth = 0) {
+function tripal_chado_field_storage_write_table($params) {
+  $entity = $params['entity'];
+  $term = $params['term'];
+  $op = $params['op'];
+  $field_vals = $params['field_vals'];
+  $base_table = $params['base_table'];
+  $tablename = $params['tablename'];
+  $type_field = array_key_exists('type_field', $params) ? $params['type_field'] : NULL;
+  $record_id = array_key_exists('record_id', $params) ? $params['record_id'] : NULL;
+  $depth = array_key_exists('depth', $params) ? $params['depth'] : 0;
 
   // Intialize the values array.
   $values = array();
@@ -126,8 +134,8 @@ function tripal_chado_field_storage_write_recursive($entity_type, $entity, $term
         continue;
       }
 
-      // If this is not the base table then do not recurse on the FK field
-      // that links this table to the base table.
+      // If this is a linking table, do not recurse on the fields that
+      // link back to the base table.
       if ($tablename != $base_table && $details['table'] == $base_table) {
         $fkey_base_linker = $local_id;
         continue;
@@ -158,10 +166,14 @@ function tripal_chado_field_storage_write_recursive($entity_type, $entity, $term
       // loop through the $fk_fields again.
       $fkey_fields_list[] = $local_id;
 
-      // Recurse on the FK field.  Pass in the ID for the FK field if one
-      // exists in the $field_vals;
-      $fk_val = tripal_chado_field_storage_write_recursive($entity_type,
-        $entity, $term, $op, $fk_vals, $base_table, $fk_table, NULL, $fk_val, $depth + 1);
+      // Recurse on the FK field.
+      $nparams = $params;
+      $nparams['field_vals'] = $fk_vals;
+      $nparams['tablename'] = $fk_table;
+      $nparams['type_field'] = NULL;
+      $nparams['record_id'] = $fk_val;
+      $nparams['depth'] = $depth + 1;
+      $fk_val = tripal_chado_field_storage_write_table($nparams);
       if (isset($fk_val) and $fk_val != '' and $fk_val != 0) {
         $values[$local_id] = $fk_val;
       }
@@ -372,14 +384,13 @@ function tripal_chado_field_storage_load($entity_type, $entities, $age,
   } // end: foreach ($entities as $id => $entity) {
 }
 /**
- * Iterates through all of the fields reformats to a key/value array.
- *
- * @param $fields
+ * Merges the values of all fields into a single array keyed by table name.
  */
-function tripal_chado_field_storage_unnest_fields($fields, $entity_type, $entity) {
+function tripal_chado_field_storage_merge_fields($fields, $entity_type, $entity) {
   $new_fields = array();
 
-  // Iterate through all of the fields.
+  // Iterate through all of the fields and organize them into a
+  // new fields array keyed by the table name
   foreach ($fields as $field_id => $ids) {
 
     // Get the field name and information about it.
@@ -400,26 +411,72 @@ function tripal_chado_field_storage_unnest_fields($fields, $entity_type, $entity
     foreach ($items as $delta => $item) {
       foreach ($item as $item_name => $value) {
         $matches = array();
-        if (preg_match('/^(.*?)__.*?$/', $item_name, $matches)) {
+        if (preg_match('/^(.*?)__(.*?)$/', $item_name, $matches)) {
           $table_name = $matches[1];
-          $new_fields[$field_name][$delta][$item_name] = $value;
+          $column_name = $matches[2];
+
+          // Is this a nested FK field? If so break it down into a sub array.
+          if (preg_match('/^(.*?)--(.*?)$/', $column_name, $matches)) {
+            $parent_item_name = $matches[1];
+            $sub_item_name = $matches[2];
+            $sub_item = tripal_chado_field_storage_expand_field($sub_item_name, $value);
+            // If we've already encountered this table and column then we've
+            // already seen the numeric FK value or we've already added a
+            // subcolumn. If the former we want to convert this to an array
+            // so we can add the details.
+            if (array_key_exists($parent_item_name, $new_fields[$table_name][$delta]) and
+                !is_array($new_fields[$table_name][$delta][$parent_item_name])) {
+              $new_fields[$table_name][$delta][$parent_item_name] = array();
+            }
+            $new_fields[$table_name][$delta][$parent_item_name] += $sub_item;
+          }
+          else {
+            // If not seen this table and column then just add it. If we've
+            // already seen it then it means it's a FK field and we've already
+            // added subfields so do nothing.
+            if (!array_key_exists($table_name, $new_fields) or
+                !array_key_exists($delta, $new_fields[$table_name]) or
+                !array_key_exists($column_name, $new_fields[$table_name][$delta])) {
+              $new_fields[$table_name][$delta][$column_name] = $value;
+            }
+          }
         }
       }
       // If there is no value set for the field using the
       // [table_name]__[field name] naming schema then check if a 'value' item
       // is present and if so use that.
-      $item_name = $chado_table . '__' . $chado_column;
-      if ((!array_key_exists($field_name, $new_fields) or
-           !array_key_exists($item_name, $new_fields[$field_name][$delta])) and
+      if ((!array_key_exists($chado_table, $new_fields) or
+           !array_key_exists($delta, $new_fields[$chado_table]) or
+           !array_key_exists($chado_column, $new_fields[$chado_table][$delta])) and
           array_key_exists('value', $items[$delta]) and
           !is_array($items[$delta]['value'])) {
-        $new_fields[$field_name][$delta][$item_name] = $items[$delta]['value'];
+        $new_fields[$chado_table][$delta][$chado_column] = $items[$delta]['value'];
       }
     }
   }
+
   return $new_fields;
 }
 
+/**
+ * Recurses through a field's item name breaking it into a nested array.
+ *
+ *
+ */
+function tripal_chado_field_storage_expand_field($item_name, $value) {
+
+   $matches = array();
+   if (preg_match('/^(.*?)--(.*?)$/', $item_name, $matches)) {
+     $parent_item_name = $matches[1];
+     $sub_item_name = $matches[2];
+     $sub_item = tripal_chado_field_storage_expand_field($sub_item_name, $value);
+     return array($parent_item_name => $sub_item);
+   }
+   else {
+     return array($item_name => $value);
+   }
+}
+
 /**
  * Implements hook_field_storage_query().
  *