Browse Source

Fixed merge conflicts

Chun-Huai Cheng 8 years ago
parent
commit
5718f9eff4
32 changed files with 1314 additions and 1019 deletions
  1. 2 3
      tripal/api/tripal.entities.api.inc
  2. 4 6
      tripal/includes/TripalEntityUIController.inc
  3. 4 1
      tripal/includes/tripal.entity.inc
  4. 1 1
      tripal/tripal.module
  5. 326 1
      tripal_chado/api/modules/tripal_chado.feature.api.inc
  6. 1 1
      tripal_chado/api/tripal_chado.mviews.api.inc
  7. 2 2
      tripal_chado/api/tripal_chado.query.api.inc
  8. 39 9
      tripal_chado/api/tripal_chado.schema.api.inc
  9. 4 1
      tripal_chado/api/tripal_chado.variables.api.inc
  10. 4 4
      tripal_chado/includes/TripalFields.old/chado_linker__expression.inc
  11. 13 12
      tripal_chado/includes/TripalFields/chado_linker__contact_widget.inc
  12. 81 0
      tripal_chado/includes/TripalFields/data__protein_sequence.inc
  13. 50 0
      tripal_chado/includes/TripalFields/data__protein_sequence_formatter.inc
  14. 43 0
      tripal_chado/includes/TripalFields/data__protein_sequence_widget.inc
  15. 90 477
      tripal_chado/includes/TripalFields/data__sequence.inc
  16. 0 7
      tripal_chado/includes/TripalFields/data__sequence_checksum.inc
  17. 5 16
      tripal_chado/includes/TripalFields/data__sequence_formatter.inc
  18. 0 7
      tripal_chado/includes/TripalFields/data__sequence_length.inc
  19. 10 11
      tripal_chado/includes/TripalFields/go__gene_expression.inc
  20. 16 16
      tripal_chado/includes/TripalFields/sbo__database_cross_reference_widget.inc
  21. 48 52
      tripal_chado/includes/TripalFields/sbo__relationship.inc
  22. 134 114
      tripal_chado/includes/TripalFields/sbo__relationship_widget.inc
  23. 16 16
      tripal_chado/includes/TripalFields/schema__alternate_name_widget.inc
  24. 96 0
      tripal_chado/includes/TripalFields/so__cds.inc
  25. 44 0
      tripal_chado/includes/TripalFields/so__cds_formatter.inc
  26. 43 0
      tripal_chado/includes/TripalFields/so__cds_widget.inc
  27. 45 53
      tripal_chado/includes/TripalFields/so__transcript.inc
  28. 1 1
      tripal_chado/includes/tripal_chado.custom_tables.inc
  29. 89 105
      tripal_chado/includes/tripal_chado.field_storage.inc
  30. 78 79
      tripal_chado/includes/tripal_chado.fields.inc
  31. 20 20
      tripal_chado/includes/tripal_chado.mapping.inc
  32. 5 4
      tripal_chado/includes/tripal_chado.migrate.inc

+ 2 - 3
tripal/api/tripal.entities.api.inc

@@ -16,7 +16,7 @@
  * @param $ids
  * @param $ids
  *   An array of entity IDs, or FALSE to load all entities.
  *   An array of entity IDs, or FALSE to load all entities.
  * @param $reset: Whether to reset the internal cache for the requested entity
  * @param $reset: Whether to reset the internal cache for the requested entity
- *   type. Unlike the entity_load() function this defaults to TRUE.
+ *   type. Defaults to FALSE.
  * @param $field_ids
  * @param $field_ids
  *   A list of numeric feild IDs that should be loaded.  The
  *   A list of numeric feild IDs that should be loaded.  The
  *   TripalField named 'content_type' is always automatically added.
  *   TripalField named 'content_type' is always automatically added.
@@ -25,7 +25,7 @@
  *   An array of entity objects indexed by their ids. When no results are
  *   An array of entity objects indexed by their ids. When no results are
  *   found, an empty array is returned.
  *   found, an empty array is returned.
  */
  */
-function tripal_load_entity($entity_type, $ids = FALSE, $reset = TRUE,
+function tripal_load_entity($entity_type, $ids = FALSE, $reset = FALSE,
     $field_ids = array()) {
     $field_ids = array()) {
 
 
   // The $conditions is deprecated in the funtion arguments of entity_load
   // The $conditions is deprecated in the funtion arguments of entity_load
@@ -45,7 +45,6 @@ function tripal_load_entity($entity_type, $ids = FALSE, $reset = TRUE,
   if ($reset) {
   if ($reset) {
     $ec->resetCache();
     $ec->resetCache();
   }
   }
-
   return $ec->load($ids, $conditions, $field_ids);
   return $ec->load($ids, $conditions, $field_ids);
 }
 }
 /**
 /**

+ 4 - 6
tripal/includes/TripalEntityUIController.inc

@@ -435,13 +435,11 @@ function tripal_entity_form_ajax_callback($form, $form_state) {
          if (!preg_match('/^\d+$/', $delta)) {
          if (!preg_match('/^\d+$/', $delta)) {
            continue;
            continue;
          }
          }
-         if (array_key_exists('#field', $field_form)) {
+         $widget_type = $instance['widget']['type'];
+         if (tripal_load_include_field_class($widget_type)) {
            $field = $field_form['#field'];
            $field = $field_form['#field'];
-           $field_type = $field['type'];
-           if (class_exists($field_type)) {
-             $tfield = new $field_type($field, $instance);
-             $tfield->widgetFormSubmit($form, $form_state, $entity_type, $entity, $langcode, $delta);
-           }
+           $widget = new $widget_type($field, $instance);
+           $widget->submit($form, $form_state, $entity_type, $entity, $langcode, $delta);
          }
          }
        }
        }
      }
      }

+ 4 - 1
tripal/includes/tripal.entity.inc

@@ -159,7 +159,10 @@ function tripal_entity_info() {
     'access callback' => 'tripal_entity_access',
     'access callback' => 'tripal_entity_access',
 
 
     // FALSE disables caching. Caching functionality is handled by Drupal core.
     // FALSE disables caching. Caching functionality is handled by Drupal core.
-    'static cache' => FALSE,
+    'static cache' => TRUE,
+
+    // Caching of fields
+    'field cache' => TRUE,
 
 
     // Bundles are added dynamically below.
     // Bundles are added dynamically below.
     'bundles' => array (),
     'bundles' => array (),

+ 1 - 1
tripal/tripal.module

@@ -521,7 +521,7 @@ function TripalBundle_load($bundle_type, $reset = FALSE) {
  *
  *
  * @see tripal_entity_load_multiple()
  * @see tripal_entity_load_multiple()
  */
  */
-function TripalEntity_load($id, $reset = TRUE) {
+function TripalEntity_load($id, $reset = FALSE) {
   // $entity = entity_load('TripalEntity', array($id), array(), $reset);
   // $entity = entity_load('TripalEntity', array($id), array(), $reset);
   $entity = tripal_load_entity('TripalEntity', array($id), $reset);
   $entity = tripal_load_entity('TripalEntity', array($id), $reset);
   return reset($entity);
   return reset($entity);

+ 326 - 1
tripal_chado/api/modules/tripal_chado.feature.api.inc

@@ -915,4 +915,329 @@ function tripal_get_feature_relationships($feature) {
     }
     }
   }
   }
   return $relationships;
   return $relationships;
-}
+}
+
+/**
+ *
+ * @param unknown $feature_id
+ * @param unknown $featurelocs
+ * @return multitype:|Ambigous <multitype:, an>
+ */
+function chado_get_featureloc_sequences($feature_id, $featurelocs) {
+
+  // if we don't have any featurelocs then no point in continuing
+  if (!$featurelocs) {
+    return array();
+  }
+
+  // get the list of relationships (including any aggregators) and iterate
+  // through each one to find information needed to color-code the reference sequence
+  $relationships = chado_get_feature_aggregate_relationships($feature_id);
+  if (!$relationships) {
+    return array();
+  }
+
+
+  // iterate through each of the realtionships features and get their
+  // locations
+  foreach ($relationships as $rindex => $rel) {
+    // get the featurelocs for each of the relationship features
+    $rel_featurelocs = chado_get_featurelocs($rel->subject_id, 'as_child', 0);
+    foreach ($rel_featurelocs as $rfindex => $rel_featureloc) {
+      // keep track of this unique source feature
+      $src = $rel_featureloc->src_feature_id . "-" . $rel_featureloc->src_cvterm_id;
+
+      // copy over the results to the relationship object.  Since there can
+      // be more than one feature location for each relationship feature we
+      // use the '$src' variable to keep track of these.
+      $rel->featurelocs = new stdClass();
+      $rel->featurelocs->$src = new stdClass();
+      $rel->featurelocs->$src->src_uniquename = $rel_featureloc->src_uniquename;
+      $rel->featurelocs->$src->src_cvterm_id  = $rel_featureloc->src_cvterm_id;
+      $rel->featurelocs->$src->src_cvname     = $rel_featureloc->src_cvname;
+      $rel->featurelocs->$src->fmin           = $rel_featureloc->fmin;
+      $rel->featurelocs->$src->fmax           = $rel_featureloc->fmax;
+      $rel->featurelocs->$src->src_name       = $rel_featureloc->src_name;
+
+      // keep track of the individual parts for each relationship
+      $start = $rel->featurelocs->$src->fmin;
+      $end   = $rel->featurelocs->$src->fmax;
+      $type  = $rel->subject_type;
+      $rel_locs[$src]['parts'][$start][$type]['start'] = $start;
+      $rel_locs[$src]['parts'][$start][$type]['end']   = $end;
+      $rel_locs[$src]['parts'][$start][$type]['type']  = $type;
+    }
+  }
+
+  // the featurelocs array provided to the function contains the locations
+  // where this feature is found.   We want to get the sequence for each
+  // location and then annotate it with the parts found from the relationships
+  // locations determiend above.
+  $floc_sequences = array();
+  foreach ($featurelocs as $featureloc) {
+
+    // build the src name so we can keep track of the different parts for each feature
+    $src = $featureloc->srcfeature_id->feature_id . "-" . $featureloc->srcfeature_id->type_id->cvterm_id;
+
+    // orient the parts to the beginning of the feature sequence
+    if (!empty($rel_locs[$src]['parts'])) {
+      $parts = $rel_locs[$src]['parts'];
+      $rparts = array();  // we will fill this up if we're on the reverse strand
+
+      foreach ($parts as $start => $types) {
+        foreach ($types as $type_name => $type) {
+          if ($featureloc->strand >= 0) {
+            // this is on the forward strand.  We need to convert the start on the src feature to the
+            // start on this feature's sequence
+            $parts[$start][$type_name]['start'] = $parts[$start][$type_name]['start'] - $featureloc->fmin;
+            $parts[$start][$type_name]['end']   = $parts[$start][$type_name]['end'] - $featureloc->fmin;
+            $parts[$start][$type_name]['type']  = $type_name;
+          }
+          else {
+            // this is on the reverse strand.  We need to swap the start and stop and calculate from the
+            // begining of the reverse sequence
+            $size = ($featureloc->fmax - $featureloc->fmin);
+            $start_orig = $parts[$start][$type_name]['start'];
+            $end_orig = $parts[$start][$type_name]['end'];
+            $new_start = $size - ($end_orig - $featureloc->fmin);
+            $new_end = $size - ($start_orig - $featureloc->fmin);
+
+            $rparts[$new_start][$type_name]['start'] = $new_start;
+            $rparts[$new_start][$type_name]['end']   = $new_end;
+            $rparts[$new_start][$type_name]['type']  = $type_name;
+          }
+        }
+      }
+
+      // now sort the parts
+      // if we're on the reverse strand we need to resort
+      if ($featureloc->strand >= 0) {
+        usort($parts, 'chado_feature__residues_sort_rel_parts_by_start');
+      }
+      else {
+        usort($rparts, 'chado_feature__residues_sort_rel_parts_by_start');
+        $parts = $rparts;
+      }
+
+      $floc_sequences[$src]['id'] = $src;
+      $floc_sequences[$src]['type'] = $featureloc->feature_id->type_id->name;
+      $args = array(':feature_id' => $featureloc->srcfeature_id->feature_id);
+      $start = $featureloc->fmin + 1;
+      $size = $featureloc->fmax - $featureloc->fmin;
+
+      // TODO: fix the hard coded $start and $size
+      // the $start and $size variables are hard-coded in the SQL statement
+      // because the db_query function places quotes around all placeholders
+      // (e.g. :start & :size) and screws up the substring function
+      $sql = "
+        SELECT substring(residues from $start for $size) as residues
+        FROM {feature}
+        WHERE feature_id = :feature_id
+      ";
+      $sequence = chado_query($sql, $args)->fetchObject();
+      $residues = $sequence->residues;
+      if ($featureloc->strand < 0) {
+        $residues = tripal_reverse_compliment_sequence($residues);
+      }
+      $strand = '.';
+      if ($featureloc->strand == 1) {
+        $strand = '+';
+      }
+      elseif ($featureloc->strand == -1) {
+        $strand = '-';
+      }
+      $floc_sequences[$src]['location'] = tripal_get_location_string($featureloc);
+      $floc_sequences[$src]['defline'] = tripal_get_fasta_defline($featureloc->feature_id, '', $featureloc, '', strlen($residues));
+      $floc_sequences[$src]['featureloc'] = $featureloc;
+      $floc_sequences[$src]['residues'] = $residues;
+      //$floc_sequences[$src]['formatted_seq'] =  tripal_feature_color_sequence($residues, $parts, $floc_sequences[$src]['defline']);
+    }
+  }
+  return $floc_sequences;
+}
+
+/**
+ * Get features related to the current feature to a given depth. Recursive function.
+ *
+ * @param $feature_id
+ * @param $substitute
+ * @param $levels
+ * @param $base_type_id
+ * @param $depth
+ *
+ */
+function chado_get_aggregate_feature_relationships($feature_id, $substitute=1,
+  $levels=0, $base_type_id=NULL, $depth=0) {
+
+  // we only want to recurse to as many levels deep as indicated by the
+  // $levels variable, but only if this variable is > 0. If 0 then we
+  // recurse until we reach the end of the relationships tree.
+  if ($levels > 0 and $levels == $depth) {
+    return NULL;
+  }
+
+  // first get the relationships for this feature
+  return chado_get_feature_relationships($feature_id, 'as_object');
+
+}
+
+/**
+ * Get the relationships for a feature.
+ *
+ * @param $feature_id
+ *   The feature to get relationships for
+ * @param $side
+ *   The side of the relationship this feature is (ie: 'as_subject' or 'as_object')
+ *
+ */
+function chado_get_feature_relationships($feature_id, $side = 'as_subject') {
+  // get the relationships for this feature.  The query below is used for both
+  // querying the object and subject relationships
+  $sql = "
+    SELECT
+    FS.name as subject_name, FS.uniquename as subject_uniquename,
+      CVTS.name as subject_type, CVTS.cvterm_id as subject_type_id,
+      FR.subject_id, FR.type_id as relationship_type_id, FR.object_id, FR.rank,
+      CVT.name as rel_type,
+      FO.name as object_name, FO.uniquename as object_uniquename,
+      CVTO.name as object_type, CVTO.cvterm_id as object_type_id
+    FROM {feature_relationship} FR
+     INNER JOIN {cvterm} CVT  ON FR.type_id    = CVT.cvterm_id
+     INNER JOIN {feature} FS  ON FS.feature_id = FR.subject_id
+     INNER JOIN {feature} FO  ON FO.feature_id = FR.object_id
+     INNER JOIN {cvterm} CVTO ON FO.type_id    = CVTO.cvterm_id
+     INNER JOIN {cvterm} CVTS ON FS.type_id    = CVTS.cvterm_id
+  ";
+  if (strcmp($side, 'as_object')==0) {
+    $sql .= " WHERE FR.object_id = :feature_id";
+  }
+  if (strcmp($side, 'as_subject')==0) {
+    $sql .= " WHERE FR.subject_id = :feature_id";
+  }
+  $sql .= " ORDER BY FR.rank";
+
+  // get the relationships
+  $results = chado_query($sql, array(':feature_id' => $feature_id));
+
+  // iterate through the relationships, put these in an array and add
+  // in the Drupal node id if one exists
+  $i=0;
+  $esql = "
+    SELECT entity_id
+    FROM {chado_entity}
+    WHERE data_table = 'feature' AND record_id = :feature_id";
+  $relationships = array();
+  while ($rel = $results->fetchObject()) {
+    $entity = db_query($esql, array(':feature_id' => $rel->subject_id))->fetchObject();
+    if ($entity) {
+      $rel->subject_entity_id = $entity->entity_id;
+    }
+    $entity = db_query($esql, array(':feature_id' => $rel->object_id))->fetchObject();
+    if ($entity) {
+      $rel->object_entity_id = $entity->entity_id;
+    }
+    $relationships[$i++] = $rel;
+  }
+  return $relationships;
+}
+
+/**
+ * Load the locations for a given feature
+ *
+ * @param $feature_id
+ *   The feature to look up locations for
+ * @param $side
+ *   Whether the feature is the scrfeature, 'as_parent', or feature, 'as_child'
+ * @param $aggregate
+ *   Whether or not to get the locations for related features
+ *
+ * @ingroup tripal_feature
+ */
+function chado_get_featurelocs($feature_id, $side = 'as_parent', $aggregate = 1) {
+
+  $sql = "
+    SELECT
+       F.name, F.feature_id, F.uniquename,
+       FS.name as src_name, FS.feature_id as src_feature_id, FS.uniquename as src_uniquename,
+       CVT.name as cvname, CVT.cvterm_id,
+       CVTS.name as src_cvname, CVTS.cvterm_id as src_cvterm_id,
+       FL.fmin, FL.fmax, FL.is_fmin_partial, FL.is_fmax_partial,FL.strand, FL.phase
+     FROM {featureloc} FL
+       INNER JOIN {feature} F   ON FL.feature_id = F.feature_id
+       INNER JOIN {feature} FS  ON FS.feature_id = FL.srcfeature_id
+       INNER JOIN {cvterm} CVT  ON F.type_id     = CVT.cvterm_id
+       INNER JOIN {cvterm} CVTS ON FS.type_id    = CVTS.cvterm_id
+       ";
+  if (strcmp($side, 'as_parent')==0) {
+    $sql .= "WHERE FL.srcfeature_id = :feature_id ";
+  }
+  if (strcmp($side, 'as_child')==0) {
+    $sql .= "WHERE FL.feature_id = :feature_id ";
+  }
+
+  $flresults = chado_query($sql, array(':feature_id' => $feature_id));
+
+  // copy the results into an array
+  $i=0;
+  $featurelocs = array();
+  while ($loc = $flresults->fetchObject()) {
+    // if a drupal node exists for this feature then add the nid to the
+    // results object
+
+    $loc->feid = tripal_get_chado_entity_id('feature', $loc->feature_id);
+    $loc->seid = tripal_get_chado_entity_id('feature', $loc->src_feature_id);
+    // add the result to the array
+    $featurelocs[$i++] = $loc;
+  }
+
+  // Add the relationship feature locs if aggregate is turned on
+  if ($aggregate and strcmp($side, 'as_parent')==0) {
+  // get the relationships for this feature without substituting any children
+  // for the parent. We want all relationships
+  $relationships = tripal_feature_get_aggregate_relationships($feature_id, 0);
+  foreach ($relationships as $rindex => $rel) {
+    // get the featurelocs for each of the relationship features
+    $rel_featurelocs = tripal_feature_load_featurelocs($rel->subject_id, 'as_child', 0);
+      foreach ($rel_featurelocs as $findex => $rfloc) {
+        $featurelocs[$i++] = $rfloc;
+      }
+    }
+  }
+
+  usort($featurelocs, 'chado_feature__residues_sort_locations');
+  return $featurelocs;
+}
+
+/**
+  * Used to sort the list of relationship parts by start position
+  *
+  * @ingroup tripal_feature
+  */
+function chado_feature__residues_sort_rel_parts_by_start($a, $b) {
+  foreach ($a as $type_name => $details) {
+    $astart = $a[$type_name]['start'];
+    break;
+  }
+  foreach ($b as $type_name => $details) {
+    $bstart = $b[$type_name]['start'];
+    break;
+  }
+  return strnatcmp($astart, $bstart);
+}
+/**
+ * Used to sort the feature locs by start position
+ *
+ * @param $a
+ *   One featureloc record (as an object)
+ * @param $b
+ *   The other featureloc record (as an object)
+ *
+ * @return
+ *   Which feature location comes first
+ *
+ * @ingroup tripal_feature
+ */
+function chado_feature__residues_sort_locations($a, $b) {
+  return strnatcmp($a->fmin, $b->fmin);
+}
+

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

@@ -397,7 +397,7 @@ function tripal_delete_mview($mview_id) {
   db_query($sql);
   db_query($sql);
 
 
   // does the table already exist?
   // does the table already exist?
-  $mview_exists = db_table_exists('chado.' . $mview->mv_table);
+  $mview_exists = chado_table_exists($mview->mv_table);
 
 
   // drop the table from chado if it exists
   // drop the table from chado if it exists
   if ($mview_exists) {
   if ($mview_exists) {

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

@@ -1394,9 +1394,9 @@ function chado_select_record($table, $columns, $values, $options = NULL) {
           // Ensure that there were results returned.
           // Ensure that there were results returned.
           elseif (count($results)==0) {
           elseif (count($results)==0) {
             tripal_report_error('tripal_chado', TRIPAL_ERROR,
             tripal_report_error('tripal_chado', TRIPAL_ERROR,
-              'chado_select_record: the foreign key definition for \'%field\' '.
+              'chado_select_record: the foreign key definition for \'%field\' on table \'%table\' '.
               'returned no results where the definition supplied was %value',
               'returned no results where the definition supplied was %value',
-              array('%field' => $field, '%value' => print_r($value, TRUE))
+              array('%field' => $field, '%table' => $table, '%value' => print_r($value, TRUE))
             );
             );
             return array();
             return array();
           }
           }

+ 39 - 9
tripal_chado/api/tripal_chado.schema.api.inc

@@ -38,22 +38,34 @@
  */
  */
 function chado_table_exists($table) {
 function chado_table_exists($table) {
   global $databases;
   global $databases;
-
   $default_db = $databases['default']['default']['database'];
   $default_db = $databases['default']['default']['database'];
-
+  $cached_obj = cache_get('chado_tables', 'cache');
+  $cached_tables = $cached_obj->data;
+  if (is_array($cached_tables) and array_key_exists($table, $cached_tables)) {
+    return $cached_tables[$table]['exists'];
+  }
   $sql = "
   $sql = "
     SELECT 1
     SELECT 1
     FROM information_schema.tables
     FROM information_schema.tables
     WHERE
     WHERE
       table_name = :table_name AND
       table_name = :table_name AND
-      table_schema = 'chado' AND
-      table_catalog = '$default_db'
+      table_schema = :chado AND
+      table_catalog = :default_db
   ";
   ";
-  $results = db_query($sql, array(':table_name' => $table));
+  $args = array(
+    ':table_name' => $table,
+    ':chado' => tripal_get_schema_name('chado'),
+    ':default_db' => $default_db
+  );
+  $results = db_query($sql, $args);
   $exists = $results->fetchObject();
   $exists = $results->fetchObject();
   if (!$exists) {
   if (!$exists) {
+    $cached_tables[$table]['exists'] = FALSE;
+    cache_set('chado_tables', $cached_tables, 'cache', CACHE_TEMPORARY);
     return FALSE;
     return FALSE;
   }
   }
+  $cached_tables[$table]['exists'] = TRUE;
+  cache_set('chado_tables', $cached_tables, 'cache', CACHE_TEMPORARY);
   return TRUE;
   return TRUE;
 }
 }
 /**
 /**
@@ -77,7 +89,13 @@ function chado_column_exists($table, $column) {
   global $databases;
   global $databases;
 
 
   $default_db = $databases['default']['default']['database'];
   $default_db = $databases['default']['default']['database'];
-
+  $cached_obj = cache_get('chado_table_columns', 'cache');
+  $cached_cols = $cached_obj->data;
+  if (is_array($cached_cols) and
+      array_key_exists($table, $cached_cols) and
+      array_key_Exists($column, $cached_cols[$table])) {
+    return $cached_cols[$table][$column]['exists'];
+  }
   $sql = "
   $sql = "
     SELECT 1
     SELECT 1
     FROM information_schema.columns
     FROM information_schema.columns
@@ -96,8 +114,12 @@ function chado_column_exists($table, $column) {
   $results = db_query($sql, $args);
   $results = db_query($sql, $args);
   $exists = $results->fetchField();
   $exists = $results->fetchField();
   if (!$exists) {
   if (!$exists) {
+    $cached_cols[$table][$column]['exists'] = FALSE;
+    cache_set('chado_table_columns', $cached_cols, 'cache', CACHE_TEMPORARY);
     return FALSE;
     return FALSE;
   }
   }
+  $cached_cols[$table][$column]['exists'] = TRUE;
+  cache_set('chado_table_columns', $cached_cols, 'cache', CACHE_TEMPORARY);
   return TRUE;
   return TRUE;
 }
 }
 
 
@@ -118,7 +140,11 @@ function chado_sequence_exists($sequence) {
   global $databases;
   global $databases;
 
 
   $default_db = $databases['default']['default']['database'];
   $default_db = $databases['default']['default']['database'];
-
+  $cached_obj = cache_get('chado_sequences', 'cache');
+  $cached_seqs = $cached_obj->data;
+  if (is_array($cached_seqs) and array_key_exists($sequence, $cached_seqs)) {
+    return $cached_seqs[$sequence]['exists'];
+  }
   $sql = "
   $sql = "
     SELECT 1
     SELECT 1
     FROM information_schema.sequences
     FROM information_schema.sequences
@@ -135,8 +161,12 @@ function chado_sequence_exists($sequence) {
   $results = db_query($sql, $args);
   $results = db_query($sql, $args);
   $exists = $results->fetchField();
   $exists = $results->fetchField();
   if (!$exists) {
   if (!$exists) {
+    $cached_seqs[$sequence]['exists'] = FALSE;
+    cache_set('chado_sequences', $cached_seqs, 'cache', CACHE_TEMPORARY);
     return FALSE;
     return FALSE;
   }
   }
+  $cached_seqs[$sequence]['exists'] = FALSE;
+  cache_set('chado_sequences', $cached_seqs, 'cache', CACHE_TEMPORARY);
   return TRUE;
   return TRUE;
 }
 }
 /**
 /**
@@ -314,12 +344,12 @@ function chado_get_version($exact = FALSE, $warn_if_unsupported = FALSE) {
     }
     }
     $is_local = 0;
     $is_local = 0;
     $previous_db = chado_set_active('chado');
     $previous_db = chado_set_active('chado');
-    $prop_exists = db_table_exists('chadoprop');
+    $prop_exists = chado_table_exists('chadoprop');
     chado_set_active($previous_db);
     chado_set_active($previous_db);
   }
   }
   else {
   else {
     $is_local = 1;
     $is_local = 1;
-    $prop_exists = db_table_exists('chado.chadoprop');
+    $prop_exists = chado_table_exists('chadoprop');
   }
   }
 
 
   // if the table doesn't exist then we don't know what version but we know
   // if the table doesn't exist then we don't know what version but we know

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

@@ -278,7 +278,10 @@ function chado_generate_var($table, $values, $base_options = array()) {
   $results = chado_select_record($table, $table_columns, $values, $base_options);
   $results = chado_select_record($table, $table_columns, $values, $base_options);
 
 
   if ($results) {
   if ($results) {
+
+    // Iterate through each result.
     foreach ($results as $key => $object) {
     foreach ($results as $key => $object) {
+
       // Add empty expandable_x arrays
       // Add empty expandable_x arrays
       $object->expandable_fields = $all->expandable_fields;
       $object->expandable_fields = $all->expandable_fields;
       $object->expandable_foreign_keys = $all->expandable_foreign_keys;
       $object->expandable_foreign_keys = $all->expandable_foreign_keys;
@@ -290,7 +293,7 @@ function chado_generate_var($table, $values, $base_options = array()) {
       // For Tripal v2 compatibility
       // For Tripal v2 compatibility
       // check if the current table maps to a node type-----------------------------------------------
       // check if the current table maps to a node type-----------------------------------------------
       // if this table is connected to a node there will be a chado_tablename table in drupal
       // if this table is connected to a node there will be a chado_tablename table in drupal
-      if (db_table_exists('chado_' . $table)) {
+      if (module_exists('tripal_core') and db_table_exists('chado_' . $table)) {
         // that has a foreign key to this one ($table_desc['primary key'][0]
         // that has a foreign key to this one ($table_desc['primary key'][0]
         // and to the node table (nid)
         // and to the node table (nid)
         $sql = "
         $sql = "

+ 4 - 4
tripal_chado/includes/TripalFields.old/chado_linker__expression.inc

@@ -22,7 +22,7 @@ class chado_linker__expression extends TripalField {
   // Set this to the name of the storage backend that by default will support
   // Set this to the name of the storage backend that by default will support
   // this field.
   // this field.
   public static $default_storage = 'field_chado_storage';
   public static $default_storage = 'field_chado_storage';
-  
+
   /**
   /**
    * @see TripalField::formatterView()
    * @see TripalField::formatterView()
    */
    */
@@ -154,7 +154,7 @@ class chado_linker__expression extends TripalField {
 
 
         // Add the linker_expressionprop
         // Add the linker_expressionprop
         $linkerprop_table =  $linker_table . 'prop';
         $linkerprop_table =  $linker_table . 'prop';
-        if (db_table_exists('chado.' . $linkerprop_table)) {
+        if (chado_table_exists($linkerprop_table)) {
           $exp_linker = chado_expand_var($exp_linker, 'table', $linkerprop_table, $options);
           $exp_linker = chado_expand_var($exp_linker, 'table', $linkerprop_table, $options);
           $exp_linkerprops = $exp_linker->feature_expressionprop;
           $exp_linkerprops = $exp_linker->feature_expressionprop;
           if ($exp_linkerprops) {
           if ($exp_linkerprops) {
@@ -174,12 +174,12 @@ class chado_linker__expression extends TripalField {
       }
       }
     }
     }
   }
   }
-  
+
   /**
   /**
    * We don't want a widget so override this function.
    * We don't want a widget so override this function.
    */
    */
   public static function widgetInfo() {
   public static function widgetInfo() {
     return array();
     return array();
   }
   }
-  
+
 }
 }

+ 13 - 12
tripal_chado/includes/TripalFields/chado_linker__contact_widget.inc

@@ -13,9 +13,10 @@ class chado_linker__contact_widget extends TripalFieldWidget {
    */
    */
   public function form(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) {
   public function form(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) {
     parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element);
     parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element);
+
     $entity = $form['#entity'];
     $entity = $form['#entity'];
     $field_name = $this->field['field_name'];
     $field_name = $this->field['field_name'];
-    
+
     // Get the FK column that links to the base table.
     // Get the FK column that links to the base table.
     $table_name = $this->field['settings']['chado_table'];
     $table_name = $this->field['settings']['chado_table'];
     $base_table = $this->field['settings']['base_table'];
     $base_table = $this->field['settings']['base_table'];
@@ -23,13 +24,13 @@ class chado_linker__contact_widget extends TripalFieldWidget {
     $pkey = $schema['primary key'][0];
     $pkey = $schema['primary key'][0];
     $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
     $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
     $fkey = $fkeys[0];
     $fkey = $fkeys[0];
-    
+
     // Get the field defaults.
     // Get the field defaults.
     $record_id = '';
     $record_id = '';
     $fkey_value = $element['#entity']->chado_record_id;
     $fkey_value = $element['#entity']->chado_record_id;
     $contact_id = '';
     $contact_id = '';
     $name = '';
     $name = '';
-    
+
     // If the field already has a value then it will come through the $items
     // If the field already has a value then it will come through the $items
     // array.  This happens when editing an existing record.
     // array.  This happens when editing an existing record.
     if (count($items) > 0 and array_key_exists($delta, $items)) {
     if (count($items) > 0 and array_key_exists($delta, $items)) {
@@ -40,20 +41,20 @@ class chado_linker__contact_widget extends TripalFieldWidget {
         $name = $contact->name;
         $name = $contact->name;
       }
       }
     }
     }
-    
+
     $schema = chado_get_schema('contact');
     $schema = chado_get_schema('contact');
-    
+
     $widget['#table_name'] = $table_name;
     $widget['#table_name'] = $table_name;
     $widget['#fkey_field'] = $fkey;
     $widget['#fkey_field'] = $fkey;
     $widget['#theme'] = 'chado_linker__contact_widget';
     $widget['#theme'] = 'chado_linker__contact_widget';
     $widget['#prefix'] =  "<span id='$table_name-$delta'>";
     $widget['#prefix'] =  "<span id='$table_name-$delta'>";
     $widget['#suffix'] =  "</span>";
     $widget['#suffix'] =  "</span>";
-    
+
     $widget['value'] = array(
     $widget['value'] = array(
       '#type' => 'value',
       '#type' => 'value',
       '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
       '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
     );
     );
-    
+
     $widget['chado-' . $table_name . '__' . $pkey] = array(
     $widget['chado-' . $table_name . '__' . $pkey] = array(
       '#type' => 'value',
       '#type' => 'value',
       '#default_value' => $record_id,
       '#default_value' => $record_id,
@@ -66,7 +67,7 @@ class chado_linker__contact_widget extends TripalFieldWidget {
       '#type' => 'value',
       '#type' => 'value',
       '#default_value' => $contact_id,
       '#default_value' => $contact_id,
     );
     );
-    
+
     $widget['name'] = array(
     $widget['name'] = array(
       '#type' => 'textfield',
       '#type' => 'textfield',
       '#title' => t('Contact'),
       '#title' => t('Contact'),
@@ -110,19 +111,19 @@ class chado_linker__contact_widget extends TripalFieldWidget {
     $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
     $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
     $fkey = $fkeys[0];
     $fkey = $fkeys[0];
     $field_name = $this->field['field_name'];
     $field_name = $this->field['field_name'];
-    
+
     // Get the field values.
     // Get the field values.
     $fkey_value = isset($form_state['values'][$field_name][$langcode][$delta]['value']) ? $form_state['values'][$field_name][$langcode][$delta]['value'] : '';
     $fkey_value = isset($form_state['values'][$field_name][$langcode][$delta]['value']) ? $form_state['values'][$field_name][$langcode][$delta]['value'] : '';
     $contact_id = isset($form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__contact_id']) ? $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__contact_id'] : '';
     $contact_id = isset($form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__contact_id']) ? $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__contact_id'] : '';
     $name = isset($form_state['values'][$field_name][$langcode][$delta]['name']) ? $form_state['values'][$field_name][$langcode][$delta]['name'] : '';
     $name = isset($form_state['values'][$field_name][$langcode][$delta]['name']) ? $form_state['values'][$field_name][$langcode][$delta]['name'] : '';
-    
+
     // If the user provided a name then we want to set the foreign key
     // If the user provided a name then we want to set the foreign key
     // value to be the chado_record_id
     // value to be the chado_record_id
     if ($name and !$contact_id) {
     if ($name and !$contact_id) {
       $contact = chado_generate_var('contact', array('name' => $name));
       $contact = chado_generate_var('contact', array('name' => $name));
       $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__contact_id'] = $contact->contact_id;
       $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__contact_id'] = $contact->contact_id;
     }
     }
-    
+
     // In the widgetForm function we automatically add the foreign key
     // In the widgetForm function we automatically add the foreign key
     // record.  But if the user did not provide a contact we want to take
     // record.  But if the user did not provide a contact we want to take
     // it out so that the Chado field_storage infrastructure won't try to
     // it out so that the Chado field_storage infrastructure won't try to
@@ -130,7 +131,7 @@ class chado_linker__contact_widget extends TripalFieldWidget {
     if (!$name and !$contact_id) {
     if (!$name and !$contact_id) {
       $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__' . $fkey] = '';
       $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__' . $fkey] = '';
     }
     }
-    
+
     // If the user removed the contact from the contact_name field
     // If the user removed the contact from the contact_name field
     // then we want to clear out the rest of the hidden values.
     // then we want to clear out the rest of the hidden values.
     // Leave the primary key so the record can be deleted.
     // Leave the primary key so the record can be deleted.

+ 81 - 0
tripal_chado/includes/TripalFields/data__protein_sequence.inc

@@ -0,0 +1,81 @@
+<?php
+
+class data__protein_sequence extends TripalField {
+
+
+  // --------------------------------------------------------------------------
+  //                     EDITABLE STATIC CONSTANTS
+  //
+  // The following constants SHOULD be set for each descendent class.  They are
+  // used by the static functions to provide information to Drupal about
+  // the field and it's default widget and formatter.
+  // --------------------------------------------------------------------------
+
+  // The term that this field maps to.  The format for the term should be:
+  // [vocab]:[accession] where [vocab] is the short name of the vocabulary
+  // and [acession] is the unique accession number for the term.  This term
+  // must already exist in the vocabulary storage backend. This
+  // value should never be changed once fields exist for this type.
+  public static $term = 'data:2976';
+
+  // The default lable for this field.
+  public static $label = 'Protein Sequence';
+
+  // The default description for this field.
+  public static $description = 'polypeptide sequences.';
+
+  // Provide a list of global settings. These can be accessed witihn the
+  // globalSettingsForm.  When the globalSettingsForm is submitted then
+  // Drupal will automatically change these settings for all fields.
+  public static $settings = array(
+    'chado_table' => '',
+    'chado_column' => '',
+    'base_table' => '',
+  );
+
+  // Provide a list of instance specific settings. These can be access within
+  // the instanceSettingsForm.  When the instanceSettingsForm is submitted
+  // then Drupal with automatically change these settings for the instnace.
+  // It is recommended to put settings at the instance level whenever possible.
+  public static $instance_settings  = array();
+
+  // Set this to the name of the storage backend that by default will support
+  // this field.
+  public static $storage = 'tripal_no_storage';
+
+  // The default widget for this field.
+  public static $default_widget = 'data__protein_sequence_widget';
+
+  // The default formatter for this field.
+  public static $default_formatter = 'data__protein_sequence_formatter';
+
+
+  /**
+   * @see TripalField::load()
+   */
+  public function load($entity, $details = array()) {
+    $field_name = $this->field['field_name'];
+    $feature = $details['record'];
+    $num_seqs = 0;
+
+    // Look for Protein sequences
+    $sql = "
+      SELECT F.*
+      FROM {feature_relationship} FR
+        INNER JOIN {feature} F on FR.subject_id = F.feature_id
+        INNER JOIN {cvterm} CVT on CVT.cvterm_id = F.type_id
+        INNER JOIN {cvterm} RCVT on RCVT.cvterm_id = FR.type_id
+      WHERE
+        FR.object_id = :feature_id and
+        CVT.name = 'polypeptide' and
+        RCVT.name = 'derives_from'
+      ORDER BY FR.rank ASC
+    ";
+    $results = chado_query($sql, array(':feature_id' => $feature->feature_id));
+    while ($protein = $results->fetchObject()) {
+      if ($protein->residues) {
+        $entity->{$field_name}['und'][$num_seqs++]['value'] = $protein->residues;
+      }
+    }
+  }
+}

+ 50 - 0
tripal_chado/includes/TripalFields/data__protein_sequence_formatter.inc

@@ -0,0 +1,50 @@
+<?php
+
+class data__protein_sequence_formatter extends TripalFieldFormatter {
+  // The default lable for this field.
+  public static $label = 'Protein Sequence';
+
+  // The list of field types for which this formatter is appropriate.
+  public static $field_types = array('data__protein_sequence');
+
+  // The list of default settings for this formatter.
+  public static $settings = array();
+
+  /**
+   *
+   * @param unknown $element
+   * @param unknown $entity_type
+   * @param unknown $entity
+   * @param unknown $langcode
+   * @param unknown $items
+   * @param unknown $display
+   */
+  public function view(&$element, $entity_type, $entity, $langcode, $items, $display) {
+    $element[0] = array(
+      // We create a render array to produce the desired markup,
+      '#type' => 'markup',
+      '#markup' => '',
+    );
+
+    $num_bases = 50;
+    foreach ($items as $delta => $item) {
+      // If there are no residues then skip this one.
+      if (!is_array($item['value']) or !array_key_exists('residues', $item['value'])) {
+        continue;
+      }
+
+      $residues = $item['value']['residues'];
+
+      $content .= '<pre class="residues-formatter">';
+      $content .= '>' . $defline . "<br>";
+      $content .= wordwrap($residues, $num_bases, "<br>", TRUE);
+      $content .= '</pre>';
+
+      $element[$delta] = array(
+        // We create a render array to produce the desired markup,
+        '#type' => 'markup',
+        '#markup' => $content,
+      );
+    }
+  }
+}

+ 43 - 0
tripal_chado/includes/TripalFields/data__protein_sequence_widget.inc

@@ -0,0 +1,43 @@
+<?php
+
+class data__protein_sequence_widget extends TripalFieldWidget {
+  // The default lable for this field.
+  public static $label = 'Protein Sequence';
+
+  // The list of field types for which this formatter is appropriate.
+  public static $field_types = array('data__protein_sequence');
+
+  /**
+   *
+   * @see TripalFieldWidget::form()
+   */
+  public function form(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) {
+    parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element);
+
+    // TODO: add the form for setting a protein sequence.
+  }
+
+  /**
+   * Performs validation of the widgetForm.
+   *
+   * Use this validate to ensure that form values are entered correctly.  Note
+   * this is different from the validate() function which ensures that the
+   * field data meets expectations.
+   *
+   * @param $form
+   * @param $form_state
+   */
+  public function validate($form, &$form_state, $entity_type, $entity, $langcode, $delta) {
+
+  }
+
+
+  /**
+   *
+   * @see TripalFieldWidget::submit()
+   */
+  public function submit($form, &$form_state, $entity_type, $entity, $langcode, $delta) {
+    $field_name = $this->field['field_name'];
+
+  }
+}

+ 90 - 477
tripal_chado/includes/TripalFields/data__sequence.inc

@@ -49,103 +49,42 @@ class data__sequence extends TripalField {
   // The default formatter for this field.
   // The default formatter for this field.
   public static $default_formatter = 'data__sequence_formatter';
   public static $default_formatter = 'data__sequence_formatter';
 
 
-  // --------------------------------------------------------------------------
-  //              PROTECTED CLASS MEMBERS -- DO NOT OVERRIDE
-  // --------------------------------------------------------------------------
-  // An array containing details about the field. The format of this array
-  // is the same as that returned by field_info_fields()
-  protected $field;
-  // An array containing details about an instance of the field. A field does
-  // not have to have an instance.  But if dealing with an instance (such as
-  // when using the widgetForm, formatterSettingsForm, etc.) it should be set.
-  protected $instance;
-
+  /**
+   * @see TripalField::load()
+   */
   public function load($entity, $details = array()) {
   public function load($entity, $details = array()) {
     $field_name = $this->field['field_name'];
     $field_name = $this->field['field_name'];
     $feature = $details['record'];
     $feature = $details['record'];
-    $num_seqs = 0;
-    
+
     // We don't want to get the sequence for traditionally large types. They are
     // We don't want to get the sequence for traditionally large types. They are
     // too big,  bog down the web browser, take longer to load and it's not
     // too big,  bog down the web browser, take longer to load and it's not
     // reasonable to print them on a page.
     // reasonable to print them on a page.
-    if(strcmp($feature->type_id->name,'scaffold') == 0 or
-        strcmp($feature->type_id->name,'chromosome') == 0 or
-        strcmp($feature->type_id->name,'supercontig') == 0 or
-        strcmp($feature->type_id->name,'pseudomolecule') == 0) {
-          $entity->{$field_name}['und'][$num_seqs]['value'] = array(
-            '@type' => 'SO:0000110',
-            'type' => 'sequence_feature',
-            'label' => 'Residues',
-            'defline' => ">This sequence is too large for this display.",
-            'residues' => '',
-          );
-          $entity->{$field_name}['und'][$num_seqs]['chado-feature__residues'] = '';
-        }
-        else {
-          $feature = chado_expand_var($feature,'field','feature.residues');
-          if ($feature->residues) {
-            $entity->{$field_name}['und'][$num_seqs]['value'] = array(
-              '@type' => 'SO:0000110',
-              'type' => 'sequence_feature',
-              'label' => 'Raw Sequence',
-              'defline' => tripal_get_fasta_defline($feature, '', NULL, '', strlen($feature->residues)),
-              'residues' => $feature->residues,
-            );
-            $entity->{$field_name}['und'][$num_seqs]['chado-feature__residues'] = $feature->residues;
-          }
-          else {
-            $entity->{$field_name}['und'][$num_seqs]['value'] = array();
-            $entity->{$field_name}['und'][$num_seqs]['chado-feature__residues'] = '';
-          }
-        }
-        $num_seqs++;
-    
-        // Add in the protein sequences. It's faster to provide the SQL rather than
-        // to use chado_generate_var based on the type.
-        $sql = "
-      SELECT F.*
-      FROM {feature_relationship} FR
-        INNER JOIN {feature} F on FR.subject_id = F.feature_id
-        INNER JOIN {cvterm} CVT on CVT.cvterm_id = F.type_id
-        INNER JOIN {cvterm} RCVT on RCVT.cvterm_id = FR.type_id
-      WHERE
-        FR.object_id = :feature_id and
-        CVT.name = 'polypeptide' and
-        RCVT.name = 'derives_from'
-      ORDER BY FR.rank ASC
-    ";
-        $results = chado_query($sql, array(':feature_id' => $feature->feature_id));
-        while ($protein = $results->fetchObject()) {
-          if ($protein->residues) {
-            $entity->{$field_name}['und'][$num_seqs++]['value'] = array(
-              '@type' => 'SO:0000104',
-              'type' => 'polypeptide',
-              'label' => 'Protein Sequence',
-              'defline' => tripal_get_fasta_defline($protein, '', NULL, '', strlen($protein->residues)),
-              'residues' => $protein->residues,
-            );
-          }
-        }
-    
-    
-        // Add in sequences from alignments.
-        $options = array(
-          'return_array' => 1,
-          'include_fk' => array(
-            'srcfeature_id' => array(
-              'type_id' => 1
-            ),
-            'feature_id' => array(
-              'type_id' => 1
-            ),
-          ),
-        );
-        $feature = chado_expand_var($feature, 'table', 'featureloc', $options);
-        $featureloc_sequences = $this->get_featureloc_sequences($feature->feature_id, $feature->featureloc->feature_id);
-    
-        // Add in the coding sequences. It's faster to provide the SQL rather than
-        // to use chado_generate_var based on the type.
-        $sql = "
+    if(strcmp($feature->type_id->name,'scaffold') != 0 and
+       strcmp($feature->type_id->name,'chromosome') != 0 and
+       strcmp($feature->type_id->name,'supercontig') != 0 and
+       strcmp($feature->type_id->name,'pseudomolecule') != 0) {
+      $feature = chado_expand_var($feature,'field','feature.residues');
+      $entity->{$field_name}['und'][0]['value'] = $feature->residues;
+    }
+
+ /*    // Add in sequences from alignments.
+    $options = array(
+      'return_array' => 1,
+      'include_fk' => array(
+        'srcfeature_id' => array(
+          'type_id' => 1
+        ),
+        'feature_id' => array(
+          'type_id' => 1
+        ),
+      ),
+    );
+    $feature = chado_expand_var($feature, 'table', 'featureloc', $options);
+    $featureloc_sequences = $this->get_featureloc_sequences($feature->feature_id, $feature->featureloc->feature_id);
+
+    // Add in the coding sequences. It's faster to provide the SQL rather than
+    // to use chado_generate_var based on the type.
+    $sql = "
       SELECT F.*
       SELECT F.*
       FROM {feature_relationship} FR
       FROM {feature_relationship} FR
         INNER JOIN {feature} F on FR.subject_id = F.feature_id
         INNER JOIN {feature} F on FR.subject_id = F.feature_id
@@ -158,398 +97,72 @@ class data__sequence extends TripalField {
         RCVT.name = 'part_of'
         RCVT.name = 'part_of'
       ORDER BY FR.rank ASC
       ORDER BY FR.rank ASC
     ";
     ";
-        $results = chado_query($sql, array(':feature_id' => $feature->feature_id));
-        $coding_seq = '';
-        while ($CDS = $results->fetchObject()) {
-          if ($CDS->residues) {
-            $coding_seq .= $CDS->residues;
-          }
-        }
-        if ($coding_seq) {
+    $results = chado_query($sql, array(':feature_id' => $feature->feature_id));
+    $coding_seq = '';
+    while ($CDS = $results->fetchObject()) {
+      if ($CDS->residues) {
+        $coding_seq .= $CDS->residues;
+      }
+    }
+    if ($coding_seq) {
+      $entity->{$field_name}['und'][$num_seqs++]['value'] = array(
+        '@type' => 'SO:0000316',
+        'type' => 'coding_sequence',
+        'label' => 'Coding sequence (CDS)',
+        'defline' => tripal_get_fasta_defline($feature, 'CDS', NULL, '', strlen($coding_seq)),
+        'residues' => $coding_seq,
+      );
+    }
+
+    foreach($featureloc_sequences as $src => $attrs){
+      // the $attrs array has the following keys
+      //   * id:  a unique identifier combining the feature id with the cvterm id
+      //   * type: the type of sequence (e.g. mRNA, etc)
+      //   * location:  the alignment location
+      //   * defline: the definition line
+      //   * formatted_seq: the formatted sequences
+      //   * featureloc:  the feature object aligned to
+      $entity->{$field_name}['und'][$num_seqs++]['value'] = array(
+        'residues' => $attrs['residues'],
+        '@type' => 'SO:0000110',
+        'type' => 'sequence_feature',
+        'defline' => tripal_get_fasta_defline($feature, '', $attrs['featureloc'], 'CDS', strlen($attrs['residues'])),
+        'label' => 'Sequence from alignment at ' . $attrs['location'],
+      );
+
+
+      // check to see if this alignment has any CDS. If so, generate a CDS sequence
+      $cds_sequence = tripal_get_feature_sequences(
+          array(
+            'feature_id' => $feature->feature_id,
+            'parent_id' => $attrs['featureloc']->srcfeature_id->feature_id,
+            'name' => $feature->name,
+            'featureloc_id' => $attrs['featureloc']->featureloc_id,
+          ),
+          array(
+            'derive_from_parent' => 1, // CDS are in parent-child relationships so we want to use the sequence from the parent
+            'aggregate' => 1, // we want to combine all CDS for this feature into a single sequence
+            'sub_feature_types' => array('CDS'), // we're looking for CDS features
+            'is_html' => 0
+          )
+          );
+
+      if (count($cds_sequence) > 0) {
+        // the tripal_get_feature_sequences() function can return multiple sequences
+        // if a feature is aligned to multiple places. In the case of CDSs we expect
+        // that one mRNA is only aligned to a single location on the assembly so we
+        // can access the CDS sequence with index 0.
+        if ($cds_sequence[0]['residues']) {
           $entity->{$field_name}['und'][$num_seqs++]['value'] = array(
           $entity->{$field_name}['und'][$num_seqs++]['value'] = array(
+            'residues' => $cds_sequence[0]['residues'],
             '@type' => 'SO:0000316',
             '@type' => 'SO:0000316',
             'type' => 'coding_sequence',
             'type' => 'coding_sequence',
-            'label' => 'Coding sequence (CDS)',
-            'defline' => tripal_get_fasta_defline($feature, 'CDS', NULL, '', strlen($coding_seq)),
-            'residues' => $coding_seq,
+            'defline' => tripal_get_fasta_defline($feature, '', $attrs['featureloc'], 'CDS', $cds_sequence[0]['length']),
+            'label' => 'Coding sequence (CDS) from alignment at  ' . $attrs['location'],
           );
           );
         }
         }
-    
-        foreach($featureloc_sequences as $src => $attrs){
-          // the $attrs array has the following keys
-          //   * id:  a unique identifier combining the feature id with the cvterm id
-          //   * type: the type of sequence (e.g. mRNA, etc)
-          //   * location:  the alignment location
-          //   * defline: the definition line
-          //   * formatted_seq: the formatted sequences
-          //   * featureloc:  the feature object aligned to
-          $entity->{$field_name}['und'][$num_seqs++]['value'] = array(
-            'residues' => $attrs['residues'],
-            '@type' => 'SO:0000110',
-            'type' => 'sequence_feature',
-            'defline' => tripal_get_fasta_defline($feature, '', $attrs['featureloc'], 'CDS', strlen($attrs['residues'])),
-            'label' => 'Sequence from alignment at ' . $attrs['location'],
-          );
-    
-    
-          // check to see if this alignment has any CDS. If so, generate a CDS sequence
-          $cds_sequence = tripal_get_feature_sequences(
-              array(
-                'feature_id' => $feature->feature_id,
-                'parent_id' => $attrs['featureloc']->srcfeature_id->feature_id,
-                'name' => $feature->name,
-                'featureloc_id' => $attrs['featureloc']->featureloc_id,
-              ),
-              array(
-                'derive_from_parent' => 1, // CDS are in parent-child relationships so we want to use the sequence from the parent
-                'aggregate' => 1, // we want to combine all CDS for this feature into a single sequence
-                'sub_feature_types' => array('CDS'), // we're looking for CDS features
-                'is_html' => 0
-              )
-              );
-    
-          if (count($cds_sequence) > 0) {
-            // the tripal_get_feature_sequences() function can return multiple sequences
-            // if a feature is aligned to multiple places. In the case of CDSs we expect
-            // that one mRNA is only aligned to a single location on the assembly so we
-            // can access the CDS sequence with index 0.
-            if ($cds_sequence[0]['residues']) {
-              $entity->{$field_name}['und'][$num_seqs++]['value'] = array(
-                'residues' => $cds_sequence[0]['residues'],
-                '@type' => 'SO:0000316',
-                'type' => 'coding_sequence',
-                'defline' => tripal_get_fasta_defline($feature, '', $attrs['featureloc'], 'CDS', $cds_sequence[0]['length']),
-                'label' => 'Coding sequence (CDS) from alignment at  ' . $attrs['location'],
-              );
-            }
-          }
-        }
-  }
-  
-  /**
-   *
-   * @param unknown $feature_id
-   * @param unknown $featurelocs
-   * @return multitype:|Ambigous <multitype:, an>
-   */
-  private function get_featureloc_sequences($feature_id, $featurelocs) {
-  
-    // if we don't have any featurelocs then no point in continuing
-    if (!$featurelocs) {
-      return array();
-    }
-  
-    // get the list of relationships (including any aggregators) and iterate
-    // through each one to find information needed to color-code the reference sequence
-    $relationships = $this->get_aggregate_relationships($feature_id);
-    if (!$relationships) {
-      return array();
-    }
-  
-  
-    // iterate through each of the realtionships features and get their
-    // locations
-    foreach ($relationships as $rindex => $rel) {
-      // get the featurelocs for each of the relationship features
-      $rel_featurelocs = $this->get_featurelocs($rel->subject_id, 'as_child', 0);
-      foreach ($rel_featurelocs as $rfindex => $rel_featureloc) {
-        // keep track of this unique source feature
-        $src = $rel_featureloc->src_feature_id . "-" . $rel_featureloc->src_cvterm_id;
-  
-        // copy over the results to the relationship object.  Since there can
-        // be more than one feature location for each relationship feature we
-        // use the '$src' variable to keep track of these.
-        $rel->featurelocs = new stdClass();
-        $rel->featurelocs->$src = new stdClass();
-        $rel->featurelocs->$src->src_uniquename = $rel_featureloc->src_uniquename;
-        $rel->featurelocs->$src->src_cvterm_id  = $rel_featureloc->src_cvterm_id;
-        $rel->featurelocs->$src->src_cvname     = $rel_featureloc->src_cvname;
-        $rel->featurelocs->$src->fmin           = $rel_featureloc->fmin;
-        $rel->featurelocs->$src->fmax           = $rel_featureloc->fmax;
-        $rel->featurelocs->$src->src_name       = $rel_featureloc->src_name;
-  
-        // keep track of the individual parts for each relationship
-        $start = $rel->featurelocs->$src->fmin;
-        $end   = $rel->featurelocs->$src->fmax;
-        $type  = $rel->subject_type;
-        $rel_locs[$src]['parts'][$start][$type]['start'] = $start;
-        $rel_locs[$src]['parts'][$start][$type]['end']   = $end;
-        $rel_locs[$src]['parts'][$start][$type]['type']  = $type;
-      }
-    }
-  
-    // the featurelocs array provided to the function contains the locations
-    // where this feature is found.   We want to get the sequence for each
-    // location and then annotate it with the parts found from the relationships
-    // locations determiend above.
-    $floc_sequences = array();
-    foreach ($featurelocs as $featureloc) {
-  
-      // build the src name so we can keep track of the different parts for each feature
-      $src = $featureloc->srcfeature_id->feature_id . "-" . $featureloc->srcfeature_id->type_id->cvterm_id;
-  
-      // orient the parts to the beginning of the feature sequence
-      if (!empty($rel_locs[$src]['parts'])) {
-        $parts = $rel_locs[$src]['parts'];
-        $rparts = array();  // we will fill this up if we're on the reverse strand
-  
-        foreach ($parts as $start => $types) {
-          foreach ($types as $type_name => $type) {
-            if ($featureloc->strand >= 0) {
-              // this is on the forward strand.  We need to convert the start on the src feature to the
-              // start on this feature's sequence
-              $parts[$start][$type_name]['start'] = $parts[$start][$type_name]['start'] - $featureloc->fmin;
-              $parts[$start][$type_name]['end']   = $parts[$start][$type_name]['end'] - $featureloc->fmin;
-              $parts[$start][$type_name]['type']  = $type_name;
-            }
-            else {
-              // this is on the reverse strand.  We need to swap the start and stop and calculate from the
-              // begining of the reverse sequence
-              $size = ($featureloc->fmax - $featureloc->fmin);
-              $start_orig = $parts[$start][$type_name]['start'];
-              $end_orig = $parts[$start][$type_name]['end'];
-              $new_start = $size - ($end_orig - $featureloc->fmin);
-              $new_end = $size - ($start_orig - $featureloc->fmin);
-  
-              $rparts[$new_start][$type_name]['start'] = $new_start;
-              $rparts[$new_start][$type_name]['end']   = $new_end;
-              $rparts[$new_start][$type_name]['type']  = $type_name;
-            }
-          }
-        }
-  
-        // now sort the parts
-        // if we're on the reverse strand we need to resort
-        if ($featureloc->strand >= 0) {
-          usort($parts, 'chado_feature__residues_sort_rel_parts_by_start');
-        }
-        else {
-          usort($rparts, 'chado_feature__residues_sort_rel_parts_by_start');
-          $parts = $rparts;
-        }
-  
-        $floc_sequences[$src]['id'] = $src;
-        $floc_sequences[$src]['type'] = $featureloc->feature_id->type_id->name;
-        $args = array(':feature_id' => $featureloc->srcfeature_id->feature_id);
-        $start = $featureloc->fmin + 1;
-        $size = $featureloc->fmax - $featureloc->fmin;
-  
-        // TODO: fix the hard coded $start and $size
-        // the $start and $size variables are hard-coded in the SQL statement
-        // because the db_query function places quotes around all placeholders
-        // (e.g. :start & :size) and screws up the substring function
-        $sql = "
-        SELECT substring(residues from $start for $size) as residues
-        FROM {feature}
-        WHERE feature_id = :feature_id
-        ";
-        $sequence = chado_query($sql, $args)->fetchObject();
-        $residues = $sequence->residues;
-        if ($featureloc->strand < 0) {
-          $residues = tripal_reverse_compliment_sequence($residues);
-        }
-        $strand = '.';
-        if ($featureloc->strand == 1) {
-          $strand = '+';
-        }
-        elseif ($featureloc->strand == -1) {
-          $strand = '-';
-        }
-        $floc_sequences[$src]['location'] = tripal_get_location_string($featureloc);
-        $floc_sequences[$src]['defline'] = tripal_get_fasta_defline($featureloc->feature_id, '', $featureloc, '', strlen($residues));
-        $floc_sequences[$src]['featureloc'] = $featureloc;
-        $floc_sequences[$src]['residues'] = $residues;
-        //$floc_sequences[$src]['formatted_seq'] =  tripal_feature_color_sequence($residues, $parts, $floc_sequences[$src]['defline']);
-      }
-    }
-    return $floc_sequences;
-  }
-  
-  /**
-   * Get features related to the current feature to a given depth. Recursive function.
-   *
-   * @param $feature_id
-   * @param $substitute
-   * @param $levels
-   * @param $base_type_id
-   * @param $depth
-   *
-   * @ingroup tripal_feature
-   */
-  private function get_aggregate_relationships($feature_id, $substitute=1,
-      $levels=0, $base_type_id=NULL, $depth=0) {
-  
-        // we only want to recurse to as many levels deep as indicated by the
-        // $levels variable, but only if this variable is > 0. If 0 then we
-        // recurse until we reach the end of the relationships tree.
-        if ($levels > 0 and $levels == $depth) {
-          return NULL;
-        }
-  
-        // first get the relationships for this feature
-        return $this->get_relationships($feature_id, 'as_object');
-  
-  }
-  
-  /**
-   * Get the relationships for a feature.
-   *
-   * @param $feature_id
-   *   The feature to get relationships for
-   * @param $side
-   *   The side of the relationship this feature is (ie: 'as_subject' or 'as_object')
-   *
-   * @ingroup tripal_feature
-   */
-  private function get_relationships($feature_id, $side = 'as_subject') {
-    // get the relationships for this feature.  The query below is used for both
-    // querying the object and subject relationships
-    $sql = "
-    SELECT
-      FS.name as subject_name, FS.uniquename as subject_uniquename,
-      CVTS.name as subject_type, CVTS.cvterm_id as subject_type_id,
-      FR.subject_id, FR.type_id as relationship_type_id, FR.object_id, FR.rank,
-      CVT.name as rel_type,
-      FO.name as object_name, FO.uniquename as object_uniquename,
-      CVTO.name as object_type, CVTO.cvterm_id as object_type_id
-    FROM {feature_relationship} FR
-     INNER JOIN {cvterm} CVT  ON FR.type_id    = CVT.cvterm_id
-     INNER JOIN {feature} FS  ON FS.feature_id = FR.subject_id
-     INNER JOIN {feature} FO  ON FO.feature_id = FR.object_id
-     INNER JOIN {cvterm} CVTO ON FO.type_id    = CVTO.cvterm_id
-     INNER JOIN {cvterm} CVTS ON FS.type_id    = CVTS.cvterm_id
-  ";
-    if (strcmp($side, 'as_object')==0) {
-      $sql .= " WHERE FR.object_id = :feature_id";
-    }
-    if (strcmp($side, 'as_subject')==0) {
-      $sql .= " WHERE FR.subject_id = :feature_id";
-    }
-    $sql .= " ORDER BY FR.rank";
-  
-    // get the relationships
-    $results = chado_query($sql, array(':feature_id' => $feature_id));
-  
-  
-    // iterate through the relationships, put these in an array and add
-    // in the Drupal node id if one exists
-    $i=0;
-    $esql = "
-        SELECT entity_id
-        FROM {chado_entity}
-        WHERE data_table = 'feature' AND record_id = :feature_id";
-    $relationships = array();
-    while ($rel = $results->fetchObject()) {
-      $entity = db_query($esql, array(':feature_id' => $rel->subject_id))->fetchObject();
-      if ($entity) {
-        $rel->subject_entity_id = $entity->entity_id;
-      }
-      $entity = db_query($esql, array(':feature_id' => $rel->object_id))->fetchObject();
-      if ($entity) {
-        $rel->object_entity_id = $entity->entity_id;
       }
       }
-      $relationships[$i++] = $rel;
-    }
-    return $relationships;
-  }
-  
-  /**
-   * Load the locations for a given feature
-   *
-   * @param $feature_id
-   *   The feature to look up locations for
-   * @param $side
-   *   Whether the feature is the scrfeature, 'as_parent', or feature, 'as_child'
-   * @param $aggregate
-   *   Whether or not to get the locations for related features
-   *
-   * @ingroup tripal_feature
-   */
-  private function get_featurelocs($feature_id, $side = 'as_parent', $aggregate = 1) {
-  
-    $sql = "
-    SELECT
-       F.name, F.feature_id, F.uniquename,
-       FS.name as src_name, FS.feature_id as src_feature_id, FS.uniquename as src_uniquename,
-       CVT.name as cvname, CVT.cvterm_id,
-       CVTS.name as src_cvname, CVTS.cvterm_id as src_cvterm_id,
-       FL.fmin, FL.fmax, FL.is_fmin_partial, FL.is_fmax_partial,FL.strand, FL.phase
-     FROM {featureloc} FL
-       INNER JOIN {feature} F   ON FL.feature_id = F.feature_id
-       INNER JOIN {feature} FS  ON FS.feature_id = FL.srcfeature_id
-       INNER JOIN {cvterm} CVT  ON F.type_id     = CVT.cvterm_id
-       INNER JOIN {cvterm} CVTS ON FS.type_id    = CVTS.cvterm_id
-   ";
-    if (strcmp($side, 'as_parent')==0) {
-      $sql .= "WHERE FL.srcfeature_id = :feature_id ";
-    }
-    if (strcmp($side, 'as_child')==0) {
-      $sql .= "WHERE FL.feature_id = :feature_id ";
-    }
-  
-    $flresults = chado_query($sql, array(':feature_id' => $feature_id));
-  
-    // copy the results into an array
-    $i=0;
-    $featurelocs = array();
-    while ($loc = $flresults->fetchObject()) {
-      // if a drupal node exists for this feature then add the nid to the
-      // results object
-  
-      $loc->feid = tripal_get_chado_entity_id('feature', $loc->feature_id);
-      $loc->seid = tripal_get_chado_entity_id('feature', $loc->src_feature_id);
-      // add the result to the array
-      $featurelocs[$i++] = $loc;
-    }
-  
-    // Add the relationship feature locs if aggregate is turned on
-    if ($aggregate and strcmp($side, 'as_parent')==0) {
-      // get the relationships for this feature without substituting any children
-      // for the parent. We want all relationships
-      $relationships = tripal_feature_get_aggregate_relationships($feature_id, 0);
-      foreach ($relationships as $rindex => $rel) {
-        // get the featurelocs for each of the relationship features
-        $rel_featurelocs = tripal_feature_load_featurelocs($rel->subject_id, 'as_child', 0);
-        foreach ($rel_featurelocs as $findex => $rfloc) {
-          $featurelocs[$i++] = $rfloc;
-        }
-      }
-    }
-  
-    usort($featurelocs, 'chado_feature__residues_sort_locations');
-    return $featurelocs;
+    } */
   }
   }
 }
 }
 
 
-/**
- * Used to sort the list of relationship parts by start position
- *
- * @ingroup tripal_feature
- */
-function chado_feature__residues_sort_rel_parts_by_start($a, $b) {
-  foreach ($a as $type_name => $details) {
-    $astart = $a[$type_name]['start'];
-    break;
-  }
-  foreach ($b as $type_name => $details) {
-    $bstart = $b[$type_name]['start'];
-    break;
-  }
-  return strnatcmp($astart, $bstart);
-}
-/**
- * Used to sort the feature locs by start position
- *
- * @param $a
- *   One featureloc record (as an object)
- * @param $b
- *   The other featureloc record (as an object)
- *
- * @return
- *   Which feature location comes first
- *
- * @ingroup tripal_feature
- */
-function chado_feature__residues_sort_locations($a, $b) {
-  return strnatcmp($a->fmin, $b->fmin);
-}

+ 0 - 7
tripal_chado/includes/TripalFields/data__sequence_checksum.inc

@@ -61,11 +61,4 @@ class data__sequence_checksum extends TripalField {
   protected $instance;
   protected $instance;
 
 
 
 
-
-  /**
-   * @see TripalField::load()
-   */
-  public function load($entity, $details = array()) {
-
-  }
 }
 }

+ 5 - 16
tripal_chado/includes/TripalFields/data__sequence_formatter.inc

@@ -11,7 +11,7 @@ class data__sequence_formatter extends TripalFieldFormatter {
   public static $settings = array();
   public static $settings = array();
 
 
   /**
   /**
-   * 
+   *
    * @param unknown $element
    * @param unknown $element
    * @param unknown $entity_type
    * @param unknown $entity_type
    * @param unknown $entity
    * @param unknown $entity
@@ -25,24 +25,13 @@ class data__sequence_formatter extends TripalFieldFormatter {
       '#type' => 'markup',
       '#type' => 'markup',
       '#markup' => '',
       '#markup' => '',
     );
     );
-    
+
     $num_bases = 50;
     $num_bases = 50;
     foreach ($items as $delta => $item) {
     foreach ($items as $delta => $item) {
-      // If there are no residues then skip this one.
-      if (!is_array($item['value']) or !array_key_exists('residues', $item['value'])) {
-        continue;
-      }
-    
-      $residues = $item['value']['residues'];
-      $label = $item['value']['label'];
-      $defline = $item['value']['defline'];
-    
-      $content = '<p>' . $label . '<p>';
-      $content .= '<pre class="residues-formatter">';
-      $content .= '>' . $defline . "<br>";
-      $content .= wordwrap($residues, $num_bases, "<br>", TRUE);
+      $content = '<pre class="residues-formatter">';
+      $content .= wordwrap($item['value'], $num_bases, "<br>", TRUE);
       $content .= '</pre>';
       $content .= '</pre>';
-    
+
       $element[$delta] = array(
       $element[$delta] = array(
         // We create a render array to produce the desired markup,
         // We create a render array to produce the desired markup,
         '#type' => 'markup',
         '#type' => 'markup',

+ 0 - 7
tripal_chado/includes/TripalFields/data__sequence_length.inc

@@ -60,11 +60,4 @@ class data__sequence_length extends TripalField {
   // when using the widgetForm, formatterSettingsForm, etc.) it should be set.
   // when using the widgetForm, formatterSettingsForm, etc.) it should be set.
   protected $instance;
   protected $instance;
 
 
-  /**
-   * 
-   * @see TripalField::load()
-   */
-  public function load($entity, $details = array()) {
-
-  }
 }
 }

+ 10 - 11
tripal_chado/includes/TripalFields/go__gene_expression.inc

@@ -81,24 +81,23 @@ class go__gene_expression extends TripalField {
    */
    */
   public function load($entity, $details = array()) {
   public function load($entity, $details = array()) {
     $record = $details['record'];
     $record = $details['record'];
-    
     $field_name = $this->field['field_name'];
     $field_name = $this->field['field_name'];
     $field_type = $this->field['type'];
     $field_type = $this->field['type'];
     $field_table = $this->field['settings']['chado_table'];
     $field_table = $this->field['settings']['chado_table'];
     $field_column = $this->field['settings']['chado_column'];
     $field_column = $this->field['settings']['chado_column'];
-    
+
     // Get the FK that links to the base record.
     // Get the FK that links to the base record.
     $schema = chado_get_schema($field_table);
     $schema = chado_get_schema($field_table);
     $base_table = $details['record']->tablename;
     $base_table = $details['record']->tablename;
     $pkey = $schema['primary key'][0];
     $pkey = $schema['primary key'][0];
     $fkey_lcolumn = key($schema['foreign keys'][$base_table]['columns']);
     $fkey_lcolumn = key($schema['foreign keys'][$base_table]['columns']);
     $fkey_rcolumn = $schema['foreign keys'][$base_table]['columns'][$fkey_lcolumn];
     $fkey_rcolumn = $schema['foreign keys'][$base_table]['columns'][$fkey_lcolumn];
-    
+
     // Set some defaults for the empty record.
     // Set some defaults for the empty record.
     $entity->{$field_name}['und'][0] = array(
     $entity->{$field_name}['und'][0] = array(
       'value' => array(),
       'value' => array(),
     );
     );
-    
+
     $linker_table = $base_table . '_expression';
     $linker_table = $base_table . '_expression';
     $options = array(
     $options = array(
       'return_array' => 1,
       'return_array' => 1,
@@ -107,11 +106,11 @@ class go__gene_expression extends TripalField {
     $exp_linkers = $record->$linker_table;
     $exp_linkers = $record->$linker_table;
     if ($exp_linkers) {
     if ($exp_linkers) {
       foreach ($exp_linkers as $i => $exp_linker) {
       foreach ($exp_linkers as $i => $exp_linker) {
-    
+
         // Because the unqiuename is a text field we must expand it.
         // Because the unqiuename is a text field we must expand it.
         $expression = $exp_linker->expression_id;
         $expression = $exp_linker->expression_id;
         $expression = chado_expand_var($expression, 'field', 'expression.uniquename', $options);
         $expression = chado_expand_var($expression, 'field', 'expression.uniquename', $options);
-    
+
         // Set the values that will be seen by the user on the page and in
         // Set the values that will be seen by the user on the page and in
         // web services, or anwhere this field is viewed.
         // web services, or anwhere this field is viewed.
         $entity->{$field_name}['und'][$i]['value'] = array(
         $entity->{$field_name}['und'][$i]['value'] = array(
@@ -119,22 +118,22 @@ class go__gene_expression extends TripalField {
           'description' => $expression->description,
           'description' => $expression->description,
           //'md5checksum' => $expression->md5checksum,
           //'md5checksum' => $expression->md5checksum,
         );
         );
-    
+
         // Add the pub information if a real pub is associated with the record.
         // Add the pub information if a real pub is associated with the record.
         $pub = $exp_linker->pub_id;
         $pub = $exp_linker->pub_id;
         if ($pub->uniquename != 'null') {
         if ($pub->uniquename != 'null') {
           $pub_details = tripal_get_minimal_pub_info($pub);
           $pub_details = tripal_get_minimal_pub_info($pub);
-    
+
           $entity->{$field_name}['und'][$i]['value']['publication'] = $pub_details;
           $entity->{$field_name}['und'][$i]['value']['publication'] = $pub_details;
           $entity->{$field_name}['und'][$i]['value']['publication']['type'] = $pub->type_id->name;
           $entity->{$field_name}['und'][$i]['value']['publication']['type'] = $pub->type_id->name;
           if (property_exists($pub, 'entity_id')) {
           if (property_exists($pub, 'entity_id')) {
             $entity->{$field_name}['und'][$i]['publication'][0]['value']['entity'] = 'TripalEntity:' . $pub->entity_id;
             $entity->{$field_name}['und'][$i]['publication'][0]['value']['entity'] = 'TripalEntity:' . $pub->entity_id;
           }
           }
         }
         }
-    
+
         // Add the linker_expressionprop
         // Add the linker_expressionprop
         $linkerprop_table =  $linker_table . 'prop';
         $linkerprop_table =  $linker_table . 'prop';
-        if (db_table_exists('chado.' . $linkerprop_table)) {
+        if (chado_table_exists($linkerprop_table)) {
           $exp_linker = chado_expand_var($exp_linker, 'table', $linkerprop_table, $options);
           $exp_linker = chado_expand_var($exp_linker, 'table', $linkerprop_table, $options);
           $exp_linkerprops = $exp_linker->feature_expressionprop;
           $exp_linkerprops = $exp_linker->feature_expressionprop;
           if ($exp_linkerprops) {
           if ($exp_linkerprops) {
@@ -150,7 +149,7 @@ class go__gene_expression extends TripalField {
         $entity->{$field_name}['und'][$i][$linker_table . '__uniquename'] = $expression->uniquename;
         $entity->{$field_name}['und'][$i][$linker_table . '__uniquename'] = $expression->uniquename;
         //$entity->{$field_name}['und'][$i][$linker_table . '__md5checksum'] = $expression->md5checksum;
         //$entity->{$field_name}['und'][$i][$linker_table . '__md5checksum'] = $expression->md5checksum;
         $entity->{$field_name}['und'][$i][$linker_table . '__description'] = $expression->description;
         $entity->{$field_name}['und'][$i][$linker_table . '__description'] = $expression->description;
-    
+
       }
       }
     }
     }
   }
   }

+ 16 - 16
tripal_chado/includes/TripalFields/sbo__database_cross_reference_widget.inc

@@ -17,7 +17,7 @@ class sbo__database_cross_reference_widget extends TripalFieldWidget {
     $field_type = $this->field['type'];
     $field_type = $this->field['type'];
     $field_table = $this->field['settings']['chado_table'];
     $field_table = $this->field['settings']['chado_table'];
     $field_column = $this->field['settings']['chado_column'];
     $field_column = $this->field['settings']['chado_column'];
-    
+
     // Get the FK column that links to the base table.
     // Get the FK column that links to the base table.
     $chado_table = $this->field['settings']['chado_table'];
     $chado_table = $this->field['settings']['chado_table'];
     $base_table = $this->field['settings']['base_table'];
     $base_table = $this->field['settings']['base_table'];
@@ -25,16 +25,16 @@ class sbo__database_cross_reference_widget extends TripalFieldWidget {
     $pkey = $schema['primary key'][0];
     $pkey = $schema['primary key'][0];
     $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
     $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
     $fkey = $fkeys[0];
     $fkey = $fkeys[0];
-    
+
     // Get the field defaults.
     // Get the field defaults.
     $record_id = '';
     $record_id = '';
-    $fkey_value = $element['#entity']->chado_record_id;
+    $fkey_value = $element['#entity'] ? $element['#entity']->chado_record_id : '';
     $dbxref_id = '';
     $dbxref_id = '';
     $db_id = '';
     $db_id = '';
     $accession = '';
     $accession = '';
     $version = '';
     $version = '';
     $description = '';
     $description = '';
-    
+
     // If the field already has a value then it will come through the $items
     // If the field already has a value then it will come through the $items
     // array.  This happens when editing an existing record.
     // array.  This happens when editing an existing record.
     if (count($items) > 0 and array_key_exists($delta, $items)) {
     if (count($items) > 0 and array_key_exists($delta, $items)) {
@@ -46,7 +46,7 @@ class sbo__database_cross_reference_widget extends TripalFieldWidget {
       $version = tripal_get_field_item_keyval($items, $delta, 'version', $version);
       $version = tripal_get_field_item_keyval($items, $delta, 'version', $version);
       $description = tripal_get_field_item_keyval($items, $delta, 'description', $description);
       $description = tripal_get_field_item_keyval($items, $delta, 'description', $description);
     }
     }
-    
+
     // Check $form_state['values'] to see if an AJAX call set the values.
     // Check $form_state['values'] to see if an AJAX call set the values.
     if (array_key_exists('values', $form_state) and array_key_exists($delta, $form_state['values'])) {
     if (array_key_exists('values', $form_state) and array_key_exists($delta, $form_state['values'])) {
       $record_id = $form_state['values'][$field_name]['und'][$delta][$field_table . '__' . $pkey];
       $record_id = $form_state['values'][$field_name]['und'][$delta][$field_table . '__' . $pkey];
@@ -57,23 +57,23 @@ class sbo__database_cross_reference_widget extends TripalFieldWidget {
       $version = $form_state['values'][$field_name]['und'][$delta]['version'];
       $version = $form_state['values'][$field_name]['und'][$delta]['version'];
       $description = $form_state['values'][$field_name]['und'][$delta]['description'];
       $description = $form_state['values'][$field_name]['und'][$delta]['description'];
     }
     }
-    
+
     $schema = chado_get_schema('dbxref');
     $schema = chado_get_schema('dbxref');
     $options = tripal_get_db_select_options();
     $options = tripal_get_db_select_options();
-    
+
     $widget['#table_name'] = $chado_table;
     $widget['#table_name'] = $chado_table;
     $widget['#fkey_field'] = $fkey;
     $widget['#fkey_field'] = $fkey;
     //$widget['#element_validate'] = array('sbo__database_cross_reference_widget_validate');
     //$widget['#element_validate'] = array('sbo__database_cross_reference_widget_validate');
     $widget['#theme'] = 'sbo__database_cross_reference_widget';
     $widget['#theme'] = 'sbo__database_cross_reference_widget';
     $widget['#prefix'] =  "<span id='$field_name-dbxref--db-id-$delta'>";
     $widget['#prefix'] =  "<span id='$field_name-dbxref--db-id-$delta'>";
     $widget['#suffix'] =  "</span>";
     $widget['#suffix'] =  "</span>";
-    
-    
+
+
     $widget['value'] = array(
     $widget['value'] = array(
       '#type' => 'value',
       '#type' => 'value',
       '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
       '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
     );
     );
-    
+
     $widget['chado-' . $field_table . '__' . $pkey] = array(
     $widget['chado-' . $field_table . '__' . $pkey] = array(
       '#type' => 'value',
       '#type' => 'value',
       '#default_value' => $record_id,
       '#default_value' => $record_id,
@@ -163,18 +163,18 @@ class sbo__database_cross_reference_widget extends TripalFieldWidget {
     $pkey = $schema['primary key'][0];
     $pkey = $schema['primary key'][0];
     $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
     $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
     $fkey = $fkeys[0];
     $fkey = $fkeys[0];
-    
-    
+
+
     // Get the field values.
     // Get the field values.
     foreach ($items as $delta => $values) {
     foreach ($items as $delta => $values) {
-    
+
       // Get the field values.
       // Get the field values.
       $dbxref_id = $values['chado-' . $field_table . '__dbxref_id'];
       $dbxref_id = $values['chado-' . $field_table . '__dbxref_id'];
       $db_id = $values['db_id'];
       $db_id = $values['db_id'];
       $accession = $values['accession'];
       $accession = $values['accession'];
       $version = $values['version'];
       $version = $values['version'];
       $description = $values['description'];
       $description = $values['description'];
-    
+
       // Make sure that if a database ID is provided that an accession is also
       // Make sure that if a database ID is provided that an accession is also
       // provided.  Here we use the form_set_error function rather than the
       // provided.  Here we use the form_set_error function rather than the
       // form_error function because the form_error will add a red_highlight
       // form_error function because the form_error will add a red_highlight
@@ -219,14 +219,14 @@ class sbo__database_cross_reference_widget extends TripalFieldWidget {
     $pkey = $schema['primary key'][0];
     $pkey = $schema['primary key'][0];
     $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
     $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
     $fkey = $fkeys[0];
     $fkey = $fkeys[0];
-    
+
     // Get the field values.
     // Get the field values.
     $dbxref_id = isset($form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__dbxref_id']) ? $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__dbxref_id'] : '';
     $dbxref_id = isset($form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__dbxref_id']) ? $form_state['values'][$field_name][$langcode][$delta]['chado-' . $field_table . '__dbxref_id'] : '';
     $db_id = isset($form_state['values'][$field_name][$langcode][$delta]['db_id']) ? $form_state['values'][$field_name][$langcode][$delta]['db_id'] : '';
     $db_id = isset($form_state['values'][$field_name][$langcode][$delta]['db_id']) ? $form_state['values'][$field_name][$langcode][$delta]['db_id'] : '';
     $accession = isset($form_state['values'][$field_name][$langcode][$delta]['accession']) ? $form_state['values'][$field_name][$langcode][$delta]['accession'] : '';
     $accession = isset($form_state['values'][$field_name][$langcode][$delta]['accession']) ? $form_state['values'][$field_name][$langcode][$delta]['accession'] : '';
     $version = isset($form_state['values'][$field_name][$langcode][$delta]['version']) ? $form_state['values'][$field_name][$langcode][$delta]['version'] : '';
     $version = isset($form_state['values'][$field_name][$langcode][$delta]['version']) ? $form_state['values'][$field_name][$langcode][$delta]['version'] : '';
     $description = isset($form_state['values'][$field_name][$langcode][$delta]['description']) ? $form_state['values'][$field_name][$langcode][$delta]['description'] : '';
     $description = isset($form_state['values'][$field_name][$langcode][$delta]['description']) ? $form_state['values'][$field_name][$langcode][$delta]['description'] : '';
-    
+
     // If the dbxref_id does not match the db_id + accession then the user
     // If the dbxref_id does not match the db_id + accession then the user
     // has selected a new dbxref record and we need to update the hidden
     // has selected a new dbxref record and we need to update the hidden
     // value accordingly.
     // value accordingly.

+ 48 - 52
tripal_chado/includes/TripalFields/sbo__relationship.inc

@@ -76,19 +76,19 @@ class sbo__relationship extends TripalField {
    */
    */
   public function load($entity, $details = array()) {
   public function load($entity, $details = array()) {
     $settings = $this->field['settings'];
     $settings = $this->field['settings'];
-    
+
     $record = $details['record'];
     $record = $details['record'];
-    
+
     $field_name = $this->field['field_name'];
     $field_name = $this->field['field_name'];
     $field_type = $this->field['type'];
     $field_type = $this->field['type'];
     $field_table = $this->field['settings']['chado_table'];
     $field_table = $this->field['settings']['chado_table'];
     $field_column = $this->field['settings']['chado_column'];
     $field_column = $this->field['settings']['chado_column'];
     $base_table = $this->field['settings']['base_table'];
     $base_table = $this->field['settings']['base_table'];
-    
+
     // Get the PKey for this table
     // Get the PKey for this table
     $schema = chado_get_schema($field_table);
     $schema = chado_get_schema($field_table);
     $pkey = $schema['primary key'][0];
     $pkey = $schema['primary key'][0];
-    
+
     // Get the Pkeys for the subject and object tables
     // Get the Pkeys for the subject and object tables
     $subject_fkey_table = '';
     $subject_fkey_table = '';
     $object_fkey_table = '';
     $object_fkey_table = '';
@@ -107,19 +107,19 @@ class sbo__relationship extends TripalField {
     $object_schema = chado_get_schema($object_fkey_table);
     $object_schema = chado_get_schema($object_fkey_table);
     $subject_pkey = $subject_schema['primary key'][0];
     $subject_pkey = $subject_schema['primary key'][0];
     $object_pkey = $object_schema['primary key'][0];
     $object_pkey = $object_schema['primary key'][0];
-    
+
     // Get the FK that links to the base record.
     // Get the FK that links to the base record.
     $schema = chado_get_schema($field_table);
     $schema = chado_get_schema($field_table);
     $fkey_lcolumn = key($schema['foreign keys'][$base_table]['columns']);
     $fkey_lcolumn = key($schema['foreign keys'][$base_table]['columns']);
     $fkey_rcolumn = $schema['foreign keys'][$base_table]['columns'][$fkey_lcolumn];
     $fkey_rcolumn = $schema['foreign keys'][$base_table]['columns'][$fkey_lcolumn];
-    
+
     // Set some defaults for the empty record.
     // Set some defaults for the empty record.
     $entity->{$field_name}['und'][0] = array(
     $entity->{$field_name}['und'][0] = array(
       'value' => array(),
       'value' => array(),
-      $field_table . '__' . $pkey => '',
-      $field_table . '__subject_id' => '',
-      $field_table . '__object_id' => '',
-      $field_table . '__type_id' => '',
+      'chado-' . $field_table . '__' . $pkey => '',
+      'chado-' . $field_table . '__subject_id' => '',
+      'chado-' . $field_table . '__object_id' => '',
+      'chado-' . $field_table . '__type_id' => '',
       // These elements don't need to follow the naming scheme above
       // These elements don't need to follow the naming scheme above
       // becasue we don't need the chado_field_storage to try and
       // becasue we don't need the chado_field_storage to try and
       // save these values.
       // save these values.
@@ -127,21 +127,21 @@ class sbo__relationship extends TripalField {
       'subject_name' => '',
       'subject_name' => '',
       'type_name' => '',
       'type_name' => '',
     );
     );
-    
+
     // If the table has rank and value fields then add those to the default
     // If the table has rank and value fields then add those to the default
     // value array.
     // value array.
     if (array_key_exists('value', $schema['fields'])) {
     if (array_key_exists('value', $schema['fields'])) {
-      $entity->{$field_name}['und'][0][$field_table . '__value'] = '';
+      $entity->{$field_name}['und'][0]['chado-' . $field_table . '__value'] = '';
     }
     }
     if (array_key_exists('rank', $schema['fields'])) {
     if (array_key_exists('rank', $schema['fields'])) {
-      $entity->{$field_name}['und'][0][$field_table . '__rank'] = '';
+      $entity->{$field_name}['und'][0]['chado-' . $field_table . '__rank'] = '';
     }
     }
-    
+
     // If we have no record then just return.
     // If we have no record then just return.
     if (!$record) {
     if (!$record) {
       return;
       return;
     }
     }
-    
+
     // Expand the object to include the relationships.
     // Expand the object to include the relationships.
     $options = array(
     $options = array(
       'return_array' => 1,
       'return_array' => 1,
@@ -168,11 +168,7 @@ class sbo__relationship extends TripalField {
     }
     }
     $srelationships = null;
     $srelationships = null;
     $orelationships = null;
     $orelationships = null;
-    if ($rel_table == 'organism_relationship') {
-      $srelationships = $record->$rel_table->subject_organism_id;
-      $orelationships = $record->$rel_table->object_organism_id;
-    }
-    else if ($rel_table == 'nd_reagent_relationship') {
+    if ($rel_table == 'nd_reagent_relationship') {
       $srelationships = $record->$rel_table->subject_reagent_id;
       $srelationships = $record->$rel_table->subject_reagent_id;
       $orelationships = $record->$rel_table->object_reagent_id;
       $orelationships = $record->$rel_table->object_reagent_id;
     }
     }
@@ -184,7 +180,7 @@ class sbo__relationship extends TripalField {
       $srelationships = $record->$rel_table->subject_id;
       $srelationships = $record->$rel_table->subject_id;
       $orelationships = $record->$rel_table->object_id;
       $orelationships = $record->$rel_table->object_id;
     }
     }
-    
+
     $i = 0;
     $i = 0;
     if ($orelationships) {
     if ($orelationships) {
       foreach ($orelationships as $relationship) {
       foreach ($orelationships as $relationship) {
@@ -222,31 +218,31 @@ class sbo__relationship extends TripalField {
         $entity->{$field_name}['und'][$i]['value']['phrase'] = 'The ' . $subject_type . ', ' .
         $entity->{$field_name}['und'][$i]['value']['phrase'] = 'The ' . $subject_type . ', ' .
             $subject_name . ', ' . $verb . ' '  . $rel_type_clean . ' this '  .
             $subject_name . ', ' . $verb . ' '  . $rel_type_clean . ' this '  .
             $object_type . '.';
             $object_type . '.';
-    
+
             $entity->{$field_name}['und'][$i]['semantic_web'] = array(
             $entity->{$field_name}['und'][$i]['semantic_web'] = array(
               'type' => $rel_acc,
               'type' => $rel_acc,
               'subject' => $relationship->subject_id->type_id->dbxref_id->db_id->name . ':' . $relationship->subject_id->type_id->dbxref_id->accession,
               'subject' => $relationship->subject_id->type_id->dbxref_id->db_id->name . ':' . $relationship->subject_id->type_id->dbxref_id->accession,
               'object' => $relationship->object_id->type_id->dbxref_id->db_id->name . ':' . $relationship->object_id->type_id->dbxref_id->accession,
               'object' => $relationship->object_id->type_id->dbxref_id->db_id->name . ':' . $relationship->object_id->type_id->dbxref_id->accession,
             );
             );
-    
-            $entity->{$field_name}['und'][$i][$field_table . '__' . $pkey] = $relationship->$pkey;
-            $entity->{$field_name}['und'][$i][$field_table . '__subject_id'] = $relationship->subject_id->$subject_pkey;
-            $entity->{$field_name}['und'][$i][$field_table . '__type_id'] = $relationship->type_id->cvterm_id;
-            $entity->{$field_name}['und'][$i][$field_table . '__object_id'] = $relationship->object_id->$object_pkey;
-    
+
+            $entity->{$field_name}['und'][$i]['chado-' . $field_table . '__' . $pkey] = $relationship->$pkey;
+            $entity->{$field_name}['und'][$i]['chado-' . $field_table . '__subject_id'] = $relationship->subject_id->$subject_pkey;
+            $entity->{$field_name}['und'][$i]['chado-' . $field_table . '__type_id'] = $relationship->type_id->cvterm_id;
+            $entity->{$field_name}['und'][$i]['chado-' . $field_table . '__object_id'] = $relationship->object_id->$object_pkey;
+
             $entity->{$field_name}['und'][$i]['type_name'] = $relationship->type_id->name;
             $entity->{$field_name}['und'][$i]['type_name'] = $relationship->type_id->name;
             $entity->{$field_name}['und'][$i]['subject_name'] = $relationship->subject_id->name . ' [id: ' . $relationship->subject_id->$fkey_rcolumn . ']';
             $entity->{$field_name}['und'][$i]['subject_name'] = $relationship->subject_id->name . ' [id: ' . $relationship->subject_id->$fkey_rcolumn . ']';
             $entity->{$field_name}['und'][$i]['object_name'] = $relationship->object_id->name  . ' [id: ' . $relationship->object_id->$fkey_rcolumn . ']';
             $entity->{$field_name}['und'][$i]['object_name'] = $relationship->object_id->name  . ' [id: ' . $relationship->object_id->$fkey_rcolumn . ']';
             if (array_key_exists('value', $schema['fields'])) {
             if (array_key_exists('value', $schema['fields'])) {
-              $entity->{$field_name}['und'][$i][$field_table . '__value'] = $relationship->value;
+              $entity->{$field_name}['und'][$i]['chado-' . $field_table . '__value'] = $relationship->value;
             }
             }
             if (array_key_exists('rank', $schema['fields'])) {
             if (array_key_exists('rank', $schema['fields'])) {
-              $entity->{$field_name}['und'][$i][$field_table . '__rank'] = $relationship->rank;
+              $entity->{$field_name}['und'][$i]['chado-' . $field_table . '__rank'] = $relationship->rank;
             }
             }
             $i++;
             $i++;
       }
       }
     }
     }
-    
+
     if ($srelationships) {
     if ($srelationships) {
       foreach ($srelationships as $relationship) {
       foreach ($srelationships as $relationship) {
         $rel_acc = $relationship->type_id->dbxref_id->db_id->name . ':' . $relationship->type_id->dbxref_id->accession;
         $rel_acc = $relationship->type_id->dbxref_id->db_id->name . ':' . $relationship->type_id->dbxref_id->accession;
@@ -283,29 +279,29 @@ class sbo__relationship extends TripalField {
         $entity->{$field_name}['und'][$i]['value']['phrase'] = 'This  ' .
         $entity->{$field_name}['und'][$i]['value']['phrase'] = 'This  ' .
             $subject_type . ' ' . $verb . ' '  . $rel_type_clean . ' the '  .
             $subject_type . ' ' . $verb . ' '  . $rel_type_clean . ' the '  .
             $object_type . ', ' . $object_name . '.';
             $object_type . ', ' . $object_name . '.';
-    
-    
+
+
             $entity->{$field_name}['und'][$i]['semantic_web'] = array(
             $entity->{$field_name}['und'][$i]['semantic_web'] = array(
               'type' => $rel_acc,
               'type' => $rel_acc,
               'subject' => $relationship->subject_id->type_id->dbxref_id->db_id->name . ':' . $relationship->subject_id->type_id->dbxref_id->accession,
               'subject' => $relationship->subject_id->type_id->dbxref_id->db_id->name . ':' . $relationship->subject_id->type_id->dbxref_id->accession,
               'object' => $relationship->object_id->type_id->dbxref_id->db_id->name . ':' . $relationship->object_id->type_id->dbxref_id->accession,
               'object' => $relationship->object_id->type_id->dbxref_id->db_id->name . ':' . $relationship->object_id->type_id->dbxref_id->accession,
             );
             );
-    
-    
-            $entity->{$field_name}['und'][$i][$field_table . '__' . $pkey] = $relationship->$pkey;
-            $entity->{$field_name}['und'][$i][$field_table . '__subject_id'] = $relationship->subject_id->$subject_pkey;
-            $entity->{$field_name}['und'][$i][$field_table . '__type_id'] = $relationship->type_id->cvterm_id;
-            $entity->{$field_name}['und'][$i][$field_table . '__object_id'] = $relationship->object_id->$object_pkey;
-    
+
+
+            $entity->{$field_name}['und'][$i]['chado-' . $field_table . '__' . $pkey] = $relationship->$pkey;
+            $entity->{$field_name}['und'][$i]['chado-' . $field_table . '__subject_id'] = $relationship->subject_id->$subject_pkey;
+            $entity->{$field_name}['und'][$i]['chado-' . $field_table . '__type_id'] = $relationship->type_id->cvterm_id;
+            $entity->{$field_name}['und'][$i]['chado-' . $field_table . '__object_id'] = $relationship->object_id->$object_pkey;
+
             $entity->{$field_name}['und'][$i]['type_name'] = $relationship->type_id->name;
             $entity->{$field_name}['und'][$i]['type_name'] = $relationship->type_id->name;
             $entity->{$field_name}['und'][$i]['subject_name'] = $relationship->subject_id->name  . ' [id: ' . $relationship->subject_id->$fkey_rcolumn . ']';
             $entity->{$field_name}['und'][$i]['subject_name'] = $relationship->subject_id->name  . ' [id: ' . $relationship->subject_id->$fkey_rcolumn . ']';
             $entity->{$field_name}['und'][$i]['object_name'] = $relationship->object_id->name  . ' [id: ' . $relationship->object_id->$fkey_rcolumn . ']';
             $entity->{$field_name}['und'][$i]['object_name'] = $relationship->object_id->name  . ' [id: ' . $relationship->object_id->$fkey_rcolumn . ']';
-    
+
             if (array_key_exists('value', $schema['fields'])) {
             if (array_key_exists('value', $schema['fields'])) {
-              $entity->{$field_name}['und'][$i][$field_table . '__value'] = $relationship->value;
+              $entity->{$field_name}['und'][$i]['chado-' . $field_table . '__value'] = $relationship->value;
             }
             }
             if (array_key_exists('rank', $schema['fields'])) {
             if (array_key_exists('rank', $schema['fields'])) {
-              $entity->{$field_name}['und'][$i][$field_table . '__rank'] = $relationship->rank;
+              $entity->{$field_name}['und'][$i]['chado-' . $field_table . '__rank'] = $relationship->rank;
             }
             }
             $i++;
             $i++;
       }
       }
@@ -355,17 +351,17 @@ class sbo__relationship extends TripalField {
       default:
       default:
         $verb = 'is';
         $verb = 'is';
     }
     }
-  
+
     return $verb;
     return $verb;
   }
   }
-  
+
   /**
   /**
    *
    *
    * @see TripalField::settingsForm()
    * @see TripalField::settingsForm()
    */
    */
   public function settingsForm($has_data) {
   public function settingsForm($has_data) {
     $element = parent::instanceSettingsForm();
     $element = parent::instanceSettingsForm();
-    
+
     //$element = parent::instanceSettingsForm();
     //$element = parent::instanceSettingsForm();
     $element['relationships'] = array(
     $element['relationships'] = array(
       '#type' => 'fieldset',
       '#type' => 'fieldset',
@@ -393,7 +389,7 @@ class sbo__relationship extends TripalField {
         could use to specify relationship types. With this option any term in .
         could use to specify relationship types. With this option any term in .
         the vocabulary can be used for the relationship type. You may select
         the vocabulary can be used for the relationship type. You may select
         more than one vocabulary.'),
         more than one vocabulary.'),
-    
+
     );
     );
     $element['relationships']['option1_vocabs'] = array(
     $element['relationships']['option1_vocabs'] = array(
       '#type' => 'select',
       '#type' => 'select',
@@ -403,7 +399,7 @@ class sbo__relationship extends TripalField {
       '#default_value' => $this->instance['settings']['relationships']['option1_vocabs'],
       '#default_value' => $this->instance['settings']['relationships']['option1_vocabs'],
       // TODO add ajax here so that the relationship autocomplete below works
       // TODO add ajax here so that the relationship autocomplete below works
     );
     );
-    
+
     $element['relationships']['option2'] = array(
     $element['relationships']['option2'] = array(
       '#type' => 'item',
       '#type' => 'item',
       '#title' => '<b>Option #2</b>',
       '#title' => '<b>Option #2</b>',
@@ -445,7 +441,7 @@ class sbo__relationship extends TripalField {
       '#type' => 'textarea',
       '#type' => 'textarea',
       '#default_value' => $this->instance['settings']['relationships']['relationship_types'],
       '#default_value' => $this->instance['settings']['relationships']['relationship_types'],
     );
     );
-    
+
     return $element;
     return $element;
   }
   }
   /**
   /**
@@ -457,7 +453,7 @@ class sbo__relationship extends TripalField {
     // Get relationships settings
     // Get relationships settings
     $settings = $form_state['values']['instance']['settings']['relationships'];
     $settings = $form_state['values']['instance']['settings']['relationships'];
     $form_state['values']['instance']['settings']['relationships']['relationship_types']= trim($settings['relationship_types']);
     $form_state['values']['instance']['settings']['relationships']['relationship_types']= trim($settings['relationship_types']);
-    
+
     // Make sure only one option is selected
     // Make sure only one option is selected
     $option1test = $settings['option1_vocabs'];
     $option1test = $settings['option1_vocabs'];
     $option1 = isset($settings['option1_vocabs']) && array_pop($option1test);
     $option1 = isset($settings['option1_vocabs']) && array_pop($option1test);
@@ -473,7 +469,7 @@ class sbo__relationship extends TripalField {
               );
               );
           return;
           return;
         }
         }
-    
+
         // For option3, make sure the supplied types are valid cvterms
         // For option3, make sure the supplied types are valid cvterms
         if ($option3) {
         if ($option3) {
           $rel_types = explode(PHP_EOL, $settings['relationship_types']);
           $rel_types = explode(PHP_EOL, $settings['relationship_types']);
@@ -546,7 +542,7 @@ class sbo__relationship extends TripalField {
             }
             }
           }
           }
         }
         }
-    
+
         // For option2: Make sure the parent term is a valid cvterm
         // For option2: Make sure the parent term is a valid cvterm
         if ($option2) {
         if ($option2) {
           $cv_id = $settings['option2_vocab'];
           $cv_id = $settings['option2_vocab'];

+ 134 - 114
tripal_chado/includes/TripalFields/sbo__relationship_widget.inc

@@ -13,131 +13,145 @@ class sbo__relationship_widget extends TripalFieldWidget {
    */
    */
   public function form(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) {
   public function form(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) {
     parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element);
     parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element);
+
+    // Get the field settings.
+    $entity = $form['#entity'];
     $field_name = $this->field['field_name'];
     $field_name = $this->field['field_name'];
     $field_type = $this->field['type'];
     $field_type = $this->field['type'];
     $field_table = $this->field['settings']['chado_table'];
     $field_table = $this->field['settings']['chado_table'];
     $field_column = $this->field['settings']['chado_column'];
     $field_column = $this->field['settings']['chado_column'];
-    
-    // Get the instance settings
-    $instance = $this->instance;
-    $settings = $instance['settings']['relationships'];
-    
-    $option1_vocabs = $settings['option1_vocabs'];
-    $option2_vocab  = $settings['option2_vocab'];
-    $option2_parent = $settings['option2_parent'];
-    $option3_rtypes = $settings['relationship_types'];
-    
-    // For testing if there are selected vocabs for option1 we'll copy the
-    // contents in a special variable for later.
-    $option1_test   = $option1_vocabs;
-    
+    $base_table = $this->field['settings']['base_table'];
+
     // Get the FK column that links to the base table.
     // Get the FK column that links to the base table.
-    $chado_table = $this->field['settings']['chado_table'];
     $base_table = $this->field['settings']['base_table'];
     $base_table = $this->field['settings']['base_table'];
-    $schema = chado_get_schema($chado_table);
+    $schema = chado_get_schema($field_table);
     $pkey = $schema['primary key'][0];
     $pkey = $schema['primary key'][0];
     $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
     $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
     $fkey = $fkeys[0];
     $fkey = $fkeys[0];
-    
+
+    // Get the instance settings. There are three options for how this widget
+    // will be displayed. Those are controlled in the instance settings
+    // of the field.
+    // Option 1:  relationship types are limited to a specific vocabulary.
+    // Option 2:  relationship types are limited to a subset of one vocabulary.
+    // Option 3:  relationship types are limited to a predefined set.
+    $instance = $this->instance;
+    $settings = '';
+    $option1_vocabs = '';
+    $option2_parent = '';
+    $option2_vocab = '';
+    $option3_rtypes  = '';
+    if (array_key_exists('relationships', $instance)) {
+      $settings = $instance['settings']['relationships'];
+      $option1_vocabs = $settings['option1_vocabs'];
+      $option2_vocab  = $settings['option2_vocab'];
+      $option2_parent = $settings['option2_parent'];
+      $option3_rtypes = $settings['relationship_types'];
+    }
+
+    // For testing if there are selected vocabs for option1 we'll copy the
+    // contents in a special variable for later.
+    $option1_test = $option1_vocabs;
+
     // Get the field defaults.
     // Get the field defaults.
     $record_id = '';
     $record_id = '';
-    $fkey_value = $element['#entity'] ? $element['#entity']->chado_record_id : '';
     $subject_id = '';
     $subject_id = '';
-    $subject_uniquename = '';
-    $type_id = '';
-    $type = '';
     $object_id = '';
     $object_id = '';
-    $object_uniquename = '';
+    $type_id = '';
     $value = '';
     $value = '';
     $rank = '';
     $rank = '';
-    
+    $subject_uniquename = '';
+    $object_uniquename = '';
+    $type = '';
+
     // Handle special cases
     // Handle special cases
     $subject_id_key = 'subject_id';
     $subject_id_key = 'subject_id';
     $object_id_key = 'object_id';
     $object_id_key = 'object_id';
-    if ($chado_table == 'organism_relationship') {
-      $subject_id_key = 'subject_organism_id';
-      $object_id_key = 'object_organism_id';
-    }
-    else if ($chado_table == 'nd_reagent_relationship') {
+    if ($field_table == 'nd_reagent_relationship') {
       $subject_id_key = 'subject_reagent_id';
       $subject_id_key = 'subject_reagent_id';
       $object_id_key = 'object_reagent_id';
       $object_id_key = 'object_reagent_id';
     }
     }
-    else if ($chado_table == 'project_relationship') {
+    else if ($field_table == 'project_relationship') {
       $subject_id_key = 'subject_project_id';
       $subject_id_key = 'subject_project_id';
       $object_id_key = 'object_project_id';
       $object_id_key = 'object_project_id';
     }
     }
-    
+
     // If the field already has a value then it will come through the $items
     // If the field already has a value then it will come through the $items
     // array.  This happens when editing an existing record.
     // array.  This happens when editing an existing record.
-    if (array_key_exists($delta, $items)) {
-      $record_id = isset($items[$delta][$field_table . '__' . $pkey]) ? $items[$delta][$field_table . '__' . $pkey] : '';
-      $subject_id = isset($items[$delta][$field_table . '__' . $subject_id_key]) ? $items[$delta][$field_table . '__' . $subject_id_key] : '';
-      $type_id = isset($items[$delta][$field_table . '__type_id']) ? $items[$delta][$field_table . '__type_id'] : '';
-      $object_id = isset($items[$delta][$field_table . '__' . $object_id_key]) ? $items[$delta][$field_table . '__' . $object_id_key] : '';
-    
-      if (isset($items[$delta][$field_table . '__value'])) {
-        $value = $items[$delta][$field_table . '__value'];
+    if (count($items) > 0 and array_key_exists($delta, $items)) {
+      // Check for element values that correspond to fields in the Chado table.
+      $record_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__' . $pkey, $record_id);
+      $subject_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__' . $subject_id_key, $subject_id);
+      $object_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__' . $object_id_key, $object_id);
+      $type_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__type_id', $type_id);
+      // Not all Chado tables have a value and rank.  So we'll only get
+      // those if applicable.
+      if (array_key_exists('value', $schema['fields'])) {
+        $value = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__value', $value);
       }
       }
-      if (isset($items[$delta][$field_table . '__rank'])) {
-        $rank = $items[$delta][$field_table . '__rank'];
+      if (array_key_exists('rank', $schema['fields'])) {
+        $rank = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__rank', $rank);
       }
       }
-    
-      $object_uniquename = isset($items[$delta]['object_name']) ? $items[$delta]['object_name'] : '';
-      $subject_uniquename = isset($items[$delta]['subject_name']) ? $items[$delta]['subject_name'] : '';
-      $type = isset($items[$delta]['type_name']) ? $items[$delta]['type_name'] : '';
+      // Get element values added to help support insert/updates.
+      $object_uniquename = tripal_get_field_item_keyval($items, $delta, 'object_name', $object_uniquename);
+      $subject_uniquename = tripal_get_field_item_keyval($items, $delta, 'subject_name', $subject_uniquename);
+      $type = tripal_get_field_item_keyval($items, $delta, 'type_name', $type);
     }
     }
-    
+
     // Check $form_state['values'] to see if an AJAX call set the values.
     // Check $form_state['values'] to see if an AJAX call set the values.
     if (array_key_exists('values', $form_state) and array_key_exists($delta, $form_state['values'])) {
     if (array_key_exists('values', $form_state) and array_key_exists($delta, $form_state['values'])) {
-      //       $record_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_table . '__' . $pkey);
-      //       $subject_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_table . '__subject_id');
-      //       $subject_uniquename = tripal_chado_get_field_form_values($field_name, $form_state, $delta, 'subject_name');
-      //       $type_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_table . '__type_id');
-      //       $type = tripal_chado_get_field_form_values($field_name, $form_state, $delta, 'type_name');
-      //       $object_id = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_table . '__object_id');
-      //       $object_uniquename = tripal_chado_get_field_form_values($field_name, $form_state, $delta, 'object_name');
-      //       $value = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_table . '__value');
-      //       $rank = tripal_chado_get_field_form_values($field_name, $form_state, $delta, $field_table . '__rank');
+      $record_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__' . $pkey];
+      $subject_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__' . $subject_id_key];
+      $object_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__' . $object_id_key];
+      $type_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__type_id'];
+      if (array_key_exists('value', $schema['fields'])) {
+        $value = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__value'];
+      }
+      if (array_key_exists('rank', $schema['fields'])) {
+        $rank = $form_state['values'][$field_name]['und'][$delta]['chado-' . $field_table . '__rank'];
+      }
+      $object_uniquename = $form_state['values'][$field_name]['und'][$delta]['object_name'];
+      $subject_uniquename = $form_state['values'][$field_name]['und'][$delta]['subject_name'];
+      $type = $form_state['values'][$field_name]['und'][$delta]['type_name'];
     }
     }
-    
-    $widget['#table_name'] = $chado_table;
+   $widget['#table_name'] = $chado_table;
     
     
     $widget['#fkeys'] = $schema['foreign keys'];
     $widget['#fkeys'] = $schema['foreign keys'];
     $widget['#base_table'] = $base_table;
     $widget['#base_table'] = $base_table;
     $widget['#chado_record_id'] = isset($form['#entity']) ? $form['#entity']->chado_record_id : '';
     $widget['#chado_record_id'] = isset($form['#entity']) ? $form['#entity']->chado_record_id : '';
     //$widget['#element_validate'] = array('sbo__relationship_validate');
     //$widget['#element_validate'] = array('sbo__relationship_validate');
     $widget['#theme'] = 'sbo__relationship_widget';
     $widget['#theme'] = 'sbo__relationship_widget';
-    $widget['#prefix'] =  "<span id='$chado_table-$delta'>";
+    $widget['#prefix'] =  "<span id='$field_table-$delta'>";
     $widget['#suffix'] =  "</span>";
     $widget['#suffix'] =  "</span>";
-    
+
     $widget['value'] = array(
     $widget['value'] = array(
       '#type' => 'value',
       '#type' => 'value',
       '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
       '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
     );
     );
-    $widget[$field_table . '__' . $pkey] = array(
+    $widget['chado-' . $field_table . '__' . $pkey] = array(
       '#type' => 'value',
       '#type' => 'value',
       '#default_value' => $record_id,
       '#default_value' => $record_id,
     );
     );
-    $widget[$field_table . '__' . $subject_id_key] = array(
+    $widget['chado-' . $field_table . '__' . $subject_id_key] = array(
       '#type' => 'value',
       '#type' => 'value',
       '#default_value' => $subject_id,
       '#default_value' => $subject_id,
     );
     );
-    $widget[$field_table . '__type_id'] = array(
+    $widget['chado-' . $field_table . '__type_id'] = array(
       '#type' => 'value',
       '#type' => 'value',
       '#default_value' => $type_id,
       '#default_value' => $type_id,
     );
     );
-    $widget[$field_table . '__' . $object_id_key] = array(
+    $widget['chado-' . $field_table . '__' . $object_id_key] = array(
       '#type' => 'value',
       '#type' => 'value',
       '#default_value' => $object_id,
       '#default_value' => $object_id,
     );
     );
     if (array_key_exists('value', $schema['fields'])) {
     if (array_key_exists('value', $schema['fields'])) {
-      $widget[$field_table . '__value'] = array(
+      $widget['chado-' . $field_table . '__value'] = array(
         '#type' => 'value',
         '#type' => 'value',
         '#default_value' => $value,
         '#default_value' => $value,
       );
       );
     }
     }
     if (array_key_exists('rank', $schema['fields'])) {
     if (array_key_exists('rank', $schema['fields'])) {
-      $widget[$field_table . '__rank'] = array(
+      $widget['chado-' . $field_table . '__rank'] = array(
         '#type' => 'value',
         '#type' => 'value',
         '#default_value' => $rank,
         '#default_value' => $rank,
       );
       );
@@ -151,8 +165,8 @@ class sbo__relationship_widget extends TripalFieldWidget {
       '#size' => 35,
       '#size' => 35,
       '#autocomplete_path' => "admin/tripal/storage/chado/auto_name/$base_table",
       '#autocomplete_path' => "admin/tripal/storage/chado/auto_name/$base_table",
     );
     );
-    
-    // Getting default values
+
+    // Getting default values for the relationship type element.
     $default_voc = '';
     $default_voc = '';
     if (isset($form_state['field'][$field_name]['und']['instance']['default_value'][0]['vocabulary'])) {
     if (isset($form_state['field'][$field_name]['und']['instance']['default_value'][0]['vocabulary'])) {
       $default_voc = $form_state['field'][$field_name]['und']['instance']['default_value'][0]['vocabulary'];
       $default_voc = $form_state['field'][$field_name]['und']['instance']['default_value'][0]['vocabulary'];
@@ -161,7 +175,7 @@ class sbo__relationship_widget extends TripalFieldWidget {
     if (isset($form_state['field'][$field_name]['und']['instance']['default_value'][0]['type_name'])) {
     if (isset($form_state['field'][$field_name]['und']['instance']['default_value'][0]['type_name'])) {
       $default_term = $form_state['field'][$field_name]['und']['instance']['default_value'][0]['type_name'];
       $default_term = $form_state['field'][$field_name]['und']['instance']['default_value'][0]['type_name'];
     }
     }
-    
+
     $default_type_id = $type_id;
     $default_type_id = $type_id;
     if (!$type_id && isset($form_state['field'][$field_name]['und']['instance']['default_value'][0]['type_id'])) {
     if (!$type_id && isset($form_state['field'][$field_name]['und']['instance']['default_value'][0]['type_id'])) {
       $default_type_id = $form_state['field'][$field_name]['und']['instance']['default_value'][0]['type_id'];
       $default_type_id = $form_state['field'][$field_name]['und']['instance']['default_value'][0]['type_id'];
@@ -203,7 +217,7 @@ class sbo__relationship_widget extends TripalFieldWidget {
         'name' => $option2_parent
         'name' => $option2_parent
       );
       );
       $parent_term = tripal_get_cvterm($values);
       $parent_term = tripal_get_cvterm($values);
-    
+
       // If the term wasn't found then see if it's a synonym.
       // If the term wasn't found then see if it's a synonym.
       if(!$parent_term) {
       if(!$parent_term) {
         $values = array(
         $values = array(
@@ -217,16 +231,14 @@ class sbo__relationship_widget extends TripalFieldWidget {
         }
         }
       }
       }
       // Get the child terms of the parent term found above.
       // Get the child terms of the parent term found above.
-      $sql =
-      "SELECT
-           subject_id,
-           (SELECT name from {cvterm} where cvterm_id = subject_id) AS name
-         FROM {cvtermpath}
-         WHERE
-           object_id = :parent_cvterm_id
-         AND
-           cv_id = :parent_cv_id
-         ORDER BY name
+      $sql = "
+        SELECT subject_id,
+          (SELECT name from {cvterm} where cvterm_id = subject_id) AS name
+        FROM {cvtermpath}
+        WHERE
+          object_id = :parent_cvterm_id AND
+          cv_id = :parent_cv_id
+        ORDER BY name
        ";
        ";
       $args = array(
       $args = array(
         ':parent_cvterm_id' => $parent_term->cvterm_id,
         ':parent_cvterm_id' => $parent_term->cvterm_id,
@@ -288,7 +300,7 @@ class sbo__relationship_widget extends TripalFieldWidget {
         '#default_value' => $cv_id,
         '#default_value' => $cv_id,
         '#ajax' => array(
         '#ajax' => array(
           'callback' => "sbo__relationship_widget_form_ajax_callback",
           'callback' => "sbo__relationship_widget_form_ajax_callback",
-          'wrapper' => "$chado_table-$delta",
+          'wrapper' => "$field_table-$delta",
           'effect' => 'fade',
           'effect' => 'fade',
           'method' => 'replace'
           'method' => 'replace'
         ),
         ),
@@ -304,7 +316,7 @@ class sbo__relationship_widget extends TripalFieldWidget {
         );
         );
       }
       }
     }
     }
-    
+
     $widget['object_name'] = array(
     $widget['object_name'] = array(
       '#type' => 'textfield',
       '#type' => 'textfield',
       '#title' => t('Object'),
       '#title' => t('Object'),
@@ -332,18 +344,14 @@ class sbo__relationship_widget extends TripalFieldWidget {
     $field_table = $this->field['settings']['chado_table'];
     $field_table = $this->field['settings']['chado_table'];
     $field_column = $this->field['settings']['chado_column'];
     $field_column = $this->field['settings']['chado_column'];
     $base_table = $this->field['settings']['base_table'];
     $base_table = $this->field['settings']['base_table'];
-    
+
     $schema = chado_get_schema($field_table);
     $schema = chado_get_schema($field_table);
     $fkeys = $schema['foreign keys'];
     $fkeys = $schema['foreign keys'];
-    
+
     // Handle special cases
     // Handle special cases
     $subject_id_key = 'subject_id';
     $subject_id_key = 'subject_id';
     $object_id_key = 'object_id';
     $object_id_key = 'object_id';
-    if ($field_table == 'organism_relationship') {
-      $subject_id_key = 'subject_organism_id';
-      $object_id_key = 'object_organism_id';
-    }
-    else if ($field_table == 'nd_reagent_relationship') {
+    if ($field_table == 'nd_reagent_relationship') {
       $subject_id_key = 'subject_reagent_id';
       $subject_id_key = 'subject_reagent_id';
       $object_id_key = 'object_reagent_id';
       $object_id_key = 'object_reagent_id';
     }
     }
@@ -351,22 +359,22 @@ class sbo__relationship_widget extends TripalFieldWidget {
       $subject_id_key = 'subject_project_id';
       $subject_id_key = 'subject_project_id';
       $object_id_key = 'object_project_id';
       $object_id_key = 'object_project_id';
     }
     }
-    
+
     foreach ($items as $delta => $item) {
     foreach ($items as $delta => $item) {
-      $subject_id = $item[$field_table . '__' . $subject_id_key];
-      $object_id = $item[ $field_table . '__' . $object_id_key];
-      $type_id = $item[$field_table . '__type_id'];
-      $type_id = isset($item['type_id']) ? $item['type_id'] : $type_id;
+      $subject_id = $item['chado' . $field_table . '__' . $subject_id_key];
+      $object_id = $item['chado' . $field_table . '__' . $object_id_key];
+      $type_id = $item['chado' . $field_table . '__type_id'];
+      $type_id = isset($item['type_id']) ? $item['chado' . $field_table . '__type_id'] : $type_id;
       $type_name = isset($item['type_name']) ? $item['type_name'] : '';
       $type_name = isset($item['type_name']) ? $item['type_name'] : '';
       $subject_name = $item['subject_name'];
       $subject_name = $item['subject_name'];
       $object_name = $item['object_name'];
       $object_name = $item['object_name'];
-    
-    
+
+
       // If the row is empty then just continue, there's nothing to validate.
       // If the row is empty then just continue, there's nothing to validate.
       if (!$type_id and !$type_name and !$subject_name and !$object_name) {
       if (!$type_id and !$type_name and !$subject_name and !$object_name) {
         continue;
         continue;
       }
       }
-    
+
       // Make sure we have values for all of the fields.
       // Make sure we have values for all of the fields.
       $form_error = FALSE;
       $form_error = FALSE;
       if (!$type_name && !$type_id) {
       if (!$type_name && !$type_id) {
@@ -390,9 +398,9 @@ class sbo__relationship_widget extends TripalFieldWidget {
       if ($form_error) {
       if ($form_error) {
         continue;
         continue;
       }
       }
-    
+
       // Before submitting this form we need to make sure that our subject_id and
       // Before submitting this form we need to make sure that our subject_id and
-      // object_ids are real values.  There are two ways to get the value, either
+      // object_ids are real records.  There are two ways to get the record, either
       // just with the text value or with an [id: \d+] string embedded.  If the
       // just with the text value or with an [id: \d+] string embedded.  If the
       // later we will pull it out.
       // later we will pull it out.
       $subject_id = '';
       $subject_id = '';
@@ -427,7 +435,7 @@ class sbo__relationship_widget extends TripalFieldWidget {
           }
           }
         }
         }
       }
       }
-    
+
       // Now check for a matching object.
       // Now check for a matching object.
       $object_id = '';
       $object_id = '';
       $fkey_rcolumn = $fkeys[$base_table]['columns'][$object_id_key];
       $fkey_rcolumn = $fkeys[$base_table]['columns'][$object_id_key];
@@ -461,7 +469,7 @@ class sbo__relationship_widget extends TripalFieldWidget {
           }
           }
         }
         }
       }
       }
-    
+
       // Make sure that either our object or our subject refers to the base record.
       // Make sure that either our object or our subject refers to the base record.
       if ($entity) {
       if ($entity) {
         $chado_record_id = $entity->chado_record_id;
         $chado_record_id = $entity->chado_record_id;
@@ -471,7 +479,7 @@ class sbo__relationship_widget extends TripalFieldWidget {
             'message' =>  t("Either the subject or the object in the relationship must refer to this record."),
             'message' =>  t("Either the subject or the object in the relationship must refer to this record."),
           );
           );
         }
         }
-    
+
         // Make sure that the object and subject are not both the same thing.
         // Make sure that the object and subject are not both the same thing.
         if ($object_id == $subject_id) {
         if ($object_id == $subject_id) {
           $errors[$this->field['field_name']][$langcode][$delta][] = array(
           $errors[$this->field['field_name']][$langcode][$delta][] = array(
@@ -495,23 +503,35 @@ class sbo__relationship_widget extends TripalFieldWidget {
     $field_column = $this->field['settings']['chado_column'];
     $field_column = $this->field['settings']['chado_column'];
     $base_table = $this->field['settings']['base_table'];
     $base_table = $this->field['settings']['base_table'];
     $chado_record_id = $entity->chado_record_id;
     $chado_record_id = $entity->chado_record_id;
-    
+
     $schema = chado_get_schema($field_table);
     $schema = chado_get_schema($field_table);
     $fkeys = $schema['foreign keys'];
     $fkeys = $schema['foreign keys'];
-    
+
+    // Handle special cases
+    $subject_id_key = 'subject_id';
+    $object_id_key = 'object_id';
+    if ($field_table == 'nd_reagent_relationship') {
+      $subject_id_key = 'subject_reagent_id';
+      $object_id_key = 'object_reagent_id';
+    }
+    else if ($field_table == 'project_relationship') {
+      $subject_id_key = 'subject_project_id';
+      $object_id_key = 'object_project_id';
+    }
+
     $type_name = array_key_exists('type_name', $item) ? $item['type_name'] : '';
     $type_name = array_key_exists('type_name', $item) ? $item['type_name'] : '';
-    $subject_id = $form_state['values'][$field_name][$langcode][$delta][$field_table . '__subject_id'];
-    $object_id = $form_state['values'][$field_name][$langcode][$delta][ $field_table . '__object_id'];
-    $type_id = $form_state['values'][$field_name][$langcode][$delta][$field_table . '__type_id'];
-    
+    $subject_id = $form_state['values'][$field_name][$langcode][$delta]['chado' . $field_table . '__' . $subject_id_key];
+    $object_id = $form_state['values'][$field_name][$langcode][$delta]['chado' . $field_table . '__' . $object_id_key];
+    $type_id = $form_state['values'][$field_name][$langcode][$delta]['chado' . $field_table . '__type_id'];
+
     $subject_name = $form_state['values'][$field_name][$langcode][$delta]['subject_name'];
     $subject_name = $form_state['values'][$field_name][$langcode][$delta]['subject_name'];
     $object_name = $form_state['values'][$field_name][$langcode][$delta]['object_name'];
     $object_name = $form_state['values'][$field_name][$langcode][$delta]['object_name'];
-    
+
     // If the row is empty then skip this one, there's nothing to validate.
     // If the row is empty then skip this one, there's nothing to validate.
     if (!($type_id or !$type_name) and !$subject_name and !$object_name) {
     if (!($type_id or !$type_name) and !$subject_name and !$object_name) {
       return;
       return;
     }
     }
-    
+
     // Get the subject ID.
     // Get the subject ID.
     $subject_id = '';
     $subject_id = '';
     $fkey_rcolumn = $fkeys[$base_table]['columns']['subject_id'];
     $fkey_rcolumn = $fkeys[$base_table]['columns']['subject_id'];
@@ -524,7 +544,7 @@ class sbo__relationship_widget extends TripalFieldWidget {
       $subject = chado_select_record($base_table, array($fkey_rcolumn), $values);
       $subject = chado_select_record($base_table, array($fkey_rcolumn), $values);
       $subject_id = $subject[0]->$fkey_rcolumn;
       $subject_id = $subject[0]->$fkey_rcolumn;
     }
     }
-    
+
     // Get the object ID.
     // Get the object ID.
     $object_id = '';
     $object_id = '';
     $fkey_rcolumn = $fkeys[$base_table]['columns']['object_id'];
     $fkey_rcolumn = $fkeys[$base_table]['columns']['object_id'];
@@ -537,12 +557,12 @@ class sbo__relationship_widget extends TripalFieldWidget {
       $object = chado_select_record($base_table, array($fkey_rcolumn), $values);
       $object = chado_select_record($base_table, array($fkey_rcolumn), $values);
       $object_id = $object[0]->$fkey_rcolumn;
       $object_id = $object[0]->$fkey_rcolumn;
     }
     }
-    
+
     // Set the IDs according to the values that were determined above.
     // Set the IDs according to the values that were determined above.
-    $form_state['values'][$field_name][$langcode][$delta][$field_table . '__subject_id'] = $subject_id;
-    $form_state['values'][$field_name][$langcode][$delta][$field_table . '__object_id'] = $object_id;
-    $form_state['values'][$field_name][$langcode][$delta][$field_table . '__type_id'] = $type_name;
-    $form_state['values'][$field_name][$langcode][$delta][$field_table . '__rank'] = $item['_weight'];
+    $form_state['values'][$field_name][$langcode][$delta]['chado' . $field_table . '__' . $subject_id_key] = $subject_id;
+    $form_state['values'][$field_name][$langcode][$delta]['chado' . $field_table . '__' . $object_id_key] = $object_id;
+    $form_state['values'][$field_name][$langcode][$delta]['chado' . $field_table . '__type_id'] = $type_name;
+    $form_state['values'][$field_name][$langcode][$delta]['chado' . $field_table . '__rank'] = $item['_weight'];
   }
   }
 }
 }
 
 

+ 16 - 16
tripal_chado/includes/TripalFields/schema__alternate_name_widget.inc

@@ -15,7 +15,7 @@ class schema__alternate_name_widget extends TripalFieldWidget {
     parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element);
     parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element);
     $entity = $form['#entity'];
     $entity = $form['#entity'];
     $field_name = $this->field['field_name'];
     $field_name = $this->field['field_name'];
-    
+
     // Get the FK column that links to the base table.
     // Get the FK column that links to the base table.
     $table_name = $this->field['settings']['chado_table'];
     $table_name = $this->field['settings']['chado_table'];
     $base_table = $this->field['settings']['base_table'];
     $base_table = $this->field['settings']['base_table'];
@@ -23,7 +23,7 @@ class schema__alternate_name_widget extends TripalFieldWidget {
     $pkey = $schema['primary key'][0];
     $pkey = $schema['primary key'][0];
     $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
     $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
     $fkey = $fkeys[0];
     $fkey = $fkeys[0];
-    
+
     // Get the field defaults.
     // Get the field defaults.
     $record_id = '';
     $record_id = '';
     $fkey_value = $element['#entity']->chado_record_id;
     $fkey_value = $element['#entity']->chado_record_id;
@@ -33,7 +33,7 @@ class schema__alternate_name_widget extends TripalFieldWidget {
     $is_internal = FALSE;
     $is_internal = FALSE;
     $syn_name = '';
     $syn_name = '';
     $syn_type = '';
     $syn_type = '';
-    
+
     // If the field already has a value then it will come through the $items
     // If the field already has a value then it will come through the $items
     // array.  This happens when editing an existing record.
     // array.  This happens when editing an existing record.
     if (array_key_exists($delta, $items)) {
     if (array_key_exists($delta, $items)) {
@@ -45,7 +45,7 @@ class schema__alternate_name_widget extends TripalFieldWidget {
       $syn_name = $items[$delta]['name'];
       $syn_name = $items[$delta]['name'];
       $syn_type = $items[$delta]['type_id'];
       $syn_type = $items[$delta]['type_id'];
     }
     }
-    
+
     // Check $form_state['values'] to see if an AJAX call set the values.
     // Check $form_state['values'] to see if an AJAX call set the values.
     if (array_key_exists('values', $form_state) and array_key_exists($delta, $form_state['values'])) {
     if (array_key_exists('values', $form_state) and array_key_exists($delta, $form_state['values'])) {
       $record_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $table_name . '__' . $pkey];
       $record_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $table_name . '__' . $pkey];
@@ -56,7 +56,7 @@ class schema__alternate_name_widget extends TripalFieldWidget {
       $syn_name = $form_state['values'][$field_name]['und'][$delta]['name'];
       $syn_name = $form_state['values'][$field_name]['und'][$delta]['name'];
       $syn_type = $form_state['values'][$field_name]['und'][$delta]['type_id'];
       $syn_type = $form_state['values'][$field_name]['und'][$delta]['type_id'];
     }
     }
-    
+
     $options = array();
     $options = array();
     $value = array('cv_id' => array('name' => 'synonym_type'));
     $value = array('cv_id' => array('name' => 'synonym_type'));
     $op = array('return_array' => 1);
     $op = array('return_array' => 1);
@@ -66,22 +66,22 @@ class schema__alternate_name_widget extends TripalFieldWidget {
         $options[$type->cvterm_id] = $type->name;
         $options[$type->cvterm_id] = $type->name;
       }
       }
     }
     }
-    
+
     // Get the schema for the synonym table so we can make sure we limit the
     // Get the schema for the synonym table so we can make sure we limit the
     // size of the name field to the proper size.
     // size of the name field to the proper size.
     $schema = chado_get_schema('synonym');
     $schema = chado_get_schema('synonym');
-    
+
     $widget['#table_name'] = $table_name;
     $widget['#table_name'] = $table_name;
     $widget['#fkey_field'] = $fkey;
     $widget['#fkey_field'] = $fkey;
     $widget['#theme'] = 'schema__alternate_name_widget';
     $widget['#theme'] = 'schema__alternate_name_widget';
     $widget['#prefix'] =  "<span id='$table_name-$delta'>";
     $widget['#prefix'] =  "<span id='$table_name-$delta'>";
     $widget['#suffix'] =  "</span>";
     $widget['#suffix'] =  "</span>";
-    
+
     $widget['value'] = array(
     $widget['value'] = array(
       '#type' => 'value',
       '#type' => 'value',
       '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
       '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
     );
     );
-    
+
     $widget['chado-' . $table_name . '__' . $pkey] = array(
     $widget['chado-' . $table_name . '__' . $pkey] = array(
       '#type' => 'value',
       '#type' => 'value',
       '#default_value' => $record_id,
       '#default_value' => $record_id,
@@ -111,14 +111,14 @@ class schema__alternate_name_widget extends TripalFieldWidget {
       '#default_value' => $syn_name,
       '#default_value' => $syn_name,
       '#size' => 25,
       '#size' => 25,
     );
     );
-    
+
     $widget['chado-' . $table_name . '__is_current'] = array(
     $widget['chado-' . $table_name . '__is_current'] = array(
       '#type' => 'checkbox',
       '#type' => 'checkbox',
       '#title' => t('Is Current'),
       '#title' => t('Is Current'),
       '#default_value' => $is_current,
       '#default_value' => $is_current,
       '#required' => $element['#required'],
       '#required' => $element['#required'],
     );
     );
-    
+
     $widget['chado-' . $table_name . '__is_internal'] = array(
     $widget['chado-' . $table_name . '__is_internal'] = array(
       '#type' => 'checkbox',
       '#type' => 'checkbox',
       '#title' => t('Is Internal'),
       '#title' => t('Is Internal'),
@@ -157,7 +157,7 @@ class schema__alternate_name_widget extends TripalFieldWidget {
     $pkey = $schema['primary key'][0];
     $pkey = $schema['primary key'][0];
     $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
     $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
     $fkey = $fkeys[0];
     $fkey = $fkeys[0];
-    
+
     $record_id = isset($form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__' . $pkey]) ? $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__' . $pkey] : '';
     $record_id = isset($form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__' . $pkey]) ? $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__' . $pkey] : '';
     $fkey_value = isset($form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__' . $fkey]) ? $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__' . $fkey] : '';
     $fkey_value = isset($form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__' . $fkey]) ? $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__' . $fkey] : '';
     $synonym_id = isset($form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__synonym_id']) ? $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__synonym_id'] : '';
     $synonym_id = isset($form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__synonym_id']) ? $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__synonym_id'] : '';
@@ -166,11 +166,11 @@ class schema__alternate_name_widget extends TripalFieldWidget {
     $is_internal = isset($form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__is_internal']) ? $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__is_internal'] : '';
     $is_internal = isset($form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__is_internal']) ? $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__is_internal'] : '';
     $syn_name = isset($form_state['values'][$field_name][$langcode][$delta]['name']) ? $form_state['values'][$field_name][$langcode][$delta]['name'] : '';
     $syn_name = isset($form_state['values'][$field_name][$langcode][$delta]['name']) ? $form_state['values'][$field_name][$langcode][$delta]['name'] : '';
     $syn_type = isset($form_state['values'][$field_name][$langcode][$delta]['type_id']) ? $form_state['values'][$field_name][$langcode][$delta]['type_id'] : '';
     $syn_type = isset($form_state['values'][$field_name][$langcode][$delta]['type_id']) ? $form_state['values'][$field_name][$langcode][$delta]['type_id'] : '';
-    
+
     // If the user provided a $syn_name and a $syn_type then we want to set
     // If the user provided a $syn_name and a $syn_type then we want to set
     // the foreign key value to be the chado_record_id.
     // the foreign key value to be the chado_record_id.
     if ($syn_name and $syn_type) {
     if ($syn_name and $syn_type) {
-    
+
       // Get the synonym. If one with the same name and type is already present
       // Get the synonym. If one with the same name and type is already present
       // then use that. Otherwise, insert a new one.
       // then use that. Otherwise, insert a new one.
       if (!$synonym_id) {
       if (!$synonym_id) {
@@ -183,11 +183,11 @@ class schema__alternate_name_widget extends TripalFieldWidget {
           ));
           ));
           $synonym = (object) $synonym;
           $synonym = (object) $synonym;
         }
         }
-    
+
         // Set the synonym_id and FK value
         // Set the synonym_id and FK value
         $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__synonym_id'] = $synonym->synonym_id;
         $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__synonym_id'] = $synonym->synonym_id;
       }
       }
-    
+
       if (!$pub_id) {
       if (!$pub_id) {
         $pub = chado_generate_var('pub', array('uniquename' => 'null'));
         $pub = chado_generate_var('pub', array('uniquename' => 'null'));
         $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__pub_id'] = $pub->pub_id;
         $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__pub_id'] = $pub->pub_id;

+ 96 - 0
tripal_chado/includes/TripalFields/so__cds.inc

@@ -0,0 +1,96 @@
+<?php
+
+class so__cds extends TripalField {
+
+
+  // --------------------------------------------------------------------------
+  //                     EDITABLE STATIC CONSTANTS
+  //
+  // The following constants SHOULD be set for each descendent class.  They are
+  // used by the static functions to provide information to Drupal about
+  // the field and it's default widget and formatter.
+  // --------------------------------------------------------------------------
+
+  // The term that this field maps to.  The format for the term should be:
+  // [vocab]:[accession] where [vocab] is the short name of the vocabulary
+  // and [acession] is the unique accession number for the term.  This term
+  // must already exist in the vocabulary storage backend. This
+  // value should never be changed once fields exist for this type.
+  public static $term = 'SO:0000316';
+
+  // The default lable for this field.
+  public static $label = 'Coding Sequence';
+
+  // The default description for this field.
+  public static $description = 'A contiguous sequence which begins with, and includes, a start codon and ends with, and includes, a stop codon.';
+
+  // Provide a list of global settings. These can be accessed witihn the
+  // globalSettingsForm.  When the globalSettingsForm is submitted then
+  // Drupal will automatically change these settings for all fields.
+  public static $settings = array(
+    'chado_table' => '',
+    'chado_column' => '',
+    'base_table' => '',
+  );
+
+  // Provide a list of instance specific settings. These can be access within
+  // the instanceSettingsForm.  When the instanceSettingsForm is submitted
+  // then Drupal with automatically change these settings for the instnace.
+  // It is recommended to put settings at the instance level whenever possible.
+  public static $instance_settings  = array();
+
+  // Set this to the name of the storage backend that by default will support
+  // this field.
+  public static $storage = 'tripal_no_storage';
+
+  // The default widget for this field.
+  public static $default_widget = 'so__cds_widget';
+
+  // The default formatter for this field.
+  public static $default_formatter = 'so__cds_formatter';
+
+  /**
+   * @see TripalField::load()
+   */
+  public function load($entity, $details = array()) {
+    $field_name = $this->field['field_name'];
+    $feature = $details['record'];
+    $num_seqs = 0;
+
+    $feature = chado_expand_var($feature, 'table', 'featureloc', $options);
+    $featureloc_sequences = chado_get_featureloc_sequences($feature->feature_id, $feature->featureloc->feature_id);
+    foreach($featureloc_sequences as $src => $attrs){
+      // Generate a CDS sequence if one exsits for this feature alignment.
+      $cds_sequence = tripal_get_feature_sequences(
+        array(
+          'feature_id' => $feature->feature_id,
+          'parent_id' => $attrs['featureloc']->srcfeature_id->feature_id,
+          'name' => $feature->name,
+          'featureloc_id' => $attrs['featureloc']->featureloc_id,
+        ),
+        array(
+          // CDS are in parent-child relationships so we want to use the
+          // sequence from the parent
+          'derive_from_parent' => 1,
+          // we want to combine all CDS for this feature into a single sequence
+          'aggregate' => 1,
+          // we're looking for CDS features
+          'sub_feature_types' => array('CDS'),
+          'is_html' => 0
+        )
+      );
+
+      if (count($cds_sequence) > 0) {
+        $defline = tripal_get_fasta_defline($feature, '', $attrs['featureloc'], 'CDS', strlen($attrs['residues']));
+
+        // the tripal_get_feature_sequences() function can return multiple sequences
+        // if a feature is aligned to multiple places. In the case of CDSs we expect
+        // that one mRNA is only aligned to a single location on the assembly so we
+        // can access the CDS sequence with index 0.
+        if ($cds_sequence[0]['residues']) {
+          $entity->{$field_name}['und'][$num_seqs++]['value'] = $defline . "\n" .  $cds_sequence[0]['residues'];
+        }
+      }
+    }
+  }
+}

+ 44 - 0
tripal_chado/includes/TripalFields/so__cds_formatter.inc

@@ -0,0 +1,44 @@
+<?php
+
+class so__cds_formatter extends TripalFieldFormatter {
+  // The default lable for this field.
+  public static $label = 'Coding Sequence';
+
+  // The list of field types for which this formatter is appropriate.
+  public static $field_types = array('so__cds');
+
+  // The list of default settings for this formatter.
+  public static $settings = array();
+
+  /**
+   * @see TripalFieldFormatter::view()
+   */
+  public function view(&$element, $entity_type, $entity, $langcode, $items, $display) {
+    $element[0] = array(
+      // We create a render array to produce the desired markup,
+      '#type' => 'markup',
+      '#markup' => '',
+    );
+
+    $num_bases = 50;
+    foreach ($items as $delta => $item) {
+      // If there are no residues then skip this one.
+      if (!is_array($item['value']) or !array_key_exists('residues', $item['value'])) {
+        continue;
+      }
+
+      $residues = $item['value']['residues'];
+
+      $content .= '<pre class="residues-formatter">';
+      $content .= '>' . $defline . "<br>";
+      $content .= wordwrap($residues, $num_bases, "<br>", TRUE);
+      $content .= '</pre>';
+
+      $element[$delta] = array(
+        // We create a render array to produce the desired markup,
+        '#type' => 'markup',
+        '#markup' => $content,
+      );
+    }
+  }
+}

+ 43 - 0
tripal_chado/includes/TripalFields/so__cds_widget.inc

@@ -0,0 +1,43 @@
+<?php
+
+class so__cds_widget extends TripalFieldWidget {
+  // The default lable for this field.
+  public static $label = 'Coding Sequence';
+
+  // The list of field types for which this formatter is appropriate.
+  public static $field_types = array('so__cds');
+
+  /**
+   *
+   * @see TripalFieldWidget::form()
+   */
+  public function form(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) {
+    parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element);
+
+    // TODO: add a widget...
+  }
+
+  /**
+   * Performs validation of the widgetForm.
+   *
+   * Use this validate to ensure that form values are entered correctly.  Note
+   * this is different from the validate() function which ensures that the
+   * field data meets expectations.
+   *
+   * @param $form
+   * @param $form_state
+   */
+  public function validate($form, &$form_state, $entity_type, $entity, $langcode, $delta) {
+
+  }
+
+
+  /**
+   *
+   * @see TripalFieldWidget::submit()
+   */
+  public function submit($form, &$form_state, $entity_type, $entity, $langcode, $delta) {
+    $field_name = $this->field['field_name'];
+
+  }
+}

+ 45 - 53
tripal_chado/includes/TripalFields/so__transcript.inc

@@ -19,7 +19,7 @@ class so__transcript extends TripalField {
   public static $term = 'SO:0000673';
   public static $term = 'SO:0000673';
 
 
   // The default lable for this field.
   // The default lable for this field.
-  public static $label = 'Transcript';
+  public static $label = 'Transcripts';
 
 
   // The default description for this field.
   // The default description for this field.
   public static $description = 'An RNA synthesized on a DNA or RNA template by an RNA polymerase.';
   public static $description = 'An RNA synthesized on a DNA or RNA template by an RNA polymerase.';
@@ -77,9 +77,11 @@ class so__transcript extends TripalField {
   public function load($entity, $details = array()) {
   public function load($entity, $details = array()) {
 
 
     $record = $details['record'];
     $record = $details['record'];
-    
     $field_name = $this->field['field_name'];
     $field_name = $this->field['field_name'];
-    
+    $field_type = $this->field['type'];
+    $field_table = $this->field['settings']['chado_table'];
+    $field_column = $this->field['settings']['chado_column'];
+
     // Set some defaults for the empty record.
     // Set some defaults for the empty record.
     $entity->{$field_name}['und'][0] = array(
     $entity->{$field_name}['und'][0] = array(
       'value' => array(
       'value' => array(
@@ -89,56 +91,46 @@ class so__transcript extends TripalField {
         'location' => '',
         'location' => '',
       ),
       ),
     );
     );
-    
-    // TODO: If the tripal_get_feature_relationships() slows this down then
-    // we may need to write a custom function to get the data.
-    $rels = tripal_get_feature_relationships($record);
-    
-    // TODO: what if other transcripts names from SO are used. In that
-    // case we should support those too (using cvtermpath table to find them).
-    // mRNA should not be hard-coded below.
-    
-    // Set the value to be a array of "table" rows.
-    $transcripts = array();
-    if (key_exists('part of', $rels['object']) &&
-        key_exists('mRNA', $rels['object']['part of'])) {
-          $transcripts =  $rels['object']['part of']['mRNA'];
-        }
-    
-        $headers = array('Name' ,'Identifier', 'Location');
-        $rows = array();
-        $i = 0;
-        foreach ($transcripts as $transcript) {
-          // link the feature to it's node
-          $feature_name = $transcript->record->subject_id->name;
-    
-          $locations = $transcript->child_featurelocs;
-          $loc = "";
-          foreach ($locations AS $location) {
-            $loc .= $location->srcfeature_name . ":" . $location->fmin . ".." . $location->fmax;
-          }
-          $type = $transcript->record->subject_id->type_id;
-          $entity->{$field_name}['und'][$i]['value'] = array(
-            'type' => $type->name,
-            'name' => $feature_name,
-            'identifier' => $transcript->record->subject_id->uniquename,
-            'location' => $loc,
-    
-          );
-          // Add in the semantic web information that describes each key in the
-          // value array.
-          $entity->{$field_name}['und'][$i]['semantic_web'] = array(
-            'type' => $type->dbxref_id->db_id->name . ":" . $type->dbxref_id->accession,
-            'name' => tripal_get_chado_semweb_term('cvterm', 'name'),
-            'identifier' => tripal_get_chado_semweb_term('feature', 'uniquename'),
-            'location' => '',
-          );
-          if (property_exists($transcript->record->subject_id, 'entity_id')) {
-            $entity_id = $transcript->record->subject_id->entity_id;
-            $entity->{$field_name}['und'][$i]['value']['entity'] = 'TripalEntity:' . $entity_id;
-          }
-          $i++;
-        }
+
+    // Get the mRNA features for this gene.
+    $sql = "
+      SELECT FS.name, FS.uniquename, FS.feature_id, FCVT.name as type
+      FROM {feature_relationship} FR
+        INNER JOIN {feature} FS on FS.feature_id = FR.subject_id
+        INNER JOIN {cvterm} FCVT on FCVT.cvterm_id = FS.type_id
+        INNER JOIN {cv} CV on CV.cv_id = FCVT.cv_id
+      WHERE
+        FR.object_id = :feature_id and
+        FCVT.name = 'mRNA' and
+        CV.name = 'sequence'
+    ";
+    $results = chado_query($sql, array(':feature_id' => $record->feature_id));
+    $i = 0;
+    while ($transcript = $results->fetchObject()) {
+      // Get the location of this mRNA.
+      $sql = "
+        SELECT FL.*, F.name as srcfeature_name
+        FROM {featureloc} FL
+          INNER JOIN {feature} F on F.feature_id = FL.srcfeature_id
+        WHERE FL.feature_id = :object_id
+      ";
+      $floc_results = chado_query($sql, array(':object_id' => $transcript->feature_id));
+      $loc = "";
+      while ($location = $floc_results->fetchObject()) {
+        $loc .= $location->srcfeature_name . ":" . $location->fmin . ".." . $location->fmax;
+      }
+      $entity->{$field_name}['und'][$i]['value'] = array(
+        'type' => $transcript->type,
+        'name' => $transcript->name,
+        'identifier' => $transcript->uniquename,
+        'location' => $loc,
+      );
+      $entity_id = tripal_get_chado_entity_id($field_table, $record->feature_id);
+      if ($entity_id) {
+         $entity->{$field_name}['und'][$i]['value']['entity'] = 'TripalEntity:' . $entity_id;
+       }
+      $i++;
+    }
   }
   }
 
 
 }
 }

+ 1 - 1
tripal_chado/includes/tripal_chado.custom_tables.inc

@@ -328,7 +328,7 @@ function tripal_custom_tables_form_validate($form, &$form_state) {
         $results = db_query($sql, array(':table_id' => $table_id));
         $results = db_query($sql, array(':table_id' => $table_id));
         $ct = $results->fetchObject();
         $ct = $results->fetchObject();
         if ($ct->table_name != $schema_array['table']) {
         if ($ct->table_name != $schema_array['table']) {
-          $exists = db_table_exists('chado.' . $schema_array['table']);
+          $exists = chado_table_exists($schema_array['table']);
           if ($exists) {
           if ($exists) {
             form_set_error($form_state['values']['schema'],
             form_set_error($form_state['values']['schema'],
               t("The table name already exists, please choose a different name."));
               t("The table name already exists, please choose a different name."));

+ 89 - 105
tripal_chado/includes/tripal_chado.field_storage.inc

@@ -44,9 +44,9 @@ function tripal_chado_field_storage_write($entity_type, $entity, $op, $fields) {
   $field_vals = tripal_chado_field_storage_write_merge_fields($fields, $entity_type, $entity);
   $field_vals = tripal_chado_field_storage_write_merge_fields($fields, $entity_type, $entity);
 
 
   // First, write the record for the base table.  If we have a record id then
   // First, write the record for the base table.  If we have a record id then
-  // this is an upate and we need to set the primary key.  If not, then this
+  // this is an update and we need to set the primary key.  If not, then this
   // is an insert and we need to set the type_id if the table supports it.
   // is an insert and we need to set the type_id if the table supports it.
-  $values = $field_vals[$base_table][0];
+  $values = $field_vals[$base_table];
   if ($record_id) {
   if ($record_id) {
     $values[$base_pkey] = $record_id;
     $values[$base_pkey] = $record_id;
   }
   }
@@ -109,93 +109,72 @@ function tripal_chado_field_storage_write($entity_type, $entity, $op, $fields) {
  *   The unique record ID.
  *   The unique record ID.
  */
  */
 function tripal_chado_field_storage_write_table($table_name, $values) {
 function tripal_chado_field_storage_write_table($table_name, $values) {
-   $schema = chado_get_schema($table_name);
-   $fkeys = $schema['foreign keys'];
-   $pkey = $schema['primary key'][0];
-
-
-//    // Before inserting or updating this table, recurse if there are any
-//    // nested FK array values.
-//    foreach ($values as $column => $value) {
-//      // If this value is an array then it must be a FK... let's recurse.
-//      if (is_array($value)) {
-
-//        // Find the name of the FK table for this column.
-//        $fktable_name = '';
-//        foreach ($fkeys as $fktable => $details) {
-//          foreach ($details['columns'] as $fkey_lcolumn => $fkey_rcolumn) {
-//            if ($fkey_lcolumn == $column) {
-//              $fktable_name = $fktable;
-//            }
-//          }
-//        }
-
-//        // Recurse on this recod.
-//        $record_id = tripal_chado_field_storage_write_table($fktable_name, $values[$column]);
-//        $values[$column] = $record_id;
-//      }
-//    }
-
-   // Fields with a cardinality greater than 1 will often submit an
-   // empty form.  We want to remove these empty submissions.  We can detect
-   // them if all of the fields are empty.
-   $num_empty = 0;
-   foreach ($values as $column => $value) {
-     if (!$value) {
-       $num_empty++;
-     }
-   }
-   if ($num_empty == count(array_keys($values))) {
-     return '';
-   }
-   // If the primary key column has a value but all other values are empty then
-   // this is a delete.
-   if (array_key_exists($pkey, $values) and $values[$pkey]) {
-     $num_vals = 0;
-     foreach ($values as $value) {
-       if ($value) {
-         $num_vals++;
-       }
-     }
-     if ($num_vals == 1) {
-       $new_vals[$pkey] = $values[$pkey];
-       if (!chado_delete_record($table_name, $new_vals)) {
-         throw new Exception('Could not delete record from table: "' . $table_name . '".');
-       }
-       return '';
-     }
-   }
+  $schema = chado_get_schema($table_name);
+  $fkeys = $schema['foreign keys'];
+  $pkey = $schema['primary key'][0];
+
+
+  // Fields with a cardinality greater than 1 will often submit an
+  // empty form.  We want to remove these empty submissions.  We can detect
+  // them if all of the fields are empty.
+  $num_empty = 0;
+  foreach ($values as $column => $value) {
+    if (!$value) {
+      $num_empty++;
+    }
+  }
+  if ($num_empty == count(array_keys($values))) {
+    return '';
+  }
 
 
-   // If the primary key column does not have a value then this is an insert.
-   if (!array_key_exists($pkey, $values) or !$values[$pkey] or !isset($values[$pkey])) {
-     // Before inserting, we want to make sure the record does not
-     // already exist.  Using the unique constraint check for a matching record.
-     $options = array('is_duplicate' => TRUE);
-     $is_duplicate = chado_select_record($table_name, array('*'), $values, $options);
-     if($is_duplicate) {
-       $record = chado_select_record($table_name, array('*'), $values);
-       return $record[0]->$pkey;
-     }
+  // If the primary key column has a value but all other values are empty then
+  // this is a delete.
+  if (array_key_exists($pkey, $values) and $values[$pkey]) {
+    $num_vals = 0;
+    foreach ($values as $value) {
+      if ($value) {
+        $num_vals++;
+      }
+    }
+    if ($num_vals == 1) {
+      $new_vals[$pkey] = $values[$pkey];
+      if (!chado_delete_record($table_name, $new_vals)) {
+        throw new Exception('Could not delete record from table: "' . $table_name . '".');
+      }
+      return '';
+    }
+  }
 
 
-     // Insert the values array as a new record in the table but remove the
-     // pkey as it should be set.
-     $new_vals = $values;
-     unset($new_vals[$pkey]);
-     $record = chado_insert_record($table_name, $new_vals);
-     if ($record === FALSE) {
-       throw new Exception('Could not insert Chado record into table: "' . $table_name . '".');
-     }
-     return $record[$pkey];
-   }
+  // If the primary key column does not have a value then this is an insert.
+  if (!array_key_exists($pkey, $values) or !$values[$pkey] or !isset($values[$pkey])) {
+    // Before inserting, we want to make sure the record does not
+    // already exist.  Using the unique constraint check for a matching record.
+    $options = array('is_duplicate' => TRUE);
+    $is_duplicate = chado_select_record($table_name, array('*'), $values, $options);
+    if($is_duplicate) {
+      $record = chado_select_record($table_name, array('*'), $values);
+      return $record[0]->$pkey;
+    }
 
 
-   // If we've made it to this point then this is an update.
-   // TODO: what if the unique constraint matches another record?  That is
-   // not being tested for here.
-   $match[$pkey] = $values[$pkey];
-   if (!chado_update_record($table_name, $match, $values)) {
-     drupal_set_message("Could not update Chado record in table: $table_name.", 'error');
-   }
-   return $values[$pkey];
+    // Insert the values array as a new record in the table but remove the
+    // pkey as it should be set.
+    $new_vals = $values;
+    unset($new_vals[$pkey]);
+    $record = chado_insert_record($table_name, $new_vals);
+    if ($record === FALSE) {
+      throw new Exception('Could not insert Chado record into table: "' . $table_name . '".');
+    }
+    return $record[$pkey];
+  }
+
+  // If we've made it to this point then this is an update.
+  // TODO: what if the unique constraint matches another record?  That is
+  // not being tested for here.
+  $match[$pkey] = $values[$pkey];
+  if (!chado_update_record($table_name, $match, $values)) {
+    drupal_set_message("Could not update Chado record in table: $table_name.", 'error');
+  }
+  return $values[$pkey];
 }
 }
 
 
 /**
 /**
@@ -244,17 +223,6 @@ function tripal_chado_field_storage_load($entity_type, $entities, $age,
     $record = chado_generate_var($base_table, $match);
     $record = chado_generate_var($base_table, $match);
     $entity->chado_record = $record;
     $entity->chado_record = $record;
 
 
-    // For now, expand all 'text' fields.
-    // TODO: we want to be a bit smarter and allow the user to configure this
-    // for now we'll expand.
-    if (isset($schema['fields'])) {
-      foreach ($schema['fields'] as $field_name => $details) {
-        if ($schema['fields'][$field_name]['type'] == 'text') {
-          $record = chado_expand_var($record, 'field', $base_table . '.' . $field_name);
-        }
-      }
-    }
-
     // Iterate through the entity's fields so we can get the column names
     // Iterate through the entity's fields so we can get the column names
     // that need to be selected from each of the tables represented.
     // that need to be selected from each of the tables represented.
     $tables = array();
     $tables = array();
@@ -331,7 +299,8 @@ function tripal_chado_field_storage_load($entity_type, $entities, $age,
  * Merges the values of all fields into a single array keyed by table name.
  * Merges the values of all fields into a single array keyed by table name.
  */
  */
 function tripal_chado_field_storage_write_merge_fields($fields, $entity_type, $entity) {
 function tripal_chado_field_storage_write_merge_fields($fields, $entity_type, $entity) {
-  $new_fields = array();
+  $all_fields = array();
+  $base_fields = array();
 
 
   // Iterate through all of the fields and organize them into a
   // Iterate through all of the fields and organize them into a
   // new fields array keyed by the table name
   // new fields array keyed by the table name
@@ -348,12 +317,12 @@ function tripal_chado_field_storage_write_merge_fields($fields, $entity_type, $e
     }
     }
     $chado_table = $field['settings']['chado_table'];
     $chado_table = $field['settings']['chado_table'];
     $chado_column = $field['settings']['chado_column'];
     $chado_column = $field['settings']['chado_column'];
+    $base_table = $field['settings']['base_table'];
 
 
     // Iterate through the field's items. Fields with cardinality ($delta) > 1
     // Iterate through the field's items. Fields with cardinality ($delta) > 1
     // are multi-valued.
     // are multi-valued.
     $items = field_get_items($entity_type, $entity, $field_name);
     $items = field_get_items($entity_type, $entity, $field_name);
     $temp = array();
     $temp = array();
-
     foreach ($items as $delta => $item) {
     foreach ($items as $delta => $item) {
 
 
       // A field may have multiple items. The field can use items
       // A field may have multiple items. The field can use items
@@ -364,30 +333,45 @@ function tripal_chado_field_storage_write_merge_fields($fields, $entity_type, $e
         if (preg_match('/^chado-(.*?)__(.*?)$/', $item_name, $matches)) {
         if (preg_match('/^chado-(.*?)__(.*?)$/', $item_name, $matches)) {
           $table_name = $matches[1];
           $table_name = $matches[1];
           $column_name = $matches[2];
           $column_name = $matches[2];
-          $temp[$table_name][$delta][$column_name] = $value;
+          // If this field belongs to the base table then we just add
+          // those values in... there's no delta.
+          if ($table_name == $base_table) {
+            $base_fields[$table_name][$column_name] = $value;
+          }
+          else {
+            $temp[$table_name][$delta][$column_name] = $value;
+          }
         }
         }
       }
       }
       // If there is no value set for the field using the
       // If there is no value set for the field using the
-      // chado-[table_name]__[field name] naming schema then check if a 'value' item
-      // is present and if so use that.
+      // chado-[table_name]__[field name] naming schema then check if a 'value'
+      // item is present and if so use that for the table column value.
       if ((!array_key_exists($chado_table, $temp) or
       if ((!array_key_exists($chado_table, $temp) or
            !array_key_exists($delta, $temp[$chado_table]) or
            !array_key_exists($delta, $temp[$chado_table]) or
            !array_key_exists($chado_column, $temp[$chado_table][$delta])) and
            !array_key_exists($chado_column, $temp[$chado_table][$delta])) and
           array_key_exists('value', $items[$delta]) and
           array_key_exists('value', $items[$delta]) and
           !is_array($items[$delta]['value'])) {
           !is_array($items[$delta]['value'])) {
-        $temp[$chado_table][$delta][$chado_column] = $items[$delta]['value'];
+        // If this field belongs to the base table then we just add
+        // those values in... there's no delta.
+        if ($base_table == $chado_table) {
+          $base_fields[$chado_table][$chado_column] = $items[$delta]['value'];
+        }
+        else {
+          $temp[$chado_table][$delta][$chado_column] = $items[$delta]['value'];
+        }
       }
       }
     }
     }
 
 
     // Now merge the records for this field with the $new_fields array
     // Now merge the records for this field with the $new_fields array
     foreach ($temp as $table_name => $details) {
     foreach ($temp as $table_name => $details) {
       foreach ($details as $delta => $list) {
       foreach ($details as $delta => $list) {
-        $new_fields[$table_name][] = $list;
+        $all_fields[$table_name][] = $list;
       }
       }
     }
     }
   }
   }
 
 
-  return $new_fields;
+  $all_fields = array_merge($base_fields, $all_fields);
+  return $all_fields;
 }
 }
 
 
 /**
 /**

+ 78 - 79
tripal_chado/includes/tripal_chado.fields.inc

@@ -98,19 +98,22 @@ function tripal_chado_bundle_create_fields_base(&$info, $details, $entity_type,
   // Get the list of columns for this table and create a new field for each one.
   // Get the list of columns for this table and create a new field for each one.
   $columns = $schema['fields'];
   $columns = $schema['fields'];
   foreach ($columns as $column_name => $details) {
   foreach ($columns as $column_name => $details) {
-    $field_name = $table_name . '__' . $column_name;
-
-    // Skip fields with a custom field:
-    if ($field_name == 'dbxref_id' or $field_name == 'organism_id') {
-      continue;
-    }
-    if ($table_name == 'feature' and ($field_name == 'md5checksum' or
-        $field_name == 'residues' or $field_name == 'seqlen')) {
-      continue;
-    }
-    if ($table_name == 'organism' and ($field_name == 'type_id')) {
-      continue;
-    }
+    $cvterm = tripal_get_chado_semweb_term($table_name, $column_name, array('return_object' => TRUE));
+    $semweb_term = $cvterm->dbxref_id->db_id->name . ':' . $cvterm->dbxref_id->accession;
+    //$field_name = $table_name . '__' . $column_name;
+    $field_name = strtolower($cvterm->dbxref_id->db_id->name . '__' . preg_replace('/ /', '_', $cvterm->name));
+
+//     // Skip fields with a custom field:
+//     if ($field_name == 'dbxref_id' or $field_name == 'organism_id') {
+//       continue;
+//     }
+//     if ($table_name == 'feature' and ($field_name == 'md5checksum' or
+//         $field_name == 'residues' or $field_name == 'seqlen')) {
+//       continue;
+//     }
+//     if ($table_name == 'organism' and ($field_name == 'type_id')) {
+//       continue;
+//     }
 
 
     // Skip the primary key field.
     // Skip the primary key field.
     if ($column_name == $schema['primary key'][0]) {
     if ($column_name == $schema['primary key'][0]) {
@@ -122,6 +125,7 @@ function tripal_chado_bundle_create_fields_base(&$info, $details, $entity_type,
       continue;
       continue;
     }
     }
 
 
+
     // Set some defaults for the field.
     // Set some defaults for the field.
     $base_info = array(
     $base_info = array(
       'field_name' => $field_name,
       'field_name' => $field_name,
@@ -134,7 +138,8 @@ function tripal_chado_bundle_create_fields_base(&$info, $details, $entity_type,
       'settings' => array(
       'settings' => array(
         'chado_table' => $table_name,
         'chado_table' => $table_name,
         'chado_column' => $column_name,
         'chado_column' => $column_name,
-        'semantic_web' => tripal_get_chado_semweb_term($table_name, $column_name),
+        'base_table' => $table_name,
+        'semantic_web' => $semweb_term,
       ),
       ),
     );
     );
 
 
@@ -234,6 +239,7 @@ function tripal_chado_bundle_create_fields_custom(&$info, $details, $entity_type
       'settings' => array(
       'settings' => array(
         'chado_table' => $table_name,
         'chado_table' => $table_name,
         'chado_column' => 'organism_id',
         'chado_column' => 'organism_id',
+        'base_table' => $table_name,
       ),
       ),
     );
     );
   }
   }
@@ -253,6 +259,7 @@ function tripal_chado_bundle_create_fields_custom(&$info, $details, $entity_type
       'settings' => array(
       'settings' => array(
         'chado_table' => $table_name,
         'chado_table' => $table_name,
         'chado_column' => 'dbxref_id',
         'chado_column' => 'dbxref_id',
+        'base_table' => $table_name,
         'semantic_web' => tripal_get_chado_semweb_term($table_name, 'dbxref_id'),
         'semantic_web' => tripal_get_chado_semweb_term($table_name, 'dbxref_id'),
       ),
       ),
     );
     );
@@ -273,6 +280,7 @@ function tripal_chado_bundle_create_fields_custom(&$info, $details, $entity_type
       'settings' => array(
       'settings' => array(
         'chado_table' => $table_name,
         'chado_table' => $table_name,
         'chado_column' => 'md5checksum',
         'chado_column' => 'md5checksum',
+        'base_table' => $table_name,
         'semantic_web' => tripal_get_chado_semweb_term($table_name, 'md5checksum'),
         'semantic_web' => tripal_get_chado_semweb_term($table_name, 'md5checksum'),
       ),
       ),
     );
     );
@@ -293,11 +301,11 @@ function tripal_chado_bundle_create_fields_custom(&$info, $details, $entity_type
       'settings' => array(
       'settings' => array(
         'chado_table' => $table_name,
         'chado_table' => $table_name,
         'chado_column' => 'residues',
         'chado_column' => 'residues',
-        'semantic_web' => tripal_get_chado_semweb_term($table_name, 'residues'),
+        'base_table' => $table_name,
       ),
       ),
     );
     );
   }
   }
-  
+
   // FEATURE SEQLEN
   // FEATURE SEQLEN
   if ($table_name == 'feature') {
   if ($table_name == 'feature') {
     $field_name = 'data__sequence_length';
     $field_name = 'data__sequence_length';
@@ -313,7 +321,7 @@ function tripal_chado_bundle_create_fields_custom(&$info, $details, $entity_type
       'settings' => array(
       'settings' => array(
         'chado_table' => $table_name,
         'chado_table' => $table_name,
         'chado_column' => 'seqlen',
         'chado_column' => 'seqlen',
-        'semantic_web' => tripal_get_chado_semweb_term($table_name, 'seqlen'),
+        'base_table' => $table_name,
       ),
       ),
     );
     );
   }
   }
@@ -335,30 +343,28 @@ function tripal_chado_bundle_create_fields_custom(&$info, $details, $entity_type
         'chado_table' => $rel_table,
         'chado_table' => $rel_table,
         'chado_column' => '',
         'chado_column' => '',
         'base_table' => $table_name,
         'base_table' => $table_name,
-        'semantic_web' => 'SO:0000673',
       ),
       ),
     );
     );
   }
   }
 
 
   // ORGANISM TYPE_ID
   // ORGANISM TYPE_ID
-  if ($table_name == 'organism' and array_key_exists('type_id', $schema['fields'])) {
-    $field_name = 'taxarank__infraspecific_taxon';
-    $field_type = 'taxarank__infraspecific_taxon';
-    $info[$field_name] = array(
-      'field_name' => $field_name,
-      'type' => $field_type,
-      'cardinality' => 1,
-      'locked' => FALSE,
-      'storage' => array(
-        'type' => 'field_chado_storage',
-      ),
-      'settings' => array(
-        'chado_table' => 'organism',
-        'chado_column' => 'type_id',
-        'semantic_web' => 'TAXRANK:0000046',
-      ),
-    );
-  }
+//   if ($table_name == 'organism' and array_key_exists('type_id', $schema['fields'])) {
+//     $field_name = 'taxarank__infraspecific_taxon';
+//     $field_type = 'taxarank__infraspecific_taxon';
+//     $info[$field_name] = array(
+//       'field_name' => $field_name,
+//       'type' => $field_type,
+//       'cardinality' => 1,
+//       'locked' => FALSE,
+//       'storage' => array(
+//         'type' => 'field_chado_storage',
+//       ),
+//       'settings' => array(
+//         'chado_table' => 'organism',
+//         'chado_column' => 'type_id',
+//       ),
+//     );
+//   }
 }
 }
 
 
 /**
 /**
@@ -392,7 +398,6 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
         'chado_table' => $contact_table,
         'chado_table' => $contact_table,
         'base_table' => $table_name,
         'base_table' => $table_name,
         'chado_column' => 'contact_id',
         'chado_column' => 'contact_id',
-        'semantic_web' => tripal_get_chado_semweb_term($table_name, 'contact_id'),
       ),
       ),
     );
     );
   }
   }
@@ -435,7 +440,6 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
         'chado_table' => $dbxref_table,
         'chado_table' => $dbxref_table,
         'chado_column' => $pkey,
         'chado_column' => $pkey,
         'base_table' => $table_name,
         'base_table' => $table_name,
-        'semantic_web' => 'SBO:0000554',
       ),
       ),
     );
     );
   }
   }
@@ -459,7 +463,6 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
         'chado_table' => $expression_table,
         'chado_table' => $expression_table,
         'chado_column' => $pkey,
         'chado_column' => $pkey,
         'base_table' => $table_name,
         'base_table' => $table_name,
-        'semantic_web' => 'GO:0010467',
       ),
       ),
     );
     );
   }
   }
@@ -482,7 +485,6 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
         'chado_table' => 'featureloc',
         'chado_table' => 'featureloc',
         'chado_column' => $pkey,
         'chado_column' => $pkey,
         'base_table' => 'feature',
         'base_table' => 'feature',
-        'semantic_web' => 'data:2012',
       ),
       ),
     );
     );
   }
   }
@@ -505,7 +507,6 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
         'chado_table' => 'featurepos',
         'chado_table' => 'featurepos',
         'chado_column' => $pkey,
         'chado_column' => $pkey,
         'base_table' => 'feature',
         'base_table' => 'feature',
-        'semantic_web' => 'OGI:0000021',
       ),
       ),
     );
     );
   }
   }
@@ -528,7 +529,6 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
       'settings' => array(
       'settings' => array(
         'chado_table' => $genotype_table,
         'chado_table' => $genotype_table,
         'chado_column' => $pkey,
         'chado_column' => $pkey,
-        'semantic_web' => 'SO:0001027',
         'base_table' => $table_name,
         'base_table' => $table_name,
       ),
       ),
     );
     );
@@ -553,7 +553,6 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
         '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',
       ),
       ),
     );
     );
   }
   }
@@ -596,7 +595,6 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
         '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',
       ),
       ),
     );
     );
   }
   }
@@ -621,7 +619,6 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
         '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',
       ),
       ),
     );
     );
   }
   }
@@ -645,7 +642,6 @@ function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type
         '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',
       ),
       ),
     );
     );
   }
   }
@@ -721,7 +717,10 @@ function tripal_chado_bundle_create_instances_base(&$info, $entity_type, $bundle
 
 
   $columns = $schema['fields'];
   $columns = $schema['fields'];
   foreach ($columns as $column_name => $details) {
   foreach ($columns as $column_name => $details) {
-    $field_name = $table_name . '__' . $column_name;
+    $cvterm = tripal_get_chado_semweb_term($table_name, $column_name, array('return_object' => TRUE));
+    $semweb_term = $cvterm->dbxref_id->db_id->name . ':' . $cvterm->dbxref_id->accession;
+    //$field_name = $table_name . '__' . $column_name;
+    $field_name = strtolower($cvterm->dbxref_id->db_id->name . '__' . preg_replace('/ /', '_', $cvterm->name));
 
 
     // Skip the primary key field.
     // Skip the primary key field.
     if ($column_name == $schema['primary key'][0]) {
     if ($column_name == $schema['primary key'][0]) {
@@ -991,7 +990,7 @@ function tripal_chado_bundle_create_instances_custom(&$info, $entity_type, $bund
       'field_name' => $field_name,
       'field_name' => $field_name,
       'entity_type' => $entity_type,
       'entity_type' => $entity_type,
       'bundle' => $bundle->name,
       'bundle' => $bundle->name,
-      'label' => 'Sequences',
+      'label' => 'Sequence',
       'description' => 'All available sequences for this record.',
       'description' => 'All available sequences for this record.',
       'required' => FALSE,
       'required' => FALSE,
       'settings' => array(
       'settings' => array(
@@ -1053,8 +1052,8 @@ function tripal_chado_bundle_create_instances_custom(&$info, $entity_type, $bund
       'field_name' => $field_name,
       'field_name' => $field_name,
       'entity_type' => $entity_type,
       'entity_type' => $entity_type,
       'bundle' => $bundle->name,
       'bundle' => $bundle->name,
-      'label' => 'Transcript',
-      'description' => 'These transcripts are associated with this gene.',
+      'label' => 'Transcripts',
+      'description' => 'Transcripts that are part of this gene.',
       'required' => FALSE,
       'required' => FALSE,
       'settings' => array(
       'settings' => array(
         'auto_attach' => FALSE,
         'auto_attach' => FALSE,
@@ -1076,33 +1075,33 @@ function tripal_chado_bundle_create_instances_custom(&$info, $entity_type, $bund
   }
   }
 
 
   // ORGANISM TYPE_ID
   // ORGANISM TYPE_ID
-  if ($table_name == 'organism' and array_key_exists('type_id', $schema['fields'])) {
-    $field_name = 'taxarank__infraspecific_taxon';
-    $info[$field_name] = array(
-      'field_name' => $field_name,
-      'entity_type' => $entity_type,
-      'bundle' => $bundle->name,
-      'label' => 'Infraspecific Taxon',
-      'description' => 'The Infraspecific Taxon.',
-      'required' => FALSE,
-      'settings' => array(
-        'auto_attach' => TRUE,
-      ),
-      'widget' => array(
-        'type' => 'taxarank__infraspecific_taxon_widget',
-        'settings' => array(
-          'display_label' => 1,
-        ),
-      ),
-      'display' => array(
-        'default' => array(
-          'label' => 'inline',
-          'type' => 'taxarank__infraspecific_taxon_formatter',
-          'settings' => array(),
-        ),
-      ),
-    );
-  }
+//   if ($table_name == 'organism' and array_key_exists('type_id', $schema['fields'])) {
+//     $field_name = 'taxarank__infraspecific_taxon';
+//     $info[$field_name] = array(
+//       'field_name' => $field_name,
+//       'entity_type' => $entity_type,
+//       'bundle' => $bundle->name,
+//       'label' => 'Infraspecific Taxon',
+//       'description' => 'The Infraspecific Taxon.',
+//       'required' => FALSE,
+//       'settings' => array(
+//         'auto_attach' => TRUE,
+//       ),
+//       'widget' => array(
+//         'type' => 'taxarank__infraspecific_taxon_widget',
+//         'settings' => array(
+//           'display_label' => 1,
+//         ),
+//       ),
+//       'display' => array(
+//         'default' => array(
+//           'label' => 'inline',
+//           'type' => 'taxarank__infraspecific_taxon_formatter',
+//           'settings' => array(),
+//         ),
+//       ),
+//     );
+//   }
 }
 }
 
 
 /**
 /**
@@ -1131,7 +1130,7 @@ function tripal_chado_bundle_create_instances_linker(&$info, $entity_type, $bund
       'description' => 'Associates an indviddual or organization with this record',
       'description' => 'Associates an indviddual or organization with this record',
       'required' => FALSE,
       'required' => FALSE,
       'settings' => array(
       'settings' => array(
-        'auto_attach' => TRUE,
+        'auto_attach' => FALSE,
       ),
       ),
       'widget' => array(
       'widget' => array(
         'type' => 'local__contact_widget',
         'type' => 'local__contact_widget',
@@ -1148,7 +1147,7 @@ function tripal_chado_bundle_create_instances_linker(&$info, $entity_type, $bund
       ),
       ),
     );
     );
   }
   }
-  
+
   // CVTERM
   // CVTERM
   $cvterm_table = $table_name . '_cvterm';
   $cvterm_table = $table_name . '_cvterm';
   if (chado_table_exists($cvterm_table)) {
   if (chado_table_exists($cvterm_table)) {

+ 20 - 20
tripal_chado/includes/tripal_chado.mapping.inc

@@ -37,44 +37,44 @@ function tripal_chado_map_cvterms() {
         }
         }
       }
       }
     }
     }
-    
+
     // Now we also want to map tripal terms for existing bundles
     // Now we also want to map tripal terms for existing bundles
-    $sql = 
-      "SELECT 
+    $sql =
+      "SELECT
          (SELECT vocabulary FROM tripal_vocab TV WHERE id = TM.vocab_id),
          (SELECT vocabulary FROM tripal_vocab TV WHERE id = TM.vocab_id),
-          accession, 
-          name 
+          accession,
+          name
        FROM tripal_term TM";
        FROM tripal_term TM";
     $results = db_query($sql);
     $results = db_query($sql);
     while ($tripal_term = $results->fetchObject()) {
     while ($tripal_term = $results->fetchObject()) {
       $voc = $tripal_term->vocabulary;
       $voc = $tripal_term->vocabulary;
       $accession = $tripal_term->accession;
       $accession = $tripal_term->accession;
       $name = $tripal_term->name;
       $name = $tripal_term->name;
-      $dbxref_sql = 
-        "SELECT dbxref_id 
-          FROM {dbxref} 
-          WHERE 
-            accession = :accession 
-          AND 
+      $dbxref_sql =
+        "SELECT dbxref_id
+          FROM {dbxref}
+          WHERE
+            accession = :accession
+          AND
             db_id = (SELECT db_id FROM {db} WHERE name = :voc)";
             db_id = (SELECT db_id FROM {db} WHERE name = :voc)";
       $dbxref_id = chado_query($dbxref_sql, array(':accession' => $accession, ':voc' => $voc))->fetchField();
       $dbxref_id = chado_query($dbxref_sql, array(':accession' => $accession, ':voc' => $voc))->fetchField();
       if ($dbxref_id) {
       if ($dbxref_id) {
-        $cvterm_sql = 
-          "SELECT cvterm_id 
-            FROM {cvterm} 
-            WHERE 
-              dbxref_id = :dbxref_id 
+        $cvterm_sql =
+          "SELECT cvterm_id
+            FROM {cvterm}
+            WHERE
+              dbxref_id = :dbxref_id
             AND name = :name";
             AND name = :name";
         $cvterm_id = chado_query($cvterm_sql, array(':dbxref_id' => $dbxref_id, ':name' => $name))->fetchField();
         $cvterm_id = chado_query($cvterm_sql, array(':dbxref_id' => $dbxref_id, ':name' => $name))->fetchField();
         if ($cvterm_id) {
         if ($cvterm_id) {
          // Check if this term is already mapped in the tripal_cvterm_mapping table
          // Check if this term is already mapped in the tripal_cvterm_mapping table
-         $check_sql = 
-           "SELECT mapping_id 
-             FROM tripal_cvterm_mapping 
+         $check_sql =
+           "SELECT mapping_id
+             FROM tripal_cvterm_mapping
              WHERE cvterm_id = :cvterm_id";
              WHERE cvterm_id = :cvterm_id";
          $mapped = db_query($check_sql, array(':cvterm_id' => $cvterm_id))->fetchField();
          $mapped = db_query($check_sql, array(':cvterm_id' => $cvterm_id))->fetchField();
          // If mapping does not exist and a table name matches the term name, add it
          // If mapping does not exist and a table name matches the term name, add it
-         if (!$mapped && db_table_exists('chado.' . $name)) {
+         if (!$mapped && chado_table_exists($name)) {
            print "Adding mapped tripal term: $name\n";
            print "Adding mapped tripal term: $name\n";
            tripal_chado_add_cvterm_mapping($cvterm_id, $name, NULL);
            tripal_chado_add_cvterm_mapping($cvterm_id, $name, NULL);
          }
          }

+ 5 - 4
tripal_chado/includes/tripal_chado.migrate.inc

@@ -472,10 +472,11 @@ function tripal_chado_migrate_form_step2_ajax_callback(&$form, &$form_state) {
  */
  */
 function tripal_chado_get_tripal_v2_content_type_options($all_option = FALSE, $has_template = FALSE) {
 function tripal_chado_get_tripal_v2_content_type_options($all_option = FALSE, $has_template = FALSE) {
   // Get all available Tripal v2 chado tables
   // Get all available Tripal v2 chado tables
-  $sql =
-  "SELECT table_name
-      FROM information_schema.tables
-      WHERE table_schema = 'public' AND table_name LIKE 'chado_%'";
+  $sql = "
+    SELECT table_name
+    FROM information_schema.tables
+    WHERE table_schema = 'public' AND table_name LIKE 'chado_%'
+  ";
   $result = db_query($sql);
   $result = db_query($sql);
   // Store 'chado_*' tables that has at least one node
   // Store 'chado_*' tables that has at least one node
   $tables = array();
   $tables = array();