Bläddra i källkod

Working on fixing fields for updated TripalField class

Stephen Ficklin 8 år sedan
förälder
incheckning
b59da95d2a

+ 40 - 0
tripal/api/tripal.fields.api.inc

@@ -87,4 +87,44 @@ function tripal_load_include_field_type($field_type) {
   return FALSE;
 }
 
+/**
+ * More easily get the value of a single item from a field's items array.
+ *
+ * A Drupal field attached to an entity may have multiple items (i.e. it has
+ * a cardinality > 1).  Each of these items will always have a 'value' key that
+ * contains the data for that field. However, fields can also have other keys
+ * with their own values.  You can easily retreive the value of these keys
+ * using this function.  What makes this function useful is that you can
+ * provide a default value to use if the key has no value.  This is useful
+ * when developing a TripalField::widgetForm function and you need to
+ * retreive default values and you don't want to have to always check if the
+ * value is set.
+ *
+ * @param $items
+ *   The fields $items array. Compatbile with that returned by field_get_items.
+ * @param $delta
+ *   The index of the item.
+ * @parm $key
+ *   The name of the key within the item.
+ * @param $default
+ *   A default value to return if the key is not set. By default the empty
+ *   string is returned.
+ *
+ * @return
+ *   The value assigned to the item's key; FALSE if the key doesn't exist or
+ *   the $default argument if no value is associated with the key.
+ */
+function tripal_get_field_item_keyval($items, $delta, $key, $default='') {
+  if (!array_key_exists($delta, $items)) {
+    return FALSE;
+  }
+  if (!array_key_exists($key, $items[$delta])) {
+    return FALSE;
+  }
+  if (!$items[$delta][$key]) {
+    return $default;
+  }
+  return $items[$delta][$key];
+}
+
 

+ 2 - 1
tripal_chado/api/tripal_chado.query.api.inc

@@ -433,11 +433,12 @@ function chado_insert_record($table, $values, $options = array()) {
 
   // get the table description
   $table_desc = chado_get_schema($table);
-  if (empty($table_desc)) {
+  if (!$table_desc) {
     tripal_report_error('tripal_chado', TRIPAL_WARNING,
       'chado_insert_record; There is no table description for !table_name',
       array('!table_name' => $table), array('print' => $print_errors)
     );
+    return;
   }
 
   // iterate through the values array and create a new 'insert_values' array

+ 33 - 33
tripal_chado/includes/TripalFields/chado_base__dbxref_id.inc

@@ -59,12 +59,12 @@ class chado_base__dbxref_id 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 (count($items) > 0 and array_key_exists($delta, $items)) {
-      $fk_val = $items[$delta][$field_table . '__' . $field_column];
-      $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'];
+      $fk_val = $items[$delta]['chado-' . $field_table . '__' . $field_column];
+      $dbxref_id = $items[$delta]['chado-' . $field_table . '__' . $field_column . '--dbxref_id'];
+      $db_id = $items[$delta]['chado-' . $field_table . '__' . $field_column . '--db_id'];
+      $accession = $items[$delta]['chado-' . $field_table . '__' . $field_column . '--accession'];
+      $version = $items[$delta]['chado-' . $field_table . '__' . $field_column . '--version'];
+      $description = $items[$delta]['chado-' . $field_table . '__' . $field_column . '--description'];
     }
 
     // Check $form_state['values'] to see if an AJAX call set the values.
@@ -112,17 +112,17 @@ class chado_base__dbxref_id extends TripalField {
       '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
     );
 
-    $widget[$field_table . '__' . $field_column] = array(
+    $widget['chado-' . $field_table . '__' . $field_column] = array(
       '#type' => 'value',
       '#default_value' => $fk_val,
     );
 
-    $widget[$field_table . '__' . $field_column . '--dbxref_id'] = array(
+    $widget['chado-' . $field_table . '__' . $field_column . '--dbxref_id'] = array(
       '#type' => 'value',
       '#default_value' => $dbxref_id,
     );
 
-    $widget[$field_table . '__' . $field_column . '--db_id'] = array(
+    $widget['chado-' . $field_table . '__' . $field_column . '--db_id'] = array(
       '#type' => 'select',
       '#title' => t('Database'),
       '#options' => $options,
@@ -135,7 +135,7 @@ class chado_base__dbxref_id extends TripalField {
         'method' => 'replace'
       ),
     );
-    $widget[$field_table . '__' . $field_column . '--accession'] = array(
+    $widget['chado-' . $field_table . '__' . $field_column . '--accession'] = array(
       '#type' => 'textfield',
       '#title' => t('Accession'),
       '#default_value' => $accession,
@@ -151,7 +151,7 @@ class chado_base__dbxref_id extends TripalField {
       ),
       '#disabled' => $db_id ? FALSE : TRUE,
     );
-    $widget[$field_table . '__' . $field_column . '--version'] = array(
+    $widget['chado-' . $field_table . '__' . $field_column . '--version'] = array(
       '#type' => 'textfield',
       '#title' => t('Version'),
       '#default_value' => $version,
@@ -159,7 +159,7 @@ class chado_base__dbxref_id extends TripalField {
       '#size' => 5,
       '#disabled' => $db_id ? FALSE : TRUE,
     );
-    $widget[$field_table . '__' . $field_column . '--description'] = array(
+    $widget['chado-' . $field_table . '__' . $field_column . '--description'] = array(
       '#type' => 'textfield',
       '#title' => t('Description'),
       '#default_value' => $description,
@@ -171,7 +171,7 @@ class chado_base__dbxref_id extends TripalField {
       '#markup' => l('Add a new database', 'admin/tripal/legacy/tripal_db/add', array('attributes' => array('target' => '_blank')))
     );
   }
-  
+
   /**
    * Callback function for validating the tripal_chado_dbxref_select_widget.
    */
@@ -186,16 +186,16 @@ class chado_base__dbxref_id extends TripalField {
     $field_type = $field['type'];
     $field_table = $field['settings']['chado_table'];
     $field_column = $field['settings']['chado_column'];
-    $field_prefix = $field_table . '__' . $field_column;
-  
-  
+    $field_prefix = 'chado-' . $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
     // to validate it as if it were being used in a data entry form.
     if ($form_state['build_info']['form_id'] =='field_ui_field_edit_form') {
       return;
     }
-  
+
     // 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, $field_prefix . '--dbxref_id');
@@ -203,7 +203,7 @@ class chado_base__dbxref_id extends TripalField {
     //   $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
     // form_error function because the form_error will add a red_highlight
@@ -220,7 +220,7 @@ class chado_base__dbxref_id extends TripalField {
     if (!$db_id and !$accession and ($version or $description)) {
       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) {
@@ -259,12 +259,12 @@ class chado_base__dbxref_id extends TripalField {
         'accession' => '',
         'URL' => '',
       ),
-      $field_table . '__' . $field_column => '',
-      $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' => '',
+      'chado-' . $field_table . '__' . $field_column => '',
+      'chado-' . $field_table . '__dbxref_id--dbxref_id' => '',
+      'chado-' . $field_table . '__dbxref_id--db_id' => '',
+      'chado-' . $field_table . '__dbxref_id--accession' => '',
+      'chado-' . $field_table . '__dbxref_id--version' => '',
+      'chado-' . $field_table . '__dbxref_id--description' => '',
     );
 
     // Get the primary dbxref record (if it's not NULL).  Because we have a
@@ -278,12 +278,12 @@ class chado_base__dbxref_id extends TripalField {
           'accession' => $dbxref->accession,
           'URL' => tripal_get_dbxref_url($dbxref),
         ),
-        $field_table . '__' . $field_column => $record->$field_column->$field_column,
-        $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,
+        'chado-' . $field_table . '__' . $field_column => $record->$field_column->$field_column,
+        'chado-' . $field_table . '__' . $field_column . '--dbxref_id'   => $dbxref->dbxref_id,
+        'chado-' . $field_table . '__' . $field_column . '--db_id'       => $dbxref->db_id->db_id,
+        'chado-' . $field_table . '__' . $field_column . '--accession'   => $dbxref->accession,
+        'chado-' . $field_table . '__' . $field_column . '--version'     => $dbxref->version,
+        'chado-' . $field_table . '__' . $field_column . '--description' => $dbxref->description,
       );
     }
   }
@@ -298,7 +298,7 @@ function chado_base__dbxref_id_widget_form_ajax_callback($form, $form_state) {
   $field_type = $field['type'];
   $field_table = $field['settings']['chado_table'];
   $field_column = $field['settings']['chado_column'];
-  $field_prefix = $field_table . '__' . $field_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');
@@ -324,7 +324,7 @@ function theme_chado_base__dbxref_id_widget($variables) {
   $field_type = $field['type'];
   $field_table = $field['settings']['chado_table'];
   $field_column = $field['settings']['chado_column'];
-  $field_prefix = $field_table . '__' . $field_column;
+  $field_prefix = 'chado-' . $field_table . '__' . $field_column;
 
   $layout = "
       <div class=\"primary-dbxref-widget\">

+ 143 - 102
tripal_chado/includes/TripalFields/chado_linker__dbxref.inc

@@ -38,7 +38,6 @@ class chado_linker__dbxref extends TripalField {
    * @see TripalField::formatterView()
    */
   public function formatterView(&$element, $entity_type, $entity, $langcode, $items, $display) {
-
     $chado_table = $this->field['settings']['chado_table'];
     foreach ($items as $delta => $item) {
       if (!$item['value']) {
@@ -46,15 +45,16 @@ class chado_linker__dbxref extends TripalField {
       }
       $content = $item['value']['vocabulary'] . ':' . $item['value']['accession'];
       if ($item['value']['URL']) {
-        $content = l($item['value']['URL'], $item['value']['URL']);
+        $content = l($content, $item['value']['URL'], array('attributes' => array('target' => '_blank')));
       }
       $element[$delta] = array(
         '#type' => 'markup',
         '#markup' => $content,
       );
     }
+
     if (count($items) == 0) {
-      $element[$delta] = array(
+      $element[0] = array(
         '#type' => 'markup',
         '#markup' => '',
       );
@@ -81,7 +81,7 @@ class chado_linker__dbxref extends TripalField {
 
     // Get the field defaults.
     $record_id = '';
-    $fkey_value = '';
+    $fkey_value = $element['#entity']->chado_record_id;
     $dbxref_id = '';
     $db_id = '';
     $accession = '';
@@ -90,25 +90,25 @@ 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][$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'];
+    if (count($items) > 0 and array_key_exists($delta, $items)) {
+      $record_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__' . $pkey, $record_id);
+      $fkey_value = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__' . $fkey, $fkey_value);
+      $dbxref_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__dbxref_id', $dbxref_id);
+      $db_id = tripal_get_field_item_keyval($items, $delta, 'db_id', $db_id);
+      $accession = tripal_get_field_item_keyval($items, $delta, 'accession', $accession);
+      $version = tripal_get_field_item_keyval($items, $delta, 'version', $version);
+      $description = tripal_get_field_item_keyval($items, $delta, 'description', $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_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');
+      $record_id = $form_state['values'][$field_name]['und'][$delta][$field_table . '__' . $pkey];
+      $fkey_value = $form_state['values'][$field_name]['und'][$delta][$field_table . '__' . $fkey];
+      $dbxref_id = $form_state['values'][$field_name]['und'][$delta][$field_table . '__dbxref_id'];
+      $db_id = $form_state['values'][$field_name]['und'][$delta][db_id];
+      $accession = $form_state['values'][$field_name]['und'][$delta]['accession'];
+      $version = $form_state['values'][$field_name]['und'][$delta]['version'];
+      $description = $form_state['values'][$field_name]['und'][$delta]['description'];
     }
 
     $schema = chado_get_schema('dbxref');
@@ -127,23 +127,23 @@ class chado_linker__dbxref extends TripalField {
       '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
     );
 
-    $widget[$field_table . '__' . $pkey] = array(
+    $widget['chado-' . $field_table . '__' . $pkey] = array(
       '#type' => 'value',
       '#default_value' => $record_id,
     );
-    $widget[$field_table . '__' . $fkey] = array(
+    $widget['chado-' . $field_table . '__' . $fkey] = array(
       '#type' => 'value',
       '#default_value' => $fkey_value,
     );
-    $widget[$field_table . '__dbxref_id'] = array(
+    $widget['chado-' . $field_table . '__dbxref_id'] = array(
       '#type' => 'value',
       '#default_value' => $dbxref_id,
     );
-    $widget[$field_table . '__dbxref_id--dbxref_id'] = array(
+    $widget['dbxref_id'] = array(
       '#type' => 'value',
       '#default_value' => $dbxref_id,
     );
-    $widget[$field_table . '__dbxref_id--db_id'] = array(
+    $widget['db_id'] = array(
       '#type' => 'select',
       '#title' => t('Database'),
       '#options' => $options,
@@ -156,7 +156,7 @@ class chado_linker__dbxref extends TripalField {
         'method' => 'replace'
       ),
     );
-    $widget[$field_table . '__dbxref_id--accession'] = array(
+    $widget['accession'] = array(
       '#type' => 'textfield',
       '#title' => t('Accession'),
       '#default_value' => $accession,
@@ -172,7 +172,7 @@ class chado_linker__dbxref extends TripalField {
       ),
       '#disabled' => $db_id ? FALSE : TRUE,
     );
-    $widget[$field_table . '__dbxref_id--version'] = array(
+    $widget['version'] = array(
       '#type' => 'textfield',
       '#title' => t('Version'),
       '#default_value' => $version,
@@ -180,7 +180,7 @@ class chado_linker__dbxref extends TripalField {
       '#size' => 5,
       '#disabled' => $db_id ? FALSE : TRUE,
     );
-    $widget[$field_table . '__dbxref_id--description'] = array(
+    $widget['description'] = array(
       '#type' => 'textfield',
       '#title' => t('Description'),
       '#default_value' => $description,
@@ -195,64 +195,105 @@ class chado_linker__dbxref extends TripalField {
     }
   }
 
-  public function widgetFormSubmit($entity_type, $entity, $langcode, &$items, $form, &$form_state) {
+  /**
+   * @see TripalField::widgetFormValidate()
+   */
+  public function widgetFormValidate($entity_type, $entity, $field, $items, &$errors) {
+    $field_name = $this->field['field_name'];
+    $field_type = $this->field['type'];
+    $table_name = $this->field['settings']['chado_table'];
+    $field_table = $this->field['settings']['chado_table'];
+    $field_column = $this->field['settings']['chado_column'];
+    $base_table = $this->field['settings']['base_table'];
+    $schema = chado_get_schema($table_name);
+    $pkey = $schema['primary key'][0];
+    $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
+    $fkey = $fkeys[0];
+
 
-    $field_name = $element['#field_name'];
-    $delta = $element['#delta'];
-    $table_name = $element['#table_name'];
-    $fkey = $element['#fkey_field'];
-    $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 . '__dbxref_id';
-    
-    // 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
-    // to validate it as if it were being used in a data entry form.
-    if ($form_state['build_info']['form_id'] =='field_ui_field_edit_form') {
-      return;
-    }
-    
     // Get the field values.
-    //   $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_prefix . '--db_id');
-    //   $accession = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_prefix . '--accession');
-    //   $version = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_prefix . '--version');
-    //   $description = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $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
-    // 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) {
-      form_set_error(implode('][', $element ['#parents']) . '][' . $field_prefix . '--db_id', t("A database and the accession must both be provided."));
-    }
-    if ($db_id and !$accession) {
-      form_set_error(implode('][', $element ['#parents']) . '][' . $field_prefix . '--accession', t("A database and the accession must both be provided."));
-    }
-    if (!$db_id and !$accession and ($version or $description)) {
-      form_set_error(implode('][', $element ['#parents']) . '][' . $field_prefix . '--db_id', t("A database and the accession must both be provided."));
-    }
-    
-    // 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 != $dbxref_id) {
-        tripal_chado_set_field_form_values($field_name, $form_state, $dbxref->dbxref_id, $delta, $table_name . '__dbxref_id');
-        tripal_chado_set_field_form_values($field_name, $form_state, $dbxref->dbxref_id, $delta, $field_prefix . '--dbxref_id');
+    foreach ($items as $delta => $values) {
+
+      // Get the field values.
+      $dbxref_id = $values['chado-' . $field_table . '__dbxref_id'];
+      $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'][$delta] = array(
+          'message' => t("A database and the accession must both be provided."),
+          'error' => 'chado_linker__dbxref',
+        );
+      }
+      if ($db_id and !$accession) {
+        $errors[$field_name][$delta]['und'][$delta] = array(
+          'message' => t("A database and the accession must both be provided."),
+          'error' => 'chado_linker__dbxref',
+        );
+      }
+      if (!$db_id and !$accession and ($version or $description)) {
+        $errors[$field_name][$delta]['und'][$delta] = array(
+          'message' => t("A database and the accession must both be provided."),
+          'error' => 'chado_linker__dbxref',
+        );
       }
     }
-    else {
-      // If the db_id and accession are not set, then remove the linker FK value to the base table.
-      tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__' . $fkey);
+  }
+  /**
+   * @see TripalField::widgetFormSubmit()
+   */
+  public function widgetFormSubmit($entity_type, $entity, $langcode, &$items, $form, &$form_state) {
+
+    $field_name = $this->field['field_name'];
+    $field_type = $this->field['type'];
+    $table_name = $this->field['settings']['chado_table'];
+    $field_table = $this->field['settings']['chado_table'];
+    $field_column = $this->field['settings']['chado_column'];
+    $base_table = $this->field['settings']['base_table'];
+    $schema = chado_get_schema($table_name);
+    $pkey = $schema['primary key'][0];
+    $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
+    $fkey = $fkeys[0];
+
+    // Get the field values.
+    foreach ($items as $delta => $values) {
+
+      // Get the field values.
+      $dbxref_id = $values['chado-' . $field_table . '__dbxref_id'];
+      $db_id = $values['db_id'];
+      $accession = $values['accession'];
+      $version = $values['version'];
+      $description = $values['description'];
+
+      // 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 != $dbxref_id) {
+          $items[$delta]['chado-' . $table_name . '__dbxref_id'] = $dbxref->dbxref_id;
+          $items[$delta]['dbxref_id'] = $dbxref->dbxref_id;
+        }
+      }
+      // If the db_id and accession are not set, then remove the linker FK
+      // value to the base table.
+      else {
+        $items[$delta]['chado-' . $table_name . '__' . $pkey] = '';
+        $items[$delta]['chado-' . $table_name . '__' . $fkey] = '';
+        $items[$delta]['chado-' . $table_name . '__dbxref_id'] = '';
+      }
     }
   }
+
   /**
    * @see TripalField::load()
    */
@@ -274,14 +315,14 @@ class chado_linker__dbxref extends TripalField {
     // 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' => '',
+      'chado-' . $field_table . '__' . $pkey => '',
+      'chado-' . $field_table . '__' . $fkey => '',
+      'chado-' . $field_table . '__dbxref_id' => '',
+      'dbxref_id' => '',
+      'db_id' => '',
+      'accession' => '',
+      'version' => '',
+      'description' => '',
     );
 
     $linker_table = $base_table . '_dbxref';
@@ -298,14 +339,14 @@ class chado_linker__dbxref extends TripalField {
             'accession' => $dbxref->accession,
             'URL' => $URL,
           ),
-          $field_table . '__' . $pkey => $linker->$pkey,
-          $field_table . '__' . $fkey => $linker->$fkey->$fkey,
-          $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,
+          'chado-' . $field_table . '__' . $pkey => $linker->$pkey,
+          'chado-' . $field_table . '__' . $fkey => $linker->$fkey->$fkey,
+          'chado-' . $field_table . '__dbxref_id' => $dbxref->dbxref_id,
+          'dbxref_id' => $dbxref->dbxref_id,
+          'db_id' => $dbxref->db_id->db_id,
+          'accession' => $dbxref->accession,
+          'version' => $dbxref->version,
+          'description' => $dbxref->description,
         );
         $i++;
       }
@@ -328,16 +369,16 @@ function theme_chado_linker__dbxref_widget($variables) {
   $layout = "
       <div class=\"secondary-dbxref-widget\">
         <div class=\"secondary-dbxref-widget-item\">" .
-        drupal_render($element[$table_name . '__dbxref_id--db_id']) . "
+        drupal_render($element['db_id']) . "
         </div>
         <div class=\"secondary-dbxref-widget-item\">" .
-        drupal_render($element[$table_name . '__dbxref_id--accession']) . "
+        drupal_render($element['accession']) . "
         </div>
         <div class=\"secondary-dbxref-widget-item\">" .
-        drupal_render($element[$table_name . '__dbxref_id--version']) . "
+        drupal_render($element['version']) . "
         </div>
         <div class=\"secondary-dbxref-widget-item\">" .
-        drupal_render($element[$table_name . '__dbxref_id--description']) . "
+        drupal_render($element['description']) . "
         </div>
         <div class=\"secondary-dbxref-widget-links\">" . drupal_render($element['links']) . "</div>
       </div>
@@ -357,12 +398,12 @@ function chado_linker__dbxref_widget_form_ajax_callback($form, $form_state) {
   $field_type = $field['type'];
   $field_table = $field['settings']['chado_table'];
   $field_column = $field['settings']['chado_column'];
-  $field_prefix = $field_table . '__dbxref_id';
+  $field_prefix = 'chado-' . $field_table . '__dbxref_id';
 
   // Check to see if this dbxref already exists. If not then
   // give a notice to the user that the dbxref will be added.
-  $db_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_prefix . '--db_id');
-  $accession = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_prefix . '--accession');
+  $db_id = $form_state['values'][$field_name]['und'][$delta]['db_id'];
+  $db_id = $form_state['values'][$field_name]['und'][$delta]['accession'];
   if ($db_id and $accession) {
     $values = array(
       'db_id' => $db_id,

+ 30 - 37
tripal_chado/includes/TripalFields/chado_linker__pub.inc

@@ -32,8 +32,8 @@ class chado_linker__pub extends TripalField {
     $list_items = array();
     $chado_table = $this->field['settings']['chado_table'];
     foreach ($items as $delta => $item) {
-      if ($item[$chado_table . '__pub_id']) {
-        $pub = chado_generate_var('pub', array('pub_id' => $item[$chado_table . '__pub_id']));
+      if ($item['chado-' . $chado_table . '__pub_id']) {
+        $pub = chado_generate_var('pub', array('pub_id' => $item['chado-' . $chado_table . '__pub_id']));
         $list_items[$pub->pyear] = $pub->uniquename;
       }
     }
@@ -79,17 +79,9 @@ class chado_linker__pub 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 (count($items) > 0 and array_key_exists($delta, $items)) {
-      $record_id = $items[$delta][$table_name . '__' . $pkey];
-      $pub_id = $items[$delta][$table_name . '__pub_id'];
-      $title = $items[$delta][$table_name . '--pub__uniquename'];
-    }
-
-    // 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($table_name, $form_state, $delta, $table_name . '__' . $pkey);
-//       $fkey_value = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__' . $fkey);
-//       $pub_id = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__pub_id');
-//       $title = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__title');
+      $record_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $table_name . '__' . $pkey, $record_id);
+      $pub_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $table_name . '__pub_id', $pub_id);
+      $title = tripal_get_field_item_keyval($items, $delta, 'uniquename', $title);
     }
 
     $schema = chado_get_schema('pub');
@@ -105,20 +97,20 @@ class chado_linker__pub extends TripalField {
       '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
     );
 
-    $widget[$table_name . '__' . $pkey] = array(
+    $widget['chado-' . $table_name . '__' . $pkey] = array(
       '#type' => 'value',
       '#default_value' => $record_id,
     );
-    $widget[$table_name . '__' . $fkey] = array(
+    $widget['chado-' . $table_name . '__' . $fkey] = array(
       '#type' => 'value',
       '#default_value' => $fkey_value,
     );
-    $widget[$table_name . '__pub_id'] = array(
+    $widget['chado-' . $table_name . '__pub_id'] = array(
       '#type' => 'value',
       '#default_value' => $pub_id,
     );
 
-    $widget[$table_name . '--pub__uniquename'] = array(
+    $widget['uniquename'] = array(
       '#type' => 'textfield',
       '#title' => t('Publication'),
       '#default_value' => $title,
@@ -146,24 +138,17 @@ class chado_linker__pub extends TripalField {
     $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
     $fkey = $fkeys[0];
 
-    // 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
-    // to validate it as if it were being used in a data entry form.
-    if ($form_state['build_info']['form_id'] =='field_ui_field_edit_form') {
-      return;
-    }
-
     // Get the field values.
     foreach ($items as $delta => $values) {
       $fkey_value = $values['value'];
-      $pub_id = $values[$table_name . '__pub_id'];
-      $uname = $values[$table_name . '--pub__uniquename'];
+      $pub_id = $values['chado-' . $table_name . '__pub_id'];
+      $uname = $values['uniquename'];
 
       // If the user provided a uniquename then we want to set the foreign key
       // value to be the chado_record_id
       if ($uname and !$pub_id) {
         $pub = chado_generate_var('pub', array('uniquename' => $uname));
-        $items[$delta][$table_name . '__pub_id'] = $pub->pub_id;
+        $items[$delta]['chado-' . $table_name . '__pub_id'] = $pub->pub_id;
       }
 
       // In the widgetFrom function we automatically add the foreign key
@@ -171,7 +156,15 @@ class chado_linker__pub extends TripalField {
       // it out so that the Chado field_storage infrastructure won't try to
       // write a record.
       if (!$uname and !$pub_id) {
-        $items[$delta][$table_name . '__' . $fkey] = '';
+        $items[$delta]['chado-' . $table_name . '__' . $fkey] = '';
+      }
+
+      // If the user removed the publication from the pub_uniquename field
+      // then we want to clear out the rest of the hidden values.
+      if (!$uname and $pub_id) {
+        $items[$delta]['chado-' . $table_name . '__' . $fkey] = '';
+        $items[$delta]['chado-' . $table_name . '__' . $pkey] = '';
+        $items[$delta]['chado-' . $table_name . '__pub_id'] = '';
       }
     }
   }
@@ -198,10 +191,10 @@ class chado_linker__pub extends TripalField {
     // Set some defaults for the empty record.
     $entity->{$field_name}['und'][0] = array(
       'value' => array(),
-      $field_table . '__' . $pkey => '',
-      $field_table . '__' . $fkey_lcolumn => '',
-      $field_table . '__' . 'pub_id' => '',
-      $field_table . '--' . 'pub__uniquename' => '',
+      'chado-' . $field_table . '__' . $pkey => '',
+      'chado-' . $field_table . '__' . $fkey_lcolumn => '',
+      'chado-' . $field_table . '__' . 'pub_id' => '',
+      'uniquename' => '',
     );
 
     $linker_table = $base_table . '_pub';
@@ -219,10 +212,10 @@ class chado_linker__pub extends TripalField {
         $pub_details['publication']['type'] = $pub->type_id->name;
 
         $entity->{$field_name}['und'][$i]['value'] = $pub_details;
-        $entity->{$field_name}['und'][$i][$field_table . '__' . $pkey] = $linker->$pkey;
-        $entity->{$field_name}['und'][$i][$field_table . '__' . $fkey_lcolumn] = $linker->$fkey_lcolumn->$fkey_lcolumn;
-        $entity->{$field_name}['und'][$i][$field_table . '__' . 'pub_id'] = $pub->pub_id;
-        $entity->{$field_name}['und'][$i][$field_table . '--' . 'pub__uniquename'] =  $pub->uniquename;
+        $entity->{$field_name}['und'][$i]['chado-' . $field_table . '__' . $pkey] = $linker->$pkey;
+        $entity->{$field_name}['und'][$i]['chado-' . $field_table . '__' . $fkey_lcolumn] = $linker->$fkey_lcolumn->$fkey_lcolumn;
+        $entity->{$field_name}['und'][$i]['chado-' . $field_table . '__' . 'pub_id'] = $pub->pub_id;
+        $entity->{$field_name}['und'][$i]['uniquename'] =  $pub->uniquename;
 
         if (property_exists($pub, 'entity_id')) {
           $entity->{$field_name}['und'][$i]['value']['entity'] = 'TripalEntity:' . $pub->entity_id;
@@ -259,7 +252,7 @@ function theme_chado_linker__pub_widget($variables) {
   $layout = "
       <div class=\"pub-widget\">
         <div class=\"pub-widget-item\">" .
-        drupal_render($element[$table_name . '--pub__uniquename']) . "
+        drupal_render($element['uniquename']) . "
         </div>
       </div>
     ";

+ 14 - 35
tripal_chado/includes/tripal_chado.field_storage.inc

@@ -111,8 +111,6 @@ function tripal_chado_field_storage_write_table($table_name, $values) {
    $fkeys = $schema['foreign keys'];
    $pkey = $schema['primary key'][0];
 
-
-
    // Before inserting or updating this table, recurse if there are any
    // nested FK array values.
    foreach ($values as $column => $value) {
@@ -274,13 +272,13 @@ function tripal_chado_field_storage_load($entity_type, $entities, $age,
           // and because $record object is created by the chado_generate_var()
           // function we must go one more level deeper to get the value
           if (is_object($record->$field_column)) {
-            $entity->{$field_name}['und'][0][$field_table . '__' . $field_column] = $record->$field_column->$field_column;
+            $entity->{$field_name}['und'][0]['chado' . $field_table . '__' . $field_column] = $record->$field_column->$field_column;
           }
           else {
             // For non FK fields we'll make the field value be the same
             // as the column value.
             $entity->{$field_name}['und'][0]['value'] = $record->$field_column;
-            $entity->{$field_name}['und'][0][$field_table . '__' . $field_column] = $record->$field_column;
+            $entity->{$field_name}['und'][0]['chado' . $field_table . '__' . $field_column] = $record->$field_column;
           }
         }
 
@@ -337,45 +335,26 @@ function tripal_chado_field_storage_write_merge_fields($fields, $entity_type, $e
     // are multi-valued.
     $items = field_get_items($entity_type, $entity, $field_name);
     foreach ($items as $delta => $item) {
+      // A field may have multiple items. The field can use items
+      // indexed with "chado-" to represent values that should map directly
+      // to chado tables and fields.
       foreach ($item as $item_name => $value) {
         $matches = array();
-        if (preg_match('/^(.*?)__(.*?)$/', $item_name, $matches)) {
+        if (preg_match('/^chado-(.*?)__(.*?)$/', $item_name, $matches)) {
           $table_name = $matches[1];
           $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)) {
-            $linker_table = $matches[1];
-            $base_table = $matches[2];
-            $sub_item = tripal_chado_field_storage_expand_field($base_table, $value);
-            if (count(array_keys($sub_item))) {
-              // 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($table_name, $new_fields) or
-                  !array_key_exists($delta, $new_fields[$table_name]) or
-                  !array_key_exists($linker_table, $new_fields[$table_name][$delta]) or
-                  !is_array($new_fields[$table_name][$delta][$linker_table])) {
-                $new_fields[$table_name][$delta][$linker_table] = array();
-              }
-              $new_fields[$table_name][$delta][$linker_table] += $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 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
+      // chado-[table_name]__[field name] naming schema then check if a 'value' item
       // is present and if so use that.
       if ((!array_key_exists($chado_table, $new_fields) or
            !array_key_exists($delta, $new_fields[$chado_table]) or

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

@@ -1109,6 +1109,7 @@ function tripal_chado_create_tripalfield_instance_linker(&$info, $entity_type, $
   // DBXREF
   $dbxref_table = $table_name . '_dbxref';
   if (chado_table_exists($dbxref_table)) {
+    $field_name = $table_name . '_dbxref';
     $info[$field_name] =  array(
       'field_name' =>  $field_name,
       'entity_type' => $entity_type,