Browse Source

Removed the _adder fields. User's now add new properties and cvterms using the typical field managmenet page.

Stephen Ficklin 8 years ago
parent
commit
1ef5aa8a95

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

@@ -53,6 +53,15 @@ class TripalField {
   // The default formatter for this field.
   public static $default_formatter = '';
 
+  // The module that manages this field.
+  public static $module = 'tripal';
+
+  // A boolean specifying that users should not be allowed to create
+  // fields and instances of this field type through the UI. Such
+  // fields can only be created programmatically with field_create_field()
+  // and field_create_instance().
+  public static $no_ui = TRUE;
+
   // --------------------------------------------------------------------------
   //              PROTECTED CLASS MEMBERS -- DO NOT OVERRIDE
   // --------------------------------------------------------------------------
@@ -127,6 +136,7 @@ class TripalField {
       'instance_settings' => $class::$default_instance_settings,
       'default_widget' => $class::$default_widget,
       'default_formatter' => $class::$default_formatter,
+      'no_ui' => $class::$no_ui,
     );
   }
 

+ 99 - 24
tripal/includes/tripal.fields.inc

@@ -231,6 +231,55 @@ function tripal_form_field_ui_field_overview_form_alter(&$form, &$form_state, $f
       want all biological content to be stored in Chado, be sure that the
       respective fields are "supported by" Chado.',
   );
+
+  $form['#submit'] = array_merge(array('tripal_form_field_ui_field_overview_form_submit'), $form['#submit']);
+}
+
+/**
+ * A submit function for the field_ui_field_overview_form.
+ */
+function tripal_form_field_ui_field_overview_form_submit($form, &$form_state) {
+  $form_values = $form_state['values']['fields'];
+  $admin_path = _field_ui_bundle_admin_path('TripalEntity', $form['#bundle']);
+
+  $destinations = array();
+
+  if (!empty($form_values['_add_new_field']['field_name'])) {
+    try {
+      // Is the field type a TripalField? If so then we want
+      // to pass of creation of the field to the module that manages that field.
+      $type = $form_values['_add_new_field']['type'];
+      if (tripal_load_include_field_class($type)) {
+        $module = $type::$module;
+        $function = $module . '_form_field_ui_field_overview_add_new';
+        $bundle = tripal_load_bundle_entity(array('name' => $form['#bundle']));
+        $field_name = $form_values['_add_new_field']['field_name'];
+        if (function_exists($function)) {
+          $function($form_values['_add_new_field'], $bundle);
+        }
+        $destinations[] = $admin_path . '/fields/' . $field_name . '/field-shcef';
+        $destinations[] = $admin_path . '/fields/' . $field_name;
+
+        // Store new field information for any additional submit handlers.
+        $form_state['fields_added']['_add_new_field'] = $field['field_name'];
+        unset($form_state['values']['fields']['_add_new_field']);
+        drupal_set_message('Please set the controlled vocabulary that best describes the data of this field. See the "Controlled Vocabulary Term" section below.');
+      }
+    }
+    catch (Exception $e) {
+      drupal_set_message(t('There was a problem creating field %label: !message', array('%label' => $instance['label'], '!message' => $e->getMessage())), 'error');
+    }
+
+    if ($destinations) {
+      $destination = drupal_get_destination();
+      $destinations[] = $destination['destination'];
+      unset($_GET['destination']);
+      $form_state['redirect'] = field_ui_get_destinations($destinations);
+    }
+    else {
+      drupal_set_message(t('Your settings have been saved.'));
+    }
+  }
 }
 
 /**
@@ -320,7 +369,7 @@ function tripal_field_instance_settings_form_process($element, &$form_state, $fo
       'header' => TRUE,
       'width' => '20%',
     ),
-    $term['vocabulary']['name'] . ' (' . $term['vocabulary']['short_name'] . ') ' . $term['vocabulary']['description']
+    $term['vocabulary']['name'] . ' (' . $vocabulary. ') ' . $term['vocabulary']['description']
   );
   $rows[] = array(
     array(
@@ -328,7 +377,7 @@ function tripal_field_instance_settings_form_process($element, &$form_state, $fo
       'header' => TRUE,
       'width' => '20%',
     ),
-    $term['name'] . ':' . $term['accession']
+    $vocabulary . ':' . $accession
   );
   $rows[] = array(
     array(
@@ -400,6 +449,9 @@ function tripal_field_instance_settings_form_process($element, &$form_state, $fo
   if (array_key_exists('values', $form_state) and array_key_exists('new_name', $form_state['values'])) {
     $term_name = array_key_exists('values', $form_state) ? $form_state['values']['new_name'] : '';
   }
+  if (array_key_exists('input', $form_state) and array_key_exists('new_name', $form_state['input'])) {
+    $term_name = array_key_exists('input', $form_state) ? $form_state['input']['new_name'] : '';
+  }
   if ($term_name) {
     $element['field_term']['instructions'] = array(
       '#type' => 'item',
@@ -468,18 +520,52 @@ function tripal_field_instance_settings_form($field, $instance) {
  * Validate our custom instance settings form fields.
  */
 function tripal_field_instance_settings_form_validate($form, &$form_state) {
+  $field = $form['#field'];
+  $instance = $form['#instance'];
+
   // If the user clicked the submit button then we want set the
   // instance settings values accordingly.
-  foreach ($form_state['input'] as $key => $value) {
-    $matches = array();
-    if (preg_match("/^term-(\d+)$/", $key, $matches) and
-        $form_state['input']['term-' . $matches[1]]) {
-      $cvterm_id = $matches[1];
-      // TODO: this should not call a Chado function.
-      $term = chado_generate_var('cvterm', array('cvterm_id' => $cvterm_id));
-      $form_state['values']['instance']['settings']['term_vocabulary'] = $term->dbxref_id->db_id->name;
-      $form_state['values']['instance']['settings']['term_accession'] = $term->dbxref_id->accession;
-      $form_state['values']['instance']['settings']['term_name'] = $term->name;
+
+  if (array_key_exists('clicked_button', $form_state) and $form_state['clicked_button']['#executes_submit_callback'] == TRUE) {
+    $has_default = FALSE;
+    if ($form_state['values']['term_vocabulary']) {
+      $has_default = TRUE;
+    }
+
+    $started_new_term = FALSE;
+    if (array_key_exists('new_name', $form_state['values']) and $form_state['values']['new_name']) {
+      $started_new_term = TRUE;
+    }
+
+    $num_selected = 0;
+    $selected_term = FALSE;
+    foreach ($form_state['input'] as $key => $value) {
+
+      $matches = array();
+
+      if (preg_match("/^term-(\d+)$/", $key, $matches) and
+          $form_state['input']['term-' . $matches[1]]) {
+        $cvterm_id = $matches[1];
+        // TODO: this should not call a Chado function.
+        $term = chado_generate_var('cvterm', array('cvterm_id' => $cvterm_id));
+        $form_state['values']['instance']['settings']['term_vocabulary'] = $term->dbxref_id->db_id->name;
+        $form_state['values']['instance']['settings']['term_accession'] = $term->dbxref_id->accession;
+        $form_state['values']['instance']['settings']['term_name'] = $term->name;
+        $selected_term = TRUE;
+        $num_selected++;
+      }
+    }
+
+    if ($num_selected > 1) {
+      form_set_error('term-', 'Please select only one term
+          from the "Controlled Vocabulary Term" section below.');
+    }
+    if ($started_new_term and !$selected_term) {
+      form_set_error('term-', 'Please select a controlled vocabulary term for
+          from the "Controlled Vocabulary Term" section below.');
+    }
+    if (!$has_default) {
+      form_set_error('term_name', 'Fields attached to this content type must be associated with a controlled vocabulary term. Please provide one.');
     }
   }
 }
@@ -494,18 +580,7 @@ function tripal_field_instance_settings_form_submit($form, &$form_state) {
  *
  */
 function tripal_field_widget_form_validate($form, &$form_state) {
-//   $entity = $form['#entity'];
-//   $entity_type = $form['#entity_type'];
-//   $langcode = $form['#language'];
-//   $delta = $form['#delta'];
-//   $field = $form['#field'];
-//   $field_type = $field['type'];
-//   tripal_load_include_field_class($field_type);
-//   if (class_exists($field_type)) {
-//     $instance = $form['#instance'];
-//     $tfield = new $field_type($field, $instance);
-//     $form = $tfield->widgetFormValidate($form, $form_state, $entity_type, $entity, $langcode, $delta);
-//   }
+
 }
 
 

+ 18 - 19
tripal_chado/includes/TripalFields/chado_linker__cvterm/chado_linker__cvterm.inc

@@ -12,7 +12,7 @@ class chado_linker__cvterm extends ChadoField {
   // --------------------------------------------------------------------------
 
   // The default lable for this field.
-  public static $default_label = 'Annotations';
+  public static $default_label = 'Chado Annotation';
 
   // The default description for this field.
   public static $description = 'This record can be annotated with terms from other
@@ -44,17 +44,11 @@ class chado_linker__cvterm extends ChadoField {
   // The default formatter for this field.
   public static $default_formatter = 'chado_linker__cvterm_formatter';
 
-  // --------------------------------------------------------------------------
-  //              PROTECTED CLASS MEMBERS -- DO NOT OVERRIDE
-  // --------------------------------------------------------------------------
-  // An array containing details about the field. The format of this array
-  // is the same as that returned by field_info_fields()
-  protected $field;
-  // An array containing details about an instance of the field. A field does
-  // not have to have an instance.  But if dealing with an instance (such as
-  // when using the widgetForm, formatterSettingsForm, etc.) it should be set.
-  protected $instance;
-
+  // A boolean specifying that users should not be allowed to create
+  // fields and instances of this field type through the UI. Such
+  // fields can only be created programmatically with field_create_field()
+  // and field_create_instance().
+  public static $no_ui = FALSE;
 
   /**
    *
@@ -76,10 +70,17 @@ class chado_linker__cvterm extends ChadoField {
     $field_column = $this->field['settings']['chado_column'];
     $base_table = $this->field['settings']['base_table'];
 
-    $matches = array();
-    preg_match('/(.*?)__(\d+)/', $field_name, $matches);
-    $table_name = $matches[1];
-    $cv_id = $matches[2];
+    $vocabulary = $this->instance['settings']['term_vocabulary'];
+    $accession = $this->instance['settings']['term_accession'];
+    $cvterm = tripal_get_cvterm(array(
+      'dbxref_id' => array(
+        'db_id' => array(
+          'name' => $vocabulary,
+        ),
+        'accession' => $accession,
+      ),
+    ));
+    $cvterm_id = $cvterm->cvterm_id;
 
     // Get the FK that links to the base record.
     $schema = chado_get_schema($field_table);
@@ -114,9 +115,7 @@ class chado_linker__cvterm extends ChadoField {
     $columns = array('*');
     $match = array(
       $fkey_lcolumn => $chado_record->$fkey_rcolumn,
-      'cvterm_id' => array(
-        'cv_id' => $cv_id,
-      ),
+      'cvterm_id' => $cvterm_id,
     );
     $options = array(
       'return_array' => TRUE,

+ 54 - 1
tripal_chado/includes/TripalFields/chado_linker__cvterm/chado_linker__cvterm_formatter.inc

@@ -2,7 +2,7 @@
 
 class chado_linker__cvterm_formatter extends ChadoFieldFormatter {
   // The default lable for this field.
-  public static $default_label = 'Annotations';
+  public static $default_label = 'Chado Annotation';
 
   // The list of field types for which this formatter is appropriate.
   public static $field_types = array('chado_linker__cvterm');
@@ -74,6 +74,59 @@ class chado_linker__cvterm_formatter extends ChadoFieldFormatter {
    * @see TripalFieldFormatter::view()
    */
   public function view(&$element, $entity_type, $entity, $langcode, $items, $display) {
+    $headers = array('Term', 'Definition', 'Is Not', 'Publication');
+    $rows = array();
+
+    $chado_table = $this->field['settings']['chado_table'];
+    foreach ($items as $delta => $item) {
+      if ($item['chado-' . $chado_table . '__cvterm_id']) {
+        $cvterm = chado_generate_var('cvterm', array('cvterm_id' => $item['chado-' . $chado_table . '__cvterm_id']));
+        $dbxref = $cvterm->dbxref_id;
+
+        // Build the accession.
+        $accession = $dbxref->db_id->name . ':' . $dbxref->accession;
+        if ($dbxref->db_id->urlprefix) {
+          $accession = l($accession, tripal_get_dbxref_url($dbxref), array('attributes' => array('target' => '_blank')));
+        }
+
+        // Build the publication reference.
+        $pub_ref = '';
+        $pub_id = $item['chado-' . $chado_table . '__pub_id'];
+        if ($pub_id) {
+          $pub = chado_generate_var('pub', array('pub_id' => $pub_id));
+          $pub_ref = $pub->uniquename;
+        }
+        $rows[] = array(
+          $accession,
+          $cvterm->definition,
+          $item['chado-' . $chado_table . '__is_not'] ? 'Yes' : '',
+          $pub_ref,
+        );
+      }
+    }
 
+    // the $table array contains the headers and rows array as well as other
+    // options for controlling the display of the table.  Additional
+    // documentation can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $table = array(
+      'header' => $headers,
+      'rows' => $rows,
+      'attributes' => array(
+        'id' => "$chado_table-table-terms",
+        'class' => 'tripal-data-table'
+      ),
+      'caption' => '',
+      'sticky' => FALSE,
+      'colgroups' => array(),
+      'empty' => 'There are no annotations of this type',
+    );
+
+    if (count($items) > 0) {
+      $element[0] = array(
+        '#type' => 'markup',
+        '#markup' => theme_table($table),
+      );
+    }
   }
 }

+ 20 - 20
tripal_chado/includes/TripalFields/chado_linker__cvterm/chado_linker__cvterm_widget.inc

@@ -2,7 +2,7 @@
 
 class chado_linker__cvterm_widget extends ChadoFieldWidget {
   // The default lable for this field.
-  public static $default_label = 'Annotations';
+  public static $default_label = 'Chado Annotation';
 
   // The list of field types for which this formatter is appropriate.
   public static $field_types = array('chado_linker__cvterm');
@@ -14,7 +14,7 @@ class chado_linker__cvterm_widget extends ChadoFieldWidget {
   public function form(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) {
     parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element);
     $field_name = $this->field['field_name'];
-    
+
     $matches = array();
     preg_match('/(.*?)__(\d+)/', $field_name, $matches);
     // If the field name is not properly formatted then we can't tell what
@@ -24,7 +24,7 @@ class chado_linker__cvterm_widget extends ChadoFieldWidget {
     }
     $table_name = $matches[1];
     $cv_id = $matches[2];
-    
+
     // Get the FK column that links to the base table.
     $chado_table = $this->field['settings']['chado_table'];
     $base_table = $this->field['settings']['base_table'];
@@ -32,7 +32,7 @@ class chado_linker__cvterm_widget extends ChadoFieldWidget {
     $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;
@@ -42,7 +42,7 @@ class chado_linker__cvterm_widget extends ChadoFieldWidget {
     $uname = '';
     $is_not = '';
     $cvterm = NULL;
-    
+
     // 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)) {
@@ -56,7 +56,7 @@ class chado_linker__cvterm_widget extends ChadoFieldWidget {
       $is_not = $items[$delta]['chado-' . $table_name . '__is_not'];
       $cvterm_id = $items[$delta]['chado-' . $table_name . '__cvterm_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'])) {
       // See example in chado_linker_contact.inc
@@ -65,25 +65,25 @@ class chado_linker__cvterm_widget extends ChadoFieldWidget {
       //       $is_not = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__is_not');
       //       $cvterm_name = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '--cvterm__name');
     }
-    
+
     if ($cvterm_name) {
       $cvterm = chado_generate_var('cvterm', array('cv_id' => $cv_id, 'name' => $cvterm_name));
     }
-    
+
     $schema = chado_get_schema('cvterm');
     $options = tripal_get_cv_select_options();
-    
+
     $widget['#table_name'] = $chado_table;
     $widget['#fkey_field'] = $fkey;
     $widget['#theme'] = 'chado_linker__cvterm_widget';
     $widget['#prefix'] =  "<span id='$table_name-$delta'>";
     $widget['#suffix'] =  "</span>";
-    
+
     $widget['value'] = array(
       '#type' => 'value',
       '#value' => key_exists($delta, $items) ? $items[$delta]['value'] : '',
     );
-    
+
     $widget['chado-' . $table_name . '__' . $pkey] = array(
       '#type' => 'value',
       '#default_value' => $record_id,
@@ -100,7 +100,7 @@ class chado_linker__cvterm_widget extends ChadoFieldWidget {
       '#type' => 'value',
       '#default_value' => $fkey_value,
     );
-    
+
     $widget['cvterm__name'] = array(
       '#type' => 'textfield',
       '#title' => t('Term Name'),
@@ -110,7 +110,7 @@ class chado_linker__cvterm_widget extends ChadoFieldWidget {
       '#autocomplete_path' => 'admin/tripal/storage/chado/auto_name/cvterm/' . $cv_id,
       '#size' => 30
     );
-    
+
     $widget['pub'] = array(
       '#type' => 'textfield',
       '#title' => t('Publication'),
@@ -124,19 +124,19 @@ class chado_linker__cvterm_widget extends ChadoFieldWidget {
       ),
       '#maxlength' => 100000,
     );
-    
+
     $widget['chado-' . $table_name . '__pub_id'] = array(
       '#type' => 'value',
       '#default_value' => $pub_id ? $pub_id : 1,
     );
-    
+
     $widget['chado-' . $table_name . '__is_not'] = array(
       '#type' => 'checkbox',
       '#title' => t('Is Not'),
       '#default_value' => $is_not,
       '#required' => $element['#required'],
     );
-    
+
     $widget['cvterm__definition'] = array(
       '#type' => 'item',
       '#markup' => '',
@@ -170,19 +170,19 @@ class chado_linker__cvterm_widget extends ChadoFieldWidget {
     $base_table = $this->field['settings']['base_table'];
     $lfkey_field = key($schema['foreign keys'][$base_table]['columns']);
     $rfkey_field = $schema['foreign keys'][$base_table]['columns'][$lfkey_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;
     }
-    
+
     // 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
     $cvterm_name = isset($form_state['values'][$field_name][$langcode][$delta]['cvterm__name']) ? $form_state['values'][$field_name][$langcode][$delta]['cvterm__name'] : '';
-    
+
     if (!$cvterm_name) {
       $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__cvterm_id'] = '';
       $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__' . $lfkey_field] = '';

+ 0 - 78
tripal_chado/includes/TripalFields/chado_linker__cvterm_adder/chado_linker__cvterm_adder.inc

@@ -1,78 +0,0 @@
-<?php
-
-class chado_linker__cvterm_adder extends ChadoField {
-
-
-  // --------------------------------------------------------------------------
-  //                     EDITABLE STATIC CONSTANTS
-  //
-  // The following constants SHOULD be set for each descendent class.  They are
-  // used by the static functions to provide information to Drupal about
-  // the field and it's default widget and formatter.
-  // --------------------------------------------------------------------------
-
-
-  // The default lable for this field.
-  public static $default_label = 'Add an Annotation Type';
-
-  // The default description for this field.
-  public static $description = 'This record may have any number of types of
-        annotations. Use this field to first add the type.';
-
-  // Provide a list of instance specific settings. These can be access within
-  // the instanceSettingsForm.  When the instanceSettingsForm is submitted
-  // then Drupal with automatically change these settings for the instnace.
-  // It is recommended to put settings at the instance level whenever possible.
-  // If you override this variable in a child class be sure to replicate the
-  // term_name, term_vocab, term_accession and term_fixed keys as these are
-  // required for all TripalFields.
-  public static $default_instance_settings  = array(
-    // The short name for the vocabulary (e.g. shcema, SO, GO, PATO, etc.).
-    'term_vocabulary' => 'local',
-    // The name of the term.
-    'term_name' => 'cvterm',
-    // The unique ID (i.e. accession) of the term.
-    'term_accession' => 'cvterm',
-    // Set to TRUE if the site admin is allowed to change the term
-    // type. This will create form elements when editing the field instance
-    // to allow the site admin to change the term settings above.
-    'term_fixed' => TRUE,
-  );
-
-  // The default widget for this field.
-  public static $default_widget = 'chado_linker__cvterm_adder_widget';
-
-  // The default formatter for this field.
-  public static $default_formatter = 'chado_linker__cvterm_adder_formatter';
-
-  // --------------------------------------------------------------------------
-  //              PROTECTED CLASS MEMBERS -- DO NOT OVERRIDE
-  // --------------------------------------------------------------------------
-  // An array containing details about the field. The format of this array
-  // is the same as that returned by field_info_fields()
-  protected $field;
-  // An array containing details about an instance of the field. A field does
-  // not have to have an instance.  But if dealing with an instance (such as
-  // when using the widgetForm, formatterSettingsForm, etc.) it should be set.
-  protected $instance;
-
-
-  /**
-   *
-   * @see TripalField::validate()
-   */
-  public function validate($entity_type, $entity, $field, $items, &$errors) {
-
-  }
-
-
-  /**
-   *
-   * @see TripalField::load()
-   */
-  public function load($entity, $details = array()) {
-
-  }
-
-
-}

+ 0 - 25
tripal_chado/includes/TripalFields/chado_linker__cvterm_adder/chado_linker__cvterm_adder_formatter.inc

@@ -1,25 +0,0 @@
-<?php
-
-class chado_linker__cvterm_adder_formatter extends ChadoFieldFormatter {
-  // The default lable for this field.
-  public static $default_label = 'Add an Annotation Type';
-
-  // The list of field types for which this formatter is appropriate.
-  public static $field_types = array('chado_linker__cvterm_adder');
-
-  /**
-   *
-   * @see TripalFieldFormatter::settingsForm()
-   */
-  public function settingsForm($view_mode, $form, &$form_state) {
-
-  }
-
-  /**
-   *
-   * @see TripalFieldFormatter::view()
-   */
-  public function view(&$element, $entity_type, $entity, $langcode, $items, $display) {
-
-  }
-}

+ 0 - 178
tripal_chado/includes/TripalFields/chado_linker__cvterm_adder/chado_linker__cvterm_adder_widget.inc

@@ -1,178 +0,0 @@
-<?php
-
-class chado_linker__cvterm_adder_widget extends ChadoFieldWidget {
-  // The default lable for this field.
-  public static $default_label = 'Add an Annotation Type';
-
-  // The list of field types for which this formatter is appropriate.
-  public static $field_types = array('chado_linker__cvterm_adder');
-
-  /**
-   *
-   * @see TripalFieldWidget::form()
-   */
-  public function form(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) {
-    parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element);
-    // This field has no value field.  Just a fieldset for adding new annotation types.
-    $widget['#type'] = 'fieldset';
-    $widget['#title'] = $element['#title'];
-    $widget['#description'] = $element['#description'];
-    $widget['#group'] = 'entity_form_vtabs';
-    
-    $widget['cvterm_class_adder_instructions'] = array(
-      '#type' => 'item',
-      '#markup' => t('You may add annotation types to this form by
-          providing a vocabulary name in the field above
-          and clicking the "Add Annotation Type" button.  This will add a
-          new field to the form above for the vocabulary you entered which
-          will allow users to associate terms from that vocabulary to
-          this record.'),
-    );
-    
-    $options = tripal_get_cv_select_options();
-    $widget['value'] = array(
-      '#type' => 'select',
-      '#title' => t('Vocabulary'),
-      '#options' => $options,
-      '#description' => t("Please enter the vocabulary that contains terms
-          you want to allow users to use for annotations."),
-    );
-    
-    //    $widget['#element_validate'] = array('chado_linker__cvterm_adder_widget_validate');
-    
-    // When this button is clicked, the form will be validated and submitted.
-    // Therefore, we set custom submit and validate functions to override the
-    // default form submit.  In the validate function we set the form_state
-    // to rebuild the form so the submit function never actually gets called,
-    // but we need it or Drupal will run the default validate anyway.
-    // we also set #limit_validation_errors to empty so fields that
-    // are required that don't have values won't generate warnings.
-    $widget['cvterm_class_adder_button'] = array(
-      '#value' => t('Add Annotation Type'),
-      '#type' => 'submit',
-      '#name' => 'cvterm_class_adder_button',
-      //      '#submit' => array('chado_linker__cvterm_adder_widget_submit'),
-      '#limit_validation_errors' => array(array($this->field['field_name'])),
-    );
-  }
-
-  /**
-   * Performs validation of the widgetForm.
-   *
-   * Use this validate to ensure that form values are entered correctly.  Note
-   * this is different from the validate() function which ensures that the
-   * field data meets expectations.
-   *
-   * @param $form
-   * @param $form_state
-   */
-  public function validate($form, &$form_state, $entity_type, $entity, $langcode, $delta) {
-    if (array_key_exists('triggering_element', $form_state) and
-        $form_state['triggering_element']['#name'] == 'cvterm_class_adder_button') {
-          $this_field = $this->field;
-          $field_name = $this_field['field_name'];
-          $bundle = $entity->bundle;
-    
-          // Get the base table name from the field annotations.
-          $base_table = $entity->chado_table;
-          $cvterm_class_adder = $form_state['values'][$base_table . '_cvterm'][$langcode][$delta]['value'];
-          $cv = chado_generate_var('cv', array('cv_id' => $cvterm_class_adder));
-    
-          // Make sure a valid vocabulary is selected
-          if (!$cv) {
-            form_set_error("$field_name][$langcode][$delta][value", "Please select a vocabulary.");
-          }
-          else {
-            // Make sure this vocabulary doesn't already have a field
-            if (key_exists($field_name . '__' . $cv->cv_id, $form_state['values'])) {
-              form_set_error("$field_name][$langcode][$delta][wrapper][terms_name", "Field for this vocabulary already exists. Please select another vocabulary.");
-            }
-          }
-        }
-  }
-
-
-  /**
-   *
-   * @see TripalFieldWidget::submit()
-   */
-  public function submit($form, &$form_state, $entity_type, $entity, $langcode, $delta) {
-    // Add the new field to the entity
-    if (array_key_exists('triggering_element', $form_state) and
-        $form_state['triggering_element']['#name'] == 'cvterm_class_adder_button') {
-    
-          $form_state['rebuild'] = TRUE;
-          $this_field = $this->field;
-          $field_name = $this_field['field_name'];
-          $bundle = $entity->bundle;
-    
-          // Get the base table name from the field annotations.
-          $base_table = $entity->chado_table;
-          $cvterm_class_adder = $form_state['values'][$base_table . '_cvterm'][$langcode][$delta]['value'];
-    
-          // Get the vocabulary.
-          //$cvterm_class_adder = tripal_chado_get_field_form_values($field_name, $form_state);
-          $cv = chado_generate_var('cv', array('cv_id' => $cvterm_class_adder));
-    
-          if (!$cv) {
-            return;
-          }
-    
-          $type_field_name = $field_name . '__' . $cv->cv_id;
-    
-          // The field name is the table name in this case. We want to get the
-          // primary key as this should be the field that maps th the value.
-          $schema = chado_get_schema($field_name);
-          $pkey = $schema['primary key'][0];
-    
-          // Add the field if it doesn't already exists.
-          $field = field_info_field($type_field_name);
-          if (!$field) {
-            $create_info = array(
-              'field_name' => $type_field_name,
-              'type' => 'chado_linker__cvterm',
-              'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-              'locked' => FALSE,
-              'storage' => array(
-                'type' => 'field_chado_storage',
-              ),
-              'settings' => array(
-                'chado_table' => $field_name,
-                'chado_column' => $pkey,
-                'base_table' => $base_table,
-              ),
-            );
-            $field = field_create_field($create_info);
-          }
-    
-          // Attach the field to the bundle if it isn't already.
-          if (!$field or !array_key_exists('bundles', $field) or
-              !array_key_exists('TripalEntity', $field['bundles']) or
-              !in_array($bundle, $field['bundles']['TripalEntity'])) {
-                $createInstanceInfo = array(
-                  'field_name' => $type_field_name,
-                  'entity_type' => 'TripalEntity',
-                  'bundle' => $bundle,
-                  'label' => ucfirst(preg_replace('/_/', ' ', $cv->name)),
-                  'description' => "Annotations from the $cv->name vocabulary",
-                  'required' => FALSE,
-                  'settings' => array(),
-                  'widget' => array(
-                    'type' => 'chado_linker__cvterm_widget',
-                    'settings' => array(
-                      'display_label' => 1,
-                    ),
-                  ),
-                  'display' => array(
-                    'default' => array(
-                      'label' => 'above',
-                      'type' => 'chado_linker__cvterm_formatter',
-                      'settings' => array(),
-                    ),
-                  ),
-                );
-                $instance = field_create_instance($createInstanceInfo);
-              }
-        }
-  }
-}

+ 8 - 2
tripal_chado/includes/TripalFields/chado_linker__prop/chado_linker__prop.inc

@@ -12,7 +12,7 @@ class chado_linker__prop extends ChadoField {
   // --------------------------------------------------------------------------
 
   // The default lable for this field.
-  public static $default_label = 'Property';
+  public static $default_label = 'Chado Property';
 
   // The default description for this field.
   public static $description = 'Add details about this property.';
@@ -43,6 +43,12 @@ class chado_linker__prop extends ChadoField {
   // The default formatter for this field.
   public static $default_formatter = 'chado_linker__prop_formatter';
 
+  // A boolean specifying that users should not be allowed to create
+  // fields and instances of this field type through the UI. Such
+  // fields can only be created programmatically with field_create_field()
+  // and field_create_instance().
+  public static $no_ui = FALSE;
+
   /**
    *
    * @see TripalField::load()
@@ -79,7 +85,7 @@ class chado_linker__prop extends ChadoField {
       'chado-' . $field_table . '__' . $pkey => '',
       'chado-' . $field_table . '__' . $fkey_lcolumn => $chado_record->{$fkey_lcolumn},
       'chado-' . $field_table . '__value' => '',
-      'chado-' . $field_table . '__type_id' => '',
+      'chado-' . $field_table . '__type_id' => $cvterm_id,
       'chado-' . $field_table . '__rank' => '',
     );
 

+ 1 - 1
tripal_chado/includes/TripalFields/chado_linker__prop/chado_linker__prop_formatter.inc

@@ -2,7 +2,7 @@
 
 class chado_linker__prop_formatter extends ChadoFieldFormatter {
   // The default lable for this field.
-  public static $default_label = 'Property';
+  public static $default_label = 'Chado Property';
 
   // The list of field types for which this formatter is appropriate.
   public static $field_types = array('chado_linker__prop');

+ 55 - 44
tripal_chado/includes/TripalFields/chado_linker__prop/chado_linker__prop_widget.inc

@@ -2,7 +2,7 @@
 
 class chado_linker__prop_widget extends ChadoFieldWidget {
   // The default lable for this field.
-  public static $default_label = 'Property';
+  public static $default_label = 'Chado Property';
 
   // The list of field types for which this formatter is appropriate.
   public static $field_types = array('chado_linker__prop');
@@ -13,64 +13,74 @@ class chado_linker__prop_widget extends ChadoFieldWidget {
    */
   public function form(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) {
     parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element);
+
     $field_name = $this->field['field_name'];
     $field_type = $this->field['type'];
     $field_table = $this->field['settings']['chado_table'];
     $field_column = $this->field['settings']['chado_column'];
     $instance = $this->instance;
-    
-    // Get the table name and cvterm that this field maps to.
-    $matches = array();
-    preg_match('/(.*?)__(\d+)/', $field_name, $matches);
-    // If the field name is not properly formatted then we can't tell what
-    // table and type this is.  So just return.
-    if (count($matches) != 3) {
-      return $widget;
-    }
-    $table_name = $matches[1];
-    $cvterm_id = $matches[2];
-    
+
     // Get the name of the pkey field for this property table and the name
     // of the FK field that links to the base table.
-    $schema = chado_get_schema($table_name);
+    $schema = chado_get_schema($field_table);
     $pkey = $schema['primary key'][0];
     $base_table = $this->field['settings']['base_table'];
     $lfkey_field = key($schema['foreign keys'][$base_table]['columns']);
     $rfkey_field = $schema['foreign keys'][$base_table]['columns'][$lfkey_field];
-    
+
     // Get the field defaults.
-    $fk_value =key_exists(0, $items) ? $items[0]['chado-' . $field_table . '__' . $lfkey_field] : '';
-    $propval = '';
-    if (array_key_exists($delta, $items)) {
-      $propval = tripal_get_field_item_keyval($items, $delta, 'chado-' . $table_name . '__value', $propval);
+    $record_id = '';
+    $fk_value = '';
+    $value = '';
+    $rank = $delta;
+    $type_id = '';
+
+    // 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)) {
+      // Check for element values that correspond to fields in the Chado table.
+      $record_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__' . $pkey, $record_id);
+      $fk_value = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__' . $lfkey_field, $fk_value);
+      $type_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__type_id', $type_id);
+      $value = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__value', $value);
+      $rank = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__rank', $rank);
+    }
+
+    // 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 = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__' . $pkey];
+      $fk_value = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__' . $lfkey_field];
+      $type_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__type_id'];
+      $value = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__value'];
+      $rank = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__rank'];
     }
-    
+
     $widget['value'] = array(
       '#type' => 'value',
-      '#value' => key_exists($delta, $items) ? $items[$delta]['value'] : '',
+      '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
     );
-    
-    $widget['chado-' . $table_name . '__' . $pkey] = array(
+
+    $widget['chado-' . $field_table . '__' . $pkey] = array(
       '#type' => 'hidden',
-      '#default_value' => !empty($items[$delta]['chado-' . $field_table . '__' . $pkey]) ? $items[$delta]['chado-' . $field_table . '__' . $pkey] : '',
+      '#default_value' => $record_id,
     );
-    $widget['chado-' . $table_name . '__' . $lfkey_field] = array(
+    $widget['chado-' . $field_table . '__' . $lfkey_field] = array(
       '#type' => 'hidden',
       '#value' => $fk_value,
     );
-    $widget['chado-' . $table_name . '__value'] = array(
+    $widget['chado-' . $field_table . '__value'] = array(
       '#type' => 'textfield',
-      '#default_value' => $propval,
+      '#default_value' => $value,
       '#title' => $instance['label'] . ' value',
       '#description' => $instance['description'],
     );
-    $widget['chado-' . $table_name . '__type_id'] = array(
+    $widget['chado-' . $field_table . '__type_id'] = array(
       '#type' => 'hidden',
-      '#value' => $cvterm_id,
+      '#value' => $type_id,
     );
-    $widget['chado-' . $table_name . '__rank'] = array(
+    $widget['chado-' . $field_table . '__rank'] = array(
       '#type' => 'hidden',
-      '#value' => $delta,
+      '#value' => $rank,
     );
   }
 
@@ -95,23 +105,24 @@ class chado_linker__prop_widget extends ChadoFieldWidget {
    */
   public function submit($form, &$form_state, $entity_type, $entity, $langcode, $delta) {
     $field_name = $this->field['field_name'];
-    $table_name = $this->field['settings']['chado_table'];
-    $schema = chado_get_schema($table_name);
+    $field_table = $this->field['settings']['chado_table'];
+    $schema = chado_get_schema($field_table);
     $pkey = $schema['primary key'][0];
     $base_table = $this->field['settings']['base_table'];
     $lfkey_field = key($schema['foreign keys'][$base_table]['columns']);
     $rfkey_field = $schema['foreign keys'][$base_table]['columns'][$lfkey_field];
-    
-    $prop_value = isset($form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__value']) ? $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__value'] : '';
-    
-    // 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 (!$prop_value) {
-      $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__' . $pkey] = '';
-      $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__rank'] = '';
-      $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__type_id'] = '';
-      $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__' . $lfkey_field] = '';
+
+    $value = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__value'];
+    $form_state['values'][$field_name]['und'][$delta]['value'] = $value;
+
+    // If the user removed the property then we want to clear out the other
+    // fields so there is no insert.
+    if (!$value) {
+      $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__' . $pkey] = '';
+      $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__' . $lfkey_field] = '';
+      $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__type_id'] = '';
+      $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__value'] = '';
+      $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__rank'] = '';
     }
   }
 }

+ 0 - 76
tripal_chado/includes/TripalFields/chado_linker__prop_adder/chado_linker__prop_adder.inc

@@ -1,76 +0,0 @@
-<?php
-
-class chado_linker__prop_adder extends ChadoField {
-
-
-  // --------------------------------------------------------------------------
-  //                     EDITABLE STATIC CONSTANTS
-  //
-  // The following constants SHOULD be set for each descendent class.  They are
-  // used by the static functions to provide information to Drupal about
-  // the field and it's default widget and formatter.
-  // --------------------------------------------------------------------------
-
-  // The default lable for this field.
-  public static $default_label = 'Add a Property Type';
-
-  // The default description for this field.
-  public static $description = 'This record may have any number of properties. Use
-            this field to first add the type.';
-
-  // Provide a list of instance specific settings. These can be access within
-  // the instanceSettingsForm.  When the instanceSettingsForm is submitted
-  // then Drupal with automatically change these settings for the instnace.
-  // It is recommended to put settings at the instance level whenever possible.
-  // If you override this variable in a child class be sure to replicate the
-  // term_name, term_vocab, term_accession and term_fixed keys as these are
-  // required for all TripalFields.
-  public static $default_instance_settings  = array(
-    // The short name for the vocabulary (e.g. shcema, SO, GO, PATO, etc.).
-    'term_vocabulary' => 'local',
-    // The name of the term.
-    'term_name' => 'property',
-    // The unique ID (i.e. accession) of the term.
-    'term_accession' => 'property',
-    // Set to TRUE if the site admin is allowed to change the term
-    // type. This will create form elements when editing the field instance
-    // to allow the site admin to change the term settings above.
-    'term_fixed' => TRUE,
-  );
-
-  // The default widget for this field.
-  public static $default_widget = 'chado_linker__prop_adder_widget';
-
-  // The default formatter for this field.
-  public static $default_formatter = 'chado_linker__prop_adder_formatter';
-
-  // --------------------------------------------------------------------------
-  //              PROTECTED CLASS MEMBERS -- DO NOT OVERRIDE
-  // --------------------------------------------------------------------------
-  // An array containing details about the field. The format of this array
-  // is the same as that returned by field_info_fields()
-  protected $field;
-  // An array containing details about an instance of the field. A field does
-  // not have to have an instance.  But if dealing with an instance (such as
-  // when using the widgetForm, formatterSettingsForm, etc.) it should be set.
-  protected $instance;
-
-
-  /**
-   *
-   * @see TripalField::validate()
-   */
-  public function validate($entity_type, $entity, $field, $items, &$errors) {
-
-  }
-
-
-  /**
-   *
-   * @see TripalField::load()
-   */
-  public function load($entity, $details = array()) {
-
-  }
-
-}

+ 0 - 25
tripal_chado/includes/TripalFields/chado_linker__prop_adder/chado_linker__prop_adder_formatter.inc

@@ -1,25 +0,0 @@
-<?php
-
-class chado_linker__prop_adder_formatter extends ChadoFieldFormatter {
-  // The default lable for this field.
-  public static $default_label = 'Add a Property Type';
-
-  // The list of field types for which this formatter is appropriate.
-  public static $field_types = array('chado_linker__prop_adder');
-
-  /**
-   *
-   * @see TripalFieldFormatter::settingsForm()
-   */
-  public function settingsForm($view_mode, $form, &$form_state) {
-
-  }
-
-  /**
-   *
-   * @see TripalFieldFormatter::view()
-   */
-  public function view(&$element, $entity_type, $entity, $langcode, $items, $display) {
-
-  }
-}

+ 0 - 281
tripal_chado/includes/TripalFields/chado_linker__prop_adder/chado_linker__prop_adder_widget.inc

@@ -1,281 +0,0 @@
-<?php
-
-class chado_linker__prop_adder_widget extends ChadoFieldWidget {
-  // The default lable for this field.
-  public static $default_label = 'Add a Property Type';
-
-  // The list of field types for which this formatter is appropriate.
-  public static $field_types = array('chado_linker__prop_adder');
-
-  /**
-   *
-   * @see TripalFieldWidget::form()
-   */
-  public function form(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) {
-    parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element);
-    $field_name = $widget['#field_name'];
-
-    $widget['#type'] = 'fieldset';
-    $widget['#title'] = $element['#title'];
-    $widget['#description'] = $element['#description'];
-    $widget['#group'] = 'entity_form_vtabs';
-
-
-    $widget['kvproperty_instructions'] = array(
-      '#type' => 'item',
-      '#markup' => t('You may add additional properties to this form by
-          providing a property name (from a vocabulary) in the field below
-          and clicking the "Lookup Term" button.  Terms that match the value
-          entered will be displayed for selection.  After selecting the
-          appropriate term click the "Use this term" button and a
-          new field will be added to the form above for the property you selected.
-          In the future, this field will be present for all records
-          of this type.'),
-    );
-
-    $term_name = isset($form_state['values'][$field_name]['und'][0]['wrapper']['term_name']) ? $form_state['values'][$field_name]['und'][0]['wrapper']['term_name'] : '';
-
-    // Drupal's vertical feild set is a bit quirky in that we can't just
-    // add a prefix and suffix to the weidget.  If we do, then the
-    // field doesn't show up on the page after an AJAX call.  We have to add
-    // an internal wrapper (below) for AJAX calls.
-    $widget['wrapper'] = array(
-      '#prefix' =>  "<span id='$field_name-lookup-form'>",
-      '#suffix' => '</span>',
-    );
-
-    // If no term has been selected yet then provide the auto complete field.
-    $widget['wrapper']['term_name'] = array(
-      '#title'       => t('Term'),
-      '#type'        => 'textfield',
-      '#description' => t("The content type must be the name of a term in
-        a controlled vocabulary and the controlled vocabulary should
-        already be loaded into Tripal.  For example, to create a content
-        type for storing 'genes', use the 'gene' term from the
-        Sequence Ontology (SO)."),
-      '#default_value' => $term_name,
-      '#autocomplete_path' => "admin/tripal/storage/chado/auto_name/cvterm/",
-    );
-
-    $widget['wrapper']['select_button'] = array(
-      '#type' => 'button',
-      '#value' => t('Lookup Term'),
-      '#name' => 'select_cvterm',
-      '#ajax' => array(
-        'callback' => "tripal_chado_prop_adder_form_ajax_callback",
-        'wrapper' => "$field_name-lookup-form",
-        'effect' => 'fade',
-        'method' => 'replace'
-      ),
-    );
-    if ($term_name) {
-      $widget['wrapper']['terms_list'] = array(
-        '#type' => 'fieldset',
-        '#title' => t('Matching Terms'),
-        '#description' => t('Please select the term the best matches the
-          content type you want to create. If the same term exists in
-          multiple vocabularies you will see more than one option below.')
-      );
-      $match = array(
-        'name' => $term_name,
-      );
-      $terms = chado_generate_var('cvterm', $match, array('return_array' => TRUE));
-      $terms = chado_expand_var($terms, 'field', 'cvterm.definition');
-      $num_terms = 0;
-      foreach ($terms as $term) {
-        // Save the user a click by setting the default value as 1 if there's
-        // only one matching term.
-        $default = FALSE;
-        $attrs = array();
-        if ($num_terms == 0 and count($terms) == 1) {
-          $default = TRUE;
-          $attrs = array('checked' => 'checked');
-        }
-        $widget['wrapper']['terms_list']['term-' . $term->cvterm_id] = array(
-          '#type' => 'checkbox',
-          '#title' =>  $term->name,
-          '#default_value' => $default,
-          '#attributes' => $attrs,
-          '#description' => '<b>Vocabulary:</b> ' . $term->cv_id->name . ' (' . $term->dbxref_id->db_id->name . ') ' . $term->cv_id->definition .
-          '<br><b>Term: </b> ' . $term->dbxref_id->db_id->name . ':' . $term->dbxref_id->accession . '.  ' .
-          '<br><b>Definition:</b>  ' . $term->definition,
-        );
-        $num_terms++;
-      }
-      if ($num_terms == 0) {
-        $widget['wrapper']['terms_list']['none'] = array(
-          '#type' => 'item',
-          '#markup' => '<i>' . t('There is no term that matches the entered text.') . '</i>'
-        );
-      }
-      else {
-        $widget['wrapper']['cardinality'] = array(
-          '#title'       => t('Number of Values'),
-          '#type'        => 'textfield',
-          '#description' => t("A number of 1 or more indicating the number of values allowed for this property. Enter -1 for unlimited values"),
-          '#size' => 10,
-          '#default_value' => 1,
-        );
-        // Add in the button for the cases of no terms or too many.
-        $widget['wrapper']['submit_button'] = array(
-          '#type' => 'submit',
-          '#value' => t('Use this term'),
-          '#name' => 'use_term_button',
-        );
-      }
-    }
-  }
-
-  /**
-   * Performs validation of the widgetForm.
-   *
-   * Use this validate to ensure that form values are entered correctly.  Note
-   * this is different from the validate() function which ensures that the
-   * field data meets expectations.
-   *
-   * @param $form
-   * @param $form_state
-   */
-  public function validate($form, &$form_state, $entity_type, $entity, $langcode, $delta) {
-    $field = $this->field;
-    $field_name = $field['field_name'];
-
-    if ($form_state['triggering_element']['#name'] == 'use_term_button') {
-      // If the user has clicked the 'user_term_button' then we need to makes
-      // sure that the cardinality textbox contains a positive integer.
-      $cardinality = $form_state['values'][$field_name][$langcode][$delta]['wrapper']['cardinality'];
-      if (!preg_match('/^-*\d+$/', $cardinality) or $cardinality < -2 or $cardinality == 0) {
-        form_set_error("$field_name][$langcode][$delta][wrapper][cardinality", "Please provide positive number for the number of values, or -1 for unlimited.");
-      }
-
-      // Get selected terms
-      $terms_list = $form_state['values'][$field_name][$langcode][$delta]['wrapper']['terms_list'];
-      $counter = 0;
-      $selected_term_id = '';
-      foreach ($terms_list AS $term => $selected) {
-        if ($selected) {
-          $selected_term_id = str_replace('term-', '', $term);
-          $counter ++;
-        }
-      }
-      // Make sure at least a term is selected
-      if ($counter == 0) {
-        form_set_error("$field_name][$langcode][$delta][wrapper][terms_list", "Please select a term.");
-      }
-      // Make sure only one term is selected
-      if ($counter > 1) {
-        form_set_error("$field_name][$langcode][$delta][wrapper][terms_list", "Please select only one term.");
-      }
-      // Make sure this property doesn't already have a field
-      if (key_exists($field_name . '__' . $selected_term_id, $form_state['values'])) {
-        form_set_error("$field_name][$langcode][$delta][wrapper][terms_name", "Property already exists. Please select another term.");
-      }
-    }
-  }
-
-
-  /**
-   *
-   * @see TripalFieldWidget::submit()
-   */
-  public function submit($form, &$form_state, $entity_type, $entity, $langcode, $delta) {
-    // Add the new field to the entity but only if the property adder button
-    // was clicked
-    if (!array_key_exists('triggering_element', $form_state) or
-        $form_state['triggering_element']['#name'] != 'use_term_button') {
-          return;
-        }
-        else {
-          // Because we're going to add a new property we want to rebuild the form
-          // rather than have it fully submit.
-          $form_state['rebuild'] = TRUE;
-        }
-
-        // Get the table and base table.
-        $base_table = $this->field['settings']['base_table'];
-
-        // Get the term for the property
-        $field = $this->field;
-        $fname = $field['field_name'];
-        $cardinality = $form_state['values'][$fname][$langcode][$delta]['wrapper']['cardinality'];
-        // Get selected terms
-        $terms_list = $form_state['values'][$fname][$langcode][$delta]['wrapper']['terms_list'];
-        $selected_term_id = '';
-        foreach ($terms_list AS $term => $selected) {
-          if ($selected) {
-            $selected_term_id = str_replace('term-', '', $term);
-          }
-        }
-        $cvterm = chado_generate_var('cvterm', array('cvterm_id' => $selected_term_id));
-
-        // Generate the name for the property table and the field name that we'll
-        // be creating.
-        $prop_table = $base_table . 'prop';
-        $field_name = $prop_table . '__' . $cvterm->cvterm_id;
-
-        // The field name is the table name in this case. We want to get the
-        // primary key as this should be the field that maps th the value.
-        $schema = chado_get_schema($prop_table);
-        $pkey = $schema['primary key'][0];
-
-        // Add the field if it doesn't already exists.
-        $field = field_info_field($field_name);
-        if (!$field) {
-          $field = field_create_field(array(
-            'field_name' => $field_name,
-            'type' => 'chado_linker__prop',
-            'cardinality' => $cardinality,
-            'locked' => FALSE,
-            'storage' => array(
-              'type' => 'field_chado_storage',
-            ),
-            'settings' => array(
-              'chado_table' => $prop_table,
-              'chado_column' => $pkey,
-              'base_table' => $base_table,
-            ),
-          ));
-        }
-
-        // Create an instance of the field.
-        $instance = field_info_instance($entity_type, $field_name,  $entity->bundle);
-        if (!$instance) {
-          $instance = field_create_instance(array(
-            'field_name' => $field_name,
-            'entity_type' => 'TripalEntity',
-            'bundle' => $entity->bundle,
-            'label' => ucfirst(preg_replace('/_/', ' ', $cvterm->name)),
-            'description' => $cvterm->definition ? $cvterm->definition : '',
-            'required' => FALSE,
-            'settings' => array(
-              'auto_attach' => FALSE,
-            ),
-            'widget' => array(
-              'type' => 'chado_linker__prop_widget',
-              'settings' => array(
-                'display_label' => 1,
-              ),
-            ),
-            'display' => array(
-              'default' => array(
-                'label' => 'inline',
-                'type' => 'chado_linker__prop_formatter',
-                'settings' => array(),
-              ),
-            ),
-          ));
-        }
-  }
-}
-
-/**
- *
- */
-function tripal_chado_prop_adder_form_ajax_callback($form, $form_state) {
-  $field_name = $form_state['triggering_element']['#parents'][0];
-
-  // Because this field is inside a vertical fieldset we can't just
-  // return $form[$field_name]. We have set the AJAX call to replace
-  // everything inside of the 'wrapper' element, so we must return that.
-  return $form[$field_name]['und'][0]['wrapper'];
-}

+ 4 - 3
tripal_chado/includes/tripal_chado.field_storage.inc

@@ -237,7 +237,7 @@ function tripal_chado_field_storage_load($entity_type, $entities, $age,
       $field_module = $field['module'];
 
       // Get the instnace for this field
-      $instance = field_info_instance($entity_type, $field_name, $entity->bundle); 
+      $instance = field_info_instance($entity_type, $field_name, $entity->bundle);
 
       // Skip fields that don't map to a Chado table (e.g. kvproperty_adder).
       if (!array_key_exists('settings', $field) or !array_key_exists('chado_table', $field['settings'])) {
@@ -346,6 +346,7 @@ function tripal_chado_field_storage_write_merge_fields($fields, $entity_type, $e
           }
         }
       }
+
       // If there is no value set for the field using the
       // chado-[table_name]__[field name] naming schema then check if a 'value'
       // item is present and if so use that for the table column value.
@@ -357,10 +358,10 @@ function tripal_chado_field_storage_write_merge_fields($fields, $entity_type, $e
         // If this field belongs to the base table then we just add
         // those values in... there's no delta.
         if ($base_table == $chado_table) {
-          $base_fields[$chado_table][$chado_column] = $items[$delta]['value'];
+          $base_fields[$chado_table][$chado_column] = $item['value'];
         }
         else {
-          $temp[$chado_table][$delta][$chado_column] = $items[$delta]['value'];
+          $temp[$chado_table][$delta][$chado_column] = $item['value'];
         }
       }
     }

+ 157 - 66
tripal_chado/includes/tripal_chado.fields.inc

@@ -131,7 +131,7 @@ function tripal_chado_bundle_create_fields_base(&$info, $details, $entity_type,
       'field_name' => $field_name,
       'type' => '',
       'cardinality' => 1,
-      'locked' => FALSE,
+      'locked' => TRUE,
       'storage' => array(
         'type' => 'field_chado_storage',
       ),
@@ -231,7 +231,7 @@ function tripal_chado_bundle_create_fields_custom(&$info, $details, $entity_type
       'field_name' => $field_name,
       'type' => $field_type,
       'cardinality' => 1,
-      'locked' => FALSE,
+      'locked' => TRUE,
       'storage' => array(
         'type' => 'field_chado_storage',
       ),
@@ -251,7 +251,7 @@ function tripal_chado_bundle_create_fields_custom(&$info, $details, $entity_type
       'field_name' => $field_name,
       'type' => $field_type,
       'cardinality' => 1,
-      'locked' => FALSE,
+      'locked' => TRUE,
       'storage' => array(
         'type' => 'field_chado_storage',
       ),
@@ -272,7 +272,7 @@ function tripal_chado_bundle_create_fields_custom(&$info, $details, $entity_type
       'field_name' => $field_name,
       'type' => $field_type,
       'cardinality' => 1,
-      'locked' => FALSE,
+      'locked' => TRUE,
       'storage' => array(
         'type' => 'field_chado_storage',
       ),
@@ -293,7 +293,7 @@ function tripal_chado_bundle_create_fields_custom(&$info, $details, $entity_type
       'field_name' => $field_name,
       'type' => $field_type,
       'cardinality' => 1,
-      'locked' => FALSE,
+      'locked' => TRUE,
       'storage' => array(
         'type' => 'field_chado_storage',
       ),
@@ -313,7 +313,7 @@ function tripal_chado_bundle_create_fields_custom(&$info, $details, $entity_type
       'field_name' => $field_name,
       'type' => $field_type,
       'cardinality' => 1,
-      'locked' => FALSE,
+      'locked' => TRUE,
       'storage' => array(
         'type' => 'field_chado_storage',
       ),
@@ -334,7 +334,7 @@ function tripal_chado_bundle_create_fields_custom(&$info, $details, $entity_type
       'field_name' => $field_name,
       'type' => $field_type,
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'locked' => FALSE,
+      'locked' => TRUE,
       'storage' => array(
         'type' => 'field_chado_storage',
       ),
@@ -354,7 +354,7 @@ function tripal_chado_bundle_create_fields_custom(&$info, $details, $entity_type
 //       'field_name' => $field_name,
 //       'type' => $field_type,
 //       'cardinality' => 1,
-//       'locked' => FALSE,
+//       'locked' => TRUE,
 //       'storage' => array(
 //         'type' => 'field_chado_storage',
 //       ),
@@ -389,7 +389,7 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
       'field_name' => $field_name,
       'type' => $field_type,
       'cardinality' => 1,
-      'locked' => FALSE,
+      'locked' => TRUE,
       'storage' => array(
         'type' => 'field_chado_storage',
       ),
@@ -401,24 +401,6 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
     );
   }
 
-  // CVTERM
-  $cvterm_table = $table_name . '_cvterm';
-  if (chado_table_exists($cvterm_table)) {
-    $field_name = $table_name . '_cvterm';
-    $field_type = 'chado_linker__cvterm_adder';
-    $info[$field_name] = array(
-      'field_name' => $field_name,
-      'type' => $field_type,
-      'cardinality' => 1,
-      'locked' => FALSE,
-      'storage' => array(
-        'type' => 'field_chado_storage',
-      ),
-      'settings' => array(
-      ),
-    );
-  }
-
   // DBXREF
   $dbxref_table = $table_name . '_dbxref';
   if (chado_table_exists($dbxref_table)) {
@@ -431,7 +413,7 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
       'field_name' =>  $field_name,
       'type' => $field_type,
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'locked' => FALSE,
+      'locked' => TRUE,
       'storage' => array(
         'type' => 'field_chado_storage',
       ),
@@ -454,7 +436,7 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
       'field_name' => $field_name,
       'type' => $field_type,
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'locked' => FALSE,
+      'locked' => TRUE,
       'storage' => array(
         'type' => 'field_chado_storage',
       ),
@@ -476,7 +458,7 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
       'field_name' => $field_name,
       'type' => $field_type,
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'locked' => FALSE,
+      'locked' => TRUE,
       'storage' => array(
         'type' => 'field_chado_storage',
       ),
@@ -498,7 +480,7 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
       'field_name' => $field_name,
       'type' => $field_type,
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'locked' => FALSE,
+      'locked' => TRUE,
       'storage' => array(
         'type' => 'field_chado_storage',
       ),
@@ -521,7 +503,7 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
       'field_name' => $field_name,
       'type' => $field_type,
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'locked' => FALSE,
+      'locked' => TRUE,
       'storage' => array(
         'type' => 'field_chado_storage',
       ),
@@ -544,7 +526,7 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
       'field_name' => $field_name,
       'type' => $field_type,
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'locked' => FALSE,
+      'locked' => TRUE,
       'storage' => array(
         'type' => 'field_chado_storage',
       ),
@@ -562,6 +544,8 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
     // Get the list of existing property types for this table.
     $sql = 'SELECT DISTINCT type_id FROM {' . $prop_table . '}';
     $props = chado_query($sql);
+    $schema = chado_get_schema($prop_table);
+    $pkey = $schema['primary key'][0];
     while ($prop = $props->fetchObject()) {
       $term = chado_generate_var('cvterm', array('cvterm_id' => $prop->type_id));
       $field_name = strtolower($term->dbxref_id->db_id->name . '__' . $term->name);
@@ -594,7 +578,7 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
       'field_name' => $field_name,
       'type' => $field_type,
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'locked' => FALSE,
+      'locked' => TRUE,
       'storage' => array(
         'type' => 'field_chado_storage',
       ),
@@ -618,7 +602,7 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
       'field_name' => $field_name,
       'type' => $field_type,
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'locked' => FALSE,
+      'locked' => TRUE,
       'storage' => array(
         'type' => 'field_chado_storage',
       ),
@@ -641,7 +625,7 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
       'field_name' => $field_name,
       'type' => $field_type,
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'locked' => FALSE,
+      'locked' => TRUE,
       'storage' => array(
         'type' => 'field_chado_storage',
       ),
@@ -1168,36 +1152,6 @@ function tripal_chado_bundle_create_instances_linker(&$info, $entity_type, $bund
     );
   }
 
-  // CVTERM
-  $cvterm_table = $table_name . '_cvterm';
-  if (chado_table_exists($cvterm_table)) {
-    $field_name = $table_name . '_cvterm';
-    $info[$field_name] = array(
-      'field_name' => $field_name,
-      'entity_type' => $entity_type,
-      'bundle' => $bundle->name,
-      'label' => 'Add Annotation Types',
-      'description' => 'Add additional annotations types to this record.',
-      'required' => FALSE,
-      'settings' => array(
-        'auto_attach' => FALSE,
-      ),
-      'widget' => array(
-        'type' => 'chado_linker__cvterm_adder_widget',
-        'settings' => array(
-          'display_label' => 1,
-        ),
-      ),
-      'display' => array(
-        'default' => array(
-          'label' => 'above',
-          'type' => 'chado_linker__cvterm_adder_formatter',
-          'settings' => array(),
-        ),
-      ),
-    );
-  }
-
   // DBXREF
   $dbxref_table = $table_name . '_dbxref';
   if (chado_table_exists($dbxref_table)) {
@@ -1537,3 +1491,140 @@ function tripal_chado_form_field_ui_field_overview_form_alter(&$form, &$form_sta
   }
 }
 
+/**
+ * Implements hook_form_field_ui_field_overview_add_new().
+ */
+function tripal_chado_form_field_ui_field_overview_add_new($new_field, $bundle) {
+  // Get the table this bundle is mapped to.
+  $term = tripal_load_term_entity(array('term_id' => $bundle->term_id));
+  $vocab = $term->vocab;
+  $params = array(
+    'vocabulary' => $vocab->vocabulary,
+    'accession' => $term->accession,
+  );
+  $mapped_table = chado_get_cvterm_mapping($params);
+  $chado_table = $mapped_table->chado_table;
+  $chado_type_table = $mapped_table->chado_table;
+  $chado_type_column = $mapped_table->chado_field;
+
+  // We allow site admins to add new chado_linker__prop fields to an entity.
+  // This function will allow us to properly add them.  But at this point we
+  // don't know the controlled vocabulary term.  We'll have to use the
+  // defaults and let the user set it using the interface.
+  if ($new_field['type'] == 'chado_linker__prop') {
+    $table_name = $chado_table . 'prop';
+
+    if (chado_table_exists($table_name)) {
+      $schema = chado_get_schema($table_name);
+      $pkey = $schema['primary key'][0];
+      $field_name = $new_field['field_name'];
+      $field_type = 'chado_linker__prop';
+
+      // First add the field.
+      field_create_field(array(
+        'field_name' => $field_name,
+        'type' => $field_type,
+        'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+        'locked' => FALSE,
+        'storage' => array(
+          'type' => 'field_chado_storage',
+        ),
+        'settings' => array(
+          'base_table' => $chado_table,
+          'chado_table' => $table_name,
+          'chado_column' => $pkey,
+        ),
+      ));
+
+      // Now add the instance
+      field_create_instance(array(
+        'field_name' => $field_name,
+        'entity_type' => 'TripalEntity',
+        'bundle' => $bundle->name,
+        'label' => $new_field['label'],
+        'description' => '',
+        'required' => FALSE,
+        'settings' => array(
+          'auto_attach' => TRUE,
+        ),
+        'widget' => array(
+          'type' => 'chado_linker__prop_widget',
+          'settings' => array(
+            'display_label' => 1,
+          ),
+        ),
+        'display' => array(
+          'default' => array(
+            'label' => 'inline',
+            'type' => 'chado_linker__prop_formatter',
+            'settings' => array(),
+          ),
+        ),
+      ));
+    }
+    else {
+      drupal_set_message('Cannot add a property field to this entity. Chado does not support properties for this data type.', 'error');
+    }
+  }
+
+  // We allow site admins to add new chado_linker__cvterm fields to an entity.
+  // This function will allow us to properly add them.  But at this point we
+  // don't know the controlled vocabulary term.  We'll have to use the
+  // defaults and let the user set it using the interface.
+
+  if ($new_field['type'] == 'chado_linker__cvterm') {
+    $table_name = $chado_table . '_cvterm';
+
+    if (chado_table_exists($table_name)) {
+      $schema = chado_get_schema($table_name);
+      $pkey = $schema['primary key'][0];
+      $field_name = $new_field['field_name'];
+      $field_type = 'chado_linker__cvterm';
+
+      // First add the field.
+      field_create_field(array(
+        'field_name' => $field_name,
+        'type' => $field_type,
+        'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+        'locked' => FALSE,
+        'storage' => array(
+          'type' => 'field_chado_storage',
+        ),
+        'settings' => array(
+          'base_table' => $chado_table,
+          'chado_table' => $table_name,
+          'chado_column' => $pkey,
+        ),
+      ));
+
+      // Now add the instance
+      field_create_instance(array(
+        'field_name' => $field_name,
+        'entity_type' => 'TripalEntity',
+        'bundle' => $bundle->name,
+        'label' => $new_field['label'],
+        'description' => '',
+        'required' => FALSE,
+        'settings' => array(
+          'auto_attach' => TRUE,
+        ),
+        'widget' => array(
+          'type' => 'chado_linker__cvterm_widget',
+          'settings' => array(
+            'display_label' => 1,
+          ),
+        ),
+        'display' => array(
+          'default' => array(
+            'label' => 'above',
+            'type' => 'chado_linker__cvterm_formatter',
+            'settings' => array(),
+          ),
+        ),
+      ));
+    }
+    else {
+      drupal_set_message('Cannot add a property field to this entity. Chado does not support annotations for this data type.', 'error');
+    }
+  }
+}