Browse Source

Fixing fields to be compatible with updated TripalField class

Stephen Ficklin 8 years ago
parent
commit
c92894ddd2

+ 43 - 9
tripal/includes/TripalBundleController.inc

@@ -37,24 +37,58 @@ class TripalBundleController extends EntityAPIControllerExportable {
    */
   public function delete($ids, DatabaseTransaction $transaction = NULL) {
     $entities = $ids ? $this->load($ids) : FALSE;
-    if ($entities) {
 
+    if (!$transaction) {
+      $transaction = db_transaction();
+    }
+
+    if ($entities) {
 
       foreach ($entities as $id => $entity) {
-        $bundle = tripal_load_bundle_entity(array('id' => $id));
+
+        // Find any TripalEntity fields that are attached to this bundle and
+        // remove them.
+        $instances = field_info_instances('TripalEntity', $entity->name);
+        foreach ($instances as $instance) {
+          // Mark the instance as deleted and purge it.
+          $field = field_info_field($instance['field_name']);
+          field_delete_instance($instance);
+          field_purge_instance($instance);
+
+          // If the field has no more instances then purge it too.
+          if (count($field['bundles']) == 1 and
+              count($field['bundles']['TripalEntity']) == 1 and
+              in_array($entity->name, $field['bundles']['TripalEntity'])) {
+            field_purge_field($field);
+          }
+        }
+
+        // Remove the entries in the chado_entity and tripal_entity t
+        $query = db_select('chado_entity', 'ce');
+        $query->join('tripal_entity', 'te', 'te.id = ce.entity_id');
+        $records = $query->fields('ce', array('chado_entity_id', 'data_table', 'record_id'))
+          ->condition('te.bundle', $entity->name)
+          ->execute();
+        $num_removed = 0;
+        while ($record = $records->fetchObject()) {
+          db_delete('chado_entity')
+            ->condition('chado_entity_id', $record->chado_entity_id)
+            ->execute();
+          db_delete('tripal_entity')
+            ->condition('id', $record->chado_entity_id)
+            ->execute();
+          $num_removed++;
+        }
+        if ($num_removed > 0) {
+          drupal_set_message(t('Removed %num records', array('%num' => $num_removed)));
+        }
 
         // Remove the terms for the bundles that are to be deleted.
         db_delete('tripal_term')
-          ->condition('id', $bundle->term_id)
+          ->condition('id', $entity->term_id)
           ->execute();
-
-        // Remove the chado_entity records for this type.
-
       }
 
-
-
-
       // Use the parent function to delete the bundles.
       parent::delete($ids, $transaction);
 

+ 0 - 2
tripal/includes/TripalEntityController.inc

@@ -66,7 +66,6 @@ class TripalEntityController extends EntityAPIController {
     }
 
     try {
-
       // First load the entity.
       $entities = entity_load('TripalEntity', $ids);
 
@@ -83,7 +82,6 @@ class TripalEntityController extends EntityAPIController {
         db_delete('tripal_entity')
           ->condition('id', $entity->id)
           ->execute();
-
       }
     }
     catch (Exception $e) {

+ 20 - 11
tripal/includes/TripalEntityUIController.inc

@@ -43,8 +43,9 @@ class TripalEntityUIController extends EntityDefaultUIController {
           throw new Exception(t("Cannot find bundle that matches: %bundle_name",
               array('%bundle_name' => $bundle_name)));
         }
+        $term_id = $matches[1];
         // Get the term for this bundle
-        $term = entity_load('TripalTerm', array('id' => $matches[1]));
+        $term = entity_load('TripalTerm', array('id' => $term_id));
         $term = reset($term);
         $default_description = $term->definition ? $term->definition : '';
         // Set a custom page for adding new tripal data entities.
@@ -91,6 +92,24 @@ class TripalEntityUIController extends EntityDefaultUIController {
       'type' => MENU_LOCAL_TASK,
       'weight' => -8,
     );
+    $items['bio_data/' . $wildcard . '/layout'] = array(
+      'title' => 'Layout',
+      'page callback' => 'drupal_goto',
+      'page arguments' => array(url("admin/structure/bio_data/manage/bio_data_$term_id/display")),
+      'access callback' => 'tripal_entity_access',
+      'access arguments' => array('admin', 1),
+      'type' => MENU_LOCAL_TASK,
+      'weight' => -8,
+    );
+    $items['bio_data/' . $wildcard . '/fields'] = array(
+      'title' => 'Fields',
+      'page callback' => 'drupal_goto',
+      'page arguments' => array(url("admin/structure/bio_data/manage/bio_data_$term_id/fields")),
+      'access callback' => 'tripal_entity_access',
+      'access arguments' => array('admin', 1),
+      'type' => MENU_LOCAL_TASK,
+      'weight' => -8,
+    );
 
     // Menu item for deleting tripal data entities.
     $items['bio_data/' . $wildcard . '/delete'] = array(
@@ -105,16 +124,6 @@ class TripalEntityUIController extends EntityDefaultUIController {
     return $items;
   }
 }
-
-/**
- *
- * @param unknown $entity
- */
-function tripal_entity_manage_fields($entity) {
-  drupal_goto('admin/structure/bio_data/manage/' . $entity->name . '/fields');
-  return '';
-}
-
 /**
  * Menu callback to display an entity.
  *

+ 1 - 1
tripal_chado/api/tripal_chado.semweb.api.inc

@@ -184,7 +184,7 @@ function tripal_get_chado_semweb_term($chado_table, $chado_column, $options = ar
     ->fetchField();
 
   if ($cvterm_id) {
-    $cvterm = tripal_get_cvterm(array('cvterm_id' => $cvterm_id));
+    $cvterm = chado_generate_var('cvterm', array('cvterm_id' => $cvterm_id));
     if (array_key_exists('return_object', $options)) {
       return $cvterm;
     }

+ 96 - 102
tripal_chado/includes/TripalFields/chado_base__dbxref_id.inc

@@ -50,7 +50,6 @@ class chado_base__dbxref_id extends TripalField {
 
     // Get the field defaults.
     $fk_val = '';
-    $dbxref_id = '';
     $db_id = '';
     $accession = '';
     $version = '';
@@ -60,35 +59,21 @@ class chado_base__dbxref_id extends TripalField {
     // 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];
-      $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'];
+      $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 = 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_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');
+      $fk_val = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__' . $field_column];
+      $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'];
     }
 
-    // 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();
 
@@ -117,12 +102,7 @@ class chado_base__dbxref_id extends TripalField {
       '#default_value' => $fk_val,
     );
 
-    $widget['chado-' . $field_table . '__' . $field_column . '--dbxref_id'] = array(
-      '#type' => 'value',
-      '#default_value' => $dbxref_id,
-    );
-
-    $widget['chado-' . $field_table . '__' . $field_column . '--db_id'] = array(
+    $widget['db_id'] = array(
       '#type' => 'select',
       '#title' => t('Database'),
       '#options' => $options,
@@ -135,7 +115,7 @@ class chado_base__dbxref_id extends TripalField {
         'method' => 'replace'
       ),
     );
-    $widget['chado-' . $field_table . '__' . $field_column . '--accession'] = array(
+    $widget['accession'] = array(
       '#type' => 'textfield',
       '#title' => t('Accession'),
       '#default_value' => $accession,
@@ -151,7 +131,7 @@ class chado_base__dbxref_id extends TripalField {
       ),
       '#disabled' => $db_id ? FALSE : TRUE,
     );
-    $widget['chado-' . $field_table . '__' . $field_column . '--version'] = array(
+    $widget['version'] = array(
       '#type' => 'textfield',
       '#title' => t('Version'),
       '#default_value' => $version,
@@ -159,7 +139,7 @@ class chado_base__dbxref_id extends TripalField {
       '#size' => 5,
       '#disabled' => $db_id ? FALSE : TRUE,
     );
-    $widget['chado-' . $field_table . '__' . $field_column . '--description'] = array(
+    $widget['description'] = array(
       '#type' => 'textfield',
       '#title' => t('Description'),
       '#default_value' => $description,
@@ -172,69 +152,85 @@ class chado_base__dbxref_id extends TripalField {
     );
   }
 
+
   /**
-   * Callback function for validating the tripal_chado_dbxref_select_widget.
+   * @see TripalField::widgetFormValidate()
    */
+  public function widgetFormValidate($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',
+        );
+      }
+    }
+  }
+
   /**
-   * @see TripalField::submit()
+   * @see TripalField::widgetFormSubmit()
    */
   public function widgetFormSubmit($entity_type, $entity, $langcode, &$items, $form, &$form_state) {
     $field_name = $this->field['field_name'];
-    $field = $form_state['field'][$field_name]['und']['field'];
-    $settings = $field['settings'];
-    $field_name = $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;
-
-
-    // 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;
-    }
+    $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.
-    //   $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');
-    //   $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
-    // 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 for the primary cross reference."));
-    }
-    if ($db_id and !$accession) {
-      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']) . '][' . $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, $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
-    // 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, 0, $field_table . '__' . $field_column);
-        tripal_chado_set_field_form_values($field_name, $form_state, $dbxref->dbxref_id, 0, $field_prefix . '--dbxref_id');
+    foreach ($items as $delta => $values) {
+      $fk_val = $values['chado-' . $field_table . '__' . $field_column];
+      $db_id = $values['db_id'];
+      $accession = $values['accession'];
+      $version = $values['version'];
+
+      // If user did not select a database, we want to remove dbxref_id from the
+      // field.
+      if (!$db_id) {
+        $items[$delta]['chado-' . $table_name . '__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) {
+          $items[$delta]['chado-' . $table_name . '__dbxref_id'] = $dbxref->dbxref_id;
+        }
       }
     }
   }
@@ -260,11 +256,10 @@ class chado_base__dbxref_id extends TripalField {
         'URL' => '',
       ),
       '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' => '',
+      'db_id' => '',
+      'accession' => '',
+      'version' => '',
+      'description' => '',
     );
 
     // Get the primary dbxref record (if it's not NULL).  Because we have a
@@ -279,11 +274,10 @@ class chado_base__dbxref_id extends TripalField {
           'URL' => tripal_get_dbxref_url($dbxref),
         ),
         '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,
+        'db_id'       => $dbxref->db_id->db_id,
+        'accession'   => $dbxref->accession,
+        'version'     => $dbxref->version,
+        'description' => $dbxref->description,
       );
     }
   }
@@ -329,16 +323,16 @@ function theme_chado_base__dbxref_id_widget($variables) {
   $layout = "
       <div class=\"primary-dbxref-widget\">
         <div class=\"primary-dbxref-widget-item\">" .
-        drupal_render($element[$field_prefix . '--db_id']) . "
+        drupal_render($element['db_id']) . "
         </div>
         <div class=\"primary-dbxref-widget-item\">" .
-        drupal_render($element[$field_prefix . '--accession']) . "
+        drupal_render($element['accession']) . "
         </div>
         <div class=\"primary-dbxref-widget-item\">" .
-        drupal_render($element[$field_prefix . '--version']) . "
+        drupal_render($element['version']) . "
         </div>
         <div class=\"primary-dbxref-widget-item\">" .
-        drupal_render($element[$field_prefix . '--description']) . "
+        drupal_render($element['description']) . "
         </div>
         <div class=\"primary-dbxref-widget-links\">" . drupal_render($element['links']) . "</div>
       </div>

+ 26 - 22
tripal_chado/includes/TripalFields/chado_base__organism_id.inc

@@ -57,8 +57,8 @@ class chado_base__organism_id extends TripalField {
     $field_column = $this->field['settings']['chado_column'];
 
     $organism_id = 0;
-    if (count($items) > 0 and array_key_exists($field_table . '__organism_id', $items[0])) {
-      $organism_id = $items[0][$field_table . '__organism_id'];
+    if (count($items) > 0 and array_key_exists('chado-' . $field_table . '__organism_id', $items[0])) {
+      $organism_id = $items[0]['chado-' . $field_table . '__organism_id'];
     }
 
     $widget['value'] = array(
@@ -66,7 +66,7 @@ class chado_base__organism_id extends TripalField {
       '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
     );
     $options = tripal_get_organism_select_options(FALSE);
-    $widget[$field_table . '__organism_id'] = array(
+    $widget['chado-' . $field_table . '__organism_id'] = array(
       '#type' => 'select',
       '#title' => $element['#title'],
       '#description' => $element['#description'],
@@ -75,28 +75,31 @@ class chado_base__organism_id extends TripalField {
       '#required' => $element['#required'],
       '#weight' => isset($element['#weight']) ? $element['#weight'] : 0,
       '#delta' => $delta,
-//      '#element_validate' => array('chado_base__organism_id_widget_validate'),
     );
   }
-  
+
+  /**
+   * @see TripalField::widgetFormValidate()
+   */
   public function widgetFormValidate($entity_type, $entity, $field, $items, &$errors) {
 
-    $settings = $field['settings'];
-    $field_name = $field['field_name'];
-    $field_type = $field['type'];
-    $field_table = $field['settings']['chado_table'];
-    $field_column = $field['settings']['chado_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;
-    }
-    //$organism_id = tripal_chado_get_field_form_values($field_name, $form_state, 0, $field_table . '__organism_id');
-    
-    if (!$organism_id) {
-      form_error($element, t("Please specify an organism."));
+    $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) {
+
+      // Get the field values.
+      $organism_id = $values['chado-' . $field_table . '__organism_id'];
+      if (!$organism_id or $organism_id == 0) {
+        $errors[$field_name]['und'][0][] = array(
+          'message' =>  t("Please specify an organism."),
+          'error' => 'chado_base__organism_id'
+        );
+      }
     }
   }
 
@@ -116,6 +119,7 @@ class chado_base__organism_id extends TripalField {
     // Set some defaults for the empty record.
     $entity->{$field_name}['und'][0] = array(
       'value' => array(
+        'chado-' . $field_table . '__organism_id' => '',
         'label' => '',
         'genus' => '',
         'species' => '',
@@ -152,7 +156,7 @@ class chado_base__organism_id extends TripalField {
           $entity->{$field_name}['und'][0]['value']['infraspecific_type'] =  $organism->type_id->name;
         }
       }
-      $entity->{$field_name}['und'][0][$field_table . '__organism_id'] = $organism->organism_id;
+      $entity->{$field_name}['und'][0]['chado-' . $field_table . '__organism_id'] = $organism->organism_id;
 
       // Is there a published entity for this organism?
       if (property_exists($entity->chado_record->$field_column, 'entity_id')) {

+ 12 - 11
tripal_chado/includes/TripalFields/chado_feature__residues.inc

@@ -74,8 +74,8 @@ class chado_feature__residues extends TripalField {
 
     // Get the field defaults.
     $residues = '';
-    if (count($items) > 0 and array_key_exists('feature__residues', $items[0])) {
-      $residues = $items[0]['feature__residues'];
+    if (count($items) > 0 and array_key_exists('chado-feature__residues', $items[0])) {
+      $residues = $items[0]['chado-feature__residues'];
     }
     if (array_key_exists('values', $form_state)) {
       //$residues = tripal_chado_get_field_form_values($field_name, $form_state, 0, 'feature__residues');
@@ -85,25 +85,27 @@ class chado_feature__residues extends TripalField {
       '#type' => 'value',
       '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
     );
-    $widget['feature__residues'] = array(
+    $widget['chado-feature__residues'] = array(
       '#type' => 'textarea',
       '#title' => $element['#title'],
       '#description' => $element['#description'],
       '#weight' => isset($element['#weight']) ? $element['#weight'] : 0,
       '#default_value' => $residues,
       '#delta' => $delta,
-//      '#element_validate' => array('chado_feature__residues_widget_validate'),
       '#cols' => 30,
     );
   }
-  
+
+  /**
+   * @see TripalField::widgetFormSubmit()
+   */
   public function widgetFormSubmit($entity_type, $entity, $langcode, &$items, $form, &$form_state) {
 
     // Remove any white spaces.
-    //$residues = tripal_chado_get_field_form_values($field_name, $form_state, 0, 'feature__residues');
+    $residues = $items[0]['chado-feature__residues'];
     if ($residues) {
       $residues = preg_replace('/\s/', '', $residues);
-      tripal_chado_set_field_form_values($field_name, $form_state, $residues, 0, 'feature__residues');
+      $items[0]['chado-feature__residues'] = $residues;
     }
   }
 
@@ -116,7 +118,6 @@ class chado_feature__residues extends TripalField {
     $feature = $details['record'];
     $num_seqs = 0;
 
-
     // We don't want to get the sequence for traditionally large types. They are
     // too big,  bog down the web browser, take longer to load and it's not
     // reasonable to print them on a page.
@@ -131,7 +132,7 @@ class chado_feature__residues extends TripalField {
         'defline' => ">This sequence is too large for this display.",
         'residues' => '',
       );
-      $entity->{$field_name}['und'][$num_seqs]['feature__residues'] = '';
+      $entity->{$field_name}['und'][$num_seqs]['chado-feature__residues'] = '';
     }
     else {
       $feature = chado_expand_var($feature,'field','feature.residues');
@@ -143,11 +144,11 @@ class chado_feature__residues extends TripalField {
           'defline' => tripal_get_fasta_defline($feature, '', NULL, '', strlen($feature->residues)),
           'residues' => $feature->residues,
         );
-        $entity->{$field_name}['und'][$num_seqs]['feature__residues'] = $feature->residues;
+        $entity->{$field_name}['und'][$num_seqs]['chado-feature__residues'] = $feature->residues;
       }
       else {
         $entity->{$field_name}['und'][$num_seqs]['value'] = array();
-        $entity->{$field_name}['und'][$num_seqs]['feature__residues'] = '';
+        $entity->{$field_name}['und'][$num_seqs]['chado-feature__residues'] = '';
       }
     }
     $num_seqs++;

+ 14 - 9
tripal_chado/includes/TripalFields/chado_feature__seqlen.inc

@@ -40,7 +40,6 @@ class chado_feature__seqlen extends TripalField {
    */
   public function widgetForm(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) {
 
-    $settings = $this->field['settings'];
     $field_name = $this->field['field_name'];
     $field_type = $this->field['type'];
     $field_table = $this->field['settings']['chado_table'];
@@ -51,29 +50,35 @@ class chado_feature__seqlen extends TripalField {
       '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
     );
 
-    $widget['feature__seqlen'] =  array(
+    $widget['chado-feature__seqlen'] =  array(
       '#type' => 'value',
       '#value' => 0,
       '#title' => $element['#title'],
       '#description' => $element['#description'],
       '#weight' => isset($element['#weight']) ? $element['#weight'] : 0,
       '#delta' => $delta,
-//      '#element_validate' => array('chado_feature__seqlen_widget_validate'),
     );
   }
-  
+
+  /**
+   * @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'];
+    $field_table = $this->field['settings']['chado_table'];
+    $field_column = $this->field['settings']['chado_column'];
+
     // Get the residues so we can calculate teh length.
-    //$residues = tripal_chado_get_field_form_values('feature__residues', $form_state, 0, 'feature__residues');
+    $residues = $form_state['values']['feature__residues']['und'][0]['value']['residues'];
     // Remove any white spaces.
     if ($residues) {
       $residues = preg_replace('/\s/', '', $residues);
-      tripal_chado_set_field_form_values($field_name, $form_state, strlen($residues), 0, 'feature__seqlen');
+      $form_state['values']['feature__residues']['und'][0]['value']['chado-feature__residues'] = $residues;
+      $items[0]['chado-feature__seqlen'] = strlen($residues);
     }
     else {
-      // Otherwise, remove the seqlen value
-      tripal_chado_set_field_form_values($field_name, $form_state, '__NULL__', 0, 'feature_seqlen');
+      $items[0]['chado-feature__seqlen'] = '__NULL__';
     }
   }
-
 }

+ 147 - 6
tripal_chado/includes/TripalFields/chado_linker__contact.inc

@@ -81,7 +81,114 @@ class chado_linker__contact extends TripalField {
    * @see TripalField::widgetForm()
    */
   public function widgetForm(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) {
+    $entity = $form['#entity'];
+    $field_name = $this->field['field_name'];
+
+    // Get the FK column that links to the base table.
+    $table_name = $this->field['settings']['chado_table'];
+    $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 defaults.
+    $record_id = '';
+    $fkey_value = $element['#entity']->chado_record_id;
+    $contact_id = '';
+    $name = '';
+
+    // 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 = tripal_get_field_item_keyval($items, $delta, 'chado-' . $table_name . '__' . $pkey, $record_id);
+      $contact_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $table_name . '__contact_id', $contact_id);
+      $name = tripal_get_field_item_keyval($items, $delta, 'name', $name);
+    }
+
+    $schema = chado_get_schema('contact');
+
+    $widget['#table_name'] = $table_name;
+    $widget['#fkey_field'] = $fkey;
+    $widget['#theme'] = 'chado_linker__contact_widget';
+    $widget['#prefix'] =  "<span id='$table_name-$delta'>";
+    $widget['#suffix'] =  "</span>";
+
+    $widget['value'] = array(
+      '#type' => 'value',
+      '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
+    );
+
+    $widget['chado-' . $table_name . '__' . $pkey] = array(
+      '#type' => 'value',
+      '#default_value' => $record_id,
+    );
+    $widget['chado-' . $table_name . '__' . $fkey] = array(
+      '#type' => 'value',
+      '#default_value' => $fkey_value,
+    );
+    $widget['chado-' . $table_name . '__contact_id'] = array(
+      '#type' => 'value',
+      '#default_value' => $contact_id,
+    );
+
+    $widget['name'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Contact'),
+      '#default_value' => $name,
+      '#autocomplete_path' => 'admin/tripal/storage/chado/auto_name/contact',
+      '#ajax' => array(
+        'callback' => "chado_linker__contact_widget_form_ajax_callback",
+        'wrapper' => "$table_name-$delta",
+        'effect' => 'fade',
+        'method' => 'replace'
+      ),
+      '#maxlength' => 100000,
+    );
+  }
 
+  /**
+   * @see TripalField::widgetFormSubmit()
+   */
+  public function widgetFormSubmit($entity_type, $entity, $langcode, &$items, $form, &$form_state) {
+
+    // Get the FK column that links to the base table.
+    $table_name = $this->field['settings']['chado_table'];
+    $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) {
+      $fkey_value = $values['value'];
+      $contact_id = $values['chado-' . $table_name . '__contact_id'];
+      $name = $values['name'];
+
+      // If the user provided a name then we want to set the foreign key
+      // value to be the chado_record_id
+      if ($name and !$contact_id) {
+        $contact = chado_generate_var('contact', array('name' => $name));
+        $items[$delta]['chado-' . $table_name . '__contact_id'] = $contact->contact_id;
+      }
+
+      // In the widgetFrom function we automatically add the foreign key
+      // record.  But if the user did not provide a contact we want to take
+      // it out so that the Chado field_storage infrastructure won't try to
+      // write a record.
+      if (!$name and !$contact_id) {
+        $items[$delta]['chado-' . $table_name . '__' . $fkey] = '';
+      }
+
+      // If the user removed the contact from the contact_name field
+      // then we want to clear out the rest of the hidden values.
+      // Leave the primary key so the record can be deleted.
+      if (!$name and $contact_id) {
+        $items[$delta]['chado-' . $table_name . '__' . $fkey] = '';
+        $items[$delta]['chado-' . $table_name . '__contact_id'] = '';
+      }
+    }
   }
 
   /**
@@ -106,9 +213,9 @@ class chado_linker__contact 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 . '__' . 'contact_id' => '',
+      'chado-' . $field_table . '__' . $pkey => '',
+      'chado-' . $field_table . '__' . $fkey_lcolumn => '',
+      'chado-' . $field_table . '__' . 'contact_id' => '',
       // Ignore the synonym_sgml column for now.
     );
 
@@ -154,9 +261,9 @@ class chado_linker__contact extends TripalField {
             'name' => 'contact_id,name',
             'description' => 'contact_id,name'
           ),
-          $field_table . '__' . $pkey => $contact_linker->$pkey,
-          $field_table . '__' . $fkey_lcolumn => $contact_linker->$fkey_lcolumn->$fkey_lcolumn,
-          $field_table . '__' . 'contact_id' => $contact->contact_id
+          'chado-' . $field_table . '__' . $pkey => $contact_linker->$pkey,
+          'chado-' . $field_table . '__' . $fkey_lcolumn => $contact_linker->$fkey_lcolumn->$fkey_lcolumn,
+          'chado-' . $field_table . '__' . 'contact_id' => $contact->contact_id
         );
 
         if (property_exists($contact, 'entity_id')) {
@@ -165,4 +272,38 @@ class chado_linker__contact extends TripalField {
       }
     }
   }
+}
+
+/**
+ * An Ajax callback for the pub widget.
+ */
+function chado_linker__contact_widget_form_ajax_callback($form, $form_state) {
+
+  $field_name = $form_state['triggering_element']['#parents'][0];
+  $delta = $form_state['triggering_element']['#parents'][2];
+
+  return $form[$field_name]['und'][$delta];
+}
+/**
+ * Theme function for the pub widget.
+ *
+ * @param $variables
+ */
+function theme_chado_linker__contact_widget($variables) {
+  $element = $variables['element'];
+
+  // These two fields were added to the widget to help identify the fields
+  // for layout.
+  $table_name = $element['#table_name'];
+  $fkey = $element['#fkey_field'];
+
+  $layout = "
+      <div class=\"pub-widget\">
+        <div class=\"pub-widget-item\">" .
+        drupal_render($element['name']) . "
+        </div>
+      </div>
+    ";
+
+  return $layout;
 }

+ 4 - 4
tripal_chado/includes/TripalFields/chado_linker__dbxref.inc

@@ -107,7 +107,7 @@ class chado_linker__dbxref extends TripalField {
       $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];
+      $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'];
@@ -231,19 +231,19 @@ class chado_linker__dbxref extends TripalField {
       // 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(
+        $errors[$field_name][$delta]['und'][] = 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(
+        $errors[$field_name][$delta]['und'][] = 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(
+        $errors[$field_name][$delta]['und'][] = array(
           'message' => t("A database and the accession must both be provided."),
           'error' => 'chado_linker__dbxref',
         );

+ 151 - 109
tripal_chado/includes/TripalFields/chado_linker__synonym.inc

@@ -30,8 +30,8 @@ class chado_linker__synonym extends TripalField {
 
     $chado_table = $this->field['settings']['chado_table'];
     foreach ($items as $delta => $item) {
-      if (array_key_exists($chado_table . '__synonym_id', $item) and
-          $item[$chado_table . '__synonym_id']) {
+      if (array_key_exists('chado-' . $chado_table . '__synonym_id', $item) and
+          $item['chado-' . $chado_table . '__synonym_id']) {
         $synonym = chado_generate_var('synonym', array('synonym_id' => $item[$chado_table . '__synonym_id']));
         $name = $synonym->name;
         if ($synonym->type_id->name != 'exact') {
@@ -73,31 +73,29 @@ class chado_linker__synonym 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][$table_name . '__' . $pkey];
-      $fkey_value = $items[$delta][$table_name . '__' . $fkey];
-      $synonym_id = $items[$delta][$table_name . '__synonym_id'];
-      $pub_id = $items[$delta][$table_name . '__pub_id'];
-      $is_current = $items[$delta][$table_name . '__is_current'];
-      $is_internal = $items[$delta][$table_name . '__is_internal'];
-      $syn_name = $items[$delta][$table_name . '__synonym_id--name'];
-      $syn_type = $items[$delta][$table_name . '__synonym_id--type_id'];
+      $record_id = $items[$delta]['chado-' . $table_name . '__' . $pkey];
+      $fkey_value = $items[$delta]['chado-' . $table_name . '__' . $fkey];
+      $synonym_id = $items[$delta]['chado-' . $table_name . '__synonym_id'];
+      $pub_id = $items[$delta]['chado-' . $table_name . '__pub_id'];
+      $is_current = $items[$delta]['chado-' . $table_name . '__is_current'];
+      $is_internal = $items[$delta]['chado-' . $table_name . '__is_internal'];
+      $syn_name = $items[$delta]['name'];
+      $syn_type = $items[$delta]['type_id'];
     }
 
     // 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);
-//       $synonym_id = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__synonym_id');
-//       $pub_id = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__pub_id');
-//       $is_current = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__is_current');
-//       $is_internal = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__is_internal');
-//       $syn_name = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__synonym_id--name');
-//       $syn_type = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__synonym_id--type_id');
+      $record_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $table_name . '__' . $pkey];
+      $fkey_value = $form_state['values'][$field_name]['und'][$delta]['chado-' . $table_name . '__' . $fkey];
+      $synonym_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $table_name . '__synonym_id'];
+      $pub_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $table_name . '__pub_id'];
+      $is_current = $form_state['values'][$field_name]['und'][$delta]['chado-' . $table_name . '__is_current'];
+      $is_internal = $form_state['values'][$field_name]['und'][$delta]['chado-' . $table_name . '__is_internal'];
+      $syn_name = $form_state['values'][$field_name]['und'][$delta]['name'];
+      $syn_type = $form_state['values'][$field_name]['und'][$delta]['type_id'];
     }
 
-    // Get the synonym type terms.  There shouldn't be too many.
-    $cv = tripal_get_default_cv('synonym', 'type_id');
-    $options = tripal_get_cvterm_select_options($cv->cv_id);
+    $options = array();
 
     // Get the schema for the synonym table so we can make sure we limit the
     // size of the name field to the proper size.
@@ -105,7 +103,6 @@ class chado_linker__synonym extends TripalField {
 
     $widget['#table_name'] = $table_name;
     $widget['#fkey_field'] = $fkey;
-//    $widget['#element_validate'] = array('chado_linker__synonym_widget_validate');
     $widget['#theme'] = 'chado_linker__synonym_widget';
     $widget['#prefix'] =  "<span id='$table_name-$delta'>";
     $widget['#suffix'] =  "</span>";
@@ -115,113 +112,158 @@ class chado_linker__synonym 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 . '__synonym_id'] = array(
+      '#type' => 'value',
+      '#default_value' => $fkey_value,
+    );
+    $widget['chado-' . $table_name . '__' . $fkey] = array(
       '#type' => 'value',
       '#default_value' => $fkey_value,
     );
     // TODO: add a widget for selecting a publication.
-    $widget[$table_name . '__pub_id'] = array(
+    $widget['chado-' . $table_name . '__pub_id'] = array(
       '#type' => 'value',
       '#default_value' => $pub_id,
     );
-    $widget[$table_name . '__synonym_id--type_id'] = array(
+    $widget['type_id'] = array(
       '#type' => 'select',
       '#title' => t('Type'),
       '#options' => $options,
       '#default_value' => $syn_type,
     );
-    $widget[$table_name . '__synonym_id--name'] = array(
+    $widget['name'] = array(
       '#type' => 'textfield',
       '#title' => t('Synonym Name'),
       '#default_value' => $syn_name,
       '#size' => 25,
     );
 
-    $widget[$table_name . '__is_current'] = array(
+    $widget['chado-' . $table_name . '__is_current'] = array(
       '#type' => 'checkbox',
       '#title' => t('Is Current'),
       '#default_value' => $is_current,
       '#required' => $element['#required'],
     );
 
-    $widget[$table_name . '__is_internal'] = array(
+    $widget['chado-' . $table_name . '__is_internal'] = array(
       '#type' => 'checkbox',
       '#title' => t('Is Internal'),
       '#default_value' => $is_internal,
       '#required' => $element['#required'],
     );
   }
-  
-  public function widgetFormSubmit($entity_type, $entity, $langcode, &$items, $form, &$form_state) {
 
-    $field_name = $element['#field_name'];
-    $delta = $element['#delta'];
-    $table_name = $element['#table_name'];
-    $fkey = $element['#fkey_field'];
-    
-    // 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;
-    }
-    
+  /**
+   * @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];
+
     // Get the field values.
-    //   $fkey_value = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__' . $fkey);
-    //   $synonym_id = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__synonym_id');
-    //   $pub_id = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__pub_id');
-    //   $is_current = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__is_current');
-    //   $is_internal = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__is_internal');
-    //   $syn_name = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '--synonym__name');
-    //   $syn_type = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '--synonym__type_id');
-    
-    // Make sure that if a synonym is provided that a type is also
-    // provided.
-    if ($syn_name and !$syn_type) {
-      form_set_error(implode('][', $element ['#parents']) . '][' . $table_name . '--synonym__type_id', t("Please set a synonym type."));
-    }
-    if (!$syn_name and $syn_type) {
-      form_set_error(implode('][', $element ['#parents']) . '][' . $table_name . '--synonym__name', t("Please set a synonym name."));
+    foreach ($items as $delta => $values) {
+
+      $record_id = $values['chado-' . $table_name . '__' . $pkey];
+      $fkey_value = $values['chado-' . $table_name . '__' . $fkey];
+      $synonym_id = $values['chado-' . $table_name . '__synonym_id'];
+      $pub_id = $values['chado-' . $table_name . '__pub_id'];
+      $is_current = $values['chado-' . $table_name . '__is_current'];
+      $is_internal = $values['chado-' . $table_name . '__is_internal'];
+      $syn_name = $values['name'];
+      $syn_type = $values['type_id'];
+
+
+      // Make sure that if a synonym is provided that a type is also
+      // provided.
+      if ($syn_name and !$syn_type) {
+        $errors[$field_name][$delta]['und'][] = array(
+          'message' => t("Please set a synonym type."),
+          'error' => 'chado_linker__synonym',
+        );
+      }
+      if (!$syn_name and $syn_type) {
+        $errors[$field_name][$delta]['und'][] = array(
+          'message' => t("Please set a synonym name."),
+          'error' => 'chado_linker__synonym',
+        );
+      }
     }
-    // If the user provided a cv_id and a name then we want to set the
-    // foreign key value to be the chado_record_idd
-    if ($syn_name and $syn_type) {
-    
-      // Get the synonym. If one with the same name and type is already present
-      // then use that. Otherwise, insert a new one.
-      if (!$synonym_id) {
-        $synonym = chado_generate_var('synonym', array('name' => $syn_name, 'type_id' => $syn_type));
-        if (!$synonym) {
-          $synonym = chado_insert_record('synonym', array(
-            'name' => $syn_name,
-            'type_id' => $syn_type,
-            'synonym_sgml' => '',
-          ));
-          $synonym = (object) $synonym;
+  }
+
+  /**
+   * @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) {
+
+      $record_id = $values['chado-' . $table_name . '__' . $pkey];
+      $fkey_value = $values['chado-' . $table_name . '__' . $fkey];
+      $synonym_id = $values['chado-' . $table_name . '__synonym_id'];
+      $pub_id = $values['chado-' . $table_name . '__pub_id'];
+      $is_current = $values['chado-' . $table_name . '__is_current'];
+      $is_internal = $values['chado-' . $table_name . '__is_internal'];
+      $syn_name = $values['name'];
+      $syn_type = $values['type_id'];
+
+      // If the user provided a $syn_name and a $syn_type then we want to set
+      // the foreign key value to be the chado_record_id.
+      if ($syn_name and $syn_type) {
+
+        // Get the synonym. If one with the same name and type is already present
+        // then use that. Otherwise, insert a new one.
+        if (!$synonym_id) {
+          $synonym = chado_generate_var('synonym', array('name' => $syn_name, 'type_id' => $syn_type));
+          if (!$synonym) {
+            $synonym = chado_insert_record('synonym', array(
+              'name' => $syn_name,
+              'type_id' => $syn_type,
+              'synonym_sgml' => '',
+            ));
+            $synonym = (object) $synonym;
+          }
+
+          // Set the synonym_id and FK value
+          $items[$delta]['chado-' . $table_name . '__synonym_id'] = $synonym->synonym_id;
+        }
+
+        if (!$pub_id) {
+          $pub = chado_generate_var('pub', array('uniquename' => 'null'));
+          $items[$delta]['chado-' . $table_name . '__pub_id'] = $pub->pub_id;
         }
-    
-        // Set the synonym_id and FK value
-        tripal_chado_set_field_form_values($field_name, $form_state, $synonym->synonym_id, $delta, $table_name . '__synonym_id');
-        $fkey_value = $element['#entity']->chado_record_id;
-        tripal_chado_set_field_form_values($field_name, $form_state, $fkey_value, $delta, $table_name . '__' . $fkey);
       }
-    
-      if (!$pub_id) {
-        $pub = chado_generate_var('pub', array('uniquename' => 'null'));
-        tripal_chado_set_field_form_values($field_name, $form_state, $pub->pub_id, $delta, $table_name . '__pub_id');
+      else {
+        // If the $syn_name is not set, then remove the linker FK value to the base table.
+        $items[$delta]['chado-' . $table_name . '__' . $fkey] = '';
+        $items[$delta]['chado-' . $table_name . '__synonym_id'] = '';
+        $items[$delta]['chado-' . $table_name . '__is_internal'] = '';
+        $items[$delta]['chado-' . $table_name . '__is_current'] = '';
       }
     }
-    else {
-      // If the $syn_name is 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);
-      tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__synonym_id');
-      tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__is_internal');
-      tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__is_current');
-    }
   }
 
   /**
@@ -249,14 +291,14 @@ class chado_linker__synonym 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 . '__' . 'synonym_id' => '',
-      $field_table . '__' . 'pub_id' => '',
-      $field_table . '__' . 'is_current' => TRUE,
-      $field_table . '__' . 'is_internal' => '',
-      $field_table . '__synonym_id--name' => '',
-      $field_table . '__synonym_id--type_id' => '',
+      'chado-' . $field_table . '__' . $pkey => '',
+      'chado-' . $field_table . '__' . $fkey_lcolumn => '',
+      'chado-' . $field_table . '__' . 'synonym_id' => '',
+      'chado-' . $field_table . '__' . 'pub_id' => '',
+      'chado-' . $field_table . '__' . 'is_current' => TRUE,
+      'chado-' . $field_table . '__' . 'is_internal' => '',
+      'name' => '',
+      'type_id' => '',
       // Ignore the synonym_sgml column for now.
     );
 
@@ -273,14 +315,14 @@ class chado_linker__synonym extends TripalField {
             'type' => $synonym->type_id->name,
             'name' => $synonym->name,
           ),
-          $field_table . '__' . $pkey = $linker->$pkey,
-          $field_table . '__' . $fkey_lcolumn => $linker->$fkey_lcolumn->$fkey_lcolumn,
-          $field_table . '__' . 'synonym_id' => $synonym->synonym_id,
-          $field_table . '__' . 'pub_id' => $linker->pub_id->pub_id,
-          $field_table . '__' . 'is_current' => $linker->is_current,
-          $field_table . '__' . 'is_internal' => $linker->is_internal,
-          $field_table . '__synonym_id--name' => $synonym->name,
-          $field_table . '__synonym_id--type_id' => $synonym->type_id->cvterm_id,
+          'chado-' . $field_table . '__' . $pkey = $linker->$pkey,
+          'chado-' . $field_table . '__' . $fkey_lcolumn => $linker->$fkey_lcolumn->$fkey_lcolumn,
+          'chado-' . $field_table . '__' . 'synonym_id' => $synonym->synonym_id,
+          'chado-' . $field_table . '__' . 'pub_id' => $linker->pub_id->pub_id,
+          'chado-' . $field_table . '__' . 'is_current' => $linker->is_current,
+          'chado-' . $field_table . '__' . 'is_internal' => $linker->is_internal,
+          'name' => $synonym->name,
+          'type_id' => $synonym->type_id->cvterm_id,
         );
         $i++;
       }
@@ -304,16 +346,16 @@ function theme_chado_linker__synonym_widget($variables) {
   $layout = "
       <div class=\"synonym-widget\">
         <div class=\"synonym-widget-item\">" .
-        drupal_render($element[$table_name . '__synonym_id--name']) . "
+          drupal_render($element['name']) . "
         </div>
         <div>" .
-        drupal_render($element[$table_name . '__synonym_id--type_id']) . "
+          drupal_render($element['type_id']) . "
         </div>
         <div class=\"synonym-widget-item\">" .
-        drupal_render($element[$table_name . '__is_internal']) . "
+          drupal_render($element['chado-' . $table_name . '__is_internal']) . "
         </div>
         <div>" .
-        drupal_render($element[$table_name . '__is_current']) . "
+          drupal_render($element['chado-' . $table_name . '__is_current']) . "
         </div>
       </div>
     ";

+ 1 - 16
tripal_chado/includes/tripal_chado.entity.inc

@@ -135,22 +135,7 @@ function tripal_chado_entity_update($entity, $type) {
  * Implements hook_entity_delete().
  */
 function tripal_chado_entity_delete($entity, $type) {
-  $record = db_select('chado_entity', 'ce')
-    ->fields('ce', array('chado_entity_id', 'data_table', 'record_id'))
-    ->condition('entity_id', $entity->id)
-    ->execute()
-    ->fetchObject();
-
-  if ($record && property_exists($record, 'chado_entity_id')) {
-    // Delete the corresponding record in Chado
-    $table = $record->data_table;
-    $record_id = $record->record_id;
-    chado_delete_record($table, array($table . '_id' => $record_id));
-
-    //Delete the record in the public.chado_entity table
-    $sql = "DELETE FROM {chado_entity} WHERE chado_entity_id = :id";
-    db_query($sql, array(':id' => $record->chado_entity_id));
-  }
+
 }
 
 /**

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

@@ -717,6 +717,7 @@ function tripal_chado_create_tripalfield_instance_base(&$info, $entity_type, $bu
         break;
       case 'boolean':
         $base_info['widget']['type'] = 'options_onoff';
+        $base_info['required'] = FALSE;
         break;
       case 'datetime':
         $base_info['widget']['type'] = 'date_select';

+ 12 - 0
tripal_chado/tripal_chado.module

@@ -530,6 +530,14 @@ function tripal_chado_menu() {
     'file path' => drupal_get_path('module', 'tripal_chado'),
     'type' => MENU_CALLBACK,
   );
+  $items['admin/tripal/storage/chado/auto_name/contact/%'] = array(
+    'page callback' => 'tripal_autocomplete_contact',
+    'page arguments' => array(6),
+    'access arguments' => array('access content'),
+    'file' => 'api/modules/tripal_chado.contact.api.inc',
+    'file path' => drupal_get_path('module', 'tripal_chado'),
+    'type' => MENU_CALLBACK,
+  );
   $items['admin/tripal/storage/chado/auto_name/feature/%'] = array(
     'page callback' => 'tripal_autocomplete_feature',
     'page arguments' => array(6),
@@ -606,6 +614,10 @@ function tripal_chado_theme($existing, $type, $theme, $path) {
       'render element' => 'element',
       'file' => 'includes/TripalFields/chado_linker__pub.inc',
     ),
+    'chado_linker__contact_widget' => array(
+      'render element' => 'element',
+      'file' => 'includes/TripalFields/chado_linker__contact.inc',
+    ),
     'chado_linker__prop_adder_widget' => array(
       'render element' => 'element',
       'file' => 'includes/TripalFields/chado_linker__prop_adder.inc',