Browse Source

Reorganized the TripalField class and removed the attach_info() function. Broke out into two new functions: create_info and create_instance_info. This is better as it doesn't try to lump creating of a field and creating of an instance into one function and it supports all of thesettings for both operations

Stephen Ficklin 9 years ago
parent
commit
76681a2520
28 changed files with 2632 additions and 1646 deletions
  1. 43 194
      tripal/api/tripal.entities.api.inc
  2. 238 22
      tripal/includes/TripalField.inc
  3. 57 0
      tripal/includes/tripal.fields.inc
  4. 20 43
      tripal/tripal.module
  5. 1 1
      tripal_chado/api/tripal_chado.api.inc
  6. 68 24
      tripal_chado/includes/fields/chado_base__dbxref_id.inc
  7. 82 32
      tripal_chado/includes/fields/chado_base__organism_id.inc
  8. 77 25
      tripal_chado/includes/fields/chado_feature__md5checksum.inc
  9. 72 55
      tripal_chado/includes/fields/chado_feature__residues.inc
  10. 77 28
      tripal_chado/includes/fields/chado_feature__seqlen.inc
  11. 68 24
      tripal_chado/includes/fields/chado_gene__transcripts.inc
  12. 91 40
      tripal_chado/includes/fields/chado_linker__contact.inc
  13. 21 4
      tripal_chado/includes/fields/chado_linker__cvterm.inc
  14. 116 49
      tripal_chado/includes/fields/chado_linker__cvterm_adder.inc
  15. 78 33
      tripal_chado/includes/fields/chado_linker__dbxref.inc
  16. 97 54
      tripal_chado/includes/fields/chado_linker__expression.inc
  17. 67 23
      tripal_chado/includes/fields/chado_linker__featureloc.inc
  18. 68 22
      tripal_chado/includes/fields/chado_linker__genotype.inc
  19. 69 22
      tripal_chado/includes/fields/chado_linker__phenotype.inc
  20. 264 283
      tripal_chado/includes/fields/chado_linker__prop.inc
  21. 122 44
      tripal_chado/includes/fields/chado_linker__prop_adder.inc
  22. 71 23
      tripal_chado/includes/fields/chado_linker__pub.inc
  23. 77 27
      tripal_chado/includes/fields/chado_linker__relationship.inc
  24. 69 22
      tripal_chado/includes/fields/chado_linker__synonym.inc
  25. 74 27
      tripal_chado/includes/fields/chado_organism__type_id.inc
  26. 0 4
      tripal_chado/includes/tripal_chado.field_storage.inc
  27. 534 518
      tripal_chado/includes/tripal_chado.fields.inc
  28. 11 3
      tripal_chado/includes/tripal_chado.setup.inc

+ 43 - 194
tripal/api/tripal.entities.api.inc

@@ -174,8 +174,49 @@ function tripal_create_bundle($vocabulary, $accession, $term_name, &$error = '')
   // Get the bundle object.
   // Get the bundle object.
   $bundle = tripal_load_bundle_entity(array('name' => $bundle_name));
   $bundle = tripal_load_bundle_entity(array('name' => $bundle_name));
 
 
-  // Allow modules now add fields to the bundle
-  module_invoke_all('add_bundle_fields', 'TripalEntity', $bundle, $term);
+  // Get the list of fields to create.
+  foreach (module_implements('field_create_info') as $module) {
+    $function = $module . '_field_create_info';
+    if (function_exists($function)) {
+      $fields = $function('TripalEntity', $bundle, $term);
+      if (!$fields){
+        continue;
+      }
+      foreach ($fields as $field_name => $info) {
+        // If the field already exists then skip it.
+        $field = field_info_field($info['field_name']);
+        if ($field) {
+          continue;
+        }
+        $field = field_create_field($info);
+        if (!$field) {
+          tripal_set_message(t("Could not create new field: %field.",
+            array('%field' =>  $info['field_name'])), TRIPAL_ERROR);
+        }
+      }
+    }
+  }
+
+  // Now get the list of field instances to add to the bundle.
+  foreach (module_implements('field_create_instance_info') as $module) {
+    $function = $module . '_field_create_instance_info';
+    if (function_exists($function)) {
+      $fields = $function('TripalEntity', $bundle, $term);
+      if (!$fields){
+        continue;
+      }
+      foreach ($fields as $field_name => $info) {
+        // If the field is already attached to this bundle then skip it.
+        $field = field_info_field($info['field_name']);
+        if ($field and array_key_exists('bundles', $field) and
+            array_key_exists('TripalEntity', $field['bundles']) and
+            in_array($bundle_name, $field['bundles']['TripalEntity'])) {
+          continue;
+        }
+        $instance = field_create_instance($info);
+      }
+    }
+  }
 
 
   return TRUE;
   return TRUE;
 }
 }
@@ -203,91 +244,6 @@ function tripal_refresh_bundle_fields($bundle_name) {
   module_invoke_all('update_bundle_fields', 'TripalEntity', $bundle, $term);
   module_invoke_all('update_bundle_fields', 'TripalEntity', $bundle, $term);
 }
 }
 
 
-
-/**
- * Adds a new field and attaches it to a bundle
- *
- * @param $field_name
- *   The name of the field.
- * @param $field_info
- *   An associative array containing the field information.  The following
- *   key/value pairs are supported:
- *     'field_type' : a valid field type.  May be any of the Drupal default
- *       fields, one created by the tripal_chado module or another custom module.
- *     'widget_type' : a valid widget type. May be any of the Drupal default
- *       fields, one created by the tripal_chado module or another custom module.
- *     'field_settings' : an array of settings that are appropriate for the
- *       selected field type.
- *     'widget_settings' : an array of settings that are appropriate for the
- *       selected widget type.
- *     'description' :  a default description for this field.
- *     'label' : a label used as a header for this field.
- *     'is_required' : indicates if the field is required in the edit form.
- *     'cardinality' : indicates the number of values this field can support.
- *       the default is 1 (meaning only one value). Use a value of
- *       FIELD_CARDINALITY_UNLIMITED for unlimited number of values.
- *     'default_value' : A default value for the field.
- *     'format' : A string indicating the format for the field. Must be
- *       specific to the field.
- * @param $entity_type_name
- *   The entity type name.
- * @param $bundle_name
- *   The bundle name.
- *
- * TODO: this function really shouldn't try to create an instance and
- * attach to a bundle  at the same time.
- */
-function tripal_add_bundle_field($field_name, $field_info, $entity_type_name, $bundle_name) {
-
-  $field = field_info_field($field_name);
-
-  // If the field exists and is attached to this bundle then just return,
-  // there is nothing left to do.
-  if ($field and array_key_exists('bundles', $field) and
-      array_key_exists($entity_type_name, $field['bundles']) and
-      in_array($bundle_name, $field['bundles'][$entity_type_name])) {
-    return;
-  }
-
-  $cardinality = 1;
-  if (array_key_exists('cardinality', $field_info) and is_numeric($field_info['cardinality'])) {
-    $cardinality = $field_info['cardinality'];
-  }
-
-  // If the field doesn't exist then create it.
-  if (!$field) {
-    $field = array(
-      'field_name' => $field_name,
-      'type' => $field_info['field_type'],
-      'cardinality' => $cardinality,
-      'locked' => FALSE,
-      'storage' => array(
-        'type' => $field_info['storage']
-      ),
-      'settings' => $field_info['field_settings'],
-    );
-    field_create_field($field);
-  }
-
-  // Attach the field to the bundle.
-  $field_instance = array(
-    'field_name' => $field_name,
-    'label' => $field_info['label'],
-    'description' => $field_info['description'],
-    'widget' => array(
-      'type' => $field_info['widget_type'],
-      'settings' => $field_info['widget_settings'],
-    ),
-    'entity_type' => $entity_type_name,
-    'required' => $field_info['is_required'],
-    'settings' => $field_info['field_settings'],
-    'bundle' => $bundle_name,
-    'default_value' => array_key_exists('default_value', $field_info) ? $field_info['default_value'] : '',
-    'format' => array_key_exists('format', $field_info) ? $field_info['format'] : '',
-  );
-  field_create_instance($field_instance);
-}
-
 /**
 /**
  * Updates an existing field and its attached instance to a bundle.
  * Updates an existing field and its attached instance to a bundle.
  *
  *
@@ -400,113 +356,6 @@ function hook_entity_create(&$entity, $entity_type) {
 }
 }
 
 
 
 
-/**
- * Adds fields to a bundle type.
- *
- * When a new bundle (Tripal content type) is created, the tripal module
- * allows any other module the implements this hook to add fields too it. This
- * hook is called automatically.
- *
- * @param $entity_type
- *   The type of entity (e.g. 'TripalEntity')
- * @param $bundle
- *   An instance of a TripalBundle object.  This is the bundle to which
- *   the fields will be added.
- * @param $term
- *   An instance of a TripalTerm object. Each TripalBundle is associated with
- *   a controlled vocabulary term. This is the term object for the bundle.
- *
- * @return
- *   There is no return value.
- */
-function hook_add_bundle_fields($entity_type, $bundle, $term) {
-
-  //
-  // The example code below is derived from the tripal_chado modules and
-  // adds a 'synonym' field to the bundle.
-  //
-
-  $bundle_name = $bundle->name;
-
-  // This array will hold details that map the bundle to tables in Chado.
-  $bundle_data = array();
-
-  // Get the cvterm that corresponds to this TripalTerm object.
-  $vocab = entity_load('TripalVocab', array($term->vocab_id));
-  $vocab = reset($vocab);
-  $match = array(
-    'dbxref_id' => array(
-      'db_id' => array(
-        'name' => $vocab->vocabulary,
-      ),
-      'accession' => $term->accession
-    ),
-  );
-  $cvterm = chado_generate_var('cvterm', $match);
-
-
-  // Get the default table that this term maps to.
-  $default = db_select('tripal_cv_defaults', 't')
-  ->fields('t')
-  ->condition('cv_id', $cvterm->cv_id->cv_id)
-  ->execute()
-  ->fetchObject();
-  if ($default) {
-    $bundle_data = array(
-      'cv_id' => $cvterm->cv_id->cv_id,
-      'cvterm_id' => $cvterm->cvterm_id,
-      'data_table' => $default->table_name,
-      'type_table' => $default->table_name,
-      'field' =>  $default->field_name,
-    );
-  }
-  else {
-    return;
-  }
-
-  // Formulate the name of the synonym table.
-  $syn_table = $bundle_data['data_table'] . '_synonym';
-
-  // Don't add a field to this bundle if
-  if (!chado_table_exists($syn_table)) {
-    return;
-  }
-
-  $field_name = $syn_table;
-  $schema = chado_get_schema($syn_table);
-  $pkey = $schema['primary key'][0];
-
-  // The Tripal Chado module needs to know what Chado table and field
-  // this field maps to, as well as the base table that it maps to
-  // if this field will map to a record in a linking table.
-  $field_settings = array(
-    // The Chado table that this field maps to.
-    'chado_table' => $syn_table,
-    // The column in the chado table that this field maps to.
-    'chado_column' => $pkey,
-    // The base table that this field is connected to.
-    'base_table' => $base_table,
-    'semantic_web' => '',
-  );
-
-  // Finally set the field values.
-  $field_info = array(
-    'field_type' => 'synonym',
-    'widget_type' => 'tripal_fields_synonym_widget',
-    'widget_settings' => array('display_label' => 1),
-    'description' => '',
-    'label' => 'Synonyms',
-    'is_required' => 0,
-    'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-    'storage' => 'field_chado_storage',
-    'field_settings' => $field_settings,
-  );
-
-  // Call the Tripal API function tripal_add_bundle_field to complete the
-  // addition of the field to the bundle.
-  tripal_add_bundle_field($field_name, $field_info, $entity_type_name, $bundle_name);
-}
-
 /**
 /**
  * @section
  * @section
  * Bundle Variables.
  * Bundle Variables.

+ 238 - 22
tripal/includes/TripalField.inc

@@ -2,30 +2,79 @@
 
 
 
 
 /**
 /**
- * A base class for all Fields supported by Tripal.
+ * A base class for all fields supported by Tripal.
  *
  *
- * This class provides all of the necessary functions for a TripalField field.
- * It helps simplify and unify the process of creating fields for Tripal.  This
- * class simply defines the function prototypes. It is up to the class that
- * extends this class to implement the functions.
+ * The Field API of Drupal defines three "levels" for fields:  field types,
+ * fields, and instances of fields.  All fields must be of a specific type, and
+ * the field types are typically defined using the hook_field_info() hook.
+ * Normally, using Drupal's Field API, fields can be created by using the
+ * field_create_field() function which defines the parameters and settings
+ * for the field.  The field_create_instance() function is then used to attach
+ * a field to a bundle and to set local parameters and settings for the field
+ * when attached to the bundle.  There are also a variety of hooks for creating
+ * widgets, formatters, customizaing settings forms, loading values, validating
+ * widget forms, etc. Rather than use all of these hooks, the TripalField class
+ * is used to consolidate and simplify creation and management of Fields.
  *
  *
- * Each module that creates new fields should use the normal Field API hooks
- * (e.g. hook_field_info(), hook_field_widget_form(), etc.) to instantiate the
- * appropriate TripalField class.
+ * A module can extend this class to create new fields, and attach them to
+ * bundles.  The class is structure to allow fields to attach themselves to
+ * bundles. This is a bit different from how fields would normally be
+ * attached. But allows a field to be self-aware and all of the functionality
+ * for a field is self-contained in the Class implementation.  To change
+ * functionality a developer need only edit the class file for a field rathaer
+ * than look for all of the Field API hook that would typically be spread
+ * around the module.
  *
  *
- * Because of the way Drupal handles callbacks, AJAX callbacks, and theme
- * functions cannot be part of the implementation of this class.  Those
- * functions if needed, should be added to the bottom of the file where the
- * child class is housed.
+ * This field also supports use of controlled vocabulaaries for providing
+ * "types" to these fields. This is important for use with the semantic web
+ * support for Tripal v3.
+ *
+ * AJAX callbacks, and theme functions unfortunately cannot be part of the
+ * implementation of this class.  To keep all functionality for a field
+ * in the same file, it is recommended that those functions, if needed, should
+ * be added to the bottom of the file where the child class is housed, and each
+ * TripalField child class should each be written in a separate file.
  *
  *
  */
  */
 class TripalField {
 class TripalField {
   /**
   /**
-   * Provides information about this field.
+   * Define this field type.
    *
    *
-   * @return array
-   *   An associative array with key/value pairs compatible with those from
-   *   the hook_field_info() function of the Drupal Field API.
+   * @return
+   * An array whose keys are field type names and whose values are arrays
+   * describing the field type. The keys are the same as for the
+   * hook_field_info() function, which are:
+   *   - label: The human-readable name of the field type.
+   *   - description: A short description for the field type.
+   *   - settings: An array whose keys are the names of the settings available
+   *     for the field type, and whose values are the default values for those
+   *     settings.
+   *   - instance_settings: An array whose keys are the names of the settings
+   *     available for instances of the field type, and whose values are the
+   *     default values for those settings. Instance-level settings can have
+   *     different values on each field instance, and thus allow greater
+   *     flexibility than field-level settings. It is recommended to put
+   *     settings at the instance level whenever possible. Notable
+   *     exceptions: settings acting on the schema definition, or settings
+   *     that Views needs to use across field instances (for example, the
+   *     list of allowed values).
+   *   - default_widget: The machine name of the default widget to be used by
+   *     instances of this field type, when no widget is specified in the
+   *     instance definition. This widget must be available whenever the field
+   *     type is available (i.e. provided by the field type module, or by a
+   *     module the field type module depends on).  Valid names are those
+   *     provided by the widget_info() function of this class.
+   *   - default_formatter: The machine name of the default formatter to be
+   *     used by instances of this field type, when no formatter is specified
+   *     in the instance definition. This formatter must be available whenever
+   *     the field type is available (i.e. provided by the field type module,
+   *     or by a module the field type module depends on).  Valid names are
+   *     those provided by the formater_info() function of this class.
+   *   - no_ui: (optional) 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(). Defaults to
+   *     FALSE.
    */
    */
   public function field_info() {
   public function field_info() {
     return array(
     return array(
@@ -34,20 +83,187 @@ class TripalField {
 
 
 
 
   /**
   /**
-   * Provides an array that allows Tripal to attach a field to an entity.
+   * Provides the information required for creating a field.
+   *
+   * These settings are global for every instance of the field.
+   *
+   * he TripalField class allows a field to decide which bundles it would
+   * like to attach itself to. Therefore, the entity type, and bundle are
+   * passed as arguments to allow the field to decide if it wants to be
+   * attached.
+   *
+   * @param $entity_type
+   *   The class name for the entity type (e.g. TripalEntity).
+   * @param TripalBundle $bundle
+   *   The TripalBundle object.  This is the bundle that is being offered
+   *   to the field for attachement. The function will determine if this
+   *   field should be attached to this bundle.
+   * @param $details
+   * @return
+   *   A field definition array. The return value is identical to that
+   *   provided to the field_create_info() function. The field_name and
+   *   type properties are required. The semantic_web value is also required
+   *   under the settings. Other properties, if omitted, will be
+   *   given the following default values:
+   *     - cardinality: 1
+   *     - locked: FALSE. Set to TRUE if you do not want your field to be
+   *       re-used or deleted.
+   *     - settings: each omitted setting is given the default value
+   *       defined in field_info().
+   *       - semantic_web: a controlled vocabulary term written in the form
+   *         [CV short name]:[accession] (e.g. SO:000745).
+   *     - storage:
+   *       - type: the storage backend specified in the 'field_storage_default'
+   *         system variable.
+   *       - settings: each omitted setting is given the default value specified
+   *         in hook_field_storage_info().
+   *
+   *  Nothing is returned when this field will not be attached to the bundle.
+   */
+  public function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+  }
+
+  /**
+   * Provides the information required for creating an instance of a field.
+   *
+   * A field instance is a field that has been created using the values provided
+   * by the create_info() function of this class, and which is attached to
+   * a bundle.
+   *
+   * The TripalField class allows a field to decide which bundles it would
+   * like to attach itself to. Therefore, the entity type, and bundle are
+   * passed as arguments to allow the field to decide if it wants to be
+   * attached and if so then this function will provide the details to create
+   * the field.  The field instance can later be attached to the bundle
+   * using information provided by the create_instance_info() function.
+   *
+   * @param $entity_type
+   *   The entity type Class to which the bundle belongs.
+   * @param $bundle.
+   *   An instance of a TripalBundle object.  This is the bundle to which
+   *   the field can be added.
+   * @param $details
+   *   An associative array containing additional details provided by the
+   *   calling module that can be used by the function to determine if the
+   *   bundle should be attached to.
    *
    *
-   * @todo: This function needs better documentation.
+   * @return
+   *  A field instance definition array. The values of thie array are identical
+   *  to those passed to the field_create_instance() function. The field_name,
+   *  entity_type and bundle (name of the bundle) properties are required.
+   *  Other properties, if omitted, will be given the following default values:
+   *    - label: the field name
+   *    - description: empty string
+   *    - required: FALSE
+   *    - default_value_function: empty string
+   *    - settings: each omitted setting is given the default value specified
+   *      in hook_field_info().
+   *    - widget:
+   *      - type: the default widget specified in field_info().
+   *      - settings: each omitted setting is given the default value specified
+   *        in widget_info().
+   *    - display: An instance can support multiple view modes. Eeach mode must
+   *      be listed as a separate key (e.g. 'default') with a the following
+   *      values (and their default specified below.  If display is not
+   *      included then the settings for the 'default' view mode will be added
+   *      automatically, and each view mode in the definition will be completed
+   *      with the following default values:
+   *      - label: 'above'
+   *      - type: the default formatter specified in field_info().
+   *      - settings: each omitted setting is given the default value specified
+   *        in formatter_info().
+   *      View modes not present in the definition are left empty, and the
+   *      field will not be displayed in this mode.
+   *
+   *  Nothing is returned when this field will not be attached to the bundle.
+   */
+  public function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+  }
+
+
+
+  /**
+   * A helper function to determine if this field wants to attach to a bundle.
+   *
+   * Because the create_info() and create_instance_info() functions both need
+   * to determine if they should attach to a bundle, this function is provided
+   * as a helper function to perform that check.  Any class that extends the
+   * TripalField class can use this function provide a single function that
+   * both create_info() and create_instance_info() can use.
+   *
+   * @param $entity_type
+   *   The entity type Class to which the bundle belongs.
+   * @param $bundle.
+   *   An instance of a TripalBundle object.  This is the bundle to which
+   *   the field can be added.
+   * @param $details
+   *   An associative array containing additional details provided by the
+   *   calling module that can be used by the function to determine if the
+   *   bundle should be attached to.
    *
    *
+   * @return
+   *   TRUE if the field should attach to the bundle. FALSE if not.
    */
    */
+  protected function can_attach($entity_type, $bundle, $details) {
+
+  }
+
   public function attach_info($entity_type, $bundle, $settings) {
   public function attach_info($entity_type, $bundle, $settings) {
 
 
   }
   }
+
   /**
   /**
-   * Provides information about the widget for this field.
+   *  Provides information about the widgets provided by this field.
    *
    *
-   * @return array
-   *   An associative array with key/value paris compatible with those from the
-   *   hook_field_widget_info() function of the Drupal Field API.
+   *  This function returns an array describing the widget types implemented by
+   *  the field.  The widgets created by this field are expecte to be used only
+   *  by this field.
+   *
+   * @param $entity_type
+   *   The entity type Class to which the bundle belongs.
+   * @param $bundle.
+   *   An instance of a TripalBundle object.  This is the bundle to which
+   *   the field can be added.
+   * @param $details
+   *   An associative array containing additional details provided by the
+   *   calling module that can be used by the function to determine if the
+   *   bundle should be attached to.
+   *
+   * @return
+   *   An associative array where the keys are widget type names. To avoid
+   *   name clashes, widget type names should be prefixed with the name of
+   *   the module that exposes them. The values are arrays describing the
+   *   widget type, with the following key/value pairs:
+   *
+   *     - label: The human-readable name of the widget type.
+   *     - description: A short description for the widget type.
+   *     - field types: An array of field types the widget supports.
+   *     - settings: An array whose keys are the names of the settings
+   *       available for the widget type, and whose values are the default
+   *       values for those settings.
+   *     - behaviors: (optional) An array describing behaviors of the widget,
+   *       with the following elements:
+   *       - multiple values: One of the following constants:
+   *          - FIELD_BEHAVIOR_DEFAULT: (default) If the widget allows the
+   *            input of one single field value (most common case). The widget
+   *            will be repeated for each value input.
+   *          - FIELD_BEHAVIOR_CUSTOM: If one single copy of the widget can
+   *            receive several field values. Examples: checkboxes, multiple
+   *            select, comma-separated textfield.
+   *        - default value: One of the following constants:
+   *          - FIELD_BEHAVIOR_DEFAULT: (default) If the widget accepts
+   *            default values.
+   *          - FIELD_BEHAVIOR_NONE: if the widget does not support
+   *            default values.
+   *     - weight: (optional) An integer to determine the weight of this
+   *       widget relative to other widgets in the Field UI when selecting a
+   *       widget for a given field instance.
    */
    */
   public function widget_info() {
   public function widget_info() {
     return array(
     return array(

+ 57 - 0
tripal/includes/tripal.fields.inc

@@ -43,6 +43,63 @@ function tripal_field_formatter_info() {
     ),
     ),
   );
   );
 }
 }
+
+/**
+ * Implements hook_create_info().
+ *
+ * This is a Tripal defined hook that supports integration with the
+ * TripalEntity field.
+ */
+function tripal_field_create_info($entity_type, $bundle, $term) {
+  return array(
+    'content_type' => array(
+      'field_name' => 'content_type',
+      'type' => 'content_type',
+      'cardinality' => 1,
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'tripal_no_storage'
+      ),
+      'settings' => array(
+        'semantic_web' => 'rdf:type',
+      ),
+    ),
+  );
+}
+
+/**
+ * Implements hook_create_instance_info().
+ *
+ * This is a Tripal defined hook that supports integration with the
+ * TripalEntity field.
+ */
+function tripal_field_create_instance_info($entity_type, $bundle, $term) {
+  return array(
+    'content_type' => array(
+      'field_name' => 'content_type',
+      'entity_type' => 'TripalEntity',
+      'bundle' => $bundle->name,
+      'label' => 'Resource Type',
+      'description' => '',
+      'required' => FALSE,
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'tripal_content_type_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'above',
+          'type' => 'tripal_content_type_formatter',
+          'settings' => array(),
+        ),
+      ),
+    ),
+  );
+}
+
 /**
 /**
  * Implements hook_field_widget_form().
  * Implements hook_field_widget_form().
  */
  */

+ 20 - 43
tripal/tripal.module

@@ -138,9 +138,16 @@ function tripal_menu() {
     'type' => MENU_NORMAL_ITEM,
     'type' => MENU_NORMAL_ITEM,
   );
   );
 
 
-  // Menu items for facilitating import of extension modules.
   $items['admin/tripal/extension'] = array(
   $items['admin/tripal/extension'] = array(
     'title' => 'Extensions',
     'title' => 'Extensions',
+    'description' => t("Configuration and management pages for Tripal extension modules."),
+    'weight' => 8,
+    'access arguments' => array('administer tripal'),
+  );
+
+  // Menu items for facilitating import of extension modules.
+  $items['admin/tripal/extension/available'] = array(
+    'title' => 'Available Extensions',
     'description' => t('Look for extensions to add new functionality to this
     'description' => t('Look for extensions to add new functionality to this
         site. Tripal can be extended with new functionality developed
         site. Tripal can be extended with new functionality developed
         by other Tripal site developers. These include modules with new or
         by other Tripal site developers. These include modules with new or
@@ -153,19 +160,19 @@ function tripal_menu() {
     'type' => MENU_NORMAL_ITEM,
     'type' => MENU_NORMAL_ITEM,
     'file' => 'includes/tripal.extensions.inc',
     'file' => 'includes/tripal.extensions.inc',
     'file path' => drupal_get_path('module', 'tripal'),
     'file path' => drupal_get_path('module', 'tripal'),
-    'weight' => 100
-  );
-  $items['admin/tripal/extension/import'] = array(
-    'title' => 'Import Extensions',
-    'description' => 'Provides a list of the available extensions that are registered at the tripal.info site. From this page you can easily import or install extensions to your site.',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('tripal_extensions_form'),
-    'access arguments' => array('administer tripal'),
-    'type' => MENU_NORMAL_ITEM,
-    'file' =>  'includes/tripal.extensions.inc',
-    'file path' => drupal_get_path('module', 'tripal'),
-    'weight' => -100,
+    'weight' => -100
   );
   );
+//   $items['admin/tripal/extension/import'] = array(
+//     'title' => 'Import Extensions',
+//     'description' => 'Provides a list of the available extensions that are registered at the tripal.info site. From this page you can easily import or install extensions to your site.',
+//     'page callback' => 'drupal_get_form',
+//     'page arguments' => array('tripal_extensions_form'),
+//     'access arguments' => array('administer tripal'),
+//     'type' => MENU_NORMAL_ITEM,
+//     'file' =>  'includes/tripal.extensions.inc',
+//     'file path' => drupal_get_path('module', 'tripal'),
+//     'weight' => -100,
+//   );
 
 
 
 
 /*
 /*
@@ -515,33 +522,3 @@ function tripal_import_api() {
   module_load_include('inc', 'tripal', 'api/tripal.notice.api');
   module_load_include('inc', 'tripal', 'api/tripal.notice.api');
   module_load_include('inc', 'tripal', 'api/tripal.variables.api');
   module_load_include('inc', 'tripal', 'api/tripal.variables.api');
 }
 }
-
-
-/**
- * Implemenation of hook_add_bundle_fields().
- *
- * In this function we add the type field.
- */
-function tripal_add_bundle_fields($entity_type, $bundle, $term) {
-  $field_name = 'content_type';
-  $bundle_name = $bundle->name;
-
-  // Create the field array.
-  $field_info = array(
-    'field_type' => 'content_type',
-    'widget_type' => 'tripal_content_type_widget',
-    'widget_settings' => array('display_label' => 1),
-    'description' => '',
-    'label' => 'Record Type',
-    'is_required' => 0,
-    'storage' => 'tripal_no_storage',
-    'field_settings' => array(
-      'semantic_web' => '',
-    ),
-  );
-
-  tripal_add_bundle_field($field_name, $field_info, $entity_type, $bundle_name);
-}
-
-
-

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

@@ -74,7 +74,7 @@ function tripal_chado_publish_records($values, $job_id = NULL) {
   $bundle = tripal_load_bundle_entity(array('name' => $bundle_name));
   $bundle = tripal_load_bundle_entity(array('name' => $bundle_name));
   $bundle_id = $bundle->id;
   $bundle_id = $bundle->id;
   $table = tripal_get_bundle_variable('chado_table', $bundle_id);
   $table = tripal_get_bundle_variable('chado_table', $bundle_id);
-  $column = tripal_get_bundle_variable('chado_column', $bundle_id);
+  $column = tripal_get_bundle_variable('chado_type_column', $bundle_id);
   $cvterm_id = tripal_get_bundle_variable('chado_cvterm_id', $bundle_id);
   $cvterm_id = tripal_get_bundle_variable('chado_cvterm_id', $bundle_id);
 
 
   // Get the table information for the Chado table.
   // Get the table information for the Chado table.

+ 68 - 24
tripal_chado/includes/fields/chado_base__dbxref_id.inc

@@ -20,47 +20,91 @@ class chado_base__dbxref_id extends TripalField {
     );
     );
   }
   }
   /**
   /**
-   * @see TripalField::attach_info()
+   * @see TripalField::can_attach()
    */
    */
-  function attach_info($entity_type, $bundle, $settings) {
+  protected function can_attach($entity_type, $bundle, $details) {
 
 
-    $field_info = array();
-
-    $table_name = $settings['data_table'];
-    $type_table = $settings['type_table'];
-    $type_field = $settings['field'];
-    $cv_id      = $settings['cv_id'];
-    $cvterm_id  = $settings['cvterm_id'];
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
     // Check the schema for the data table if it does not have
     // Check the schema for the data table if it does not have
     // a 'dbxref_id' column then we don't want to attach this field.
     // a 'dbxref_id' column then we don't want to attach this field.
     $schema = chado_get_schema($table_name);
     $schema = chado_get_schema($table_name);
-    if (!array_key_exists('dbxref_id', $schema['fields'])) {
-      return $field_info;
+    if (array_key_exists('dbxref_id', $schema['fields'])) {
+      return TRUE;
     }
     }
+    return FALSE;
+  }
 
 
-    // There is an dbxref_id column so attach the field!
-    $field_info = array(
+  /**
+   * @see TripalField::create_info()
+   */
+  function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    };
+
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
+
+    return array(
       'field_name' => $table_name . '__dbxref_id',
       'field_name' => $table_name . '__dbxref_id',
-      'field_type' => 'chado_base__dbxref_id',
-      'widget_type' => 'chado_base__dbxref_id_widget',
-      'description' => 'This field specifies the unique stable accession (ID) for
-        this record. It requires that this site have a database entry.',
-      'label' => 'Accession',
-      'is_required' => 0,
-      'storage' => 'field_chado_storage',
-      'widget_settings' => array(
-        'display_label' => 1
+      'type' => 'chado_base__dbxref_id',
+      'cardinality' => 1,
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
       ),
       ),
-      'field_settings' => array(
+      'settings' => array(
         'chado_table' => $table_name,
         'chado_table' => $table_name,
         'chado_column' => 'dbxref_id',
         'chado_column' => 'dbxref_id',
         'semantic_web' => 'data:2091',
         'semantic_web' => 'data:2091',
       ),
       ),
     );
     );
+  }
 
 
-    return $field_info;
+  /**
+   * @see TripalField::create_instance_info()
+   */
+  function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
+    return array(
+      'field_name' => $table_name . '__dbxref_id',
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Accession',
+      'description' => 'This field specifies the unique stable accession (ID) for
+        this record. It requires that this site have a database entry.',
+      'required' => FALSE,
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'chado_base__dbxref_id_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'deafult' => array(
+          'label' => 'above',
+          'type' => 'chado_base__dbxref_id_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
   }
   }
   /**
   /**
    * @see TripalField::widget_info()
    * @see TripalField::widget_info()

+ 82 - 32
tripal_chado/includes/fields/chado_base__organism_id.inc

@@ -22,57 +22,107 @@ class chado_base__organism_id extends TripalField {
     );
     );
   }
   }
   /**
   /**
-   * @see TripalField::attach_info()
+   * @see TripalField::can_attach()
    */
    */
-  public function attach_info($entity_type, $bundle, $settings) {
+  protected function can_attach($entity_type, $bundle, $details) {
 
 
-    $field_info = array();
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
-    $table_name = $settings['data_table'];
-    $type_table = $settings['type_table'];
-    $type_field = $settings['field'];
-    $cv_id      = $settings['cv_id'];
-    $cvterm_id  = $settings['cvterm_id'];
-
-    // Check the schema for the data table if it does not have
-    // an 'organism_id' column then we don't want to attach this field.
     $schema = chado_get_schema($table_name);
     $schema = chado_get_schema($table_name);
-    if (!array_key_exists('organism_id', $schema['fields'])) {
-      return $field_info;
-    }
 
 
-    // If this is the organism table then do not attach as that is the
-    // primary key
+    // If this is the organism table then do not attach as the organism_id
+    // field is the primary key and we don't want a field for that.
     if ($table_name == 'organism') {
     if ($table_name == 'organism') {
-      return $field_info;
+      return FALSE;
+    }
+
+    // Check the schema for the data table if it has
+    // an 'organism_id' column then we want to attach this field.
+    if (array_key_exists('organism_id', $schema['fields'])) {
+      return TRUE;
+    }
+
+    return FALSE;
+  }
+
+  /**
+   * @see TripalField::create_info()
+   */
+  public function create_info($entity_type, $bundle, $details) {
+
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
+
+    return array(
+      'field_name' => $table_name . '__organism_id',
+      'type' => 'chado_base__organism_id',
+      'cardinality' => 1,
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+      'settings' => array(
+        'chado_table' => $table_name,
+        'chado_column' => 'organism_id',
+        'semantic_web' => 'local:organism',
+      ),
+    );
+  }
+  /**
+   * @see TripalField::create_instance_info()
+   */
+  public function create_instance_info($entity_type, $bundle, $details) {
+
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
     }
     }
 
 
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
+
     $is_required = FALSE;
     $is_required = FALSE;
+    $schema = chado_get_schema($table_name);
     if (array_key_exists('not null', $schema['fields']['organism_id']) and
     if (array_key_exists('not null', $schema['fields']['organism_id']) and
         $schema['fields']['organism_id']['not null']) {
         $schema['fields']['organism_id']['not null']) {
       $is_required = TRUE;
       $is_required = TRUE;
     }
     }
 
 
-    // There is an organism_id column so attach the field!
-    $field_info = array(
+    return array(
       'field_name' => $table_name . '__organism_id',
       'field_name' => $table_name . '__organism_id',
-      'field_type' => 'chado_base__organism_id',
-      'widget_type' => 'chado_base__organism_id_widget',
-      'description' => 'Select an organism.',
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
       'label' => 'Organism',
       'label' => 'Organism',
-      'is_required' => $is_required,
-      'storage' => 'field_chado_storage',
-      'widget_settings' => array(
-        'display_label' => 1
+      'description' => 'Select an organism.',
+      'required' => $is_required,
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'chado_base__organism_id_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
       ),
       ),
-      'field_settings' => array(
-        'chado_table' => $table_name,
-        'chado_column' => 'organism_id',
-        'semantic_web' => 'local:organism',
+      'display' => array(
+        'deafult' => array(
+          'label' => 'above',
+          'type' => 'chado_base__organism_id_formatter',
+          'settings' => array(),
+        ),
       ),
       ),
     );
     );
-
-    return $field_info;
   }
   }
 
 
   /**
   /**

+ 77 - 25
tripal_chado/includes/fields/chado_feature__md5checksum.inc

@@ -21,38 +21,90 @@ class chado_feature__md5checksum  extends TripalField {
   }
   }
 
 
   /**
   /**
-   * @see TripalField::attach_info()
+   * @see TripalField::can_attach()
    */
    */
-  function attach_info($entity_type, $bundle, $settings) {
-    $field_info = array();
-
-    $table_name = $settings['data_table'];
-    $type_table = $settings['type_table'];
-    $type_field = $settings['field'];
-    $cv_id      = $settings['cv_id'];
-    $cvterm_id  = $settings['cvterm_id'];
+  protected function can_attach($entity_type, $bundle, $details) {
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
     if ($table_name == 'feature') {
     if ($table_name == 'feature') {
-      $field_info = array(
-        'field_name' => $table_name . '__md5checksum',
-        'field_type' => 'chado_feature__md5checksum',
-        'widget_type' => 'chado_feature__md5checksum_widget',
-        'description' => 'The MD5 checksum for the sequence.',
-        'label' => 'The Sequence MD5 Checksum',
-        'is_required' => 0,
-        'storage' => 'field_chado_storage',
-        'widget_settings' => array(
+      return TRUE;
+    }
+    return FALSE;
+  }
+  /**
+   * @see TripalField::create_info()
+   */
+  function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
+
+    return array(
+      'field_name' => $table_name . '__md5checksum',
+      'type' => 'chado_feature__md5checksum',
+      'cardinality' => 1,
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+      'settings' => array(
+        'chado_table' => $table_name,
+        'chado_column' => 'md5checksum',
+        'semantic_web' => 'data:2190',
+      ),
+    );
+  }
+  /**
+   * @see TripalField::create_instance_info()
+   */
+  function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
+
+    return array(
+      'field_name' => $table_name . '__md5checksum',
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Sequence Checksum',
+      'description' => 'The MD5 checksum for the sequence. The checksum here
+        will always be unique for the raw unformatted sequence. To verify that the
+        sequence has not been corrupted, download the raw sequence and use an MD5 tool
+        to calculate the value. If the value calculated is identical the one shown
+        here, then the downloaded sequence is uncorrupted.',
+      'required' => FALSE,
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'chado_feature__md5checksum_widget',
+        'settings' => array(
           'display_label' => 1,
           'display_label' => 1,
           'md5_fieldname' => 'feature__md5checksum',
           'md5_fieldname' => 'feature__md5checksum',
         ),
         ),
-        'field_settings' => array(
-          'chado_table' => 'feature',
-          'chado_column' => 'md5checksum',
-          'semantic_web' => 'local:md5_checksum',
+      ),
+      'display' => array(
+        'deafult' => array(
+          'label' => 'above',
+          'type' => 'chado_feature__md5checksum_formatter',
+          'settings' => array(),
         ),
         ),
-      );
-    }
-    return $field_info;
+      ),
+    );
   }
   }
 
 
   /**
   /**

+ 72 - 55
tripal_chado/includes/fields/chado_feature__residues.inc

@@ -3,10 +3,7 @@
 class chado_feature__residues extends TripalField {
 class chado_feature__residues extends TripalField {
 
 
   /**
   /**
-   * Implements hook_info() for fields.
-   *
-   * This is a hook provided by the tripal_chado module for offloading the
-   * hook_field_info() hook for each field to specify.
+   * @see TripalField::field_info()
    */
    */
   function field_info() {
   function field_info() {
     return array(
     return array(
@@ -24,57 +21,89 @@ class chado_feature__residues extends TripalField {
     );
     );
   }
   }
   /**
   /**
-   * Implements hook_attach_info().
-   *
-   * This is a hook provided by the tripal_Chado module. It allows the field
-   * to specify which bundles it will attach to and to specify thee settings.
-   *
-   * @param $entity_type
-   * @param $entity
-   * @param $term
-   *
-   * @return
-   *   A field array
+   * @see TripalField::can_attach()
    */
    */
-  function attach_info($entity_type, $bundle, $settings) {
-    $field_info = array();
-
-    $table_name = $settings['data_table'];
-    $type_table = $settings['type_table'];
-    $type_field = $settings['field'];
-    $cv_id      = $settings['cv_id'];
-    $cvterm_id  = $settings['cvterm_id'];
-
+  protected function can_attach($entity_type, $bundle, $details) {
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
     // If  this is not the feature table then we don't want to attach.
     // If  this is not the feature table then we don't want to attach.
-    if ($table_name != 'feature') {
-      return $field_info;
+    if ($table_name == 'feature') {
+      return TRUE;
     }
     }
+    return FALSE;
+  }
+  /**
+   * @see TripalField::create_info()
+   */
+  function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
-    $field_info = array(
+    return array(
       'field_name' => 'feature__residues',
       'field_name' => 'feature__residues',
-      'field_type' => 'chado_feature__residues',
-      'widget_type' => 'chado_feature__residues_widget',
-      'description' => 'An IUPAC compatible residues for this feature.',
-      'label' => 'Sequences',
-      'is_required' => 0,
-      'storage' => 'field_chado_storage',
-      'widget_settings' => array(
-        'display_label' => 1
+      'type' => 'chado_feature__residues',
+      'cardinality' => 1,
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
       ),
       ),
-      'field_settings' => array(
+      'settings' => array(
         'chado_table' => $table_name,
         'chado_table' => $table_name,
         'chado_column' => 'residues',
         'chado_column' => 'residues',
         'semantic_web' => 'SO:0000110',
         'semantic_web' => 'SO:0000110',
       ),
       ),
     );
     );
-    return $field_info;
   }
   }
   /**
   /**
-   * Implements hook_widget_info.
-   *
-   * This is a hook provided by the tripal_chado module for offloading
-   * the hook_field_widget_info() hook for each field to specify.
+   * @see TripalField::create_instance_info()
+   */
+  function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
+
+    return array(
+      'field_name' => 'feature__residues',
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Sequences',
+      'description' => 'All available sequences for this record.',
+      'required' => FALSE,
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'chado_feature__residues_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'deafult' => array(
+          'label' => 'above',
+          'type' => 'chado_feature__residues_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
+
+  /**
+   * @see TripalField::widget_info()
    */
    */
   function widget_info() {
   function widget_info() {
     return array(
     return array(
@@ -83,12 +112,7 @@ class chado_feature__residues extends TripalField {
     );
     );
   }
   }
   /**
   /**
-   * Implements hook_formatter_info.
-   *
-   * This is a hook provided by the tripal_chado module for
-   * offloading the hook_field_formatter_info() for each field
-   * to specify.
-   *
+   * @see TripalField::formatter_info()
    */
    */
   function formatter_info() {
   function formatter_info() {
     return array(
     return array(
@@ -97,14 +121,7 @@ class chado_feature__residues extends TripalField {
     );
     );
   }
   }
   /**
   /**
-   *
-   * @param unknown $entity_type
-   * @param unknown $entity
-   * @param unknown $field
-   * @param unknown $instance
-   * @param unknown $langcode
-   * @param unknown $items
-   * @param unknown $display
+   * @see TripalField::formatter_view()
    */
    */
   function formatter_view(&$element, $entity_type, $entity, $field,
   function formatter_view(&$element, $entity_type, $entity, $field,
     $instance, $langcode, $items, $display) {
     $instance, $langcode, $items, $display) {

+ 77 - 28
tripal_chado/includes/fields/chado_feature__seqlen.inc

@@ -18,41 +18,90 @@ class chado_feature__seqlen extends TripalField {
       ),
       ),
     );
     );
   }
   }
+
   /**
   /**
-   * @see TripalField::attach_info()
+   * @see TripalField::can_attach()
    */
    */
-  function attach_info($entity_type, $bundle, $settings) {
-    $field_info = array();
-
-    $table_name = $settings['data_table'];
-    $type_table = $settings['type_table'];
-    $type_field = $settings['field'];
-    $cv_id      = $settings['cv_id'];
-    $cvterm_id  = $settings['cvterm_id'];
+  protected function can_attach($entity_type, $bundle, $details) {
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
-    // If  this is not the feature table then we don't want to attach.
     if ($table_name == 'feature') {
     if ($table_name == 'feature') {
-      $field_info = array(
-        'field_name' => 'feature__seqlen',
-        'field_type' => 'chado_feature__seqlen',
-        'widget_type' => 'chado_feature__seqlen_widget',
-        'description' => 'The length of the sequence (residues).',
-        'label' => 'Sequence Length',
-        'is_required' => 0,
-        'storage' => 'field_chado_storage',
-        'widget_settings' => array(
-          'display_label' => 1
-        ),
-        'field_settings' => array(
-          'chado_table' => $table_name,
-          'chado_column' => 'seqlen',
-          'semantic_web' => 'data:1249',
-        ),
-      );
+      return TRUE;
     }
     }
+    return FALSE;
+  }
+  /**
+   * @see TripalField::create_info()
+   */
+  function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
-    return $field_info;
+    return array(
+      'field_name' => 'feature__seqlen',
+      'type' => 'chado_feature__seqlen',
+      'cardinality' => 1,
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+      'settings' => array(
+        'chado_table' => $table_name,
+        'chado_column' => 'seqlen',
+        'semantic_web' => 'data:1249',
+      ),
+    );
+  }
+  /**
+   * @see TripalField::create_instance_info()
+   */
+  function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
+
+    return array(
+      'field_name' => 'feature__seqlen',
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Raw Sequence Length',
+      'description' => 'The number of residues in the raw sequence.  This length
+        is only for the assigned raw sequence and does not represent the length of any
+        sequences derived from alignments. If this value is zero but aligned sequences
+        are present then this record has no official assigned sequence.',
+      'required' => FALSE,
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'chado_feature__seqlen_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'deafult' => array(
+          'label' => 'above',
+          'type' => 'chado_feature__seqlen_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
   }
   }
+
   /**
   /**
    * @see TripalField::widget_info()
    * @see TripalField::widget_info()
    */
    */

+ 68 - 24
tripal_chado/includes/fields/chado_gene__transcripts.inc

@@ -19,48 +19,92 @@ class chado_gene__transcripts extends TripalField {
       ),
       ),
     );
     );
   }
   }
-
   /**
   /**
-   * @see TripalField::attach_info()
+   * @see TripalField::can_attach()
    */
    */
-  public function attach_info($entity_type, $bundle, $target) {
-    $field_info = array();
-
-    $table_name = $target['data_table'];
-    $type_table = $target['type_table'];
-    $type_field = $target['field'];
-    $cv_id      = $target['cv_id'];
-    $cvterm_id  = $target['cvterm_id'];
+  protected function can_attach($entity_type, $bundle, $details) {
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
     // If the linker table does not exists or this is not a gene then we don't want to add attach.
     // If the linker table does not exists or this is not a gene then we don't want to add attach.
     $rel_table = $table_name . '_relationship';
     $rel_table = $table_name . '_relationship';
-    if (!chado_table_exists($rel_table) || $bundle->label != 'gene') {
-      return $field_info;
+    if (chado_table_exists($rel_table) and $bundle->label == 'gene') {
+      return TRUE;
     }
     }
+    return FALSE;
+  }
+  /**
+   * @see TripalField::create_info()
+   */
+  function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
+    $rel_table = $table_name . '_relationship';
     $schema = chado_get_schema($rel_table);
     $schema = chado_get_schema($rel_table);
     $pkey = $schema['primary key'][0];
     $pkey = $schema['primary key'][0];
 
 
-    // Initialize the field array.
-    $field_info = array(
+    return array(
       'field_name' => 'gene_transcripts',
       'field_name' => 'gene_transcripts',
-      'field_type' => 'chado_gene__transcripts',
-      'widget_type' => 'chado_gene__transcripts_widget',
-      'widget_settings' => array('display_label' => 1),
-      'description' => '',
-      'label' => 'Transcripts',
-      'is_required' => 0,
+      'type' => 'chado_gene__transcripts',
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'storage' => 'field_chado_storage',
-      'field_settings' => array(
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+      'settings' => array(
         'chado_table' => $rel_table,
         'chado_table' => $rel_table,
-        'chado_column' => $pkey,
+        'chado_column' => 'md5checksum',
         'base_table' => $table_name,
         'base_table' => $table_name,
         'semantic_web' => 'SO:0000673',
         'semantic_web' => 'SO:0000673',
       ),
       ),
     );
     );
+  }
+  /**
+   * @see TripalField::create_instance_info()
+   */
+  function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
-    return $field_info;
+    return array(
+      'field_name' => 'gene_transcripts',
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Transcripts',
+      'description' => 'These transcripts are associated with this gene.',
+      'required' => FALSE,
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'chado_gene__transcripts_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'deafult' => array(
+          'label' => 'above',
+          'type' => 'chado_gene__transcripts_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
   }
   }
 
 
   /**
   /**

+ 91 - 40
tripal_chado/includes/fields/chado_linker__contact.inc

@@ -20,6 +20,97 @@ class chado_linker__contact extends TripalField {
       ),
       ),
     );
     );
   }
   }
+  /**
+   * @see TripalField::can_attach()
+   */
+  protected function can_attach($entity_type, $bundle, $details) {
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];;
+
+    // If the linker table does not exists then we don't want to add attach.
+    $contact_table = $table_name . '_contact';
+    if (chado_table_exists($contact_table)) {
+      return TRUE;
+    }
+    return FALSE;
+  }
+  /**
+   * @see TripalField::create_info()
+   */
+  function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
+
+    $contact_table = $table_name . '_contact';
+    $schema = chado_get_schema($contact_table);
+    $pkey = $schema['primary key'][0];
+
+    return array(
+      'field_name' => $contact_table,
+      'type' => 'chado_linker__contact',
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+      'settings' => array(
+        'chado_table' => $contact_table,
+        'chado_column' => $pkey,
+        'base_table' => $table_name,
+        'semantic_web' => 'local:contact'
+      ),
+    );
+  }
+  /**
+   * @see TripalField::create_instance_info()
+   */
+  function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];;
+
+    $contact_table = $table_name . '_contact';
+
+    return array(
+      'field_name' => $contact_table,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Contacts',
+      'description' => 'An individual, organization or entity that has had
+        some responsibility for the creation, delivery or maintenance of
+        the associated data.',
+      'required' => FALSE,
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'chado_linker__contact_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'deafult' => array(
+          'label' => 'above',
+          'type' => 'chado_linker__contact_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
   /**
   /**
    * @see TripalField::widget_info()
    * @see TripalField::widget_info()
    */
    */
@@ -41,47 +132,7 @@ class chado_linker__contact extends TripalField {
       ),
       ),
     );
     );
   }
   }
-  /**
-   * @see TripalField::attach_info()
-   */
-  public function attach_info($entity_type, $bundle, $settings) {
-    $field_info = array();
 
 
-    $table_name = $settings['data_table'];
-    $type_table = $settings['type_table'];
-    $type_field = $settings['field'];
-    $cv_id      = $settings['cv_id'];
-    $cvterm_id  = $settings['cvterm_id'];
-
-    // If the linker table does not exists then we don't want to add attach.
-    $contact_table = $table_name . '_contact';
-    if (!chado_table_exists($contact_table)) {
-      return $field_info;
-    }
-
-    $schema = chado_get_schema($contact_table);
-    $pkey = $schema['primary key'][0];
-
-    // Initialize the field array.
-    $field_info = array(
-      'field_name' => $table_name . '_contact',
-      'field_type' => 'chado_linker__contact',
-      'widget_type' => 'chado_linker__contact_widget',
-      'widget_settings' => array('display_label' => 1),
-      'description' => '',
-      'label' => 'Contacts',
-      'is_required' => 0,
-      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'storage' => 'field_chado_storage',
-      'field_settings' => array(
-        'chado_table' => $contact_table,
-        'chado_column' => $pkey,
-        'base_table' => $table_name,
-        'semantic_web' => 'local:contact'
-      ),
-    );
-    return $field_info;
-  }
 
 
   /**
   /**
    * @see TripalField::formatter_view()
    * @see TripalField::formatter_view()

+ 21 - 4
tripal_chado/includes/fields/chado_linker__cvterm.inc

@@ -20,14 +20,31 @@ class chado_linker__cvterm extends TripalField {
     );
     );
   }
   }
   /**
   /**
-   * @see TripalField::attach_info()
+   * @see TripalField::can_attach()
    */
    */
-  function attach_info($entity_type, $bundle, $target) {
-    $field_info = array();
+  protected function can_attach($entity_type, $bundle, $details) {
 
 
     // This field is only attached by the chado_linker__cvterm_addr field.
     // This field is only attached by the chado_linker__cvterm_addr field.
+    return FALSE;
+  }
+  /**
+   * @see TripalField::create_info()
+   */
+  function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+    // This field is only attached by the chado_linker__cvterm_addr field.
+  }
+  /**
+   * @see TripalField::create_instance_info()
+   */
+  function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
 
 
-    return $field_info;
+    // This field is only attached by the chado_linker__cvterm_addr field.
   }
   }
   /**
   /**
    * @see TripalField::widget_info()
    * @see TripalField::widget_info()

+ 116 - 49
tripal_chado/includes/fields/chado_linker__cvterm_adder.inc

@@ -20,45 +20,88 @@ class chado_linker__cvterm_addr extends TripalField {
     );
     );
   }
   }
   /**
   /**
-   * @see TripalField::attach_info()
+   * @see TripalField::can_attach()
    */
    */
-  function attach_info($entity_type, $bundle, $settings) {
-
+  protected function can_attach($entity_type, $bundle, $details) {
     $field_info = array();
     $field_info = array();
 
 
-    $table_name = $settings['data_table'];
-    $type_table = $settings['type_table'];
-    $type_field = $settings['field'];
-    $cv_id      = $settings['cv_id'];
-    $cvterm_id  = $settings['cvterm_id'];
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
 
 
     // If the linker table does not exists then we don't want to add attach.
     // If the linker table does not exists then we don't want to add attach.
     $cvterm_table = $table_name . '_cvterm';
     $cvterm_table = $table_name . '_cvterm';
-    if (!chado_table_exists($cvterm_table)) {
-      return $field_info;
+    if (chado_table_exists($cvterm_table)) {
+      return TRUE;
+    }
+    return FALSE;
+  }
+  /**
+   * @see TripalField::create_info()
+   */
+  function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
     }
     }
 
 
-    // Initialize the field array.
-    $field_info = array(
-      'field_name' => $cvterm_table,
-      'field_type' => 'chado_linker__cvterm_adder',
-      'widget_type' => 'chado_linker__cvterm_adder_widget',
-      'field_settings' => array(
-        'base_table' => $table_name,
-      ),
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
+
+    return array(
+      'field_name' => $table_name . '_cvterm',
+      'type' => 'chado_linker__cvterm_adder',
       'cardinality' => 1,
       'cardinality' => 1,
-      'storage' => 'field_chado_storage',
-      'widget_settings' => array('display_label' => 1),
-      'description' => '',
-      'label' => 'Additional Annotation Types',
-      'is_required' => 0,
-      // This feld is never visible so there are no field settings for
-      // Chado nor the semantiv web.
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+      'settings' => array(
+      ),
     );
     );
+  }
+  /**
+   * @see TripalField::create_instance_info()
+   */
+  function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
-    return $field_info;
+    return array(
+      'field_name' => $table_name . '_cvterm',
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Add Annotation Types',
+      'description' => 'Add additional annotations types to this record.',
+      'required' => FALSE,
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'chado_linker__cvterm_adder_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'deafult' => array(
+          'label' => 'above',
+          'type' => 'chado_linker__cvterm_adder_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
   }
   }
+
   /**
   /**
    * @see TripalField::widget_info()
    * @see TripalField::widget_info()
    */
    */
@@ -153,29 +196,53 @@ function chado_linker__cvterm_adder_widget_validate($element, &$form_state) {
     $schema = chado_get_schema($field_name);
     $schema = chado_get_schema($field_name);
     $pkey = $schema['primary key'][0];
     $pkey = $schema['primary key'][0];
 
 
-    $field_info = array(
-      'field_type' => 'cvterm',
-      'widget_type' => 'tripal_chado_cvterm_widget',
-      'field_settings' => array(
-        'chado_table' => $field_name,
-        'chado_column' => $pkey,
-        'base_table' => $base_table,
-      ),
-      'storage' => 'field_chado_storage',
-      'widget_settings' => array(),
-      'description' => "Annotations from the $cv->name vocabulary",
-      'label' => ucfirst(preg_replace('/_/', ' ', $cv->name)),
-      'is_required' => FALSE,
-      // All annotations are unlimited.
-      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-    );
-    tripal_add_bundle_field($type_field_name, $field_info, $entity_type, $bundle);
+    // Add the field if it doesn't already exists.
+    $field = field_info_field('cvterm');
+    if (!$field) {
+      $create_info = array(
+        'field_name' => 'cvterm',
+        'type' => 'tripal_chado_cvterm_widget',
+        '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_name, $field['bundles']['TripalEntity'])) {
+      $create_instance_info = array(
+        'field_name' => 'cvtmerm',
+        'entity_type' => 'TripalEntity',
+        'bundle' => $bundle->name,
+        'label' => ucfirst(preg_replace('/_/', ' ', $cv->name)),
+        'description' => "Annotations from the $cv->name vocabulary",
+        'required' => FALSE,
+        'settings' => array(),
+        'widget' => array(
+          'type' => 'tripal_chado_cvterm_widget',
+          'settings' => array(
+            'display_label' => 1,
+          ),
+        ),
+        'display' => array(
+          'deafult' => array(
+            'label' => 'above',
+            'type' => 'tripal_chado_cvterm_formatter',
+            'settings' => array(),
+          ),
+        ),
+      );
+      $instance = field_create_instance($create_instance_info);
+    }
   }
   }
-}
-/**
- * Callback function for submitting the chado_linker__cvterm_adder_widget.
- */
-function chado_linker__cvterm_adder_widget_submit($element, &$form_state) {
-
 }
 }

+ 78 - 33
tripal_chado/includes/fields/chado_linker__dbxref.inc

@@ -33,49 +33,94 @@ class chado_linker__dbxref extends TripalField {
     );
     );
   }
   }
   /**
   /**
-   * @see TripalField::attach_info()
+   * @see TripalField::can_attach()
    */
    */
-  function attach_info($entity_type, $bundle, $settings) {
-    $field_info = array();
-
-    $table_name = $settings['data_table'];
-    $type_table = $settings['type_table'];
-    $type_field = $settings['field'];
-    $cv_id      = $settings['cv_id'];
-    $cvterm_id  = $settings['cvterm_id'];
+  protected function can_attach($entity_type, $bundle, $details) {
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
     // If the linker table does not exists then we don't want to add attach.
     // If the linker table does not exists then we don't want to add attach.
     $dbxref_table = $table_name . '_dbxref';
     $dbxref_table = $table_name . '_dbxref';
     if (chado_table_exists($dbxref_table)) {
     if (chado_table_exists($dbxref_table)) {
+      return TRUE;
+    }
+    return FALSE;
+  }
+  /**
+   * @see TripalField::create_info()
+   */
+  function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
-      // We already have a dbxref_id field.
-      $schema = chado_get_schema($dbxref_table);
-      $pkey = $schema['primary key'][0];
-
-      // Initialize the field array.
-      $field_info = array(
-        'field_name' => $dbxref_table,
-        'field_type' => 'chado_linker__dbxref',
-        'widget_type' => 'chado_linker__dbxref_widget',
-        'widget_settings' => array('display_label' => 1),
-        'description' => 'This field specifies the IDs where this
-           record may be available in other external online databases.',
-        'label' => 'Cross References',
-        'is_required' => 0,
-        'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-        'storage' => 'field_chado_storage',
-        'field_settings' => array(
-          'chado_table' => $dbxref_table,
-          'chado_column' => $pkey,
-          'base_table' => $table_name,
-          'semantic_web' => 'SBO:0000554',
-        ),
-      );
+    $dbxref_table = $table_name . '_dbxref';
+    $schema = chado_get_schema($dbxref_table);
+    $pkey = $schema['primary key'][0];
 
 
+    return array(
+      'field_name' => $dbxref_table,
+      'type' => 'chado_linker__dbxref',
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+      'settings' => array(
+        'chado_table' => $dbxref_table,
+        'chado_column' => $pkey,
+        'base_table' => $table_name,
+        'semantic_web' => 'SBO:0000554',
+      ),
+    );
+  }
+  /**
+   * @see TripalField::create_instance_info()
+   */
+  function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
     }
     }
 
 
-    return $field_info;
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
+
+    $dbxref_table = $table_name . '_dbxref';
+    return array(
+      'field_name' => $dbxref_table,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Cross References',
+      'description' => 'The IDs where this record may be available in other external online databases.',
+      'required' => FALSE,
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'chado_linker__dbxref_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'deafult' => array(
+          'label' => 'above',
+          'type' => 'chado_linker__dbxref_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
   }
   }
+
   /**
   /**
    * @see TripalField::widget_info()
    * @see TripalField::widget_info()
    */
    */

+ 97 - 54
tripal_chado/includes/fields/chado_linker__expression.inc

@@ -2,6 +2,9 @@
 
 
 class chado_linker__expression extends TripalField {
 class chado_linker__expression extends TripalField {
 
 
+  /**
+   * @see TripalField::field_info()
+   */
   public function field_info() {
   public function field_info() {
     return array(
     return array(
       'label' => t('Expression'),
       'label' => t('Expression'),
@@ -17,70 +20,119 @@ class chado_linker__expression extends TripalField {
       ),
       ),
     );
     );
   }
   }
- function widget_info() {
-    return array(
-      'label' => t('Expressions'),
-      'field types' => array('chado_linker__expression'),
-    );
-  }
-
-  public function formatter_info() {
-    return array(
-      'label' => t('Expression'),
-      'field types' => array('chado_linker__expression'),
-      'settings' => array(
-      ),
-    );
-  }
-  public function attach_info($entity_type, $bundle, $settings) {
-    $field_info = array();
-
-    $table_name = $settings['data_table'];
-    $type_table = $settings['type_table'];
-    $type_field = $settings['field'];
-    $cv_id      = $settings['cv_id'];
-    $cvterm_id  = $settings['cvterm_id'];
+  /**
+   * @see TripalField::can_attach()
+   */
+  protected function can_attach($entity_type, $bundle, $details) {
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
     // If the linker table does not exists then we don't want to add attach.
     // If the linker table does not exists then we don't want to add attach.
     $expression_table = $table_name . '_expression';
     $expression_table = $table_name . '_expression';
-    if (!chado_table_exists($expression_table)) {
-      return $field_info;
+    if (chado_table_exists($expression_table)) {
+      return TRUE;
+    }
+    return FALSE;
+  }
+  /**
+   * @see TripalField::create_info()
+   */
+  function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
     }
     }
 
 
-    $schema = chado_get_schema($expression_table);
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
+
+    $schema = chado_get_schema('featureloc');
     $pkey = $schema['primary key'][0];
     $pkey = $schema['primary key'][0];
 
 
-    // Initialize the field array.
-    $field_info = array(
+    return array(
       'field_name' => $table_name . '_expression',
       'field_name' => $table_name . '_expression',
-      'field_type' => 'chado_linker__expression',
-      'widget_type' => 'chado_linker__expression_widget',
-      'widget_settings' => array('display_label' => 1),
-      'description' => '',
-      'label' => 'Expression',
-      'is_required' => 0,
+      'type' => 'chado_linker__expression',
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'storage' => 'field_chado_storage',
-      'field_settings' => array(
-        'chado_table' => $expression_table,
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+      'settings' => array(
+        'chado_table' => $table_name . '_expression',
         'chado_column' => $pkey,
         'chado_column' => $pkey,
         'base_table' => $table_name,
         'base_table' => $table_name,
         'semantic_web' => 'local:expression',
         'semantic_web' => 'local:expression',
       ),
       ),
     );
     );
-    return $field_info;
   }
   }
+  /**
+   * @see TripalField::create_instance_info()
+   */
+  function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
 
 
-  public function formatter_settings_summary($field, $instance, $view_mode) {
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
+    return array(
+      'field_name' => $table_name . '_expression',
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Expression',
+      'description' => 'Information about the expression of this record.',
+      'required' => FALSE,
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'chado_linker__expression_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'deafult' => array(
+          'label' => 'above',
+          'type' => 'chado_linker__expression_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
   }
   }
 
 
-  public function formatter_settings_form($field, $instance,
-      $view_mode, $form, &$form_state) {
-
+  /**
+   * @see TripalField::widget_info()
+   */
+ function widget_info() {
+    return array(
+      'label' => t('Expressions'),
+      'field types' => array('chado_linker__expression'),
+    );
   }
   }
 
 
+  /**
+   * @see TripalField::formatter_info()
+   */
+  public function formatter_info() {
+    return array(
+      'label' => t('Expression'),
+      'field types' => array('chado_linker__expression'),
+      'settings' => array(
+      ),
+    );
+  }
 
 
+  /**
+   * @see TripalField::formatter_view()
+   */
   public function formatter_view(&$element, $entity_type, $entity,
   public function formatter_view(&$element, $entity_type, $entity,
       $field, $instance, $langcode, $items, $display) {
       $field, $instance, $langcode, $items, $display) {
 
 
@@ -152,13 +204,9 @@ class chado_linker__expression extends TripalField {
     );
     );
   }
   }
 
 
-
-  public function widget_form(&$widget, &$form, &$form_state, $field, $instance,
-      $langcode, $items, $delta, $element) {
-
-
-  }
-
+  /**
+   * @see TripalField::load()
+   */
   public function load($field, $entity, $details) {
   public function load($field, $entity, $details) {
     $record = $details['record'];
     $record = $details['record'];
 
 
@@ -232,9 +280,4 @@ class chado_linker__expression extends TripalField {
     }
     }
   }
   }
 
 
-  public function settings_form($field, $instance, $has_data) {
-
-  }
-
-
 }
 }

+ 67 - 23
tripal_chado/includes/fields/chado_linker__featureloc.inc

@@ -19,47 +19,91 @@ class chado_linker__featureloc extends TripalField {
       ),
       ),
     );
     );
   }
   }
-
   /**
   /**
-   * @see TripalField::attach_info()
+   * @see TripalField::can_attach()
    */
    */
-  public function attach_info($entity_type, $bundle, $target) {
-    $field_info = array();
-
-    $table_name = $target['data_table'];
-    $type_table = $target['type_table'];
-    $type_field = $target['field'];
-    $cv_id      = $target['cv_id'];
-    $cvterm_id  = $target['cvterm_id'];
+  protected function can_attach($entity_type, $bundle, $details) {
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
     // If  this is not the feature table then we don't want to attach.
     // If  this is not the feature table then we don't want to attach.
-    if ($table_name != 'feature') {
-      return $field_info;
+    if ($table_name == 'feature') {
+      return TRUE;
     }
     }
+    return FALSE;
+  }
+  /**
+   * @see TripalField::create_info()
+   */
+  function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
     $schema = chado_get_schema('featureloc');
     $schema = chado_get_schema('featureloc');
     $pkey = $schema['primary key'][0];
     $pkey = $schema['primary key'][0];
 
 
-    // Initialize the field array.
-    $field_info = array(
+    return array(
       'field_name' => 'featureloc',
       'field_name' => 'featureloc',
-      'field_type' => 'chado_linker__featureloc',
-      'widget_type' => 'chado_linker__featureloc_widget',
-      'widget_settings' => array('display_label' => 1),
-      'description' => '',
-      'label' => 'Aligned Locations',
-      'is_required' => 0,
+      'type' => 'chado_linker__featureloc',
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'storage' => 'field_chado_storage',
-      'field_settings' => array(
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+      'settings' => array(
         'chado_table' => 'featureloc',
         'chado_table' => 'featureloc',
         'chado_column' => $pkey,
         'chado_column' => $pkey,
         'base_table' => 'feature',
         'base_table' => 'feature',
         'semantic_web' => 'SO:position_of',
         'semantic_web' => 'SO:position_of',
       ),
       ),
     );
     );
+  }
+  /**
+   * @see TripalField::create_instance_info()
+   */
+  function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
-    return $field_info;
+    return array(
+      'field_name' => 'featureloc',
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Aligned Locations',
+      'description' => 'The locations on other genomic sequences where this
+        record has been aligned.',
+      'required' => FALSE,
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'chado_linker__featureloc_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'deafult' => array(
+          'label' => 'above',
+          'type' => 'chado_linker__featureloc_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
   }
   }
 
 
   /**
   /**

+ 68 - 22
tripal_chado/includes/fields/chado_linker__genotype.inc

@@ -42,45 +42,91 @@ class chado_linker__genotype extends TripalField {
     );
     );
   }
   }
   /**
   /**
-   * @see TripalField::attach_info()
+   * @see TripalField::can_attach()
    */
    */
-  public function attach_info($entity_type, $bundle, $settings) {
-    $field_info = array();
-
-    $table_name = $settings['data_table'];
-    $type_table = $settings['type_table'];
-    $type_field = $settings['field'];
-    $cv_id      = $settings['cv_id'];
-    $cvterm_id  = $settings['cvterm_id'];
+  protected function can_attach($entity_type, $bundle, $details) {
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
     // If the linker table does not exists then we don't want to add attach.
     // If the linker table does not exists then we don't want to add attach.
     $genotype_table = $table_name . '_genotype';
     $genotype_table = $table_name . '_genotype';
-    if (!chado_table_exists($genotype_table)) {
-      return $field_info;
+    if (chado_table_exists($genotype_table)) {
+      return TRUE;
     }
     }
+    return FALSE;
+  }
+  /**
+   * @see TripalField::create_info()
+   */
+  function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
+    $genotype_table = $table_name . '_genotype';
     $schema = chado_get_schema($genotype_table);
     $schema = chado_get_schema($genotype_table);
     $pkey = $schema['primary key'][0];
     $pkey = $schema['primary key'][0];
 
 
-    // Initialize the field array.
-    $field_info = array(
+    return array(
       'field_name' => $table_name . '__genotype',
       'field_name' => $table_name . '__genotype',
-      'field_type' => 'chado_linker__genotype',
-      'widget_type' => 'chado_linker__genotype_widget',
-      'widget_settings' => array('display_label' => 1),
-      'description' => '',
-      'label' => 'Genotypes',
-      'is_required' => 0,
+      'type' => 'chado_feature__md5checksum',
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'storage' => 'field_chado_storage',
-      'field_settings' => array(
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+      'settings' => array(
         'chado_table' => $genotype_table,
         'chado_table' => $genotype_table,
         'chado_column' => $pkey,
         'chado_column' => $pkey,
         'semantic_web' => 'SO:0001027',
         'semantic_web' => 'SO:0001027',
         'base_table' => $table_name,
         'base_table' => $table_name,
       ),
       ),
     );
     );
-    return $field_info;
+  }
+  /**
+   * @see TripalField::create_instance_info()
+   */
+  function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
+
+    return array(
+      'field_name' => $table_name . '__genotype',
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Genotypes',
+      'description' => 'The genotypes associated with this record.',
+      'required' => FALSE,
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'chado_linker__genotype_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'deafult' => array(
+          'label' => 'above',
+          'type' => 'chado_linker__genotype_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
   }
   }
 
 
   /**
   /**

+ 69 - 22
tripal_chado/includes/fields/chado_linker__phenotype.inc

@@ -42,45 +42,92 @@ class chado_linker__phenotype extends TripalField {
     );
     );
   }
   }
   /**
   /**
-   * @see TripalField::attach_info()
+   * @see TripalField::can_attach()
    */
    */
-  public function attach_info($entity_type, $bundle, $settings) {
-    $field_info = array();
-
-    $table_name = $settings['data_table'];
-    $type_table = $settings['type_table'];
-    $type_field = $settings['field'];
-    $cv_id      = $settings['cv_id'];
-    $cvterm_id  = $settings['cvterm_id'];
+  protected function can_attach($entity_type, $bundle, $details) {
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
     // If the linker table does not exists then we don't want to add attach.
     // If the linker table does not exists then we don't want to add attach.
     $phenotype_table = $table_name . '_phenotype';
     $phenotype_table = $table_name . '_phenotype';
-    if (!chado_table_exists($phenotype_table)) {
-      return $field_info;
+    if (chado_table_exists($phenotype_table)) {
+      return TRUE;
     }
     }
+    return FALSE;
+  }
+  /**
+   * @see TripalField::create_info()
+   */
+  function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
+    $phenotype_table = $table_name . '_phenotype';
     $schema = chado_get_schema($phenotype_table);
     $schema = chado_get_schema($phenotype_table);
     $pkey = $schema['primary key'][0];
     $pkey = $schema['primary key'][0];
 
 
-    // Initialize the field array.
-    $field_info = array(
+    return array(
       'field_name' => $table_name . '__phenotype',
       'field_name' => $table_name . '__phenotype',
-      'field_type' => 'chado_linker__phenotype',
-      'widget_type' => 'chado_linker__phenotype_widget',
-      'widget_settings' => array('display_label' => 1),
-      'description' => '',
-      'label' => 'Phenotypes',
-      'is_required' => 0,
+      'type' => 'chado_linker__phenotype',
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'storage' => 'field_chado_storage',
-      'field_settings' => array(
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+      'settings' => array(
         'chado_table' => $phenotype_table,
         'chado_table' => $phenotype_table,
         'chado_column' => $pkey,
         'chado_column' => $pkey,
         'base_table' => $table_name,
         'base_table' => $table_name,
         'semantic_web' => 'SBO:0000358',
         'semantic_web' => 'SBO:0000358',
       ),
       ),
     );
     );
-    return $field_info;
+  }
+  /**
+   * @see TripalField::create_instance_info()
+   */
+  function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
+
+    return array(
+      'field_name' => $table_name . '__phenotype',
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Phenotypes',
+      'description' => 'The phenotypes associated with this record.',
+      'required' => FALSE,
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'chado_linker__phenotype_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'deafult' => array(
+          'label' => 'above',
+          'type' => 'chado_linker__phenotype_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+
   }
   }
 
 
   /**
   /**

+ 264 - 283
tripal_chado/includes/fields/chado_linker__prop.inc

@@ -1,317 +1,298 @@
 <?php
 <?php
-/**
- * Implements hook_info() for fields.
- *
- * This is a hook provided by the tripal_chado module for offloading the
- * hook_field_info() hook for each field to specify.
- */
-function chado_linker__prop_info() {
-  return array(
-    'label' => t('Add a Property'),
-    'description' => t('Add details about this property.'),
-    'default_widget' => 'chado_linker__prop_widget',
-    'default_formatter' => 'chado_linker__prop_formatter',
-    'settings' => array(),
-    'storage' => array(
-      'type' => 'field_chado_storage',
-      'module' => 'tripal_chado',
-      'active' => TRUE
-    ),
-  );
-}
-/**
- * Implements hook_attach_info().
- *
- * This is a hook provided by the tripal_Chado module. It allows the field
- * to specify which bundles it will attach to and to specify thee settings.
- *
- * @param $entity_type
- * @param $entity
- * @param $term
- *
- * @return
- *   A field array
- */
-function chado_linker__prop_attach_info($entity_type, $bundle, $target) {
-  $field_info = array();
 
 
-  // This field is only attached by the chado_linker__prop_addr field.
-
-  return $field_info;
-}
-/**
- * Implements hook_widget_info.
- *
- * This is a hook provided by the tripal_chado module for offloading
- * the hook_field_widget_info() hook for each field to specify.
- */
-function chado_linker__prop_widget_info() {
-  return array(
-    'label' => t('Property'),
-    'field types' => array('chado_linker__prop'),
-  );
-}
-/**
- * Implements hook_formatter_info.
- *
- * This is a hook provided by the tripal_chado module for
- * offloading the hook_field_formatter_info() for each field
- * to specify.
- *
- */
-function chado_linker__prop_formatter_info() {
-  return array(
-    'label' => t('Property'),
-    'field types' => array('chado_linker__prop'),
-    'settings' => array(
-    ),
-  );
-}
-/**
- *
- * @param unknown $entity_type
- * @param unknown $entity
- * @param unknown $field
- * @param unknown $instance
- * @param unknown $langcode
- * @param unknown $items
- * @param unknown $display
- */
-function chado_linker__prop_formatter(&$element, $entity_type, $entity, $field,
-  $instance, $langcode, $items, $display) {
+class chado_linker__prop extends TripalField {
+  /**
+   * @see TripalField::field_info()
+   */
+  function field_info() {
+    return array(
+      'label' => t('Add a Property'),
+      'description' => t('Add details about this property.'),
+      'default_widget' => 'chado_linker__prop_widget',
+      'default_formatter' => 'chado_linker__prop_formatter',
+      'settings' => array(),
+      'storage' => array(
+        'type' => 'field_chado_storage',
+        'module' => 'tripal_chado',
+        'active' => TRUE
+      ),
+    );
+  }
+  /**
+   * @see TripalField::can_attach()
+   */
+  protected function can_attach($entity_type, $bundle, $details) {
+    // This field is only attached by the chado_linker__prop_addr field.
+    return FALSE;
+  }
+  /**
+   * @see TripalField::create_info()
+   */
+  function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
 
 
-  $field_name = $field['field_name'];
-  $chado_table = $field['settings']['chado_table'];
+    // This field is only attached by the chado_linker__prop_addr field.
 
 
-  $properties = array();
-  foreach ($items as $delta => $item) {
-    $properties[] = $item[$chado_table . '__value'];
   }
   }
-  $content = implode(', ', $properties);
-  $element[$delta] = array(
-    '#type' => 'markup',
-    '#markup' => $content,
-  );
-}
-/**
- *
- * @param unknown $field_name
- * @param unknown $widget
- * @param unknown $form
- * @param unknown $form_state
- * @param unknown $field
- * @param unknown $instance
- * @param unknown $langcode
- * @param unknown $items
- * @param unknown $delta
- * @param unknown $element
- */
-function chado_linker__prop_widget(&$widget, $form, $form_state, $field, $instance, $langcode, $items, $delta, $element) {
-  $entity = $form['#entity'];
-  $field_name = $field['field_name'];
+  /**
+   * @see TripalField::create_instance_info()
+   */
+  function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
 
 
-  // Get the record and table mapping info.
-  $chado_table = $entity->chado_table;
-  $chado_column = $entity->chado_column;
-  $chado_record = $entity->chado_record;
+    // This field is only attached by the chado_linker__prop_addr field.
 
 
-  $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];
+  /**
+   * @see TripalField::attach_info()
+   */
+  function attach_info($entity_type, $bundle, $target) {
+    $field_info = array();
 
 
-  // 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);
-  $pkey = $schema['primary key'][0];
-  $lfkey_field = key($schema['foreign keys'][$chado_table]['columns']);
-  $rfkey_field = $schema['foreign keys'][$chado_table]['columns'][$lfkey_field];
+    // This field is only attached by the chado_linker__prop_addr field.
 
 
-  // Get the field defaults.
-  $fk_value = '';
-  $propval = '';
-  if (array_key_exists($delta, $items)) {
-    $propval = $items[$delta][$table_name . '__value'];
+    return $field_info;
+  }
+  /**
+   * @see TripalField::widget_info()
+   */
+  function widget_info() {
+    return array(
+      'label' => t('Property'),
+      'field types' => array('chado_linker__prop'),
+    );
   }
   }
-  if ($chado_record) {
-    $fk_value = $chado_record->$rfkey_field;
+  /**
+   * @see TripalField::formatter_info()
+   */
+  function formatter_info() {
+    return array(
+      'label' => t('Property'),
+      'field types' => array('chado_linker__prop'),
+      'settings' => array(
+      ),
+    );
   }
   }
+  /**
+   * @see TripalField::formatter_view()
+   */
+  function formatter_view(&$element, $entity_type, $entity, $field,
+    $instance, $langcode, $items, $display) {
 
 
+    $field_name = $field['field_name'];
+    $chado_table = $field['settings']['chado_table'];
 
 
-  // The group of elements all-together need some extra functionality
-  // after building up the full list (like draggable table rows).
-  $widget['#theme'] = 'field_multiple_value_form';
-  $widget['#title'] = $element['#title'];
-  $widget['#description'] = $element['#description'];
-  $widget['#field_name'] = $element['#field_name'];
-  $widget['#language'] = $element['#language'];
-  $widget['#weight'] = isset($element['#weight']) ? $element['#weight'] : 0;
-  $widget['#element_validate'] = array('chado_linker__prop_widget_validate');
-  $widget['#cardinality'] = 1;
+    $properties = array();
+    foreach ($items as $delta => $item) {
+      $properties[] = $item[$chado_table . '__value'];
+    }
+    $content = implode(', ', $properties);
+    $element[$delta] = array(
+      '#type' => 'markup',
+      '#markup' => $content,
+    );
+  }
+  /**
+   * @see TripalField::widget_form()
+   */
+  function widget_form(&$widget, &$form, &$form_state, $field, $instance,
+      $langcode, $items, $delta, $element) {
 
 
-  $widget['value'] = array(
-    '#type' => 'value',
-    '#value' => $items[$delta]['value'],
-  );
+    $entity = $form['#entity'];
+    $field_name = $field['field_name'];
 
 
-  $widget[$table_name . '__' . $pkey] = array(
-    '#type' => 'hidden',
-    '#default_value' => !empty($items[$delta]['value']) ? $items[$delta]['value'] : '',
-  );
-  $widget[$table_name . '__' . $lfkey_field] = array(
-    '#type' => 'hidden',
-    '#value' => $fk_value,
-  );
-  $widget[$table_name . '__value'] = array(
-    '#type' => 'textfield',
-    '#default_value' => $propval,
-  );
-  $widget[$table_name . '__type_id'] = array(
-    '#type' => 'hidden',
-    '#value' => $cvterm_id,
-  );
-  $widget[$table_name . '__rank'] = array(
-    '#type' => 'hidden',
-    '#value' => $delta,
-  );
-  return $widget;
-}
+    // Get the record and table mapping info.
+    $chado_table = $entity->chado_table;
+    $chado_column = $entity->chado_column;
+    $chado_record = $entity->chado_record;
 
 
-/**
- *
- * @param unknown $form
- * @param unknown $form_state
- */
-function chado_linker__prop_widget_form_ajax_callback($form, $form_state) {
-  $field_name = $form_state['triggering_element']['#parents'][0];
-  return $form[$field_name];
-}
-/**
- * Callback function for validating the chado_linker__prop_widget.
- */
-function chado_linker__prop_widget_validate($element, &$form_state) {
-  $field_name = $element['#field_name'];
-  $delta = $element['#delta'];
-  $entity = $element['#entity'];
-  $matches = array();
+    $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 record and table mapping info.
-  $chado_table = $entity->chado_table;
-  $chado_column = $entity->chado_column;
+    // 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);
+    $pkey = $schema['primary key'][0];
+    $lfkey_field = key($schema['foreign keys'][$chado_table]['columns']);
+    $rfkey_field = $schema['foreign keys'][$chado_table]['columns'][$lfkey_field];
 
 
-  // Get the table name and cvterm_id for this field.
-  preg_match('/(.*?)__(\d+)/', $field_name, $matches);
-  $table_name = $matches[1];
-  $cvterm_id = $matches[2];
+    // Get the field defaults.
+    $fk_value = '';
+    $propval = '';
+    if (array_key_exists($delta, $items)) {
+      $propval = $items[$delta][$table_name . '__value'];
+    }
+    if ($chado_record) {
+      $fk_value = $chado_record->$rfkey_field;
+    }
 
 
-  // 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);
-  $pkey = $schema['primary key'][0];
-  $lfkey_field = key($schema['foreign keys'][$chado_table]['columns']);
 
 
-  // If we don't have a property value then we need to set all other fields
-  // to be empty so that when the module tries to save the field on the
-  // entity it won't try to save a partial record.
-  $pkey_val = tripal_chado_get_field_form_values($field_name, $form_state, $delta);
-  $prop_value = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $table_name . "__value");
-  $fk_val = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $table_name . '__' . $lfkey_field);
-  $type_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $table_name . '__type_id');
+    // The group of elements all-together need some extra functionality
+    // after building up the full list (like draggable table rows).
+    $widget['#theme'] = 'field_multiple_value_form';
+    $widget['#title'] = $element['#title'];
+    $widget['#description'] = $element['#description'];
+    $widget['#field_name'] = $element['#field_name'];
+    $widget['#language'] = $element['#language'];
+    $widget['#weight'] = isset($element['#weight']) ? $element['#weight'] : 0;
+    $widget['#element_validate'] = array('chado_linker__prop_widget_validate');
+    $widget['#cardinality'] = 1;
 
 
-  if (!$prop_value) {
-    tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__' . $lfkey_field);
-    tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__value');
-    tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__type_id');
-    tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__rank');
-  }
-  else {
-    $rank = tripal_chado_get_field_form_values($field_name, $form_state, $delta, '_weight');
-    tripal_chado_set_field_form_values($field_name, $form_state, $rank, $delta, $table_name . '__rank');
-  }
-  // Remove the properties for this record. We will re-add it. Otherwise,
-  // if we change ranks, we wind up with multiple records in the property table.
-  if ($pkey_val) {
-    $match = array(
-      $pkey => $pkey_val
+    $widget['value'] = array(
+      '#type' => 'value',
+      '#value' => $items[$delta]['value'],
+    );
+
+    $widget[$table_name . '__' . $pkey] = array(
+      '#type' => 'hidden',
+      '#default_value' => !empty($items[$delta]['value']) ? $items[$delta]['value'] : '',
+    );
+    $widget[$table_name . '__' . $lfkey_field] = array(
+      '#type' => 'hidden',
+      '#value' => $fk_value,
+    );
+    $widget[$table_name . '__value'] = array(
+      '#type' => 'textfield',
+      '#default_value' => $propval,
     );
     );
-    chado_delete_record($table_name, $match);
+    $widget[$table_name . '__type_id'] = array(
+      '#type' => 'hidden',
+      '#value' => $cvterm_id,
+    );
+    $widget[$table_name . '__rank'] = array(
+      '#type' => 'hidden',
+      '#value' => $delta,
+    );
+    return $widget;
   }
   }
-}
-/**
- * Callback function for submitting the chado_linker__prop_widget.
- */
-function chado_linker__prop_widget_submit($element, &$form_state) {
-}
 
 
-/**
- * Loads the field values with appropriate data.
- *
- * This function is called by the tripal_chado_field_storage_load() for
- * each property managed by the field_chado_storage storage type.  This is
- * an optional hook function that is only needed if the field has
- * multiple form elements.
- *
- * @param $field
- * @param $entity
- * @param $base_table
- * @param $record
- */
-function chado_linker__prop_load($field, $entity, $base_table, $record) {
 
 
-  $field_name = $field['field_name'];
-  $field_type = $field['type'];
-  $field_table = $field['settings']['chado_table'];
-  $field_column = $field['settings']['chado_column'];
+  /**
+   * @see TripalField::validate()
+   */
+  function validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
+    $field_name = $element['#field_name'];
+    $delta = $element['#delta'];
+    $entity = $element['#entity'];
+    $matches = array();
+
+    // Get the record and table mapping info.
+    $chado_table = $entity->chado_table;
+    $chado_column = $entity->chado_column;
 
 
-  $matches = array();
-  preg_match('/(.*?)__(\d+)/', $field_name, $matches);
-  $table_name = $matches[1];
-  $cvterm_id = $matches[2];
+    // Get the table name and cvterm_id for this field.
+    preg_match('/(.*?)__(\d+)/', $field_name, $matches);
+    $table_name = $matches[1];
+    $cvterm_id = $matches[2];
 
 
-  // Get the FK that links to the base record.
-  $schema = chado_get_schema($field_table);
-  $pkey = $schema['primary key'][0];
-  $fkey_lcolumn = key($schema['foreign keys'][$base_table]['columns']);
-  $fkey_rcolumn = $schema['foreign keys'][$base_table]['columns'][$fkey_lcolumn];
+    // 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);
+    $pkey = $schema['primary key'][0];
+    $lfkey_field = key($schema['foreign keys'][$chado_table]['columns']);
 
 
-  // Set some defaults for the empty record.
-  $entity->{$field_name}['und'][0] = array(
-    'value' => '',
-    $field_table . '__' . $pkey => '',
-    $field_table . '__' . $fkey_lcolumn => '',
-    $field_table . '__value' => '',
-    $field_table . '__type_id' => '',
-    $field_table . '__rank' => '',
-  );
+    // If we don't have a property value then we need to set all other fields
+    // to be empty so that when the module tries to save the field on the
+    // entity it won't try to save a partial record.
+    $pkey_val = tripal_chado_get_field_form_values($field_name, $form_state, $delta);
+    $prop_value = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $table_name . "__value");
+    $fk_val = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $table_name . '__' . $lfkey_field);
+    $type_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $table_name . '__type_id');
 
 
-  // Get the properties associated with this base record for this fields
-  // given type.
-  $columns = array('*');
-  $match = array(
-    $fkey_lcolumn => $record->$fkey_rcolumn,
-    'type_id' => $cvterm_id,
-  );
-  $options = array(
-    'return_array' => TRUE,
-    'order_by' => array('rank' => 'ASC')
-  );
-  $properties = chado_select_record($field_table, $columns, $match, $options);
-  for ($i = 0; $i < count($properties); $i++) {
-    $property = $properties[$i];
-    foreach ($schema['fields'] as $fname => $details) {
-      $entity->{$field_name}['und'][$i] = array(
-        'value' => array(),
-        $field_table . '__' . $pkey => $property->$pkey,
-        $field_table . '__' . $fkey_lcolumn => $property->$fkey_lcolumn,
-        $field_table . '__value' => $property->value,
-        $field_table . '__type_id' => $property->type_id,
-        $field_table . '__rank' => $property->rank,
+    if (!$prop_value) {
+      tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__' . $lfkey_field);
+      tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__value');
+      tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__type_id');
+      tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__rank');
+    }
+    else {
+      $rank = tripal_chado_get_field_form_values($field_name, $form_state, $delta, '_weight');
+      tripal_chado_set_field_form_values($field_name, $form_state, $rank, $delta, $table_name . '__rank');
+    }
+    // Remove the properties for this record. We will re-add it. Otherwise,
+    // if we change ranks, we wind up with multiple records in the property table.
+    if ($pkey_val) {
+      $match = array(
+        $pkey => $pkey_val
       );
       );
+      chado_delete_record($table_name, $match);
+    }
+  }
+  /**
+   * @see TripalField::load()
+   */
+  function load($field, $entity, $details) {
+
+    $field_name = $details['field_name'];
+    $field_type = $details['type'];
+    $field_table = $details['settings']['chado_table'];
+    $field_column = $details['settings']['chado_column'];
+
+    $matches = array();
+    preg_match('/(.*?)__(\d+)/', $field_name, $matches);
+    $table_name = $matches[1];
+    $cvterm_id = $matches[2];
+
+    // Get the FK that links to the base record.
+    $schema = chado_get_schema($field_table);
+    $pkey = $schema['primary key'][0];
+    $fkey_lcolumn = key($schema['foreign keys'][$base_table]['columns']);
+    $fkey_rcolumn = $schema['foreign keys'][$base_table]['columns'][$fkey_lcolumn];
+
+    // Set some defaults for the empty record.
+    $entity->{$field_name}['und'][0] = array(
+      'value' => '',
+      $field_table . '__' . $pkey => '',
+      $field_table . '__' . $fkey_lcolumn => '',
+      $field_table . '__value' => '',
+      $field_table . '__type_id' => '',
+      $field_table . '__rank' => '',
+    );
+
+    // Get the properties associated with this base record for this fields
+    // given type.
+    $columns = array('*');
+    $match = array(
+      $fkey_lcolumn => $record->$fkey_rcolumn,
+      'type_id' => $cvterm_id,
+    );
+    $options = array(
+      'return_array' => TRUE,
+      'order_by' => array('rank' => 'ASC')
+    );
+    $properties = chado_select_record($field_table, $columns, $match, $options);
+    for ($i = 0; $i < count($properties); $i++) {
+      $property = $properties[$i];
+      foreach ($schema['fields'] as $fname => $details) {
+        $entity->{$field_name}['und'][$i] = array(
+          'value' => array(),
+          $field_table . '__' . $pkey => $property->$pkey,
+          $field_table . '__' . $fkey_lcolumn => $property->$fkey_lcolumn,
+          $field_table . '__value' => $property->value,
+          $field_table . '__type_id' => $property->type_id,
+          $field_table . '__rank' => $property->rank,
+        );
+      }
     }
     }
   }
   }
 }
 }
+/**
+ *
+ * @param unknown $form
+ * @param unknown $form_state
+ */
+function chado_linker__prop_widget_form_ajax_callback($form, $form_state) {
+  $field_name = $form_state['triggering_element']['#parents'][0];
+  return $form[$field_name];
+}

+ 122 - 44
tripal_chado/includes/fields/chado_linker__prop_adder.inc

@@ -21,41 +21,86 @@ class chado_linker__prop_adder extends TripalField {
     );
     );
   }
   }
   /**
   /**
-   * @see TripalField::attach_info()
- */
-  function attach_info($entity_type, $bundle, $target) {
-    $field_info = array();
-
-    $table_name = $target['data_table'];
-    $type_table = $target['type_table'];
-    $type_field = $target['field'];
-    $cv_id      = $target['cv_id'];
-    $cvterm_id  = $target['cvterm_id'];
+   * @see TripalField::can_attach()
+   */
+  protected function can_attach($entity_type, $bundle, $details) {
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
     // If the linker table does not exists then we don't want to add attach.
     // If the linker table does not exists then we don't want to add attach.
     $prop_table = $table_name . 'prop';
     $prop_table = $table_name . 'prop';
-    if (!chado_table_exists($prop_table)) {
-      return $field_info;
+    if (chado_table_exists($prop_table)) {
+      return TRUE;
+    }
+    return FALSE;
+  }
+  /**
+   * @see TripalField::create_info()
+   */
+  function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
     }
     }
 
 
-    // Initialize the field array.
-    $field_info = array(
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
+
+    $prop_table = $table_name . 'prop';
+    return array(
       'field_name' => $prop_table,
       'field_name' => $prop_table,
-      'field_type' => 'chado_linker__prop_adder',
-      'widget_type' => 'chado_linker__prop_adder_widget',
-      'field_settings' => array(
-        'base_table' => $table_name,
-      ),
+      'type' => 'chado_linker__prop_adder',
       'cardinality' => 1,
       'cardinality' => 1,
-      'storage' => 'field_chado_storage',
-      'widget_settings' => array('display_label' => 1),
-      'description' => '',
-      'label' => 'Additional Properties',
-      'is_required' => 0,
-      // This feld is never visible so there are no field settings for
-      // Chado nor the semantic web.
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+      'settings' => array(
+      ),
+    );
+  }
+  /**
+   * @see TripalField::create_instance_info()
+   */
+  function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
+
+    $prop_table = $table_name . 'prop';
+    return array(
+      'field_name' => $prop_table,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Add Properties',
+      'description' => 'Add additional property types to this record.',
+      'required' => FALSE,
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'chado_linker__prop_adder_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'deafult' => array(
+          'label' => 'above',
+          'type' => 'chado_linker__prop_adder_formatter',
+          'settings' => array(),
+        ),
+      ),
     );
     );
-    return $field_info;
   }
   }
   /**
   /**
    * @see TripalField::widget_info()
    * @see TripalField::widget_info()
@@ -146,23 +191,56 @@ function chado_linker__prop_adder_widget_validate($element, &$form_state) {
           $schema = chado_get_schema($field_name);
           $schema = chado_get_schema($field_name);
           $pkey = $schema['primary key'][0];
           $pkey = $schema['primary key'][0];
 
 
-          $field_info = array(
-            'field_type' => 'kvproperty',
-            'widget_type' => 'tripal_chado_kvproperty_widget',
-            'field_settings' => array(
-              'chado_table' => $field_name,
-              'chado_column' => $pkey,
-              'base_table' => $base_table,
-            ),
-            'storage' => 'field_chado_storage',
-            'widget_settings' => array(),
-            'description' => $term[0]->definition ? $term[0]->definition : '',
-            'label' => ucfirst(preg_replace('/_/', ' ', $term[0]->name)),
-            'is_required' => FALSE,
-            // All properties are unlimited.
-            'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-          );
-          tripal_add_bundle_field($prop_field_name, $field_info, $entity_type, $bundle);
+          // Add the field if it doesn't already exists.
+          $field = field_info_field('cvterm');
+          if (!$field) {
+            $create_info = array(
+              'field_name' => 'property-' . $term[0]->cvterm_id,
+              'type' => 'tripal_chado_kvproperty_widget',
+              '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,
+                'semantic_web' => '',
+              ),
+            );
+            $field = field_create_field($create_info);
+          }
+
+          // Attach the field to the bundle if it isn't already.
+          if (!$field and array_key_exists('bundles', $field) or
+              !array_key_exists('TripalEntity', $field['bundles']) or
+              !in_array($bundle_name, $field['bundles']['TripalEntity'])) {
+
+            $create_instance_info = array(
+              'field_name' => 'property-' . $term[0]->cvterm_id,
+              'entity_type' => 'TripalEntity',
+              'bundle' => $bundle->name,
+              'label' => ucfirst(preg_replace('/_/', ' ', $term[0]->name)),
+              'description' => $term[0]->definition ? $term[0]->definition : '',
+              'required' => FALSE,
+              'settings' => array(),
+              'widget' => array(
+                'type' => 'tripal_chado_kvproperty_widget',
+                'settings' => array(
+                  'display_label' => 1,
+                ),
+              ),
+              'display' => array(
+                'deafult' => array(
+                  'label' => 'above',
+                  'type' => 'tripal_chado_kvproperty_formatter',
+                  'settings' => array(),
+                ),
+              ),
+            );
+            $instance = field_create_instance($create_instance_info);
+          }
         }
         }
         else if (count($term) > 1) {
         else if (count($term) > 1) {
           form_set_error(implode('][', $element ['#parents']) . '][value', t("This term is present in multiple vocabularies. Please select the appropriate one."));
           form_set_error(implode('][', $element ['#parents']) . '][value', t("This term is present in multiple vocabularies. Please select the appropriate one."));

+ 71 - 23
tripal_chado/includes/fields/chado_linker__pub.inc

@@ -20,45 +20,93 @@ class chado_linker_pub extends TripalField {
     );
     );
   }
   }
   /**
   /**
-   * @see TripalField::attach_info()
+   * @see TripalField::can_attach()
    */
    */
-  function attach_info($entity_type, $bundle, $target) {
-    $field_info = array();
-
-    $table_name = $target['data_table'];
-    $type_table = $target['type_table'];
-    $type_field = $target['field'];
-    $cv_id      = $target['cv_id'];
-    $cvterm_id  = $target['cvterm_id'];
+  protected function can_attach($entity_type, $bundle, $details) {
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
     // If the linker table does not exists then we don't want to add attach.
     // If the linker table does not exists then we don't want to add attach.
     $pub_table = $table_name . '_pub';
     $pub_table = $table_name . '_pub';
-    if (!chado_table_exists($pub_table)) {
-      return $field_info;
+    if (chado_table_exists($pub_table)) {
+      return TRUE;
     }
     }
+    return FALSE;
+  }
+  /**
+   * @see TripalField::create_info()
+   */
+  function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
+    $pub_table = $table_name . '_pub';
     $schema = chado_get_schema($pub_table);
     $schema = chado_get_schema($pub_table);
     $pkey = $schema['primary key'][0];
     $pkey = $schema['primary key'][0];
-
-    // Initialize the field array.
-    $field_info = array(
+    return array(
       'field_name' => $table_name . '__pub',
       'field_name' => $table_name . '__pub',
-      'field_type' => 'chado_linker__pub',
-      'widget_type' => 'chado_linker__pub_widget',
-      'widget_settings' => array('display_label' => 1),
-      'description' => '',
-      'label' => 'Publications',
-      'is_required' => 0,
+      'type' => 'chado_linker__pub',
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'storage' => 'field_chado_storage',
-      'field_settings' => array(
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+      'settings' => array(
         'chado_table' => $pub_table,
         'chado_table' => $pub_table,
         'chado_column' => $pkey,
         'chado_column' => $pkey,
         'base_table' => $table_name,
         'base_table' => $table_name,
         'semantic_web' => 'schema:publication',
         'semantic_web' => 'schema:publication',
       ),
       ),
     );
     );
-    return $field_info;
+  }
+  /**
+   * @see TripalField::create_instance_info()
+   */
+  function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
+
+    return array(
+      'field_name' => $table_name . '__pub',
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Publications',
+      'description' => 'This record has been referenced or is sourced from
+        these publications.',
+      'required' => FALSE,
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'chado_linker__pub_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'deafult' => array(
+          'label' => 'above',
+          'type' => 'chado_linker__pub_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+
   }
   }
   /**
   /**
    * @see TripalField::widget_info()
    * @see TripalField::widget_info()

+ 77 - 27
tripal_chado/includes/fields/chado_linker__relationship.inc

@@ -18,50 +18,93 @@ class chado_linker__relationship extends TripalField {
       ),
       ),
     );
     );
   }
   }
-
   /**
   /**
-   * @see TripalField::attach_info()
+   * @see TripalField::can_attach()
    */
    */
-  function attach_info($entity_type, $bundle, $target) {
-    $field_info = array();
-
-    $table_name = $target['data_table'];
-    $type_table = $target['type_table'];
-    $type_field = $target['field'];
-    $cv_id      = $target['cv_id'];
-    $cvterm_id  = $target['cvterm_id'];
+  protected function can_attach($entity_type, $bundle, $details) {
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
     // If the linker table does not exists then we don't want to add attach.
     // If the linker table does not exists then we don't want to add attach.
     $rel_table = $table_name . '_relationship';
     $rel_table = $table_name . '_relationship';
-    if (!chado_table_exists($rel_table)) {
-      return $field_info;
+    if (chado_table_exists($rel_table)) {
+      return TRUE;
     }
     }
+    return FALSE;
+  }
+  /**
+   * @see TripalField::create_info()
+   */
+  function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
+    $rel_table = $table_name . '_relationship';
     $schema = chado_get_schema($rel_table);
     $schema = chado_get_schema($rel_table);
     $pkey = $schema['primary key'][0];
     $pkey = $schema['primary key'][0];
-
-    // Initialize the field array.
-    $field_info = array(
+    return array(
       'field_name' => $table_name . '_relationship',
       'field_name' => $table_name . '_relationship',
-      'field_type' => 'chado_linker__relationship',
-      'widget_type' => 'chado_linker__relationship_widget',
-      'widget_settings' => array('display_label' => 1),
-      'description' => 'A generic field for displaying relationships between data types',
-      'label' => 'Relationships',
-      'is_required' => 0,
+      'type' => 'chado_linker__relationship',
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'storage' => 'field_chado_storage',
-      'field_settings' => array(
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+      'settings' => array(
         'chado_table' => $rel_table,
         'chado_table' => $rel_table,
         'chado_column' => $pkey,
         'chado_column' => $pkey,
         'base_table' => $table_name,
         'base_table' => $table_name,
         'semantic_web' => 'SBO:0000374',
         'semantic_web' => 'SBO:0000374',
       ),
       ),
     );
     );
+  }
+  /**
+   * @see TripalField::create_instance_info()
+   */
+  function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
 
 
-    return $field_info;
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
+    return array(
+      'field_name' => $table_name . '_relationship',
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Relationships',
+      'description' => 'Other records with relationships to this record.',
+      'required' => FALSE,
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'chado_linker__relationship_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'deafult' => array(
+          'label' => 'above',
+          'type' => 'chado_linker__relationship_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
   }
   }
+
   /**
   /**
    * @see TripalField::widget_info()
    * @see TripalField::widget_info()
    */
    */
@@ -200,8 +243,12 @@ class chado_linker__relationship extends TripalField {
       $type_id = $items[$delta][$field_table . '__type_id'];
       $type_id = $items[$delta][$field_table . '__type_id'];
       $object_id = $items[$delta][$field_table . '__object_id'];
       $object_id = $items[$delta][$field_table . '__object_id'];
 
 
-      $value = $items[$delta][$field_table . '__value'];
-      $rank = $items[$delta][$field_table . '__rank'];
+      if (array_key_exists('value', $schema['fields'])) {
+        $value = $items[$delta][$field_table . '__value'];
+      }
+      if (array_key_exists('rank', $schema['fields'])) {
+        $rank = $items[$delta][$field_table . '__rank'];
+      }
 
 
       $object_uniquename = $items[$delta]['object_name'];
       $object_uniquename = $items[$delta]['object_name'];
       $subject_uniquename = $items[$delta]['subject_name'];
       $subject_uniquename = $items[$delta]['subject_name'];
@@ -273,10 +320,13 @@ class chado_linker__relationship extends TripalField {
       '#autocomplete_path' => "admin/tripal/storage/chado/auto_name/$base_table",
       '#autocomplete_path' => "admin/tripal/storage/chado/auto_name/$base_table",
     );
     );
     $default_cv = tripal_get_default_cv($field_table, 'type_id');
     $default_cv = tripal_get_default_cv($field_table, 'type_id');
+    $options = array();
     if (!$default_cv) {
     if (!$default_cv) {
       drupal_set_message("There is no default vocabulary set for the relationships....");
       drupal_set_message("There is no default vocabulary set for the relationships....");
     }
     }
-    $options = tripal_get_cvterm_select_options($default_cv->cv_id, TRUE);
+    else {
+      $options = tripal_get_cvterm_select_options($default_cv->cv_id, TRUE);
+    }
     $widget['type_name'] = array(
     $widget['type_name'] = array(
       '#type' => 'select',
       '#type' => 'select',
       '#title' => t('Type'),
       '#title' => t('Type'),

+ 69 - 22
tripal_chado/includes/fields/chado_linker__synonym.inc

@@ -20,45 +20,92 @@ class chado_linker__synonym extends TripalField {
     );
     );
   }
   }
   /**
   /**
-   * @see TripalField::attach_info()
+   * @see TripalField::can_attach()
    */
    */
-  function attach_info($entity_type, $bundle, $target) {
-    $field_info = array();
-
-    $table_name = $target['data_table'];
-    $type_table = $target['type_table'];
-    $type_field = $target['field'];
-    $cv_id      = $target['cv_id'];
-    $cvterm_id  = $target['cvterm_id'];
+  protected function can_attach($entity_type, $bundle, $details) {
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
     // If the linker table does not exists then we don't want to add attach.
     // If the linker table does not exists then we don't want to add attach.
     $syn_table = $table_name . '_synonym';
     $syn_table = $table_name . '_synonym';
-    if (!chado_table_exists($syn_table)) {
-      return $field_info;
+    if (chado_table_exists($syn_table)) {
+      return TRUE;
     }
     }
+    return FALSE;
+  }
+  /**
+   * @see TripalField::create_info()
+   */
+  function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
+    $syn_table = $table_name . '_synonym';
     $schema = chado_get_schema($syn_table);
     $schema = chado_get_schema($syn_table);
     $pkey = $schema['primary key'][0];
     $pkey = $schema['primary key'][0];
 
 
-    // Initialize the field array.
-    $field_info = array(
+    return array(
       'field_name' => $table_name . '_synonym',
       'field_name' => $table_name . '_synonym',
-      'field_type' => 'chado_linker__synonym',
-      'widget_type' => 'chado_linker__synonym_widget',
-      'widget_settings' => array('display_label' => 1),
-      'description' => '',
-      'label' => 'Synonyms',
-      'is_required' => 0,
+      'type' => 'chado_linker__synonym',
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
-      'storage' => 'field_chado_storage',
-      'field_settings' => array(
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+      'settings' => array(
         'chado_table' => $syn_table,
         'chado_table' => $syn_table,
         'chado_column' => $pkey,
         'chado_column' => $pkey,
         'base_table' => $table_name,
         'base_table' => $table_name,
         'semantic_web' => 'schema:alternateName',
         'semantic_web' => 'schema:alternateName',
       ),
       ),
     );
     );
-    return $field_info;
+  }
+  /**
+   * @see TripalField::create_instance_info()
+   */
+  function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
+
+    return array(
+      'field_name' => $table_name . '_synonym',
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Synonyms',
+      'description' => 'Alternate names, aliases or synonyms for this record.',
+      'required' => FALSE,
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'chado_linker__synonym_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'deafult' => array(
+          'label' => 'above',
+          'type' => 'chado_linker__synonym_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
   }
   }
   /**
   /**
    * @see TripalField::widget_info()
    * @see TripalField::widget_info()

+ 74 - 27
tripal_chado/includes/fields/chado_organism__type_id.inc

@@ -21,41 +21,88 @@ class chado_organism__type_id extends TripalField {
     );
     );
   }
   }
   /**
   /**
-   * @see TripalField::attach_info()
+   * @see TripalField::can_attach()
    */
    */
-  public function attach_info($entity_type, $bundle, $settings) {
-
-    $field_info = array();
-
-    $table_name = $settings['data_table'];
-    $type_table = $settings['type_table'];
-    $type_field = $settings['field'];
-    $cv_id      = $settings['cv_id'];
-    $cvterm_id  = $settings['cvterm_id'];
+  function can_attach($entity_type, $bundle, $details){
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
 
 
     $schema = chado_get_schema($table_name);
     $schema = chado_get_schema($table_name);
 
 
     // If this is the organism table and Chado v1.3 then attach.
     // If this is the organism table and Chado v1.3 then attach.
     if ($table_name == 'organism' and array_key_exists('type_id', $schema['fields'])) {
     if ($table_name == 'organism' and array_key_exists('type_id', $schema['fields'])) {
-      $field_info = array(
-        'field_name' => 'organism__type_id',
-        'field_type' => 'chado_organism__type_id',
-        'widget_type' => 'chado_organism__type_id_widget',
-        'description' => 'Select an Infraspecific Type.',
-        'label' => 'Infrapsecific Type',
-        'is_required' => 0,
-        'storage' => 'field_chado_storage',
-        'widget_settings' => array(
-          'display_label' => 1
+      return TRUE;
+    }
+    return FALSE;
+  }
+  /**
+   * @see TripalField::create_info()
+   */
+  function create_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
+
+    return array(
+      'field_name' => 'organism__type_id',
+      'type' => 'chado_organism__type_id',
+      'cardinality' => 1,
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+      'settings' => array(
+        'chado_table' => 'organism',
+        'chado_column' => 'type_id',
+        'semantic_web' => 'local:infraspecific_type',
+      ),
+    );
+  }
+  /**
+   * @see TripalField::create_instance_info()
+   */
+  function create_instance_info($entity_type, $bundle, $details) {
+    if (!$this->can_attach($entity_type, $bundle, $details)) {
+      return;
+    }
+
+    $table_name = $details['chado_table'];
+    $type_table = $details['chado_type_table'];
+    $type_field = $details['chado_type_column'];
+    $cv_id      = $details['chado_cv_id'];
+    $cvterm_id  = $details['chado_cvterm_id'];
+
+    return array(
+      'field_name' => 'organism__type_id',
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Infrapsecific Type',
+      'description' => 'The Infrapsecific Type.',
+      'required' => FALSE,
+      'settings' => array(),
+      'widget' => array(
+        'type' => 'chado_organism__type_id_widget',
+        'settings' => array(
+          'display_label' => 1,
         ),
         ),
-        'field_settings' => array(
-          'chado_table' => 'organism',
-          'chado_column' => 'type_id',
-          'semantic_web' => 'local:infraspecific_type',
+      ),
+      'display' => array(
+        'deafult' => array(
+          'label' => 'above',
+          'type' => 'chado_organism__type_id_formatter',
+          'settings' => array(),
         ),
         ),
-      );
-    }
-    return $field_info;
+      ),
+    );
   }
   }
 
 
   /**
   /**

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

@@ -313,10 +313,6 @@ function tripal_chado_field_storage_load($entity_type, $entities, $age,
             $field_obj->load($field, $entity, array('record' => $record));
             $field_obj->load($field, $entity, array('record' => $record));
           }
           }
         }
         }
-
-        if (function_exists($load_function)) {
-          $load_function($field, $entity, $base_table, $record);
-        }
       }
       }
 
 
     } // end: foreach ($fields as $field_id => $ids) {
     } // end: foreach ($fields as $field_id => $ids) {

+ 534 - 518
tripal_chado/includes/tripal_chado.fields.inc

@@ -25,20 +25,539 @@ function tripal_chado_field_info() {
   foreach ($field_files as $file) {
   foreach ($field_files as $file) {
     $field_type = $file->name;
     $field_type = $file->name;
     module_load_include('inc', 'tripal_chado', 'includes/fields/' . $field_type);
     module_load_include('inc', 'tripal_chado', 'includes/fields/' . $field_type);
-
     if (preg_match('/^chado/', $field_type) and class_exists($field_type)) {
     if (preg_match('/^chado/', $field_type) and class_exists($field_type)) {
       $field_obj = new $field_type();
       $field_obj = new $field_type();
       $info[$field_type] = $field_obj->field_info();
       $info[$field_type] = $field_obj->field_info();
     }
     }
+  }
+  return $info;
+
+}
+
+/**
+ * Implements hook_field_create_info().
+ *
+ * This is a Tripal defined hook that supports integration with the
+ * TripalEntity field.
+ */
+function tripal_chado_field_create_info($entity_type, $bundle, $term) {
+
+  $bundle_name = $bundle->name;
+
+  // The details array is used to pass to the TripalEntity->create_info()
+  // function to provide more details about how the bundle is used by this
+  // module.
+  $details = array();
 
 
-    $function = $field_type . '_info';
-    if (function_exists($function)) {
-      $info[$field_type] = $function();
+  // This array will hold details that map the bundle to tables in Chado.
+  $bundle_data = array();
+
+  // Get the cvterm that corresponds to this TripalTerm object.
+  $vocab = entity_load('TripalVocab', array($term->vocab_id));
+  $vocab = reset($vocab);
+  $match = array(
+    'dbxref_id' => array(
+      'db_id' => array(
+        'name' => $vocab->vocabulary,
+      ),
+      'accession' => $term->accession
+    ),
+  );
+  $cvterm = chado_generate_var('cvterm', $match);
+
+  // The organism table does not have a type_id so we won't ever find
+  // a record for it in the tripal_cv_defaults table.
+  if ($cvterm->name == 'organism') {
+    $details = array(
+      'chado_cv_id' => $cvterm->cv_id->cv_id,
+      'chado_cvterm_id' => $cvterm->cvterm_id,
+      'chado_table' => 'organism',
+      'chado_type_table' => 'organism',
+      'chado_type_column' =>  '',
+    );
+  }
+  // The analysis table does not have a type_id so we won't ever find
+  // a record for it in the tripalcv_defaults table.
+  else if ($cvterm->name == 'analysis') {
+    $details = array(
+      'chado_cv_id' => $cvterm->cv_id->cv_id,
+      'chado_cvterm_id' => $cvterm->cvterm_id,
+      'chado_table' => 'analysis',
+      'chado_type_table' => 'analysis',
+      'chado_type_column' =>  '',
+    );
+  }
+  else if ($cvterm->name == 'project') {
+    $details = array(
+      'chado_cv_id' => $cvterm->cv_id->cv_id,
+      'chado_cvterm_id' => $cvterm->cvterm_id,
+      'chado_table' => 'project',
+      'chado_type_table' => 'project',
+      'chado_type_column' =>  '',
+    );
+  }
+  else {
+    // TODO: WHAT TO DO IF A VOCABULARY IS USED AS A DEFAULT FOR MULTIPLE
+    // TABLES.
+    // Look to see if this vocabulary is used as a default for any table.
+      $default = db_select('tripal_cv_defaults', 't')
+      ->fields('t')
+      ->condition('cv_id', $cvterm->cv_id->cv_id)
+      ->execute()
+      ->fetchObject();
+    if ($default) {
+      $details = array(
+        'chado_cv_id' => $cvterm->cv_id->cv_id,
+        'chado_cvterm_id' => $cvterm->cvterm_id,
+        'chado_table' => $default->table_name,
+        'chado_type_table' => $default->table_name,
+        'chado_type_column' =>  $default->field_name,
+      );
+    }
+  }
+
+  // Save the mapping information so that we can reuse it when we need to
+  // look things up for later (such as the hook_create_instance_info() function.
+  tripal_set_bundle_variable('chado_cv_id', $bundle->id, $details['chado_cv_id']);
+  tripal_set_bundle_variable('chado_cvterm_id', $bundle->id, $details['chado_cvterm_id']);
+  tripal_set_bundle_variable('chado_table', $bundle->id, $details['chado_table']);
+  tripal_set_bundle_variable('chado_type_table', $bundle->id, $details['chado_type_table']);
+  tripal_set_bundle_variable('chado_type_column', $bundle->id, $details['chado_type_column']);
+
+  $base_fields = tripal_chado_field_create_base('create_info', $entity_type, $bundle, $details);
+  $custom_fields = tripal_chado_field_create_info_custom($entity_type, $bundle, $details);
+  return array_merge($base_fields, $custom_fields);
+}
+
+/**
+ * A helper function for the tripal_chado_field_create_info() function.
+ *
+ * This function adds in the custom fields info by instantiating the class
+ * for the custom field, calling the create_info() function and
+ * returning the info array.
+ *
+ * @param $entity_type
+ *   The type of entity (e.g TripalEntity)
+ * @param $bundle
+ *   The bundle object.
+ * @param $details
+ *   An array containing the mapping of the bundle to the Chado table.
+ */
+function tripal_chado_field_create_info_custom($entity_type, $bundle, $details) {
+  $info = array();
+
+  // Find all of the files in the tripal_chado/includes/fields directory.
+  $fields_path = drupal_get_path('module', 'tripal_chado') . '/includes/fields';
+  $field_files = file_scan_directory($fields_path, '/^chado_.*\.inc$/');
+
+  // Iterate through the fields, include the file and run the info function.
+  foreach ($field_files as $file) {
+    $field_type = $file->name;
+    module_load_include('inc', 'tripal_chado', 'includes/fields/' . $field_type);
+    if (preg_match('/^chado/', $field_type) and class_exists($field_type)) {
+      $field_obj = new $field_type();
+      $result = $field_obj->create_info($entity_type, $bundle, $details);
+      if (is_array($result)) {
+        $info[$result['field_name']] = $result;
+      }
     }
     }
   }
   }
   return $info;
   return $info;
+}
+
+/**
+ * Retrieves either the create_info or create_instance_info arrays.
+ *
+ * The logic for creating the fields for the base table is so similar for
+ * both the create_info and create_instance_info arrays they are both
+ * handled by this function to prevent duplication of code.
+ *
+ * @param $step
+ *   Set to 'create_info' to retrun the create_info array or
+ *   'create_instance_info' to return the create_instance_info array.
+ * @param $entity_type
+ *   The type of entity (e.g TripalEntity)
+ * @param $bundle
+ *   The bundle object.
+ * @param $details
+ *   An array containing the mapping of the bundle to the Chado table.
+ *
+ * @return
+ *   An array compabile with the tripal_chado_field_create_info() and
+ *   tripal_chado_field_create_instance_info() functions.
+ */
+function tripal_chado_field_create_base($step, $entity_type, $bundle, $details) {
+  $table_name = $details['chado_table'];
+  $type_table = $details['chado_type_table'];
+  $type_field = $details['chado_type_column'];
+
+  // Iterate through the columns of the table and see if fields have been
+  // created for each one. If not, then create them.
+  $schema = chado_get_schema($table_name);
+  $columns = $schema['fields'];
+  $fields = array();
+  foreach ($columns as $column_name => $details) {
+    $field_name = $table_name . '__' . $column_name;
+
+    // Skip the primary key field.
+    if ($column_name == $schema['primary key'][0]) {
+      continue;
+    }
 
 
+    // Skip the type field.
+    if ($table_name == $type_table and $column_name == $type_field) {
+      continue;
+    }
+
+    // Get the field defaults for this column.
+    $field_info = array();
+    if ($step == 'create_info') {
+      $field_info = tripal_chado_field_create_info_base_defaults($field_name,
+        $table_name, $schema, $column_name);
+    }
+    if ($step == 'create_instance_info') {
+      $field_info = tripal_chado_field_create_instance_info_base_defaults($bundle->name,
+        $field_name, $table_name, $schema, $column_name);
+    }
+
+    // TODO: add in a call to drupal_alter to allow other modules to change
+    // the field settings.
+
+    // Add the field to the bundle.
+    $fields[$field_name] = $field_info;
+  }
+  return $fields;
 }
 }
+/**
+ * A helper function for the tripal_chado_field_create_info() function.
+ *
+ * This function generates the default chado_info array for a column in
+ * a base table of Chado.  All of fields returned by this function use
+ * default Drupal fields to manage the data in Chado columns.  For
+ * custom handling of columns there are custom TripalEntity extensions that
+ * are added by the tripal_chado_field_create_info_custom() function.  A
+ * custom field will superceed any default base field of the same name
+ * provided here.
+ *
+ * @param $field_name
+ *   The name for the new field.
+ * @param $table_name
+ *   The Chado table
+ * @param $schema
+ *   The Drupal schema array for the Chado table.
+ * @param $column_name
+ *   The name of the column in the Chado table.
+ * @return
+ *   An associative array compatible with the tripal_chado_field_create_info()
+ *   function.
+ */
+function tripal_chado_field_create_info_base_defaults($field_name, $table_name,
+    $schema, $column_name) {
+
+  $details = $schema['fields'][$column_name];
+
+  // Set some defaults for the field.
+  $field = array(
+    'field_name' => $field_name,
+    'type' => '',
+    'cardinality' => 1,
+    'locked' => FALSE,
+    'storage' => array(
+      'type' => 'field_chado_storage',
+    ),
+    'settings' => array(
+      'chado_table' => $table_name,
+      'chado_column' => $column_name,
+      'semantic_web' => '',
+    ),
+  );
+
+  // Alter the field info array depending on the column details.
+  switch($details['type']) {
+    case 'char':
+      $field['type'] = 'text';
+      $field['settings']['max_length'] = $details['length'];
+      break;
+    case 'varchar':
+      $field['type'] = 'text';
+      $field['settings']['max_length'] = $details['length'];
+      break;
+    case 'text':
+      $field['type'] = 'text';
+      $field['settings']['max_length'] = 17179869184;
+      $field['settings']['text_processing'] = 1;
+      break;
+    case 'blob':
+      // not sure how to support a blob field.
+      continue;
+      break;
+    case 'int':
+      $field['type'] = 'number_integer';
+      break;
+    case 'float':
+      $field['type'] = 'number_float';
+      $field['settings']['precision'] = 10;
+      $field['settings']['scale'] = 2;
+      $field['settings']['decimal_separator'] = '.';
+      break;
+    case 'numeric':
+      $field['type'] = 'number_decimal';
+      break;
+    case 'serial':
+      // Serial fields are most likely not needed as a field.
+      break;
+    case 'boolean':
+      $field['type'] = 'list_boolean';
+      $field['settings']['allowed_values'] = array(0 => "No", 1 => "Yes");
+      break;
+    case 'datetime':
+      // Use the Drupal Date and Date API to create the field/widget
+      $field['type'] = 'datetime';
+      break;
+  }
+
+  // Set some default semantic web information
+  if ($column_name == 'uniquename') {
+    $field['settings']['text_processing'] = 0;
+  }
+  //
+  // PUB TABLE
+  //
+  elseif ($table_name == 'pub' and $column_name == 'uniquename') {
+    $field['type'] = 'text';
+    $field['settings']['text_processing'] = 0;
+  }
+
+  //
+  // ANALYSIS TABLE
+  //
+  elseif ($table_name == 'analysis' and $column_name == 'sourceuri') {
+    $field['type'] = 'text';
+    $field['settings']['text_processing'] = 0;
+  }
+
+  return $field;
+}
+
+/**
+ * Implements hook_field_create_instance_info().
+ *
+ * This is a Tripal defined hook that supports integration with the
+ * TripalEntity field.
+ */
+function tripal_chado_field_create_instance_info($entity_type, $bundle, $term) {
+
+  // Get the details about the mapping of this bundle to the Chado table:
+  $details = array(
+    'chado_cv_id' => tripal_get_bundle_variable('chado_cv_id', $bundle->id),
+    'chado_cvterm_id' => tripal_get_bundle_variable('chado_cvterm_id', $bundle->id),
+    'chado_table' => tripal_get_bundle_variable('chado_table', $bundle->id),
+    'chado_type_table' => tripal_get_bundle_variable('chado_type_table', $bundle->id),
+    'chado_type_column' => tripal_get_bundle_variable('chado_type_column', $bundle->id),
+  );
+
+  $base_fields = tripal_chado_field_create_base('create_instance_info', $entity_type, $bundle, $details);
+  $custom_fields = tripal_chado_field_create_instance_info_custom($entity_type, $bundle, $details);
+  return array_merge($base_fields, $custom_fields);
+
+}
+/**
+ * A helper function for the tripal_chado_field_create_instance_info() function.
+ *
+ * This function generates the default chado_instance_info array for a column in
+ * a base table of Chado.  All of fields returned by this function use
+ * default Drupal fields to manage the data in Chado columns.  For
+ * custom handling of columns there are custom TripalEntity extensions that
+ * are added by the tripal_chado_field_create_info_custom() function.  A
+ * custom field will superceed any default base field of the same name
+ * provided here.
+ *
+ * @param $bundle_name
+ *   The name of the bundle to which this field will be attached.
+ * @param $field_name
+ *   The name for the new field.
+ * @param $table_name
+ *   The Chado table
+ * @param $schema
+ *   The Drupal schema array for the Chado table.
+ * @param $column_name
+ *   The name of the column in the Chado table.
+ * @return
+ *   An associative array compatible with the tripal_chado_field_create_info()
+ *   function.
+ */
+function tripal_chado_field_create_instance_info_base_defaults($bundle_name,
+    $field_name, $table_name, $schema, $column_name) {
+
+  $details = $schema['fields'][$column_name];
+
+  $field =  array(
+      'field_name' => $field_name,
+      'entity_type' => 'TripalEntity',
+      'bundle' => $bundle_name,
+      'label' => ucwords(preg_replace('/_/', ' ', $column_name)),
+      'description' => '',
+      'required' => FALSE,
+      'settings' => array(),
+      'widget' => array(
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'above',
+          'settings' => array(),
+        ),
+      ),
+    );
+
+  // Determine if the field is required.
+  if (array_key_exists('not null', $details) and $details['not null'] === TRUE) {
+    $field_info['required'] = TRUE;
+  }
+
+  // Alter the field info array depending on the column details.
+  switch($details['type']) {
+    case 'char':
+      $field['widget']['type'] = 'text_textfield';
+      break;
+    case 'varchar':
+      $field['widget']['type'] = 'text_textfield';
+      break;
+    case 'text':
+      $field['widget']['type'] = 'text_textarea';
+      $field['widget']['settings']['format'] = filter_default_format();
+      break;
+    case 'blob':
+      // not sure how to support a blob field.
+      continue;
+      break;
+    case 'int':
+      $field['widget']['type'] = 'number';
+      break;
+    case 'float':
+      $field['widget']['type'] = 'number';
+      break;
+    case 'numeric':
+      $field['widget']['type'] = 'number';
+      break;
+    case 'serial':
+      // Serial fields are most likely not needed as a field.
+      break;
+    case 'boolean':
+      $field['widget']['type'] = 'options_onoff';
+      break;
+    case 'datetime':
+      $field['widget']['type'] = 'date_select';
+      $field['widget']['settings']['increment'] = 1;
+      $field['widget']['settings']['tz_handling'] = 'none';
+      $field['widget']['settings']['collapsible'] = TRUE;
+
+      // TODO: Add settings so that the minutes increment by 1.
+      // And turn off the timezone, as the Chado field doesn't support it.
+      break;
+  }
+
+  // Set some default semantic web information
+  if ($column_name == 'uniquename') {
+    $field['widget_type'] = 'text_textfield';
+  }
+  elseif ($field['label'] == 'Timeaccessioned') {
+    $field['label'] = 'Time Accessioned';
+    $field['description'] = 'Please enter the time that this record was first added to the database.';
+  }
+  elseif ($field['label'] == 'Timelastmodified') {
+    $field['label'] = 'Time Last Modified';
+    $field['description'] = 'Please enter the time that this record was last modified. The default is the current time.';
+  }
+  //
+  // ORGANISM TABLE
+  //
+  elseif ($table_name == 'organism' and $column_name == 'comment') {
+    $field['label'] = 'Description';
+  }
+  //
+  // PUB TABLE
+  //
+  elseif ($table_name == 'pub' and $column_name == 'uniquename') {
+    $field['widget_type'] = 'text_textfield';
+  }
+
+  //
+  // ANALYSIS TABLE
+  //
+  elseif ($table_name == 'analysis' and $column_name == 'program') {
+    $field['description'] = 'The program name (e.g. blastx, blastp, sim4, genscan. If the analysis was not derived from a software package then provide a very brief description of the pipeline, workflow or method.';
+    $field['label'] = 'Program, Pipeline, Workflow or Method Name.';
+  }
+  elseif ($table_name == 'analysis' and $column_name == 'sourceuri') {
+    $field['widget_type'] = 'text_textfield';
+    $field['label'] = 'Source URL';
+    $field['description'] = 'The URL where the original source data was derived.  Ideally, this should link to the page where more information about the source data can be found.';
+  }
+  elseif ($table_name == 'analysis' and $column_name == 'sourcename') {
+    $field['label'] = 'Source Name';
+    $field['description'] = 'The name of the source data. This could be a file name, data set or a small description for how the data was collected. For long descriptions use the larger description field.';
+  }
+  elseif ($table_name == 'analysis' and $column_name == 'sourceversion') {
+    $field['label'] = 'Source Version';
+    $field['description'] = 'If hte source data set has a version include it here.';
+  }
+  elseif ($table_name == 'analysis' and $column_name == 'algorithm') {
+    $field['label'] = 'Source Version';
+    $field['description'] = 'The name of the algorithm used to produce the dataset if different from the program.';
+  }
+  elseif ($table_name == 'analysis' and $column_name == 'programversion') {
+    $field['label'] = 'Program Version';
+    $field['description'] = 'The version of the program used to perform this analysis. (e.g. TBLASTX 2.0MP-WashU [09-Nov-2000]. Enter "n/a" if no version is available or applicable.';
+  }
+  //
+  // PROJECT TABLE
+  //
+  elseif ($table_name == 'project' and $column_name == 'description') {
+    $field['label'] = 'Short Description';
+  }
+
+  return $field;
+}
+
+/**
+ * A helper function for the tripal_chado_field_create_instance_info() function.
+ *
+ * This function adds in the custom fields info by instantiating the class
+ * for the custom field, calling the create_instance_info() function and
+ * returning the info array.
+ *
+ * @param $entity_type
+ *   The type of entity (e.g TripalEntity)
+ * @param $bundle
+ *   The bundle object.
+ * @param $details
+ *   An array containing the mapping of the bundle to the Chado table.
+ */
+function tripal_chado_field_create_instance_info_custom($entity_type, $bundle, $details) {
+  $info = array();
+
+  // Find all of the files in the tripal_chado/includes/fields directory.
+  $fields_path = drupal_get_path('module', 'tripal_chado') . '/includes/fields';
+  $field_files = file_scan_directory($fields_path, '/^chado_.*\.inc$/');
+
+  // Iterate through the fields, include the file and run the info function.
+  foreach ($field_files as $file) {
+    $field_type = $file->name;
+    module_load_include('inc', 'tripal_chado', 'includes/fields/' . $field_type);
+    if (preg_match('/^chado/', $field_type) and class_exists($field_type)) {
+      $field_obj = new $field_type();
+      $result = $field_obj->create_instance_info($entity_type, $bundle, $details);
+      if (is_array($result)) {
+        $info[$result['field_name']] = $result;
+      }
+    }
+  }
+  return $info;
+}
+
 /**
 /**
  * Implements hook_field_widget_info().
  * Implements hook_field_widget_info().
  *
  *
@@ -55,16 +574,10 @@ function tripal_chado_field_widget_info() {
     $field_type = $field['type'];
     $field_type = $field['type'];
     if ($field['storage']['type'] == 'field_chado_storage') {
     if ($field['storage']['type'] == 'field_chado_storage') {
       module_load_include('inc', 'tripal_chado', 'includes/fields/' . $field_type);
       module_load_include('inc', 'tripal_chado', 'includes/fields/' . $field_type);
-
       if (preg_match('/^chado/', $field_type) and class_exists($field_type)) {
       if (preg_match('/^chado/', $field_type) and class_exists($field_type)) {
         $field_obj = new $field_type();
         $field_obj = new $field_type();
         $widgets[$field_type . '_widget'] = $field_obj->widget_info();
         $widgets[$field_type . '_widget'] = $field_obj->widget_info();
       }
       }
-
-      $function = $field_type . '_widget_info';
-      if (function_exists($function)) {
-        $widgets[$field_type . '_widget'] = $function();
-      }
     }
     }
   }
   }
   return $widgets;
   return $widgets;
@@ -85,16 +598,10 @@ function tripal_chado_field_formatter_info() {
     $field_type = $field['type'];
     $field_type = $field['type'];
     if ($field['storage']['type'] == 'field_chado_storage') {
     if ($field['storage']['type'] == 'field_chado_storage') {
       module_load_include('inc', 'tripal_chado', 'includes/fields/' . $field_type);
       module_load_include('inc', 'tripal_chado', 'includes/fields/' . $field_type);
-
       if (preg_match('/^chado/', $field_type) and class_exists($field_type)) {
       if (preg_match('/^chado/', $field_type) and class_exists($field_type)) {
         $field_obj = new $field_type();
         $field_obj = new $field_type();
         $formatters[$field_type . '_formatter'] = $field_obj->formatter_info();
         $formatters[$field_type . '_formatter'] = $field_obj->formatter_info();
       }
       }
-
-      $function = $field_type . '_formatter_info';
-      if (function_exists($function)) {
-        $formatters[$field_type . '_formatter'] = $function();
-      }
     }
     }
   }
   }
   return $formatters;
   return $formatters;
@@ -112,12 +619,6 @@ function tripal_chado_field_settings_form($field, $instance, $has_data) {
     $field_obj = new $field_type();
     $field_obj = new $field_type();
     $form = $field_obj->settings_form($field, $instance, $has_data);
     $form = $field_obj->settings_form($field, $instance, $has_data);
   }
   }
-
-  $function = $field_type . '_settings_form';
-  if (function_exists($function)) {
-    $form = $function($field, $instance, $has_data);
-  }
-
   return $form;
   return $form;
 }
 }
 /**
 /**
@@ -133,12 +634,6 @@ function tripal_chado_field_formatter_settings_summary($field, $instance, $view_
     $field = new $field_type();
     $field = new $field_type();
     $summary = $field->formatter_settings_summary($field, $instance, $view_mode);
     $summary = $field->formatter_settings_summary($field, $instance, $view_mode);
   }
   }
-
-  $function = $field_type . '_formatter_settings_summary';
-  if (function_exists($function)) {
-    $summary = $function($field, $instance, $view_mode);
-  }
-
   return $summary;
   return $summary;
 }
 }
 
 
@@ -183,11 +678,6 @@ function tripal_chado_field_formatter_view($entity_type, $entity, $field,
     $field_obj->formatter_view($element, $entity_type, $entity, $field, $instance, $langcode, $items, $display);
     $field_obj->formatter_view($element, $entity_type, $entity, $field, $instance, $langcode, $items, $display);
   }
   }
 
 
-  $function = $display['type'];
-  if (function_exists($function)) {
-    $function($element, $entity_type, $entity, $field, $instance, $langcode, $items, $display);
-  }
-
   return $element;
   return $element;
 }
 }
 
 
@@ -199,98 +689,20 @@ function tripal_chado_field_widget_form(&$form, &$form_state, $field,
 
 
   $widget = $element;
   $widget = $element;
 
 
-  $field_name = $instance['field_name'];
-  $field_type = $field['type'];
-  form_load_include($form_state, 'inc', 'tripal_chado', 'includes/fields/' . $field_type);
-  module_load_include('inc', 'tripal_chado', 'includes/fields/' . $field_name);
-
-  if (preg_match('/^chado/', $field_type) and class_exists($field_type)) {
-    $field_obj = new $field_type();
-    $field_obj->widget_form($widget, $form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
-  }
-
-  $function = $field_type . '_widget';
-  if (function_exists($function)) {
-    $function($widget, $form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
-  }
-
-  return $widget;
-}
-
-/**
- * Returns the values of the field from the $form_state.
- */
-function tripal_chado_get_field_form_values($field_name, $form_state, $delta = 0, $child = NULL) {
-  $value = NULL;
-  // The form_state must have the 'values' key. If not then just return.
-  if (!array_key_exists('values', $form_state)) {
-    return $value;
-  }
-
-  // If the field name is not in the form_state['values'] then return.
-  if (!array_key_exists($field_name, $form_state['values'])) {
-    return $value;
-  }
-
-  // Iterate through the values looking for the field_name provided.
-  foreach ($form_state['values'][$field_name] as $langcode => $items) {
-    if (!array_key_exists($delta, $items)) {
-      continue;
-    }
-    $item = $items[$delta];
-    if ($child){
-      if(array_key_exists($child, $item) and $item[$child] != '') {
-        $value = $item[$child];
-      }
-    }
-    else {
-      $value = $item['value'];
-    }
-  }
-  return $value;
-}
-
-/**
- * Sets the values of the field from the $form_state.  If no child
- * argument is specified then the 'value' field is set.
- *
- * @param $field_name
- *   The name of the field to set.
- * @param $form_state
- *   The form's form_state array.
- * @param $newvalue
- *   The new value to set for the field.
- * @param $delta
- *   If cardinality of a field is greater than 1 the delta indicates
- *   which instance to set.
- * @param $child
- *   The name of the property to set iff other than 'value'.
- *
- * @return
- *   TRUE if the value was set, FALSE otherwise.
- */
-function tripal_chado_set_field_form_values($field_name, &$form_state, $newvalue, $delta = 0, $child = NULL) {
-  // The form_state must have the 'values' key. If not then just return.
-  if (!array_key_exists('values', $form_state)) {
-    return FALSE;
-  }
-
-  // If the field name is not in the form_state['values'] then reutrn.
-  if (!array_key_exists($field_name, $form_state['values'])) {
-    return FALSE;
-  }
+  $field_name = $instance['field_name'];
+  $field_type = $field['type'];
+  form_load_include($form_state, 'inc', 'tripal_chado', 'includes/fields/' . $field_type);
+  module_load_include('inc', 'tripal_chado', 'includes/fields/' . $field_name);
 
 
-  foreach ($form_state['values'][$field_name] as $langcode => $items) {
-    if ($child) {
-      $form_state['values'][$field_name][$langcode][$delta][$child] = $newvalue;
-    }
-    else {
-      $form_state['values'][$field_name][$langcode][$delta]['value'] = $newvalue;
-    }
+  if (preg_match('/^chado/', $field_type) and class_exists($field_type)) {
+    $field_obj = new $field_type();
+    $field_obj->widget_form($widget, $form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
   }
   }
-  return TRUE;
+
+  return $widget;
 }
 }
 
 
+
 /**
 /**
  * Implements hook_field_widget_form_alter().
  * Implements hook_field_widget_form_alter().
  */
  */
@@ -359,159 +771,7 @@ function tripal_chado_field_submit($entity_type, $entity, $field, $instance,
   }
   }
 }
 }
 
 
-/**
- * Returns a $field_info array for a field based on a database column.
- *
- */
-function tripal_chado_get_bundle_fields_base__fields_defaults($table_name, $schema, $column_name) {
-  $details = $schema['fields'][$column_name];
-
-  // Create an array with information about this field.
-  $field = array(
-    'field_type' => '',
-    'widget_type' => '',
-    'description' => '',
-    'label' => ucwords(preg_replace('/_/', ' ', $column_name)),
-    'is_required' => 0,
-    'storage' => 'field_chado_storage',
-    'widget_settings' => array(
-      'display_label' => 1
-    ),
-    'field_settings' => array(
-      // The table in Chado where this field maps to.
-      'chado_table' => $table_name,
-      // The column in the Chado table that this field maps to.
-      'chado_column' => $column_name,
-      'semantic_web' => '',
-    ),
-  );
-
-  // Alter the field info array depending on the column details.
-  switch($details['type']) {
-    case 'char':
-      $field['field_type'] = 'text';
-      $field['widget_type'] = 'text_textfield';
-      $field['field_settings']['max_length'] = $details['length'];
-      break;
-    case 'varchar':
-      $field['field_type'] = 'text';
-      $field['widget_type'] = 'text_textfield';
-      $field['field_settings']['max_length'] = $details['length'];
-      break;
-    case 'text':
-      $field['field_type'] = 'text';
-      $field['widget_type'] = 'text_textarea';
-      $field['field_settings']['max_length'] = 17179869184;
-      $field['field_settings']['text_processing'] = 1;
-      $field['format'] = filter_default_format();
-      break;
-    case 'blob':
-      // not sure how to support a blob field.
-      continue;
-      break;
-    case 'int':
-      $field['field_type'] = 'number_integer';
-      $field['widget_type'] = 'number';
-      break;
-    case 'float':
-      $field['field_type'] = 'number_float';
-      $field['widget_type'] = 'number';
-      $field['field_settings']['precision'] = 10;
-      $field['field_settings']['scale'] = 2;
-      $field['field_settings']['decimal_separator'] = '.';
-      break;
-    case 'numeric':
-      $field['field_type'] = 'number_decimal';
-      $field['widget_type'] = 'number';
-      break;
-    case 'serial':
-      // Serial fields are most likely not needed as a field.
-      break;
-    case 'boolean':
-      $field['field_type'] = 'list_boolean';
-      $field['widget_type'] = 'options_onoff';
-      $field['field_settings']['allowed_values'] = array(0 => "No", 1 => "Yes");
-      break;
-    case 'datetime':
-      // Use the Drupal Date and Date API to create the field/widget
-      $field['field_type'] = 'datetime';
-      $field['widget_type'] = 'date_select';
-      $field['widget_settings']['increment'] = 1;
-      $field['widget_settings']['tz_handling'] = 'none';
-      $field['widget_settings']['collapsible'] = TRUE;
-
-      // TODO: Add settings so that the minutes increment by 1.
-      // And turn off the timezone, as the Chado field doesn't support it.
-      break;
-  }
-
-  // Set some default semantic web information
-  if ($column_name == 'uniquename') {
-    $field['widget_type'] = 'text_textfield';
-    $field['field_settings']['text_processing'] = 0;
-  }
-  elseif ($field['label'] == 'Timeaccessioned') {
-    $field['label'] = 'Time Accessioned';
-    $field['description'] = 'Please enter the time that this record was first added to the database.';
-  }
-  elseif ($field['label'] == 'Timelastmodified') {
-    $field['label'] = 'Time Last Modified';
-    $field['description'] = 'Please enter the time that this record was last modified. The default is the current time.';
-  }
-  //
-  // ORGANISM TABLE
-  //
-  elseif ($field['field_settings']['chado_table'] == 'organism' and $field['field_settings']['chado_column'] == 'comment') {
-    $field['label'] = 'Description';
-  }
-  //
-  // PUB TABLE
-  //
-  elseif ($field['field_settings']['chado_table'] == 'pub' and $field['field_settings']['chado_column'] == 'uniquename') {
-    $field['field_type'] = 'text';
-    $field['widget_type'] = 'text_textfield';
-    $field['field_settings']['text_processing'] = 0;
-  }
-
-  //
-  // ANALYSIS TABLE
-  //
-  elseif ($field['field_settings']['chado_table'] == 'analysis' and $field['field_settings']['chado_column'] == 'program') {
-    $field['description'] = 'The program name (e.g. blastx, blastp, sim4, genscan. If the analysis was not derived from a software package then provide a very brief description of the pipeline, workflow or method.';
-    $field['label'] = 'Program, Pipeline, Workflow or Method Name.';
-  }
-  elseif ($field['field_settings']['chado_table'] == 'analysis' and $field['field_settings']['chado_column'] == 'sourceuri') {
-    $field['field_type'] = 'text';
-    $field['widget_type'] = 'text_textfield';
-    $field['field_settings']['text_processing'] = 0;
-    $field['label'] = 'Source URL';
-    $field['description'] = 'The URL where the original source data was derived.  Ideally, this should link to the page where more information about the source data can be found.';
-  }
-  elseif ($field['field_settings']['chado_table'] == 'analysis' and $field['field_settings']['chado_column'] == 'sourcename') {
-    $field['label'] = 'Source Name';
-    $field['description'] = 'The name of the source data. This could be a file name, data set or a small description for how the data was collected. For long descriptions use the larger description field.';
-  }
-  elseif ($field['field_settings']['chado_table'] == 'analysis' and $field['field_settings']['chado_column'] == 'sourceversion') {
-    $field['label'] = 'Source Version';
-    $field['description'] = 'If hte source data set has a version include it here.';
-  }
-  elseif ($field['field_settings']['chado_table'] == 'analysis' and $field['field_settings']['chado_column'] == 'algorithm') {
-    $field['label'] = 'Source Version';
-    $field['description'] = 'The name of the algorithm used to produce the dataset if different from the program.';
-  }
-  elseif ($field['field_settings']['chado_table'] == 'analysis' and $field['field_settings']['chado_column'] == 'programversion') {
-    $field['label'] = 'Program Version';
-    $field['description'] = 'The version of the program used to perform this analysis. (e.g. TBLASTX 2.0MP-WashU [09-Nov-2000]. Enter "n/a" if no version is available or applicable.';
-  }
-  //
-  // PROJECT TABLE
-  //
-  elseif ($field['field_settings']['chado_table'] == 'project' and $field['field_settings']['chado_column'] == 'description') {
-    $field['label'] = 'Short Description';
-  }
 
 
-  return $field;
-}
 
 
 /**
 /**
  * Implements hook_form_FORM_ID_alter().
  * Implements hook_form_FORM_ID_alter().
@@ -546,6 +806,7 @@ function tripal_chado_form_field_ui_display_overview_form_alter(&$form, &$form_s
  * for users to show or manage.
  * for users to show or manage.
  */
  */
 function tripal_chado_form_field_ui_field_overview_form_alter(&$form, &$form_state, $form_id) {
 function tripal_chado_form_field_ui_field_overview_form_alter(&$form, &$form_state, $form_id) {
+
   // Remove the kvproperty_addr field as it isn't ever displayed. It's just used
   // Remove the kvproperty_addr field as it isn't ever displayed. It's just used
   // on the add/edit form of an entity for adding new property fields.
   // on the add/edit form of an entity for adding new property fields.
   $fields_names = element_children($form['fields']);
   $fields_names = element_children($form['fields']);
@@ -583,251 +844,6 @@ function tripal_chado_field_is_empty($item, $field) {
   return TRUE;
   return TRUE;
 }
 }
 
 
-/**
- * Implements hook_update_bundle_fields().
- *
- */
-function tripal_chado_update_bundle_fields($entity_type, $bundle, $term) {
-  // Get the list of fields that should be attached to this bundle and
-  // add them.
-  $bundle_name = $bundle->name;
-  $fields = tripal_chado_get_bundle_fields($entity_type, $bundle, $term);
-  foreach ($fields as $field_name => $field_info) {
-    tripal_update_bundle_field($field_name, $field_info, $entity_type, $bundle_name);
-  }
-}
-
-/**
- * Implements hook_add_bundle_fields().
- */
-function tripal_chado_add_bundle_fields($entity_type, $bundle, $term) {
-
-  // Get the list of fields that should be attached to this bundle and
-  // add them.
-  $bundle_name = $bundle->name;
-  $fields = tripal_chado_get_bundle_fields($entity_type, $bundle, $term);
-  foreach ($fields as $field_name => $field_info) {
-    tripal_add_bundle_field($field_name, $field_info, $entity_type, $bundle_name);
-  }
-}
-/**
- * Retreives a list of the fields that should be attached to the bundle.
- *
- * @return
- *   An associative array of fields to attach to the bundle. The keys are the
- *   field names and the values is an info array that can be passed to the
- *   tripal_add_bundle_field() function.
- */
-function tripal_chado_get_bundle_fields($entity_type, $bundle, $term) {
-
-  $fields = array();
-
-  $bundle_name = $bundle->name;
-
-  // This array will hold details that map the bundle to tables in Chado.
-  $bundle_data = array();
-
-  // Get the cvterm that corresponds to this TripalTerm object.
-  $vocab = entity_load('TripalVocab', array($term->vocab_id));
-  $vocab = reset($vocab);
-  $match = array(
-    'dbxref_id' => array(
-      'db_id' => array(
-        'name' => $vocab->vocabulary,
-      ),
-      'accession' => $term->accession
-    ),
-  );
-  $cvterm = chado_generate_var('cvterm', $match);
-
-  // The organism table does not have a type_id so we won't ever find
-  // a record for it in the tripal_cv_defaults table.
-  if ($cvterm->name == 'organism') {
-    $bundle_data = array(
-      'cv_id' => $cvterm->cv_id->cv_id,
-      'cvterm_id' => $cvterm->cvterm_id,
-      'data_table' => 'organism',
-      'type_table' => 'organism',
-      'field' =>  '',
-    );
-  }
-  // The analysis table does not have a type_id so we won't ever find
-  // a record for it in the tripalcv_defaults table.
-  else if ($cvterm->name == 'analysis') {
-    $bundle_data = array(
-      'cv_id' => $cvterm->cv_id->cv_id,
-      'cvterm_id' => $cvterm->cvterm_id,
-      'data_table' => 'analysis',
-      'type_table' => 'analysis',
-      'field' =>  '',
-    );
-  }
-  else if ($cvterm->name == 'project') {
-    $bundle_data = array(
-      'cv_id' => $cvterm->cv_id->cv_id,
-      'cvterm_id' => $cvterm->cvterm_id,
-      'data_table' => 'project',
-      'type_table' => 'project',
-      'field' =>  '',
-    );
-  }
-  else {
-    // TODO: WHAT TO DO IF A VOCABULARY IS USED AS A DEFAULT FOR MULTIPLE
-    // TABLES.
-    // Look to see if this vocabulary is used as a default for any table.
-    $default = db_select('tripal_cv_defaults', 't')
-      ->fields('t')
-      ->condition('cv_id', $cvterm->cv_id->cv_id)
-      ->execute()
-      ->fetchObject();
-    if ($default) {
-      $bundle_data = array(
-        'cv_id' => $cvterm->cv_id->cv_id,
-        'cvterm_id' => $cvterm->cvterm_id,
-        'data_table' => $default->table_name,
-        'type_table' => $default->table_name,
-        'field' =>  $default->field_name,
-      );
-    }
-  }
-
-  // Save the mapping information so that we can reuse it when we need to
-  // look things up for later for an entity
-  tripal_set_bundle_variable('chado_cvterm_id', $bundle->id, $bundle_data['cvterm_id']);
-  tripal_set_bundle_variable('chado_table', $bundle->id, $bundle_data['data_table']);
-  tripal_set_bundle_variable('chado_column', $bundle->id, $bundle_data['field']);
-
-  // Find all of the files in the tripal_chado/includes/fields directory.
-  $fields_path = drupal_get_path('module', 'tripal_chado') . '/includes/fields';
-  $field_files = file_scan_directory($fields_path, '/^chado_.*\.inc$/');
-
-  // Add fields from the base table.
-  tripal_chado_get_bundle_fields_base__fields($fields, $entity_type, $bundle_name, $bundle_data);
-
-  // Iterate through the fields, include the file and run the info function.
-  foreach ($field_files as $file) {
-    $field_type = $file->name;
-    module_load_include('inc', 'tripal_chado', 'includes/fields/' . $field_type);
-
-    if (preg_match('/^chado/', $field_type) and class_exists($field_type)) {
-      $field_obj = new $field_type();
-      $field_info = $field_obj->attach_info($entity_type, $bundle, $bundle_data);
-    }
-
-    $function = $field_type . '_attach_info';
-    if (function_exists($function)) {
-      $field_info = $function($entity_type, $bundle, $bundle_data);
-    }
-
-    if (!is_array($field_info) or count(array_keys($field_info)) == 0) {
-      continue;
-    }
-    $field_name = $field_info['field_name'];
-
-    $fields[$field_name] = $field_info;
-  }
-
-  // Add in the semantic web details
-  foreach ($fields as $field_name => $field) {
-    if (!array_key_exists('chado_table', $field['field_settings'])) {
-      continue;
-    }
-    $chado_column = $field['field_settings']['chado_column'];
-    $chado_table = $field['field_settings']['chado_table'];
-
-    // Get the semantic web mapping for this field. First look for a
-    // table specific mapping.
-    $smweb = db_select('chado_semweb', 'CS')
-      ->fields('CS')
-      ->condition('chado_column', $chado_column)
-      ->condition('chado_table', $chado_table)
-      ->execute()
-      ->fetchObject();
-    // We don't have a table/column specific mapping, so let's look for a
-    // generic column mapping.
-    if (!$smweb) {
-      $smweb = db_select('chado_semweb', 'CS')
-      ->fields('CS')
-      ->condition('chado_column', $chado_column)
-      ->execute()
-      ->fetchObject();
-    }
-    if ($smweb) {
-      $cvterm = tripal_get_cvterm(array('cvterm_id' => $smweb->cvterm_id));
-      $fields[$field_name]['field_settings']['semantic_web'] = $cvterm->dbxref_id->db_id->name . ':' . $cvterm->dbxref_id->accession;
-    }
-  }
-
-  return $fields;
-}
-
-
-/**
- * Adds the fields for the base table to the entity.
- */
-function tripal_chado_get_bundle_fields_base__fields(&$fields, $entity_type_name, $bundle_name, $bundle_data) {
-
-  $table_name = $bundle_data['data_table'];
-  $type_table = $bundle_data['type_table'];
-  $type_field = $bundle_data['field'];
-
-  // Iterate through the columns of the table and see if fields have been
-  // created for each one. If not, then create them.
-  $schema = chado_get_schema($table_name);
-  $columns = $schema['fields'];
-  foreach ($columns as $column_name => $details) {
-    $field_name = $table_name . '__' . $column_name;
-
-    // Skip the primary key field.
-    if ($column_name == $schema['primary key'][0]) {
-      continue;
-    }
-
-    // Skip the type field.
-    if ($table_name == $type_table and $column_name == $type_field) {
-      continue;
-    }
-
-    // Get the field defaults for this column.
-    $field_info = tripal_chado_get_bundle_fields_base__fields_defaults($table_name, $schema, $column_name);
-
-
-    // TODO: add in a call to drupal_alter to allow other modules to change
-    // the field settings.
-
-    // Determine if the field is required.
-    if (array_key_exists('not null', $details) and $details['not null'] === TRUE) {
-      $field_info['is_required'] = array_key_exists('default', $details) ? 0 : 1;
-    }
-
-    // If we don't have a field type then we don't need to create a field.
-    if (!$field_info['field_type']) {
-      // If we don't have a field type but it is required and doesn't have
-      // a default value then we are in trouble.
-      if ($field_info['is_required'] and !array_key_exists('default', $details)) {
-        throw new Exception(t('The %table.%field type, %type, is not yet supported for Entity fields, but it is required,',
-            array('%table' => $table_name, '%field' => $column_name, '%type' => $details['type'])));
-      }
-      continue;
-    }
-
-    // If this field is a foreign key field then we will have a custom field.
-    $is_fk = FALSE;
-    if (array_key_exists('foreign keys', $schema)) {
-      foreach ($schema['foreign keys'] as $remote_table => $fk_details) {
-        if (array_key_exists($column_name, $fk_details['columns'])) {
-          $is_fk = TRUE;
-        }
-      }
-    }
-
-    // Add the field to the bundle.
-    $fields[$field_name] = $field_info;
-  }
-}
-
-
-
 
 
 
 
 
 

+ 11 - 3
tripal_chado/includes/tripal_chado.setup.inc

@@ -390,17 +390,25 @@ function tripal_chado_prepare_chado() {
     // For the TripalBundle entities we will want to associate the cvterm_id,
     // For the TripalBundle entities we will want to associate the cvterm_id,
     // and the chado table and field that it maps to.  We will use a few
     // and the chado table and field that it maps to.  We will use a few
     // variables to do this:
     // variables to do this:
+    tripal_insert_variable(
+      'chado_cv_id',
+      'The ID of the controlled vocabulary in the chado.cv table..'
+    );
     tripal_insert_variable(
     tripal_insert_variable(
       'chado_cvterm_id',
       'chado_cvterm_id',
-      'The cvterm_id that a TripalBundle maps to.'
+      'The ID of the controlled vocabulary term in the chado.cvterm table.'
     );
     );
     tripal_insert_variable(
     tripal_insert_variable(
       'chado_table',
       'chado_table',
       'The name of the table to which a TripalBundle maps.'
       'The name of the table to which a TripalBundle maps.'
     );
     );
     tripal_insert_variable(
     tripal_insert_variable(
-      'chado_column',
-      'The name of the column within the table that a TripalBundle maps to.'
+      'chado_type_table',
+      'The table that houses the foreign key the cvterm table.'
+    );
+    tripal_insert_variable(
+      'chado_type_column',
+      'The name of the column within the type table that houses the cvterm.'
     );
     );
 
 
     // We want to provide a set of commonly used entity types by default. This
     // We want to provide a set of commonly used entity types by default. This