浏览代码

Nightly checkin

Stephen Ficklin 9 年之前
父节点
当前提交
63d74cf89b

+ 156 - 0
tripal_chado/api/modules/tripal_chado.feature.api.inc

@@ -722,3 +722,159 @@ function tripal_get_location_string($featureloc) {
   return $featureloc->srcfeature_id->name . ":" . ($featureloc->fmin + 1) . ".." . $featureloc->fmax .  $strand;
 }
 
+
+/**
+ * Quickly retrieves relationships for a feature.
+ *
+ * Using the chado_expand_var function to retrieve a set
+ * of relationships can be very slow, especialy if there are many relationships
+ * This function is intended to help speed up the retrieval of relationships
+ * by only retrieving the base information for the relationship and returning
+ * an array with
+ *
+ * @param $feature
+ *   The feature object
+
+ * @return
+ *   An array with two objects
+ *
+ * @ingroup tripal_feature_api
+ */
+function tripal_get_feature_relationships($feature) {
+  // expand the feature object to include the feature relationships.
+  $options = array(
+    'return_array' => 1,
+    'order_by' => array('rank' => 'ASC'),
+    // we don't want to fully recurse we only need information about the
+    // relationship type and the object and subject features (including feature type
+    // and organism)
+    'include_fk' => array(
+      'type_id' => 1,
+      'object_id' => array(
+        'type_id' => 1,
+        'organism_id' => 1
+      ),
+      'subject_id'  => array(
+        'type_id' => 1,
+        'organism_id' => 1
+      ),
+    ),
+  );
+  $feature = chado_expand_var($feature, 'table', 'feature_relationship', $options);
+
+  // get the subject relationships
+  $srelationships = $feature->feature_relationship->subject_id;
+  $orelationships = $feature->feature_relationship->object_id;
+
+
+  // get alignment as child. The $feature->featureloc element
+  // is already populated from the alignment preprocess function
+  $options = array(
+    'include_fk' => array(
+      'srcfeature_id' => 1,
+      'feature_id' => 1,
+    ),
+  );
+  $feature = chado_expand_var($feature, 'table', 'featureloc', $options);
+  $cfeaturelocs = $feature->featureloc->feature_id;
+  if (!$cfeaturelocs) {
+    $cfeaturelocs = array();
+  }
+  elseif (!is_array($cfeaturelocs)) {
+    $cfeaturelocs = array($cfeaturelocs);
+  }
+
+  // prepare the SQL statement to get the featureloc for the
+  // feature in the relationships.
+  $flrels_sql = "
+    SELECT
+      FL.featureloc_id, F.name as srcfeature_name, FL.srcfeature_id,
+      FL.feature_id, FL.fmin, FL.fmax, FL.strand, FL.phase
+    FROM {featureloc} FL
+      INNER JOIN {feature} F ON F.feature_id = FL.srcfeature_id
+    WHERE FL.feature_id = :feature_id and FL.srcfeature_id = :srcfeature_id
+  ";
+
+  // combine both object and subject relationshisp into a single array
+  $relationships = array();
+  $relationships['object'] = array();
+  $relationships['subject'] = array();
+
+  // iterate through the object relationships
+  if ($orelationships) {
+    foreach ($orelationships as $relationship) {
+      $rel = new stdClass();
+      // get locations where the child feature and this feature overlap with the
+      // same landmark feature.
+      $rel->child_featurelocs = array();
+      foreach ($cfeaturelocs as $featureloc) {
+        $res = chado_query($flrels_sql, array(':feature_id' => $relationship->subject_id->feature_id, ':srcfeature_id' => $featureloc->srcfeature_id->feature_id));
+        while ($loc = $res->fetchObject()) {
+          // add in the node id of the src feature if it exists and save this location
+          if (property_exists($featureloc->srcfeature_id, 'nid')) {
+            $loc->nid = $featureloc->srcfeature_id->nid;
+          }
+          $rel->child_featurelocs[] = $loc;
+        }
+      }
+      $rel->record = $relationship;
+
+      // get the relationship and child types
+      $rel_type = t(preg_replace('/_/', " ", $relationship->type_id->name));
+      $child_type = $relationship->subject_id->type_id->name;
+
+      // get the node id of the subject
+//       $sql = "SELECT nid FROM {chado_feature} WHERE feature_id = :feature_id";
+//       $n = db_query($sql, array(':feature_id' => $relationship->subject_id->feature_id))->fetchObject();
+//       if ($n) {
+//         $rel->record->nid = $n->nid;
+//       }
+
+      if (!array_key_exists($rel_type, $relationships['object'])) {
+        $relationships['object'][$rel_type] = array();
+      }
+      if (!array_key_exists($child_type, $relationships['object'][$rel_type])) {
+        $relationships['object'][$rel_type][$child_type] = array();
+      }
+      $relationships['object'][$rel_type][$child_type][] = $rel;
+    }
+  }
+
+  // now add in the subject relationships
+  if ($srelationships) {
+    foreach ($srelationships as $relationship) {
+      $rel = new stdClass();
+      // get locations where this feature overlaps with the parent
+      $rel->parent_featurelocs = array();
+      foreach ($cfeaturelocs as $featureloc) {
+        $res = chado_query($flrels_sql, array(':feature_id' => $relationship->object_id->feature_id, ':srcfeature_id' => $featureloc->srcfeature_id->feature_id));
+        while ($loc = $res->fetchObject()) {
+          // add in the node id of the src feature if it exists and save this location
+          if (property_exists($featureloc->srcfeature_id, 'nid')) {
+            $loc->nid = $featureloc->srcfeature_id->nid;
+          }
+          $rel->parent_featurelocs[] = $loc;
+        }
+      }
+      $rel->record = $relationship;
+      $rel_type = t(preg_replace('/_/', " ", $relationship->type_id->name));
+      $parent_type = $relationship->object_id->type_id->name;
+
+//       // get the node id of the subject
+//       $sql = "SELECT nid FROM {chado_feature} WHERE feature_id = :feature_id";
+//       $n = db_query($sql, array(':feature_id' => $relationship->object_id->feature_id))->fetchObject();
+//       if ($n) {
+//         $rel->record->nid = $n->nid;
+//       }
+
+      if (!array_key_exists($rel_type, $relationships['subject'])) {
+        $relationships['subject'][$rel_type] = array();
+      }
+      if (!array_key_exists($parent_type, $relationships['subject'][$rel_type])) {
+        $relationships['subject'][$rel_type][$parent_type] = array();
+      }
+      $relationships['subject'][$rel_type][$parent_type][] = $rel;
+    }
+  }
+  return $relationships;
+}

+ 60 - 0
tripal_chado/includes/fields/chado_base__dbxref_id.inc

@@ -21,6 +21,66 @@ function chado_base__dbxref_id_info() {
     ),
   );
 }
+/**
+ * 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 the settings.
+ *
+ * @param $entity_type
+ * @param $entity
+ * @param $term
+ *
+ * @return
+ *   A field array
+ */
+function chado_base__dbxref_id_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'];
+
+  // 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.
+  $schema = chado_get_schema($table_name);
+  if (!array_key_exists('organism_id', $schema['fields'])) {
+    return $field_info;
+  }
+
+  // There is an dbxref_id column so attach the field!
+  $field_info = array(
+    'field_name' => $table_name . '__dbxref_id',
+    'field_type' => 'chado_base__dbxref_id',
+    'widget_type' => 'chado_base__dbxref_id_widget',
+    'description' => 'This record can be cross referenced with a ' .
+      'record in another online database. The primary reference is for the ' .
+      'most prominent reference.  At a minimum, the database and accession ' .
+      'must be provided.  To remove a set reference, change the database ' .
+      'field to "Select a Database".',
+    'label' => 'Cross Reference',
+    'is_required' => 0,
+    'storage' => 'field_chado_storage',
+    'widget_settings' => array(
+      'display_label' => 1
+    ),
+    'field_settings' => array(
+      'chado_table' => $table_name,
+      'chado_column' => 'dbxref_id',
+      'semantic_web' => array(
+        'type' => 'organism',
+        'ns' => 'local',
+        'nsurl' => '',
+      ),
+    ),
+  );
+
+  return $field_info;
+
+}
 /**
  * Implements hook_widget_info.
  *

+ 56 - 0
tripal_chado/includes/fields/chado_base__organism_id.inc

@@ -19,6 +19,62 @@ function chado_base__organism_id_info() {
     ),
   );
 }
+/**
+ * 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_base__organism_id_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'];
+
+
+  // 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);
+  if (!array_key_exists('organism_id', $schema['fields'])) {
+    return $field_info;
+  }
+
+  // There is an organism_id column so attach the field!
+  $field_info = array(
+    'field_name' => $table_name . '__organism_id',
+    'field_type' => 'chado_base__organism_id',
+    'widget_type' => 'chado_base__organism_id_widget',
+    'description' => 'Select an organism.',
+    'label' => 'Oraganism',
+    'is_required' => 0,
+    'storage' => 'field_chado_storage',
+    'widget_settings' => array(
+      'display_label' => 1
+    ),
+    'field_settings' => array(
+      'chado_table' => $table_name,
+      'chado_column' => 'organism_id',
+      'semantic_web' => array(
+        'type' => 'organism',
+        'ns' => 'local',
+        'nsurl' => '',
+      ),
+    ),
+  );
+
+  return $field_info;
+}
 /**
  * Implements hook_widget_info.
  *

+ 52 - 0
tripal_chado/includes/fields/chado_feature__md5checksum.inc

@@ -19,6 +19,58 @@ function chado_feature__md5checksum_info() {
     ),
   );
 }
+/**
+ * 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 the settings.
+ *
+ * @param $entity_type
+ * @param $entity
+ * @param $term
+ *
+ * @return
+ *   A field array
+ */
+function chado_feature__md5checksum_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'];
+
+
+  // If  this is not the feature table then we don't want to attach.
+  if ($table_name != 'feature') {
+    return $field_info;
+  }
+
+  // Create an array with information about this field.
+  $field_info = array(
+    'field_name' => 'feature__md5checksum',
+    'field_type' => 'chado_feature__md5checksum',
+    'widget_type' => 'chado_feature__md5checksum_widget',
+    'description' => 'The MD5 checksum for the sequence.',
+    'label' => 'MD5 Checksum',
+    'is_required' => 0,
+    'storage' => 'field_chado_storage',
+    'widget_settings' => array(
+      'display_label' => 1
+    ),
+    'field_settings' => array(
+      'chado_table' => $table_name,
+      'chado_column' => 'md5checksum',
+      'semantic_web' => array(
+        'type' => '',
+        'ns' => '',
+        'nsurl' => '',
+      ),
+    ),
+  );
+  return $field_info;
+}
 /**
  * Implements hook_widget_info.
  *

+ 51 - 0
tripal_chado/includes/fields/chado_feature__residues.inc

@@ -19,6 +19,57 @@ function chado_feature__residues_info() {
     ),
   );
 }
+/**
+ * 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_feature__residues_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'];
+
+
+  // If  this is not the feature table then we don't want to attach.
+  if ($table_name != 'feature') {
+    return $field_info;
+  }
+
+  $field_info = array(
+    'field_name' => 'feature__residues',
+    'field_type' => 'chado_feature__residues',
+    'widget_type' => 'chado_feature__residues_widget',
+    'description' => 'An IUPAC compatible residues for this feature.',
+    'label' => 'Residues',
+    'is_required' => 0,
+    'storage' => 'field_chado_storage',
+    'widget_settings' => array(
+      'display_label' => 1
+    ),
+    'field_settings' => array(
+      'chado_table' => $table_name,
+      'chado_column' => 'residues',
+      'semantic_web' => array(
+        'type' => '',
+        'ns' => '',
+        'nsurl' => '',
+      ),
+    ),
+  );
+  return $field_info;
+}
 /**
  * Implements hook_widget_info.
  *

+ 52 - 0
tripal_chado/includes/fields/chado_feature__seqlen.inc

@@ -19,6 +19,58 @@ function chado_feature__seqlen_info() {
     ),
   );
 }
+/**
+ * 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_feature__seqlen_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'];
+
+
+  // If  this is not the feature table then we don't want to attach.
+  if ($table_name != 'feature') {
+    return $field_info;
+  }
+
+  $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' => array(
+        'type' => '',
+        'ns' => '',
+        'nsurl' => '',
+      ),
+    ),
+  );
+
+  return $field_info;
+}
 /**
  * Implements hook_widget_info.
  *

+ 20 - 0
tripal_chado/includes/fields/chado_linker__cvterm.inc

@@ -20,6 +20,26 @@ function chado_linker__cvterm_info() {
     ),
   );
 }
+/**
+ * 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__cvterm_attach_info($entity_type, $bundle, $target) {
+  $field_info = array();
+
+  // This field is only attached by the chado_linker__cvterm_addr field.
+
+  return $field_info;
+}
 /**
  * Implements hook_widget_info.
  *

+ 48 - 0
tripal_chado/includes/fields/chado_linker__cvterm_adder.inc

@@ -25,6 +25,54 @@ function chado_linker__cvterm_adder_info() {
     ),
   );
 }
+/**
+ * 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__cvterm_adder_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'];
+
+
+  // If the linker table does not exists then we don't want to add attach.
+  $cvterm_table = $table_name . '_cvterm';
+  if (!chado_table_exists($cvterm_table)) {
+    return $field_info;
+  }
+
+  // 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,
+    ),
+    '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.
+  );
+
+  return $field_info;
+}
 /**
  * Implements hook_widget_info.
  *

+ 65 - 0
tripal_chado/includes/fields/chado_linker__dbxref.inc

@@ -21,6 +21,71 @@ function chado_linker__dbxref_info() {
     ),
   );
 }
+/**
+ * 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__dbxref_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'];
+
+
+  // If the linker table does not exists then we don't want to add attach.
+  $dbxref_table = $table_name . '_dbxref';
+  if (!chado_table_exists($dbxref_table)) {
+    return $field_info;
+  }
+
+  // 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' => '',
+    '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' => array(
+        'type' => '',
+        'ns' => '',
+        'nsurl' => '',
+      ),
+    ),
+  );
+
+  // If the base table has a 'dbxref_id' then change the label to
+  // indicate these are secondary cross references.
+  $schema = chado_get_schema($table_name);
+  if (array_key_exists('dbxref_id', $schema['fields'])) {
+    $field_info['label'] = 'Secondary Cross References';
+  }
+
+  return $field_info;
+}
 /**
  * Implements hook_widget_info.
  *

+ 53 - 0
tripal_chado/includes/fields/chado_linker__featureloc.inc

@@ -20,6 +20,59 @@ function chado_linker__featureloc_info() {
     ),
   );
 }
+/**
+ * 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__featureloc_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'];
+
+  // If  this is not the feature table then we don't want to attach.
+  if ($table_name != 'feature') {
+    return $field_info;
+  }
+
+  $schema = chado_get_schema('featureloc');
+  $pkey = $schema['primary key'][0];
+
+  // Initialize the field array.
+  $field_info = array(
+    'field_name' => 'featureloc',
+    'field_type' => 'chado_linker__featureloc',
+    'widget_type' => 'chado_linker__featureloc_widget',
+    'widget_settings' => array('display_label' => 1),
+    'description' => '',
+    'label' => 'Alignments',
+    'is_required' => 0,
+    'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+    'storage' => 'field_chado_storage',
+    'field_settings' => array(
+      'chado_table' => 'featureloc',
+      'chado_column' => $pkey,
+      'base_table' => 'feature',
+      'semantic_web' => array(
+        'type' => '',
+        'ns' => '',
+        'nsurl' => '',
+      ),
+    ),
+  );
+}
 /**
  * Implements hook_widget_info.
  *

+ 20 - 0
tripal_chado/includes/fields/chado_linker__prop.inc

@@ -19,6 +19,26 @@ function chado_linker__prop_info() {
     ),
   );
 }
+/**
+ * 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.
  *

+ 48 - 0
tripal_chado/includes/fields/chado_linker__prop_adder.inc

@@ -25,6 +25,54 @@ function chado_linker__prop_adder_info() {
     ),
   );
 }
+/**
+ * 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_adder_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'];
+
+
+  // If the linker table does not exists then we don't want to add attach.
+  $prop_table = $table_name . 'prop';
+  if (!chado_table_exists($prop_table)) {
+    return $field_info;
+  }
+
+  // Initialize the field array.
+  $field_info = array(
+    'field_name' => $prop_table,
+    'field_type' => 'chado_linker__prop_adder',
+    'widget_type' => 'chado_linker__prop_adder_widget',
+    'field_settings' => array(
+      'base_table' => $table_name,
+    ),
+    '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.
+  );
+
+  return $field_info;
+}
 /**
  * Implements hook_widget_info.
  *

+ 56 - 0
tripal_chado/includes/fields/chado_linker__pub.inc

@@ -20,6 +20,62 @@ function chado_linker__pub_info() {
     ),
   );
 }
+/**
+ * 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__pub_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'];
+
+  // If the linker table does not exists then we don't want to add attach.
+  $pub_table = $table_name . '_pub';
+  if (!chado_table_exists($pub_table)) {
+    return $field_info;
+  }
+
+  $schema = chado_get_schema($pub_table);
+  $pkey = $schema['primary key'][0];
+
+  // Initialize the field array.
+  $field_info = array(
+    '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,
+    'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+    'storage' => 'field_chado_storage',
+    'field_settings' => array(
+      'chado_table' => $pub_table,
+      'chado_column' => $pkey,
+      'base_table' => $table_name,
+      'semantic_web' => array(
+        'type' => '',
+        'ns' => '',
+        'nsurl' => '',
+      ),
+    ),
+  );
+
+  return $field_info;
+}
 /**
  * Implements hook_widget_info.
  *

+ 55 - 0
tripal_chado/includes/fields/chado_linker__synonym.inc

@@ -19,6 +19,61 @@ function chado_linker__synonym_info() {
     ),
   );
 }
+/**
+ * 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__synonym_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'];
+
+  // If the linker table does not exists then we don't want to add attach.
+  $syn_table = $table_name . '_synonym';
+  if (!chado_table_exists($syn_table)) {
+    return $field_info;
+  }
+
+  $schema = chado_get_schema($syn_table);
+  $pkey = $schema['primary key'][0];
+
+  // Initialize the field array.
+  $field_info = array(
+    '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,
+    'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+    'storage' => 'field_chado_storage',
+    'field_settings' => array(
+      'chado_table' => $syn_table,
+      'chado_column' => $pkey,
+      'base_table' => $table_name,
+      'semantic_web' => array(
+        'type' => '',
+        'ns' => '',
+        'nsurl' => '',
+      ),
+    ),
+  );
+  return $field_info;
+}
 /**
  * Implements hook_widget_info.
  *

+ 121 - 0
tripal_chado/includes/fields/tripal_chado_field.inc

@@ -0,0 +1,121 @@
+<?php
+
+/* TODO: it may be eaiser to help train developers at creating new
+ * fields if it was a class rather than a bunch of hooks. Below is
+ * the starting point.
+ */
+
+/**
+ * A base class for all Fields supported by the Tripal Chado module.
+ *
+ */
+class TripalChadoField {
+  /**
+   * 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.
+   */
+  public function info() {
+    return array(
+    );
+  }
+  /**
+   * 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.
+   */
+  public function widget_info() {
+    return array(
+    );
+  }
+  /**
+   * 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.
+   *
+   */
+  public function formatter_info() {
+    return array(
+    );
+  }
+  /**
+   * Implements hook_formatter_settings_summary.
+   *
+   * This is a hook provided by the tripal_chado module for
+   * offloading the hook_field_formatter_settings_summary() for each field
+   * to specify.
+   *
+   */
+  public function formatter_settings_summary($field, $instance, $view_mode) {
+
+  }
+
+  /**
+   * Provides a settings form for the formatter.
+   *
+   * This is a hook provided by the tripal_chado module for
+   * offloading the hook_field_formatter_settings_form() for each field
+   * to specify.
+   */
+  public function formatter_settings_form($field, $instance,
+      $view_mode, $form, &$form_state) {
+
+  }
+
+  /**
+   *
+   */
+  public function formatter(&$element, $entity_type, $entity,
+      $field, $instance, $langcode, $items, $display) {
+  }
+
+  /**
+   * 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
+   */
+  public function load($field, $entity, $base_table, $record) {
+
+  }
+
+  /**
+   * Implements hook_ws_formatter().
+   */
+  public function ws_formatter(&$element, $entity_type, $entity,
+      $field, $instance, $items) {
+
+  }
+
+  /**
+   *  Implements hook_widget().
+   */
+  public function widget(&$widget, $form, $form_state, $field, $instance,
+      $langcode, $items, $delta, $element) {
+
+  }
+  /**
+   * Callback function for validating the chado_base__organism_id_widget.
+   */
+  static function widget_validate($element, &$form_state) {
+
+  }
+
+  /**
+   *
+   */
+  public function attach_info($entity_type, $bundle) {
+
+  }
+}

+ 89 - 97
tripal_chado/includes/tripal_chado.fields.inc

@@ -355,27 +355,27 @@ function tripal_chado_add_bundle_fields_base__fields_defaults($table_name, $sche
   //
   // GENERIC COLUMNS
   //
-  if ($field['field_settings']['chado_column'] == 'organism_id') {
-    $field['field_type'] = 'chado_base__organism_id';
-    $field['widget_type'] = 'chado_base__organism_id_widget';
-    $field['label'] = 'Organism';
-    $field['description'] = 'Select an organism.';
-    $field['field_settings']['semantic_web']['type'] = 'organism';
-    $field['field_settings']['semantic_web']['ns'] = 'local';
-    $field['field_settings']['semantic_web']['nsurl'] = '';
-
-  }
-  elseif ($field['field_settings']['chado_column'] =='dbxref_id') {
-    $field['field_type'] = 'chado_base__dbxref_id';
-    $field['widget_type'] = 'chado_base_dbxref_id_widget';
-    $field['label'] = 'Cross Reference';
-    $field['description'] = 'This record can be cross referenced with a ' .
-        'record in another online database. The primary reference is for the ' .
-        'most prominent reference.  At a minimum, the database and accession ' .
-        'must be provided.  To remove a set reference, change the database ' .
-        'field to "Select a Database".';
-  }
-  elseif ($field['label'] == 'Timeaccessioned') {
+//   if ($field['field_settings']['chado_column'] == 'organism_id') {
+//     $field['field_type'] = 'chado_base__organism_id';
+//     $field['widget_type'] = 'chado_base__organism_id_widget';
+//     $field['label'] = 'Organism';
+//     $field['description'] = 'Select an organism.';
+//     $field['field_settings']['semantic_web']['type'] = 'organism';
+//     $field['field_settings']['semantic_web']['ns'] = 'local';
+//     $field['field_settings']['semantic_web']['nsurl'] = '';
+
+//   }
+//   elseif ($field['field_settings']['chado_column'] =='dbxref_id') {
+//     $field['field_type'] = 'chado_base__dbxref_id';
+//     $field['widget_type'] = 'chado_base_dbxref_id_widget';
+//     $field['label'] = 'Cross Reference';
+//     $field['description'] = 'This record can be cross referenced with a ' .
+//         'record in another online database. The primary reference is for the ' .
+//         'most prominent reference.  At a minimum, the database and accession ' .
+//         'must be provided.  To remove a set reference, change the database ' .
+//         'field to "Select a Database".';
+//   }
+  if ($field['label'] == 'Timeaccessioned') {
     $field['label'] = 'Time Accessioned';
     $field['description'] = 'Please enter the time that this record was first added to the database.';
   }
@@ -400,7 +400,7 @@ function tripal_chado_add_bundle_fields_base__fields_defaults($table_name, $sche
     $field['field_settings']['semantic_web']['ns'] = 'foaf';
     $field['field_settings']['semantic_web']['nsurl'] = 'http://xmlns.com/foaf/0.1/';
   }
-  elseif ($field['field_settings']['chado_table'] == 'feature' and $field['field_settings']['chado_column'] == 'md5checksum') {
+  /* elseif ($field['field_settings']['chado_table'] == 'feature' and $field['field_settings']['chado_column'] == 'md5checksum') {
     $field['field_type'] = 'chado_feature__md5checksum';
     $field['widget_type'] = 'chado_feature__md5checksum_widget';
     $field['label'] = 'MD5 Checksum';
@@ -417,7 +417,7 @@ function tripal_chado_add_bundle_fields_base__fields_defaults($table_name, $sche
     $field['widget_type'] = 'chado_feature__residues_widget';
     $field['label'] = 'Residues';
     $field['description'] = 'Please provide an IUPAC compatible residues for this feature. Spaces and new lines are allowed.';
-  }
+  } */
   //
   // ANALYSIS TABLE
   //
@@ -611,88 +611,35 @@ function tripal_chado_add_bundle_fields($entity_type, $bundle, $term) {
   tripal_set_bundle_variable('chado_table', $bundle->id, $bundle_data['data_table']);
   tripal_set_bundle_variable('chado_column', $bundle->id, $bundle_data['field']);
 
-  //////////////////////////////////////////////////////////////////////////////
-  // ADD FIELDS TO BUNDLE
-  ////////////////////////////////////////////////////////////////////////////
 
-  /* TODO: the arrays for adding fields should be specified in the field
-   * files themselves so that field developers have complete control over
-   * how the fields behave and what entities they are attached to without
-   * having to edit this function.
-   */
 
-  ////
-  //
-  // Base table fields.
-  //
-  // Adds the fields for the base table to the entity.  Adds fields
-  // for all columns including FK fields.  Excludes primary key and the
-  // type_id field (that's inherent in the bundle).
-  tripal_chado_add_bundle_fields_base__fields($entity_type, $bundle_name, $bundle_data);
-
-  ////
-  //
-  // Property table fields.
-  //
-  // Check to see if there are any property tables with FKs to this
-  // base table. If so, add the fields for that type of table.
-  $prop_table = $bundle_data['data_table'] . 'prop';
-  if (chado_table_exists($prop_table)) {
-    tripal_chado_add_bundle_fields_linker__prop_adder_field($entity_type, $bundle_name, $prop_table, $bundle_data['data_table']);
-  }
+  // Call the hook_attach_info() for all Chado fields to see if any of them
+  // want to attach themsevles to this bundle.
+  $fields = field_info_fields();
+  foreach ($fields as $field) {
+    $field_type = $field['type'];
+    if ($field['storage']['type'] == 'field_chado_storage') {
+      module_load_include('inc', 'tripal_chado', 'includes/fields/' . $field_type);
+      $function = $field_type . '_attach_info';
 
-  ////
-  //
-  // Dbxref table fields.
-  //
-  // Check to see if there are any dbxref tables with FKs to this
-  // base table. If so, add the fields for that type of table.
-  $dbxref_table = $bundle_data['data_table'] . '_dbxref';
-  if (chado_table_exists($dbxref_table)) {
-    tripal_chado_add_bundle_fields_linker__dbxref_field($entity_type, $bundle_name, $dbxref_table, $bundle_data['data_table']);
-  }
+      if (function_exists($function)) {
+        // Get the field info.
+        $field_info = $function($entity_type, $bundle, $bundle_data);
+        if (!is_array($field_info) or count(array_keys($field_info)) == 0) {
+          continue;
+        }
 
-  ////
-  //
-  // Cvterm table fields.
-  //
-  // Check to see if there are any cvterm tables with FKs to this
-  // base table. If so, add the fields for that type of table.
-  $cvterm_table = $bundle_data['data_table'] . '_cvterm';
-  if (chado_table_exists($cvterm_table)) {
-    tripal_chado_add_bundle_fields_linker__cvterm_adder_field($entity_type, $bundle_name, $cvterm_table, $bundle_data['data_table']);
+        $field_name = $field_info['field_name'];
+        tripal_add_bundle_field($field_name, $field_info, $entity_type, $bundle_name);
+      }
+    }
   }
 
+  // Adds any remaining base fields that may not have been dealt with
+  // by a custom field.
+  //tripal_chado_add_bundle_fields_base__fields($entity_type, $bundle_name, $bundle_data);
 
-  ////
-  //
-  // Synonym table fields.
-  //
-  // Check to see if there are any synonym tables with FKs to this
-  // base table. If so, add the fields for that type of table.
-  $syn_table = $bundle_data['data_table'] . '_synonym';
-  if (chado_table_exists($syn_table)) {
-    tripal_chado_add_bundle_fields_linker__synonym_field($entity_type, $bundle_name, $syn_table, $bundle_data['data_table']);
-  }
 
-  ////
-  //
-  // Pub table fields.
-  //
-  // Check to see if there are any pub tables with FKs to this
-  // base table. If so, add the fields for that type of table.
-  $pub_table = $bundle_data['data_table'] . '_pub';
-  if (chado_table_exists($pub_table)) {
-    tripal_chado_add_bundle_fields_linker__pub_field($entity_type, $bundle_name, $pub_table, $bundle_data['data_table']);
-  }
-
-  ////
-  //
-  // Featureloc fields.
-  //
-  if ($bundle_data['data_table'] == 'feature') {
-    tripal_chado_add_bundle_fields_linker__featureloc_field($entity_type, $bundle_name);
-  }
 }
 
 /**
@@ -835,7 +782,52 @@ function tripal_chado_add_bundle_fields_linker__featureloc_field($entity_type_na
 
   tripal_add_bundle_field($field_name, $field_info, $entity_type_name, $bundle_name);
 }
+/**
+ * Adds the fields for managing relationships that are stored in a [base]_relationship table.
+ *
+ * @param $entity_type
+ * @param $bundle_name
+ * @param $base_table
+ * @param $dbxref_table
+ */
+function tripal_chado_add_bundle_fields_linker__relationship_field(
+    $entity_type_name, $bundle_name, $rel_table, $base_table) {
+
+  $field_name = $rel_table;
+  $schema = chado_get_schema($rel_table);
+  $pkey = $schema['primary key'][0];
 
+  // Initialize the field array.
+  $field_info = array(
+    'field_type' => 'chado_linker__relationship',
+    'widget_type' => 'chado_linker__relationship_widget',
+    'widget_settings' => array('display_label' => 1),
+    'description' => '',
+    'label' => 'Relationsihps',
+    'is_required' => 0,
+    'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+    'storage' => 'field_chado_storage',
+    'field_settings' => array(
+      // The Chado table that this field maps to.
+      'chado_table' => $rel_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' => array(
+        // The type is the term from a vocabulary that desribes this field..
+        'type' => '',
+        // The namepsace for the vocabulary (e.g. 'foaf').
+        'ns' => '',
+        // The URL for the namespace.  It must be that the type can be
+        // appended to the URL.
+        'nsurl' => '',
+      ),
+    ),
+  );
+
+  tripal_add_bundle_field($field_name, $field_info, $entity_type_name, $bundle_name);
+}
 /**
  * Adds the fields for managing xrefs that are stored in a [base]_dbxref table.
  *