Browse Source

Fixes to templates and update to GFF3 loader

spficklin 14 years ago
parent
commit
94ef4739bb
23 changed files with 906 additions and 555 deletions
  1. 7 1
      theme_tripal/css/tripal_feature.css
  2. 29 14
      theme_tripal/node-chado_feature.tpl.php
  3. 7 9
      theme_tripal/tripal_feature/tripal_feature_base.tpl.php
  4. 138 0
      theme_tripal/tripal_feature/tripal_feature_featurelocs.tpl.php
  5. 0 60
      theme_tripal/tripal_feature/tripal_feature_featurelocs_as_child.tpl.php
  6. 0 62
      theme_tripal/tripal_feature/tripal_feature_featurelocs_as_parent.tpl.php
  7. 50 23
      theme_tripal/tripal_feature/tripal_feature_properties.tpl.php
  8. 25 29
      theme_tripal/tripal_feature/tripal_feature_references.tpl.php
  9. 119 0
      theme_tripal/tripal_feature/tripal_feature_relationships.tpl.php
  10. 0 45
      theme_tripal/tripal_feature/tripal_feature_relationships_as_object.tpl.php
  11. 0 43
      theme_tripal/tripal_feature/tripal_feature_relationships_as_subject.tpl.php
  12. 11 11
      theme_tripal/tripal_feature/tripal_feature_sequence.tpl.php
  13. 12 4
      theme_tripal/tripal_feature/tripal_feature_synonyms.tpl.php
  14. 3 2
      theme_tripal/tripal_organism/tripal_organism_base.tpl.php
  15. 1 1
      theme_tripal/tripal_organism/tripal_organism_description.tpl.php
  16. 2 2
      theme_tripal/tripal_stock/tripal_stock_properties.tpl.php
  17. 3 0
      tripal_analysis_blast/tripal_analysis_blast.module
  18. 43 10
      tripal_core/tripal_core.api.inc
  19. 2 2
      tripal_db/tripal_db.api.inc
  20. 156 11
      tripal_feature/gff_loader.php
  21. 95 1
      tripal_feature/tripal_feature.api.inc
  22. 137 129
      tripal_feature/tripal_feature.module
  23. 66 96
      tripal_organism/tripal_organism.module

+ 7 - 1
theme_tripal/css/tripal_feature.css

@@ -67,4 +67,10 @@ table.tripal_feature-references-table th {
    float: none;
    display: block;
 }
-
+.tripal_feature-obsolete {
+   color: red;
+   font-weight: bold;
+   font-style: italic;
+   padding-bottom: 15px; 
+   text-align: center;
+}

+ 29 - 14
theme_tripal/node-chado_feature.tpl.php

@@ -26,6 +26,7 @@
  //print '<pre>'.print_r($variables,TRUE).'</pre>';
 drupal_add_css('./tripal-node-templates.css');
 $feature  = $variables['node']->feature;
+dpm($feature);
 ?>
 
 <?php if ($teaser) { 
@@ -89,30 +90,44 @@ if (Drupal.jsEnabled) {
    <?php include('tripal_feature/tripal_feature_synonyms.tpl.php'); ?>
 
    <!-- Sequence -->
-   <?php include('tripal_feature/tripal_feature_sequence.tpl.php'); ?>
+   <?php 
+   if($feature->type_id->name == 'scaffold' or 
+      $feature->type_id->name == 'chromosome' or
+      $feature->type_id->name == 'pseudomolecule')
+   {
+      // don't even try to load the sequence for really big feature types.
+   } 
+   else {
+      include('tripal_feature/tripal_feature_sequence.tpl.php'); 
+   }
+   ?>
 
    <!-- Formatted Sequences -->
    <?php include('tripal_feature/tripal_feature_featureloc_sequences.tpl.php'); ?>
 
-   <!-- Object Relationships -->
-   <?php include('tripal_feature/tripal_feature_relationships_as_object.tpl.php'); ?>
-
-   <!-- Subject Relationships -->
-   <?php include('tripal_feature/tripal_feature_relationships_as_subject.tpl.php'); ?>
-
-   <!-- Feature locations as Child -->
-   <?php include('tripal_feature/tripal_feature_featurelocs_as_child.tpl.php'); ?>
-
-   <!-- Subject Relationships -->
-   <?php include('tripal_feature/tripal_feature_featurelocs_as_parent.tpl.php'); ?>
+   <!-- Relationships -->
+   <?php include('tripal_feature/tripal_feature_relationships.tpl.php'); ?>
+
+   <!-- Feature locations -->
+   <?php 
+   if($feature->type_id->name == 'scaffold' or 
+      $feature->type_id->name == 'chromosome' or
+      $feature->type_id->name == 'pseudomolecule')
+   {
+      // don't even try to load the feature locations for features that are typically
+      // very large landmarks
+   } 
+   else {
+      include('tripal_feature/tripal_feature_featurelocs.tpl.php'); 
+   }
+   ?>
 
    <?php print $content ?>
 </div>
 
 <!-- Table of contents -->
 <div id="tripal_feature_toc" class="tripal_toc">
-   <div id="tripal_feature_toc_title" class="tripal_toc_title">Resources for <?php print $feature->cvname?><br><?php print $feature->featurename ?></div>
-   <span id="tripal_feature_toc_desc" class="tripal_toc_desc">Select a link below for more information</span>
+   <div id="tripal_feature_toc_title" class="tripal_toc_title">Resources</div>
    <ul id="tripal_feature_toc_list" class="tripal_toc_list">
 
    </ul>

+ 7 - 9
theme_tripal/tripal_feature/tripal_feature_base.tpl.php

@@ -1,21 +1,19 @@
 <?php
 
 $feature  = $variables['node']->feature;
-$accession = $variables['node']->accession;
-$organism = $variables['node']->organism;
-$org_nid = $variables['node']->org_nid;
+
 ?>
 <div id="tripal_feature-base-box" class="tripal_feature-info-box tripal-info-box">
   <div class="tripal_feature-info-box-title tripal-info-box-title">Feature Details</div>
   <div class="tripal_feature-info-box-desc tripal-info-box-desc"></div>
 
-   <?php if($feature->is_obsolete == 't'){ ?>
-      <div class="tripal_feature-obsolete">This feature is obsolete and no longer used in analysis, but is here for reference</div>
+   <?php if(strcmp($feature->is_obsolete,'t')==0){ ?>
+      <div class="tripal_feature-obsolete">This feature is obsolete</div>
    <?php }?>
    <table id="tripal_feature-base-table" class="tripal_feature-table tripal-table tripal-table-vert">
       <tr class="tripal_feature-table-odd-row tripal-table-even-row">
         <th>Name</th>
-        <td><?php print $feature->featurename; ?></td>
+        <td><?php print $feature->name; ?></td>
       </tr>
       <tr class="tripal_feature-table-odd-row tripal-table-odd-row">
         <th nowrap>Unique Name</th>
@@ -23,7 +21,7 @@ $org_nid = $variables['node']->org_nid;
       </tr>
       <tr class="tripal_feature-table-odd-row tripal-table-even-row">
         <th>Internal ID</th>
-        <td><?php print $accession; ?></td>
+        <td><?php print $feature->feature_id; ?></td>
       </tr>
       <tr class="tripal_feature-table-odd-row tripal-table-odd-row">
         <th>Length</th>
@@ -31,7 +29,7 @@ $org_nid = $variables['node']->org_nid;
       </tr>
       <tr class="tripal_feature-table-odd-row tripal-table-even-row">
         <th>Type</th>
-        <td><?php print $feature->cvname; ?></td>
+        <td><?php print $feature->type_id->name; ?></td>
       </tr>
       <tr class="tripal_feature-table-odd-row tripal-table-odd-row">
         <th>Organism</th>
@@ -40,7 +38,7 @@ $org_nid = $variables['node']->org_nid;
       	   <a href="<?php print url("node/$org_nid") ?>"><?php print $organism->genus ." " . $organism->species ." (" .$organism->common_name ." )"?></a>
       	 <?php 
           } else { 
-            print $organism->genus ." " . $organism->species ." (" .$organism->common_name ." )";
+            print $feature->organism_id->genus ." " . $feature->organism_id->species ." (" .$feature->organism_id->common_name .")";
           } ?>
         </td>
      	</tr>           	                                

+ 138 - 0
theme_tripal/tripal_feature/tripal_feature_featurelocs.tpl.php

@@ -0,0 +1,138 @@
+<?php
+
+$feature = $variables['node']->feature;
+
+// get the featurelocs. if only one featureloc exists then we want to convert
+// the object into an array, otherwise the value is an array
+$ffeaturelocs = $feature->featureloc->feature_id;
+if (!$ffeaturelocs) {
+   $ffeaturelocs = array();
+} elseif (!is_array($ffeaturelocs)) { 
+   $ffeaturelocs = array($ffeaturelocs); 
+}
+$sfeaturelocs = $feature->featureloc->srcfeature_id;
+if (!$sfeaturelocs) {
+   $sfeaturelocs = array();
+} elseif (!is_array($sfeaturelocs)) { 
+   $sfeaturelocs = array($sfeaturelocs); 
+}
+
+?>
+<div id="tripal_feature-featurelocs_as_child-box" class="tripal_feature-info-box tripal-info-box">
+  <div class="tripal_feature-info-box-title tripal-info-box-title">Alignments</div>
+  <div class="tripal_feature-info-box-desc tripal-info-box-desc"><?php print $feature->name;?> is aligined to the following</div>
+  <?php if(count($ffeaturelocs) > 0){ ?>
+  <table id="tripal_feature-featurelocs_as_child-table" class="tripal_feature-table tripal-table tripal-table-horz">
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Location</th>
+      <th>Phase</th>
+      <th>Direction</th>
+    </tr>
+    <?php
+      $i = 0; 
+      foreach ($ffeaturelocs as $featureloc){
+
+         $class = 'tripal_feature-table-odd-row tripal-table-odd-row';
+         if($i % 2 == 0 ){
+            $class = 'tripal_feature-table-odd-row tripal-table-even-row';
+         } 
+         $location = $featureloc->srcfeature_id->name .":".$featureloc->fmin . ".." . $featureloc->fmax;
+         if($location->srcfeature_id->nid){
+           $location = "<a href=\"" . url("node/$location->srcfeature_id->nid") . "\">".$featureloc->srcfeature_id->name .":".$featureloc->fmin . ".." . $featureloc->fmax ."</a> ";
+         }
+         ?>
+         <tr class="<?php print $class ?>">
+           <td><?php 
+              if($featureloc->feature_id->nid){
+                 print "<a href=\"" . url("node/".$featureloc->feature_id->name) . "\">".$featureloc->feature_id->name."</a>";
+              } else {
+                 print $featureloc->feature_id->name;
+              }?>
+           </td>
+           <td><?php print $featureloc->feature_id->type_id->name ?></td>
+           <td><?php print $location ?></td>
+           <td><?php print $featureloc->phase ?></td>
+           <td><?php 
+              if($featureloc->strand == -1){
+                 print "reverse";
+              } 
+              elseif($featureloc->strand == 1){
+                 print "forward";
+              } 
+              elseif($featureloc->strand == 0){
+                 print "N/A";
+              } 
+              else {
+                 print $featureloc->strand;
+              }?>
+            </td>
+         </tr>
+         <?php
+         $i++;  
+      } ?>
+    </table>
+  <?php } else { ?>
+    <div class="tripal-no-results">There are no alignments</div> 
+  <?php }?>
+
+  <br><br><div class="tripal_feature-info-box-desc tripal-info-box-desc">The following are aligned to <?php print $feature->name;?></div>
+  <?php if(count($sfeaturelocs) > 0){ ?>
+  <table id="tripal_feature-featurelocs_as_child-table" class="tripal_feature-table tripal-table tripal-table-horz">
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Location</th>
+      <th>Phase</th>
+      <th>Direction</th>
+    </tr>
+    <?php
+      $i = 0; 
+      foreach ($sfeaturelocs as $featureloc){
+
+         $class = 'tripal_feature-table-odd-row tripal-table-odd-row';
+         if($i % 2 == 0 ){
+            $class = 'tripal_feature-table-odd-row tripal-table-even-row';
+         } 
+         $location = $featureloc->srcfeature_id->name .":".$featureloc->fmin . ".." . $featureloc->fmax;
+         if($location->srcfeature_id->nid){
+           $location = "<a href=\"" . url("node/$location->srcfeature_id->nid") . "\">".$featureloc->srcfeature_id->name .":".$featureloc->fmin . ".." . $featureloc->fmax ."</a> ";
+         }
+         ?>
+         <tr class="<?php print $class ?>">
+           <td><?php 
+              if($featureloc->feature_id->nid){
+                 print "<a href=\"" . url("node/".$featureloc->feature_id->name) . "\">".$featureloc->feature_id->name."</a>";
+              } else {
+                 print $featureloc->feature_id->name;
+              }?>
+           </td>
+           <td><?php print $featureloc->feature_id->type_id->name ?></td>
+           <td><?php print $location ?></td>
+           <td><?php print $featureloc->phase ?></td>
+           <td><?php 
+              if($featureloc->strand == -1){
+                 print "reverse";
+              } 
+              elseif($featureloc->strand == 1){
+                 print "forward";
+              } 
+              elseif($featureloc->strand == 0){
+                 print "N/A";
+              } 
+              else {
+                 print $featureloc->strand;
+              }?>
+            </td>
+         </tr>
+         <?php
+         $i++;  
+      } ?>
+    </table>
+  <?php } else { ?>
+    <div class="tripal-no-results">There are no alignments</div> 
+  <?php }?>
+</div>
+
+

+ 0 - 60
theme_tripal/tripal_feature/tripal_feature_featurelocs_as_child.tpl.php

@@ -1,60 +0,0 @@
-<?php
-
-$featurelocs_as_child = $variables['tripal_feature']['featurelocs_as_child'];
-$feature = $variables['node']->feature;
-
-?>
-<div id="tripal_feature-featurelocs_as_child-box" class="tripal_feature-info-box tripal-info-box">
-  <div class="tripal_feature-info-box-title tripal-info-box-title">Locations where <?php print $feature->featurename;?> is found</div>
-  <div class="tripal_feature-info-box-desc tripal-info-box-desc">The <?php print $feature->featurename;?> feature is located relative to the following features:</div>
-  <?php if(count($featurelocs_as_child) > 0){ ?>
-  <table id="tripal_feature-featurelocs_as_child-table" class="tripal_feature-table tripal-table tripal-table-horz">
-    <tr>
-      <th>Name</th>
-      <th>Type</th>
-      <th>Position</th>
-      <th>Phase</th>
-      <th>Direction</th>
-    </tr>
-    <?php
-      $i = 0; 
-      foreach ($featurelocs_as_child as $index => $loc){
-         $class = 'tripal_feature-table-odd-row tripal-table-odd-row';
-         if($i % 2 == 0 ){
-            $class = 'tripal_feature-table-odd-row tripal-table-even-row';
-         } 
-         $src_name = $loc->src_name;
-         if($loc->snid){
-           $src_name = "<a href=\"" . url("node/$loc->snid") . "\">".$loc->src_name .":".$loc->fmin . ".." . $loc->fmax ."</a> ";
-         }
-         ?>
-         <tr class="<?php print $class ?>">
-           <td><?php print $loc->name ?></td>
-           <td><?php print $loc->cvname ?></td>
-           <td><?php print $src_name ?></td>
-           <td><?php print $loc->phase ?></td>
-           <td><?php 
-              if($loc->strand == -1){
-                 print "reverse";
-              } 
-              elseif($loc->strand == 1){
-                 print "forward";
-              } 
-              elseif($loc->strand == 0){
-                 print "N/A";
-              } 
-              else {
-                 print $loc->strand;
-              }?>
-            </td>
-         </tr>
-         <?php
-         $i++;  
-      } ?>
-    </table>
-  <?php } else { ?>
-    <div class="tripal-no-results">There are no locations where this feature is found</div> 
-  <?php }?>
-</div>
-
-

+ 0 - 62
theme_tripal/tripal_feature/tripal_feature_featurelocs_as_parent.tpl.php

@@ -1,62 +0,0 @@
-<?php
-
-$featurelocs_as_parent = $variables['tripal_feature']['featurelocs_as_parent'];
-$feature = $variables['node']->feature;
-
-?>
-<div id="tripal_feature-featurelocs_as_parent-box" class="tripal_feature-info-box tripal-info-box">
-  <div class="tripal_feature-info-box-title tripal-info-box-title">Features located relative to <?php print $feature->featurename;?></div>
-  <div class="tripal_feature-info-box-desc tripal-info-box-desc">The features shown below are located relative to <?php print $feature->featurename;?></div>
-  <?php if(count($featurelocs_as_parent) > 0){ ?>
-  <table id="tripal_feature-featurelocs_as_parent-table" class="tripal_feature-table tripal-table tripal-table-horz">
-    <tr>
-      <th>Name</th>
-      <th>Type</th>
-      <th>Position</th>
-      <th>Phase</th>
-      <th>Direction</th>
-    </tr>
-    <?php
-      $i = 0; 
-      foreach ($featurelocs_as_parent as $index => $loc){
-         $class = 'tripal_feature-table-odd-row tripal-table-odd-row';
-         if($i % 2 == 0 ){
-            $class = 'tripal_feature-table-odd-row tripal-table-even-row';
-         } 
-         $locname = $loc->name;
-         if($loc->fnid){
-           $locname = "<a href=\"" . url("node/$loc->fnid") . "\">$loc->name</a> ";
-         }
-         ?>
-         <tr class="<?php print $class ?>">
-           <td><?php print $locname ?></td>
-           <td><?php print $loc->cvname ?></td>
-           <td><?php print $loc->src_name .":".$loc->fmin . ".." . $loc->fmax ?></td>
-           <td>
-             <?php print $loc->phase ?>
-           </td>
-           <td><?php 
-              if($loc->strand == -1){
-                 print "reverse";
-              } 
-              elseif($loc->strand == 1){
-                 print "forward";
-              } 
-              elseif($loc->strand == 0){
-                 print "N/A";
-              } 
-              else {
-                 print $loc->strand;
-              }?>
-           </td>
-         </tr>
-         <?php
-         $i++;  
-      } ?>
-  </table>
-  <?php } else { ?>
-    <div class="tripal-no-results">There are no features located relative to <?php print $feature->featurename;?></div> 
-  <?php }?>
-</div>
-
-

+ 50 - 23
theme_tripal/tripal_feature/tripal_feature_properties.tpl.php

@@ -1,31 +1,58 @@
 <?php
-$properties = $variables['tripal_feature']['properties'];
-$feature = $variables['node']->feature;
+// Purpose: Provide layout and content for feature properties. This includes all
+//   fields in the featureprop table with the feature_id of the current feature
+//   supplemented with extra details for the type to provide human-readable
+//   output
+//
+// Note: This template controls the layout/content for the default feature node
+//   template (node-chado_feature.tpl.php) and the Feature Properties Block
+//
+// Variables Available:
+//   - $node: a standard object which contains all the fields associated with
+//       nodes including nid, type, title, taxonomy. It also includes feature
+//       specific fields such as feature_name, uniquename, feature_type, synonyms,
+//       properties, db_references, object_relationships, subject_relationships,
+//       organism, etc.
+//   - $node->properties: an array of feature property objects where each object
+//       the following fields: featureprop_id, type_id, type, value, rank
+//       and includes synonyms
+//   NOTE: For a full listing of fields available in the node object the
+//       print_r $node line below or install the Drupal Devel module which 
+//       provides an extra tab at the top of the node page labelled Devel
 ?>
+
+<?php
+ //uncomment this line to see a full listing of the fields avail. to $node
+ //print '<pre>'.print_r($node,TRUE).'</pre>';
+?>
+
+<?php
+  $properties = $node->feature->featureprop;
+  if (!$properties) {
+    $properties = array();
+  } elseif (!is_array($properties)) { 
+    $properties = array($properties); 
+  }
+?>
+
 <div id="tripal_feature-properties-box" class="tripal_feature-info-box tripal-info-box">
   <div class="tripal_feature-info-box-title tripal-info-box-title">Properties</div>
-  <div class="tripal_feature-info-box-desc tripal-info-box-desc">The feature '<?php print $feature->featurename ?>' has these properties</div>
-  <?php if(count($properties) > 0){ ?>
-  <table id="tripal_feature-properties-table" class="tripal_feature-table tripal-table tripal-table-horz">
-    <tr>
-      <th>Synonym</th>
-    </tr>
-    <?php
-    $i = 0; 
-    foreach ($properties as $result){
-      $class = 'tripal_feature-table-odd-row tripal-table-odd-row';
+  <div class="tripal_feature-info-box-desc tripal-info-box-desc">Properties for the feature '<?php print $node->feature->name ?>' include:</div>
+	<?php if(count($properties) > 0){ ?>
+  <table class="tripal_feature-table tripal-table tripal-table-horz">
+  <tr><th>Type</th><th>Value</th></tr>
+	<?php	// iterate through each property
+		$i = 0;
+		foreach ($properties as $result){
+		  $class = 'tripal_feature-table-odd-row tripal-table-odd-row';
       if($i % 2 == 0 ){
          $class = 'tripal_feature-table-odd-row tripal-table-even-row';
       }
-      ?>
-      <tr class="<?php print $class ?>">
-        <td><?php print $result->name?></td>
-      </tr>
-      <?php
-      $i++;  
-    } ?>
-  </table>
-  <?php } else { ?>
-    <div class="tripal-no-results">There are no properties for this feature</div> 
-  <?php }?>
+			print '<tr class="'.$class.'"><td>'.$result->type_id->name.'</td><td>'.$result->value.'</td></tr>';
+			$i++;
+		} ?>
+		</table>
+	<?php } else {
+	  print '<div class="tripal-no-results">There are no properties for the current feature.</div>';
+	} ?>
 </div>

+ 25 - 29
theme_tripal/tripal_feature/tripal_feature_references.tpl.php

@@ -1,31 +1,24 @@
 <?php
-
-/*
-
-References variables
---------------------
-
-$variables['references']:  an array of references indexed 0 .. n, where 'n' the
-  number of references available for this feature.
-
-These variables are avaliable for each reference in the array:
-  
-  uniquename
-  feature_id
-  accession
-  dbdesc
-  db_id
-  db_name
-  urlprefix
-  dbxref_id
-
-*/
-$references = $variables['tripal_feature']['references'];
 $feature = $variables['node']->feature;
+
+// get the references. if only one reference exists then we want to convert
+// the object into an array, otherwise the value is an array
+$references = $feature->feature_dbxref;
+if (!$references) {
+   $references = array();
+} elseif (!is_array($references)) { 
+   $references = array($references); 
+}
+// check to see if the reference 'GFF_source' is there.  This reference is
+// used to help the GBrowse chado adapter find features.  We don't need to show
+// it
+if($references[0]->dbxref_id->db_id->name == 'GFF_source' and count($references)==1){
+   $references = array();
+}
 ?>
 <div id="tripal_feature-references-box" class="tripal_feature-info-box tripal-info-box">
   <div class="tripal_feature-info-box-title tripal-info-box-title">References</div>
-  <div class="tripal_feature-info-box-desc tripal-info-box-desc">The feature '<?php print $feature->featurename ?>' is also available at these locations</div>
+  <div class="tripal_feature-info-box-desc tripal-info-box-desc">External references for this <?php print $feature->type_id->name ?></div>
   <?php if(count($references) > 0){ ?>
   <table id="tripal_feature-references-table" class="tripal_feature-table tripal-table tripal-table-horz">
     <tr>
@@ -34,19 +27,22 @@ $feature = $variables['node']->feature;
     </tr>
     <?php
     $i = 0; 
-    foreach ($references as $result){ 
+    foreach ($references as $feature_dbxref){ 
+      if($feature_dbxref->dbxref_id->db_id->name == 'GFF_source'){
+         continue;  // skip the GFF_source entry as this is just needed for the GBrowse chado adapter
+      }
       $class = 'tripal_feature-table-odd-row tripal-table-odd-row';
       if($i % 2 == 0 ){
          $class = 'tripal_feature-table-odd-row tripal-table-even-row';
       }
       ?>
       <tr class="<?php print $class ?>">
-        <td><?php print $result->db_name?></td>
+        <td><?php print $feature_dbxref->dbxref_id->db_id->name?></td>
         <td><?php 
-           if($result->urlprefix){ 
-              ?><a href="<?php print $result->urlprefix.$result->accession?>" target="_blank"><?php print $result->accession?></a><?php 
+           if($feature_dbxref->db_id->urlprefix){ 
+              ?><a href="<?php print $feature_dbxref->db_id->urlprefix.$feature_dbxref->dbxref_id->accession?>" target="_blank"><?php print $feature_dbxref->dbxref_id->accession?></a><?php 
            } else { 
-             print $result->accession; 
+             print $feature_dbxref->dbxref_id->accession; 
            } 
            ?>
         </td>
@@ -56,6 +52,6 @@ $feature = $variables['node']->feature;
     } ?>
   </table>
   <?php } else { ?>
-    <div class="tripal-no-results">There are no references for this feature</div> 
+    <div class="tripal-no-results">There are no external references</div> 
   <?php }?>
 </div>

+ 119 - 0
theme_tripal/tripal_feature/tripal_feature_relationships.tpl.php

@@ -0,0 +1,119 @@
+<?php
+
+$feature = $variables['node']->feature;
+
+// get the featurelocs. if only one featureloc exists then we want to convert
+// the object into an array, otherwise the value is an array
+$orelationships = $feature->feature_relationship->object_id;
+if (!$orelationships) {
+   $orelationships = array();
+} elseif (!is_array($orelationships)) { 
+   $orelationships = array($orelationships); 
+}
+// do the same for the subject relationships
+$srelationships = $feature->feature_relationship->subject_id;
+if (!$srelationships) {
+   $srelationships = array();
+} elseif (!is_array($srelationships)) { 
+   $srelationships = array($srelationships); 
+}
+// now combine the two
+$relationships = array_merge($orelationships,$srelationships);
+
+
+?>
+<div id="tripal_feature-relationships-box" class="tripal_feature-info-box tripal-info-box">
+  <div class="tripal_feature-info-box-title tripal-info-box-title">Relationships</div>
+  <div class="tripal_feature-info-box-desc tripal-info-box-desc">Subject relationships</div>
+  <?php if(count($srelationships) > 0){ ?>
+  <table id="tripal_feature-subject_relationships-table" class="tripal_feature-table tripal-table tripal-table-horz">
+    <tr>
+      <th>Subject</th>
+      <th>Type</th>
+      <th>Relationship</th>
+      <th>Object</th>
+      <th>Type</th>
+    </tr>
+    <?php
+    $i = 0; 
+
+    foreach ($srelationships as $relationship){  
+      $class = 'tripal_feature-table-odd-row tripal-table-odd-row';
+      if($i % 2 == 0 ){
+         $class = 'tripal_feature-table-odd-row tripal-table-even-row';
+      }
+      $subject_name = $relationship->subject_id->name;
+      if(!$subject_name){
+         $subject_name = $relationship->subject_id->uniquename;
+      }
+      $object_name = $relationship->object_id->name;
+      if(!$object_name){
+         $object_name = $relationship->object_id->uniquename;
+      }?>
+      <tr class="<?php print $class ?>">
+        <td><?php print $subject_name?></td>
+        <td><?php print $relationship->subject_id->type_id->name?></td>
+        <td><b><?php print $relationship->type_id->name?></b></td>
+        <td>
+           <?php if(isset($relationship->object_id->nid)){
+                  print "<a href=\"" . url("node/".$relationship->object_id->nid) . "\">$object_name</a>";
+           } else {
+                  print "$object_name";
+           }?> 
+        </td>
+        <td><?php print $relationship->object_id->type_id->name?></td>
+      </tr>
+    <?php } ?>
+  </table>
+  <?php } else {?>
+    <div class="tripal-no-results">There are no subject relationships for this feature</div>
+  <?php } ?> 
+
+
+  <br><br><div class="tripal_feature-info-box-desc tripal-info-box-desc">Object relationships</div>
+  <?php if(count($orelationships) > 0){ ?>
+
+  <table id="tripal_feature-object_relationships-table" class="tripal_feature-table tripal-table tripal-table-horz">
+    <tr>
+      <th>Subject</th>
+      <th>Type</th>
+      <th>Relationship</th>
+      <th>Object</th>
+      <th>Type</th>
+    </tr>
+    <?php
+    $i = 0; 
+
+    foreach ($orelationships as $relationship){  
+      $class = 'tripal_feature-table-odd-row tripal-table-odd-row';
+      if($i % 2 == 0 ){
+         $class = 'tripal_feature-table-odd-row tripal-table-even-row';
+      }
+      $subject_name = $relationship->subject_id->name;
+      if(!$subject_name){
+         $subject_name = $relationship->subject_id->uniquename;
+      }
+      $object_name = $relationship->object_id->name;
+      if(!$object_name){
+         $object_name = $relationship->object_id->uniquename;
+      }?>
+      <tr class="<?php print $class ?>">
+        <td>
+           <?php if(isset($relationship->subject_id->nid)){
+                  print "<a href=\"" . url("node/".$relationship->subject_id->nid) . "\">$subject_name</a>";
+           } else {
+                  print "$subject_name";
+           }?>     
+        </td>
+        <td><?php print $relationship->subject_id->type_id->name?></td>
+        <td><b><?php print $relationship->type_id->name?></b></td>
+        <td><?php  print "$object_name";?> </td>
+        <td><?php print $relationship->object_id->type_id->name?></td>
+      </tr>
+    <?php } ?>
+  </table>
+  <?php } else {?>
+    <div class="tripal-no-results">There are no object relationships for this feature</div>
+  <?php } ?> 
+</div>
+

+ 0 - 45
theme_tripal/tripal_feature/tripal_feature_relationships_as_object.tpl.php

@@ -1,45 +0,0 @@
-<?php
-
-$object_relationships = $variables['tripal_feature']['object_relationships'];
-$feature = $variables['node']->feature;
-
-?>
-<div id="tripal_feature-object_relationships-box" class="tripal_feature-info-box tripal-info-box">
-  <div class="tripal_feature-info-box-title tripal-info-box-title">Object Relationships</div>
-  <div class="tripal_feature-info-box-desc tripal-info-box-desc">The feature '<?php print $feature->featurename ?>' has an object relationship with the following</div>
-  <?php if(count($object_relationships) > 0){ ?>
-  <table id="tripal_feature-object_relationships-table" class="tripal_feature-table tripal-table tripal-table-horz">
-    <tr>
-      <th>Name</th>
-      <th>Type</th>
-      <th>Relationship</th>
-    </tr>
-    <?php
-    $i = 0; 
-    foreach ($object_relationships as $result){   
-      $class = 'tripal_feature-table-odd-row tripal-table-odd-row';
-      if($i % 2 == 0 ){
-         $class = 'tripal_feature-table-odd-row tripal-table-even-row';
-      }
-      $subject_name = $result->subject_name;
-      if(!$subject_name){
-         $subject_name = $result->subject_uniquename;
-      }?>
-      <tr class="<?php print $class ?>">
-        <td>
-           <?php if(isset($result->subject_nid)){
-                  print "<a href=\"" . url("node/$result->subject_nid") . "\">$result->subject_name ($result->subject_type)</a> ";
-           } else {
-                  print "$subject_name";
-           }?>     
-        </td>
-        <td><?php print $result->subject_type?></td>
-        <td><b><?php print $result->rel_type?></b></td>
-      </tr>
-    <?php } ?>
-  </table>
-  <?php } else {?>
-    <div class="tripal-no-results">There are no object relationships for this feature</div>
-  <?php } ?> 
-</div>
-

+ 0 - 43
theme_tripal/tripal_feature/tripal_feature_relationships_as_subject.tpl.php

@@ -1,43 +0,0 @@
-<?php
-
-$subject_relationships = $variables['tripal_feature']['subject_relationships'];
-$feature = $variables['node']->feature;
-
-?>
-<div id="tripal_feature-subject_relationships-box" class="tripal_feature-info-box tripal-info-box">
-  <div class="tripal_feature-info-box-title tripal-info-box-title">Subject Relationships</div>
-  <div class="tripal_feature-info-box-desc tripal-info-box-desc">The feature '<?php print $feature->featurename ?>' has a subject relationship with the following</div>
-  <?php if(count($subject_relationships) > 0){ ?>
-  <table id="tripal_feature-subject_relationships-table" class="tripal_feature-table tripal-table tripal-table-horz">
-    <tr>
-      <th>Relationship</th>
-      <th>Feature</th>
-      <th>Type</th>
-    </tr>
-    <?php
-    $i = 0; 
-    foreach ($subject_relationships as $result){ 
-      $class = 'tripal_feature-table-odd-row tripal-table-odd-row';
-      if($i % 2 == 0 ){
-         $class = 'tripal_feature-table-odd-row tripal-table-even-row';
-      } ?>
-      <tr class="<?php print $class ?>">
-        <td><b><?php print $result->rel_type?></b></td>
-        <td> 
-           <?php if(isset($result->object_nid)){
-             print "<a href=\"" . url("node/$result->object_nid") . "\">$result->object_name</a> ";
-           } else {
-             print "$result->object_name ";
-           } ?>
-        </td>
-        <td><?php print $result->object_type?></td>          
-      </tr>
-      <?php
-      $i++;  
-    }?>
-  </table>
-  <?php } else { ?>
-    <div class="tripal-no-results">There are no subject relationships for this feature</div> 
-  <?php }?>
-</div>
-

+ 11 - 11
theme_tripal/tripal_feature/tripal_feature_sequence.tpl.php

@@ -2,16 +2,16 @@
 $feature = $variables['node']->feature;
 ?>
 <div id="tripal_feature-sequence-box" class="tripal_feature-info-box tripal-info-box">
-  <div class="tripal_feature-info-box-title tripal-info-box-title"><?php print $feature->cvname ?> Sequence</div>
-  <div class="tripal_feature-info-box-desc tripal-info-box-desc">The nucleotide or peptide sequence for this feature</div>
-  <?php print $feature->cvname; ?> sequence        
-  <pre id="tripal_feature-sequence-residues"><?php 
-     if($feature->residues){
-        // format the sequence to break ever 100 residues
-        print ereg_replace("(.{60})","\\1<br>",$feature->residues); 
-     } else {
-        print "sequence currently not available";
-     } ?>
-  </pre>
+  <div class="tripal_feature-info-box-title tripal-info-box-title"><?php print $feature->type_id->name ?> Sequence</div>
+  <div class="tripal_feature-info-box-desc tripal-info-box-desc">The sequence for this <?php print $feature->type_id->name; ?> </div>
+  <?php 
+  if($feature->residues){ ?>   
+    <pre id="tripal_feature-sequence-residues"><?php 
+    // format the sequence to break ever 100 residues
+    print ereg_replace("(.{60})","\\1<br>",$feature->residues); ?>  
+    </pre> <?php
+  } else {
+      print '<div class="tripal-no-results">The sequence is currently not available</div>';
+  } ?>
 </div>
 

+ 12 - 4
theme_tripal/tripal_feature/tripal_feature_synonyms.tpl.php

@@ -1,11 +1,19 @@
 <?php
-$synonyms = $variables['tripal_feature']['synonyms'];
 $feature = $variables['node']->feature;
 
+// get the references. if only one reference exists then we want to convert
+// the object into an array, otherwise the value is an array
+$synonyms = $feature->feature_synonym;
+if (!$synonyms) {
+   $synonyms = array();
+} elseif (!is_array($synonyms)) { 
+   $synonyms = array($synonyms); 
+}
+
 ?>
 <div id="tripal_feature-synonyms-box" class="tripal_feature-info-box tripal-info-box">
   <div class="tripal_feature-info-box-title tripal-info-box-title">Synonyms</div>
-  <div class="tripal_feature-info-box-desc tripal-info-box-desc">The feature '<?php print $feature->featurename ?>' has the following synonyms</div>
+  <div class="tripal_feature-info-box-desc tripal-info-box-desc">The feature '<?php print $feature->name ?>' has the following synonyms</div>
   <?php if(count($synonyms) > 0){ ?>
   <table id="tripal_feature-synonyms-table" class="tripal_feature-table tripal-table tripal-table-horz">
     <tr>
@@ -13,14 +21,14 @@ $feature = $variables['node']->feature;
     </tr>
     <?php
     $i = 0; 
-    foreach ($synonyms as $result){
+    foreach ($synonyms as $feature_synonym){
       $class = 'tripal-table-odd-row';
       if($i % 2 == 0 ){
          $class = 'tripal-table-even-row';
       }
       ?>
       <tr class="<?php print $class ?>">
-        <td><?php print $result->name?></td>
+        <td><?php print $feature_synonym->synonym_id->name?></td>
       </tr>
       <?php
       $i++;  

+ 3 - 2
theme_tripal/tripal_organism/tripal_organism_base.tpl.php

@@ -1,5 +1,6 @@
 <?php
-$organism = $variables['node']->organism;
+  $organism = $variables['node']->organism;
+  
 ?>
 <div id="tripal_organism-base-box" class="tripal_organism-info-box tripal-info-box">
   <div class="tripal_organism-info-box-title tripal-info-box-title">Organism Details</div>
@@ -25,7 +26,7 @@ $organism = $variables['node']->organism;
    </table>
    <table  id="tripal_organism-table-description" class="tripal_organism-table tripal-table tripal-table-horz">
       <tr class="tripal_organism-table-odd-row tripal-table-even-row">
-        <td><?php print $organism->description; ?></td>
+        <td><?php print $organism->comment; ?></td>
       </tr>        	                                
    </table>
 </div>

+ 1 - 1
theme_tripal/tripal_organism/tripal_organism_description.tpl.php

@@ -5,7 +5,7 @@ $organism = $variables['node']->organism;
   <div class="tripal_organism-info-box-title tripal-info-box-title">Organism Description</div>
    <table id="tripal_organism-table-description" class="tripal_organism-table tripal-table tripal-table-horz">
       <tr class="tripal_organism-table-odd-row tripal-table-even-row">
-        <td><?php print $organism->description; ?></td>
+        <td><?php print $organism->comment; ?></td>
       </tr>        	                                
    </table>
 </div>

+ 2 - 2
theme_tripal/tripal_stock/tripal_stock_properties.tpl.php

@@ -55,6 +55,6 @@
 		} ?>
 		</table>
 	<?php } else {
-	  print '<b>There are no properties for the current stock.</b>';
+	  print '<div class="tripal-no-results">There are no properties for the current stock.</div>';
 	} ?>
-</div>
+</div>

+ 3 - 0
tripal_analysis_blast/tripal_analysis_blast.module

@@ -167,6 +167,9 @@ function tripal_get_feature_blast_results($feature_id, $db_id, $max){
       ),         
    );
    $blast_results = tripal_core_chado_select('analysisfeatureprop',array('*'),$select);
+   if (!$blast_results){
+      return;
+   }
 
 	// get the HTML content for viewing each of the XML file
 	$blast_obj_array = array ();

+ 43 - 10
tripal_core/tripal_core.api.inc

@@ -438,12 +438,17 @@ function tripal_core_chado_update($table,$match,$values){
 *     value for the number of recrods rather than the array of records.  this
 *     can be useful in 'if' statements to check the presence of particula records.
 *  - return_sql
-*     Set this to 'true' to have this function return an array where the first element is the sql 
-*     that would have been run and the second is an array of arguments.
+*     Set this to 'true' to have this function return an array where the first 
+*     element is the sql that would have been run and the second is an array of 
+*     arguments.
 *  - case_insensitive_columns
 *     An array of columns to do a case insensitive search on.
 *  - regex_columns
 *     An array of columns where the value passed in should be treated as a regular expression
+*  - order_by
+*     An associative array containing the column names of the table as keys
+*     and the type of sort (i.e. ASC, DESC) as the values.  The results in the
+*     query will be sorted by the key values in the direction listed by the value
 * 
 * @return
 *  A database query result resource, FALSE if the query was not executed 
@@ -482,6 +487,7 @@ function tripal_core_chado_select($table,$columns,$values,$options = null){
     if (!is_array($options)) { $options = array(); }
     if (!$options['case_insensitive_columns']) { $options['case_insensitive_columns'] = array(); }
     if (!$options['regex_columns']) { $options['regex_columns'] = array(); }
+    if (!$options['order_by']) { $options['order_by'] = array(); }
     
    if (!is_array($columns)){
       watchdog('tripal_feature', 'the $columns argument for tripal_core_chado_select must be an array.');
@@ -569,9 +575,18 @@ function tripal_core_chado_select($table,$columns,$values,$options = null){
          }
        }
      }
-     $sql = substr($sql,0,-4);  // get rid of the trailing 'AND'
+     $sql = substr($sql,0,-4);  // get rid of the trailing 'AND '
+   }
+   // finally add any ordering of the results to the SQL statement
+   if(count($options['order_by']) > 0){
+      $sql .= " ORDER BY ";
+      foreach($options['order_by'] as $field => $dir){
+         $sql .= "$field $dir, ";
+      }
+      $sql = substr($sql,0,-2);  // get rid of the trailing ', '
    }
 
+
    // if the caller has requested the SQL rather than the results...
    // which happens in the case of wanting to use the Drupal pager, then do so
    if($options['return_sql']){
@@ -694,6 +709,11 @@ function tripal_core_chado_get_foreign_key($table_desc,$field,$values, $options
  * @param $values
  *   A select values array that selects the records you want from the base table
  *   (this has the same form as tripal_core_chado_select)
+ * @param $base_options
+ *   An array containing options for the base table.  For example, an
+ *   option of 'order_by' may be used to sort results in the base table
+ *   if more than one are returned.  The options must be compatible with
+ *   the options accepted by the tripal_core_chado_select() function.
  * @return
  *   Either an object (if only one record was selected from the base table) 
  *   or an array of objects (if more than one record was selected from the base table).
@@ -733,7 +753,7 @@ function tripal_core_chado_get_foreign_key($table_desc,$field,$values, $options
  *
  * @ingroup tripal_api
  */
-function tripal_core_generate_chado_var($table, $values) {
+function tripal_core_generate_chado_var($table, $values, $base_options=array()) {
   
   // get description for the current table----------------------------------------------------------
   $table_desc = module_invoke_all('chado_'.$table.'_schema');
@@ -810,7 +830,7 @@ function tripal_core_generate_chado_var($table, $values) {
   } //end of foreach type to be removed
   
   // get the values for the record in the current table---------------------------------------------
-  $results = tripal_core_chado_select($table, $table_columns, $values);   
+  $results = tripal_core_chado_select($table, $table_columns, $values,$base_options);   
   
   foreach ($results as $key => $object) {
     // Add empty expandable_x arrays
@@ -931,7 +951,11 @@ function tripal_core_generate_chado_var($table, $values) {
  *   Must be one of 'field', 'table', 'node'. Indicates what is being expanded.
  * @param $to_expand
  *   The name of the field/table/node to be expanded
- *
+ * @param $table_options
+ *   An array containing options for the base table.  For example, an
+ *   option of 'order_by' may be used to sort results in the base table
+ *   if more than one are returned.  The options must be compatible with
+ *   the options accepted by the tripal_core_chado_select() function.
  * @return
  *   A chado object supplemented with the field/table/node requested to be expanded
  *
@@ -955,7 +979,7 @@ function tripal_core_generate_chado_var($table, $values) {
  *
  * @ingroup tripal_api
  */
-function tripal_core_expand_chado_vars ($object, $type, $to_expand, $values = NULL) {
+function tripal_core_expand_chado_vars ($object, $type, $to_expand,$table_options = array()) {
   $base_table = $object->tablename;
   
   // check to see if they are expanding an array of objects
@@ -1025,12 +1049,21 @@ function tripal_core_expand_chado_vars ($object, $type, $to_expand, $values = NU
           }
           $foreign_object = tripal_core_generate_chado_var(
             $foreign_table,
-            $values
+            array($left => $object->{$right}),
+            $table_options
           );
   
           if ($foreign_object) {
-            $object->{$foreign_table} = $foreign_object;
-            $object->expanded = $to_expand;
+            // in the case where the a foreign key relationships exists more 
+            // than once with the same table we want to alter the 
+            // array structure
+            if(count($foreign_table_desc['foreign keys'][$base_table]['columns']) > 1){
+               $object->{$foreign_table}->{$left} = $foreign_object;
+               $object->expanded = $to_expand;
+            } else {
+               $object->{$foreign_table} = $foreign_object;
+               $object->expanded = $to_expand;
+            }
           }
         }
       } else {

+ 2 - 2
tripal_db/tripal_db.api.inc

@@ -278,7 +278,7 @@ function tripal_db_get_dbxref_by_accession ($accession, $db_id=0) {
  *
  * @ingroup tripal_schema_api
  */
-function tripal_stock_chado_dbxref_schema() {
+function tripal_db_chado_dbxref_schema() {
   $description = array();
 
   $description['foreign keys']['db'] = array(
@@ -289,4 +289,4 @@ function tripal_stock_chado_dbxref_schema() {
   ); 
 
   return $description;
-}
+}

+ 156 - 11
tripal_feature/gff_loader.php

@@ -248,6 +248,9 @@ function tripal_core_load_gff3($gff_file, $organism_id,$analysis_id,$add_only =0
 
    $num_lines = sizeof($lines);
    $interval = intval($num_lines * 0.01);
+   if($interval == 0){
+      $interval = $num_lines;
+   }
    $in_fasta = 0;
    foreach ($lines as $line_num => $line) {
       $i++;  // update the line count
@@ -278,6 +281,7 @@ function tripal_core_load_gff3($gff_file, $organism_id,$analysis_id,$add_only =0
       $cols = explode("\t",$line);
       if(sizeof($cols) != 9){
          print "ERROR: improper number of columns on line $i\n";
+         print_r($cols);
          return '';
       }
       // get the column values
@@ -438,9 +442,10 @@ function tripal_core_load_gff3($gff_file, $organism_id,$analysis_id,$add_only =0
             $attr_uniquename,$attr_name,$residues,$attr_is_analysis,
             $attr_is_obsolete, $add_only);
 
-         // store all of the features so far use later by parent and target
+         // store all of the features for use later by parent and target
          // relationships
          $gff_features[$feature->uniquename]['type'] = $type;
+         $gff_features[$feature->uniquename]['strand'] = $strand;
 
          if($feature){
 
@@ -459,16 +464,72 @@ function tripal_core_load_gff3($gff_file, $organism_id,$analysis_id,$add_only =0
             if(array_key_exists('Dbxref',$tags)){
                tripal_core_load_gff3_dbxref($feature,$tags['Dbxref']);
             }
+            // add any aliases for this feature
+            if(array_key_exists('Ontology_term',$tags)){
+               tripal_core_load_gff3_ontology($feature,$tags['Ontology_term']);
+            }
             // add parent relationships
             if(array_key_exists('Parent',$tags)){
-               tripal_core_load_gff3_parents($feature,$cvterm,$tags['Parent'],$gff_features,$organism_id);
+               tripal_core_load_gff3_parents($feature,$cvterm,$tags['Parent'],$gff_features,$organism_id,$fmin);
             }
             // add in the GFF3_source dbxref so that GBrowse can find the feature using the source column
             $source_ref = array('GFF_source:'.$source);
             tripal_core_load_gff3_dbxref($feature,$source_ref);
          }
+      }      
+   }
+   // now set the rank of any parent/child relationships.  The order is based
+   // on the fmin.  The start rank is 1.  This allows features with other
+   // relationships to be '0' (the default), and doesn't interfer with the
+   // ordering defined here.
+   foreach($gff_features as $parent => $details){
+      // only iterate through parents that have children
+
+      if($details['children']){
+         // get the parent
+         $values = array(
+            'uniquename' => $parent,
+            'type_id' => array(
+               'cv_id' => array(
+                  'name' => 'sequence'
+               ),
+               'name' => $details['type'],
+            ),
+            'organism_id' => $organism->organism_id,
+         );
+         $pfeature = tripal_core_chado_select('feature',array('*'),$values);
+
+         // sort the children by order of their fmin positions (values of assoc. array)
+         // if the parent is on the reverse strand then sort in reverse
+         if($details['strand'] == -1){
+            arsort($details['children']); 
+         } else {
+            asort($details['children']); 
+         }
+
+         // now iterate through the children and set their rank
+         $rank = 1;
+         print "Updating child ranks for $parent (".$details['type'].")\n";
+         foreach($details['children'] as $kfeature_id => $kfmin){
+            $match = array(
+               'object_id' => $pfeature[0]->feature_id,
+               'subject_id' => $kfeature_id,
+               'type_id' => array(
+                  'cv_id' => array(
+                     'name' => 'relationship'
+                  ),
+                  'name' => 'part_of',
+               ),
+            );
+            $values = array(
+               'rank' => $rank,          
+            );
+            tripal_core_chado_update('feature_relationship',$match,$values);
+            $rank++;
+         }
       }
    }
+
    tripal_db_set_active($previous_db);
    return '';
 }
@@ -478,7 +539,7 @@ function tripal_core_load_gff3($gff_file, $organism_id,$analysis_id,$add_only =0
  *
  * @ingroup gff3_loader
  */
-function tripal_core_load_gff3_parents($feature,$cvterm,$parents,$gff_features,$organism_id){
+function tripal_core_load_gff3_parents($feature,$cvterm,$parents,&$gff_features,$organism_id,$fmin){
 
    $uname = $feature->uniquename;
    $type = $cvterm->name;
@@ -499,10 +560,17 @@ function tripal_core_load_gff3_parents($feature,$cvterm,$parents,$gff_features,$
    foreach($parents as $parent){  
       $parent_type = $gff_features[$parent]['type'];
 
+      // try to find the parent
       $parentcvterm = db_fetch_object(db_query($cvtermsql,'sequence',$parent_type,$parent_type));
       $relcvterm = db_fetch_object(db_query($cvtermsql,'relationship',$rel_type,$rel_type));
       $parent_feature = db_fetch_object(db_query($feature_sql,$organism_id,$parent,$parentcvterm->cvterm_id));
 
+      // we want to add this feature to the child list for the parent
+      // when the loader finishes, it will go back through the parent
+      // features and rank the children by position
+      $gff_features[$parent]['children'][$feature->feature_id] = $fmin;
+
+      // if the parent exists then add the relationship otherwise print error and skip
       if($parent_feature){
 
          // check to see if the relationship already exists
@@ -510,7 +578,8 @@ function tripal_core_load_gff3_parents($feature,$cvterm,$parents,$gff_features,$
          $rel = db_fetch_object(db_query($sql,$feature->feature_id,$parent_feature->feature_id,$relcvterm->cvterm_id));
          if($rel){
             print "   Relationship already exists, skipping '$uname' ($type) $rel_type '$parent' ($parent_type)\n";
-         } else {      
+         } else {  
+            // the relationship doesn't already exist, so add it.    
             $sql = "INSERT INTO {feature_relationship} (subject_id,object_id,type_id)
                     VALUES (%d,%d,%d)";
             $result = db_query($sql,$feature->feature_id,$parent_feature->feature_id,$relcvterm->cvterm_id);
@@ -519,7 +588,7 @@ function tripal_core_load_gff3_parents($feature,$cvterm,$parents,$gff_features,$
             } else {
                print "   Inserted relationship relationship: '$uname' ($type) $rel_type '$parent' ($parent_type)\n";
             }
-         } 
+         }          
       }
       else {
          print "WARNING: cannot establish relationship '$uname' ($type) $rel_type '$parent' ($parent_type): Cannot find the parent\n";
@@ -547,7 +616,7 @@ function tripal_core_load_gff3_dbxref($feature,$dbxrefs){
       // first check for the fully qualified URI (e.g. DB:<dbname>. If that
       // can't be found then look for the name as is.  If it still can't be found
       // the create the database
-      $db = tripal_core_chado_select('db',array('db_id'),array('name' => "DB:$dbname"));      
+      $db = tripal_core_chado_select('db',array('db_id'),array('name' => "DB:$dbname"));  
       if(sizeof($db) == 0){
          $db = tripal_core_chado_select('db',array('db_id'),array('name' => "$dbname"));      
       }        
@@ -555,7 +624,7 @@ function tripal_core_load_gff3_dbxref($feature,$dbxrefs){
          $ret = tripal_core_chado_insert('db',array('name' => $dbname, 
            'description' => 'Added automatically by the GFF loader'));
          if($ret){ 
-            print "Added new database: $dbname\n";
+            print "   Added new database: $dbname\n";
             $db = tripal_core_chado_select('db',array('db_id'),array('name' => "$dbname"));      
          } else {
             print "ERROR: cannot find or add the database $dbname\n";
@@ -577,7 +646,7 @@ function tripal_core_load_gff3_dbxref($feature,$dbxrefs){
       }
       $dbxref = $dbxref[0];
 
-      // check to see if tihs feature dbxref already exists
+      // check to see if this feature dbxref already exists
       $fdbx = tripal_core_chado_select('feature_dbxref',array('feature_dbxref_id'),
          array('dbxref_id' => $dbxref->dbxref_id,'feature_id' => $feature->feature_id));
 
@@ -588,18 +657,94 @@ function tripal_core_load_gff3_dbxref($feature,$dbxrefs){
             'feature_id' => $feature->feature_id,
             'dbxref_id' => $dbxref->dbxref_id));
          if($ret){
-            print "Adding dbxref $dbname:$accession\n";
+            print "   Adding Dbxref $dbname:$accession\n";
          } else {
-            print "ERROR: failed to insert dbxref: $dbname:$accession\n";
+            print "ERROR: failed to insert Dbxref: $dbname:$accession\n";
             return 0;
          }
       } else {
-         print "Dbxref already exists, skipping $dbname:$accession\n";
+         print "   Dbxref already associated, skipping $dbname:$accession\n";
       }
    }
    return 1;
 }
+/**
+ *
+ *
+ * @ingroup gff3_loader
+ */
+function tripal_core_load_gff3_ontology($feature,$dbxrefs){
 
+   // iterate through each of the dbxrefs
+   foreach($dbxrefs as $dbxref){
+
+      // get the database name from the reference.  If it doesn't exist then create one.
+      $ref = explode(":",$dbxref);
+      $dbname = $ref[0];
+      $accession = $ref[1];
+
+      // first look for the database name 
+      $db = tripal_core_chado_select('db',array('db_id'),array('name' => "DB:$dbname"));  
+      if(sizeof($db) == 0){
+         $db = tripal_core_chado_select('db',array('db_id'),array('name' => "$dbname"));      
+      }        
+      if(sizeof($db) == 0){
+         print "ERROR: Database, $dbname is missing for reference: $dbname:$accession\n";
+         return 0;
+      } 
+      $db = $db[0];
+       
+      // now check to see if the accession exists
+      $dbxref = tripal_core_chado_select('dbxref',array('dbxref_id'),array(
+         'accession' => $accession,'db_id' => $db->db_id));
+      if(sizeof($dbxref) == 0){
+         print "ERROR: Accession, $accession is missing for reference: $dbname:$accession\n";
+         return 0;
+      }
+      $dbxref = $dbxref[0];
+
+      // now check to see if the cvterm exists
+      $cvterm = tripal_core_chado_select('cvterm',array('cvterm_id'),array(
+         'dbxref_id' => $dbxref->dbxref_id));
+      // if it doesn't exist in the cvterm table, look for an alternate id
+      if(sizeof($cvterm) == 0){
+         $cvterm = tripal_core_chado_select('cvterm_dbxref',array('cvterm_id'),array(
+            'dbxref_id' => $dbxref->dbxref_id));
+      }
+      if(sizeof($cvterm) == 0){
+         print "ERROR: CVTerm is missing for reference: $dbname:$accession\n";
+         return 0;
+      }
+      $cvterm = $cvterm[0];
+      
+
+      // check to see if this feature cvterm already exists
+      $fcvt = tripal_core_chado_select('feature_cvterm',array('feature_cvterm_id'),
+         array('cvterm_id' => $cvterm->cvterm_id,'feature_id' => $feature->feature_id));
+
+      // now associate this feature with the cvterm if it doesn't already exist
+      if(sizeof($fcvt)==0){
+         $values = array(
+            'feature_id' => $feature->feature_id,
+            'cvterm_id' => $cvterm->cvterm_id,
+            'pub_id' => array(
+               'uniquename' => 'null',
+            ),
+         );
+         $ret = tripal_core_chado_insert('feature_cvterm',$values);
+
+         if($ret){
+            print "   Adding ontology term $dbname:$accession\n";
+         } else {
+            print "ERROR: failed to insert ontology term: $dbname:$accession\n";
+            return 0;
+         }
+      } else {
+         print "   Ontology term already associated, skipping $dbname:$accession\n";
+      }
+   }
+   return 1;
+}
 /**
  *
  *

+ 95 - 1
tripal_feature/tripal_feature.api.inc

@@ -157,4 +157,98 @@ function tripal_feature_chado_feature_dbxref_schema() {
   );
 
   return $description;
-}
+}
+/**
+ * Implements hook_chado_feature_relationship_schema()
+ * Purpose: To add descriptions and foreign keys to default table description
+ * Note: This array will be merged with the array from all other implementations
+ *
+ * @return
+ *    Array describing the feature_dbxref table
+ *
+ * @ingroup tripal_feature
+ */
+function tripal_feature_chado_feature_relationship_schema() {
+  $description = array();
+
+  // Default table description in tripal_core.schema.api.inc: tripal_core_chado_feature_dbxref_schema()
+
+  $description['foreign keys']['feature'] = array(
+        'table' => 'feature',
+        'columns' => array(
+          'object_id' => 'feature_id',
+          'subject_id' => 'feature_id',
+        ),
+  );
+  $description['foreign keys']['cvterm'] = array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_feature_relationship_schema()
+ * Purpose: To add descriptions and foreign keys to default table description
+ * Note: This array will be merged with the array from all other implementations
+ *
+ * @return
+ *    Array describing the feature_dbxref table
+ *
+ * @ingroup tripal_feature
+ */
+function tripal_feature_chado_feature_cvterm_schema() {
+  $description = array();
+
+  // Default table description in tripal_core.schema.api.inc: tripal_core_chado_feature_dbxref_schema()
+
+  $description['foreign keys']['feature'] = array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+        ),
+  );
+  $description['foreign keys']['cvterm'] = array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+  );
+  $description['foreign keys']['pub'] = array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+  );
+  return $description;
+}
+/**
+*
+**/
+function tripal_feature_chado_feature_synonym_schema() {
+  $description = array();
+
+  // Default table description in tripal_core.schema.api.inc: tripal_core_chado_feature_dbxref_schema()
+
+  $description['foreign keys']['feature'] = array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+        ),
+  );
+  $description['foreign keys']['synonym'] = array(
+        'table' => 'synonym',
+        'columns' => array(
+          'synonym_id' => 'synonym_id',
+        ),
+  );
+  $description['foreign keys']['pub'] = array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+  );
+
+  return $description;
+}

+ 137 - 129
tripal_feature/tripal_feature.module

@@ -403,57 +403,110 @@ function tripal_feature_block($op = 'list', $delta = 0, $edit=array()){
 function chado_feature_insert($node){
    // remove spaces, newlines from residues
    $residues = preg_replace("/[\n\r\s]/","",$node->residues);
-
-   // If this feature already exists then don't recreate it in chado
-   // TODO: the unique index in chado for this also includes the type_id. If the site
-   // ever needs to have the same feature name for different types then this will break.
-   $feature_sql = "SELECT * 
-                   FROM {Feature} F
-                     INNER JOIN {cvterm} CVT ON F.type_id = CVT.cvterm_id
-                   WHERE uniquename = '%s' and organism_id = %d and CVT.name = '%s'";
-   $previous_db = tripal_db_set_active('chado');
-   $feature = db_fetch_object(db_query($feature_sql,$node->uniquename,$node->organism_id,$node->feature_type));
-   tripal_db_set_active($previous_db);
-
-   // if the feature doesn't exist then let's create it in chado.
-   if(!$feature){
-      $sql = "INSERT INTO {feature} (organism_id, name, uniquename, residues, seqlen,".
-             "    is_obsolete, type_id)".
-             " VALUES(%d,'%s','%s','%s',%d, %s, ".
-             "   (SELECT cvterm_id ".
-             "    FROM {CVTerm} CVT ".
-             "    INNER JOIN CV ON CVT.cv_id = CV.cv_id ".
-             "    WHERE CV.name = 'sequence' and CVT.name = '%s'))";
-      $obsolete = 'FALSE';
-      if($node->is_obsolete){
-         $obsolete = 'TRUE';
-      }
-
-      // use chado database
-      $previous_db = tripal_db_set_active('chado');
-      db_query($sql,$node->organism_id,$node->fname,$node->uniquename,
-      $residues,strlen($residues),$obsolete,$node->feature_type);
-
-      // now that we've added the feature, get the feature id for this feature
-      $feature = db_fetch_object(db_query($feature_sql,$node->uniquename,$node->organism_id,$node->feature_type));
-
-      // now use drupal database
-      tripal_db_set_active($previous_db);
+   $obsolete = 'FALSE';
+   if($node->is_obsolete){
+      $obsolete = 'TRUE';
    }
+   $values = array(
+      'cv_id' => array(
+         'name' => 'sequence'
+      ),
+      'name' => $node->feature_type
+   );
+   $type = tripal_core_chado_select('cvterm',array('cvterm_id'),$values);
+   $values = array(
+      'organism_id' => $node->organism_id,
+      'name' => $node->fname,
+      'uniquename' => $node->uniquename,
+      'residues' => $residues,
+      'seqlen' => strlen($residues),
+      'is_obsolete' => $obsolete,
+      'type_id' => $type[0]->cvterm_id,
+      'md5checksum' => md5($residues)
+   );
 
+   $istatus = tripal_core_chado_insert('feature', $values);
+   if (!$istatus) {
+		drupal_set_message('Unable to add feature.', 'warning');
+		watchdog('tripal_organism', 
+			'Insert feature: Unable to create feature where values: %values', 
+			array('%values' => print_r($values, TRUE)),
+			WATCHDOG_WARNING
+		);
+	}  
+   $values = array(
+      'organism_id' => $node->organism_id,
+      'uniquename' => $node->uniquename,
+      'type_id' => $type[0]->cvterm_id,
+   );
+   $feature = tripal_core_chado_select('feature',array('feature_id'),$values);   
    // add the genbank accession and synonyms
-   chado_feature_add_synonyms($node->synonyms,$feature->feature_id);
+   chado_feature_add_synonyms($node->synonyms,$feature[0]->feature_id);
 
    // make sure the entry for this feature doesn't already exist in the chado_feature table
    // if it doesn't exist then we want to add it.
    $node_check_sql = "SELECT * FROM {chado_feature} ".
                      "WHERE feature_id = '%s'";
-   $node_check = db_fetch_object(db_query($node_check_sql,$feature->feature_id));
+   $node_check = db_fetch_object(db_query($node_check_sql,$feature[0]->feature_id));
    if(!$node_check){
       // next add the item to the drupal table
       $sql = "INSERT INTO {chado_feature} (nid, vid, feature_id, sync_date) ".
              "VALUES (%d, %d, %d, " . time() . ")";
-      db_query($sql,$node->nid,$node->vid,$feature->feature_id);
+      db_query($sql,$node->nid,$node->vid,$feature[0]->feature_id);
+   }
+}
+/**
+ *
+ *
+ * @ingroup tripal_feature
+ */
+function chado_feature_update($node){
+   if($node->revision){
+      // TODO -- decide what to do about revisions
+   } else {
+      $residues = preg_replace("/[\n\r\s]/","",$node->residues);
+      $obsolete = 'FALSE';
+      if($node->is_obsolete){
+         $obsolete = 'TRUE';
+      }
+
+      // get the feature type id
+      $values = array(
+         'cv_id' => array(
+            'name' => 'sequence'
+         ),
+         'name' => $node->feature_type
+      );
+      $type = tripal_core_chado_select('cvterm',array('cvterm_id'),$values);
+
+      $feature_id = chado_get_id_for_node('feature',$node) ;
+
+      if(sizeof($type) > 0){
+         $match = array(
+            'feature_id' => $feature_id,
+         );     
+         $values = array(
+            'organism_id' => $node->organism_id,
+            'name' => $node->fname,
+            'uniquename' => $node->uniquename,
+            'residues' => $residues,
+            'seqlen' => strlen($residues),
+            'is_obsolete' => $obsolete,
+            'type_id' => $type[0]->cvterm_id,
+            'md5checksum' => md5($residues)
+         );
+         $org_status = tripal_core_chado_update('feature', $match,$values); 
+         // add the genbank synonyms
+         chado_feature_add_synonyms($node->synonyms,$feature_id);
+      }    
+      else {
+		   drupal_set_message('Unable to update feature.', 'warning');
+		   watchdog('tripal_organism', 
+			   'Update feature: Unable to update feature where values: %values', 
+			   array('%values' => print_r($values, TRUE)),
+			   WATCHDOG_WARNING
+		   );
+      }
    }
 }
 /**
@@ -462,11 +515,8 @@ function chado_feature_insert($node){
  * @ingroup tripal_feature
  */
 function chado_feature_delete($node){
-   // get feature_id so we can remove it from chado database
-   $sql_drupal = "SELECT feature_id ".
-                 "FROM {chado_feature} ".
-                 "WHERE nid = %d AND vid = %d";
-   $feature_id = db_result(db_query($sql_drupal, $node->nid, $node->vid));
+
+   $feature_id  = chado_get_id_for_node('feature',$node);
 
    // remove the drupal content  
    $sql_del = "DELETE FROM {chado_feature} ".
@@ -494,49 +544,6 @@ function chado_feature_delete($node){
       "chado");
 
 }
-/**
- *
- *
- * @ingroup tripal_feature
- */
-function chado_feature_update($node){
-   if($node->revision){
-      // TODO -- decide what to do about revisions
-   } else {
-      // get the feature for this node:
-      $sql = 'SELECT feature_id FROM {chado_feature} WHERE vid = %d';
-      $feature = db_fetch_object(db_query($sql, $node->vid));
-
-      // remove spaces, newlines from residues
-      $residues = preg_replace("/[\n\r\s]/","",$node->residues);
-
-      $sql = "UPDATE {feature} ".
-             " SET residues = '%s', ".
-             "   name = '%s', ".
-             "   uniquename = '%s', ".
-             "   seqlen = %d, ".
-             "   organism_id = %d, ".
-             "   is_obsolete = %s, ".
-             "   type_id = (SELECT cvterm_id ".
-             "              FROM {CVTerm} CVT ".
-             "              INNER JOIN CV ON CVT.cv_id = CV.cv_id ".
-             "              WHERE CV.name = 'sequence' and CVT.name = '%s') ".
-             "WHERE feature_id = %d ";
-      $obsolete = 'FALSE';
-      if($node->is_obsolete){
-         $obsolete = 'TRUE';
-      }
-      $previous_db = tripal_db_set_active('chado');  // use chado database
-      db_query($sql,$residues,$node->fname,$node->uniquename,
-      strlen($residues),$node->organism_id,$obsolete,$node->feature_type,
-      $feature->feature_id);
-      tripal_db_set_active($previous_db);  // now use drupal database
-
-      // add the genbank accession & synonyms
-      // chado_feature_add_gbaccession($node->gbaccession,$feature->feature_id);
-      chado_feature_add_synonyms($node->synonyms,$feature->feature_id);
-   }
-}
 /**
  *
  *
@@ -544,8 +551,6 @@ function chado_feature_update($node){
  */
 function chado_feature_add_synonyms($synonyms,$feature_id){
 
-drupal_set_message($synonyms);
-
    // make sure we only have a single space between each synonym
    $synonyms = preg_replace("/[\s\n\r]+/"," ",$synonyms);
    // split the synonyms into an array based on a space as the delimieter
@@ -674,10 +679,29 @@ function chado_feature_add_gbaccession($accession,$feature_id){
  * @ingroup tripal_feature
  */
 function chado_feature_form ($node,$param){
+
    $type = node_get_types('type', $node);
    $form = array();
+
    $feature = $node->feature;
+
+
+   // if the node has synonyms then use that as the form may be returning
+   // from an error.  Otherwise try to find synonyms from the database
    $synonyms = $node->synonyms;
+   $feature = tripal_core_expand_chado_vars($feature,'table','feature_synonym');
+   $feature_synonyms = $feature->feature_synonym;
+   if(!$synonyms){
+      if (!is_array($feature_synonyms)) {
+         $synonyms = $feature_synonyms->synonym_id->name;
+      } 
+      elseif(is_array($feature_synonyms)) { 
+         foreach($feature_synonyms as $index => $synonym){
+            $synonyms .= $synonym->synonym_id->name ."\n";
+         }
+      }
+   }
+
    $analyses = $node->analyses;
    $references = $node->references;
 
@@ -733,7 +757,7 @@ function chado_feature_form ($node,$param){
       '#type' => 'textfield',
       '#title' => t('Feature Name'),
       '#required' => TRUE,
-      '#default_value' => $feature->featurename,
+      '#default_value' => $feature->name,
       '#description' => t('Enter the name used by humans to refer to this feature.'),
       '#weight' => 1,
       '#maxlength' => 255
@@ -752,7 +776,7 @@ function chado_feature_form ($node,$param){
      '#type'        => t('select'),
      '#description' => t("Choose the feature type."),
      '#required'    => TRUE,
-     '#default_value' => $feature->cvname,
+     '#default_value' => $feature->type_id->name,
      '#options'     => $ftypes,
      '#weight'      => 2
    );
@@ -774,7 +798,7 @@ function chado_feature_form ($node,$param){
      '#type'        => t('select'),
      '#description' => t("Choose the organism with which this feature is associated "),
      '#required'    => TRUE,
-     '#default_value' => $feature->organism_id,
+     '#default_value' => $feature->organism_id->organism_id,
      '#options'     => $organisms,
      '#weight'      => 3,
    );
@@ -885,37 +909,12 @@ function chado_feature_validate($node){
  * @ingroup tripal_feature
  */
 function chado_feature_load($node){
-   // add the feature_id for this node:
-   $sql = 'SELECT feature_id FROM {chado_feature} WHERE nid = %d';
-   $feature = db_fetch_object(db_query($sql, $node->nid));
-   $feature_id = $feature->feature_id;
-
-   // get information about this feature and add it to the items in this node
-   $sql = "SELECT F.feature_id, F.name as featurename, F.uniquename, ".
-          "F.residues, F.seqlen, O.genus, O.species, O.common_name, ".
-          "  CVT.name as cvname, O.organism_id, F.type_id, F.is_obsolete  ".
-          "FROM {Feature} F ".
-          "  INNER JOIN Organism O ON F.organism_id = O.organism_id ".
-          "  INNER JOIN CVterm CVT ON F.type_id = CVT.cvterm_id ".
-          "WHERE F.feature_id = %d";
-   $previous_db = tripal_db_set_active('chado');  // use chado database
-   $feature = db_fetch_object(db_query($sql,$feature_id));
-   tripal_db_set_active($previous_db);  // now use drupal database
-   $additions->feature = $feature;
-   $additions->seqlen = $feature->seqlen;
-   $organism_id = $feature->organism_id;
-
-   // add organism node nid
-   $sql = "SELECT nid FROM {chado_organism} WHERE organism_id = %d";
-   $org_nid = db_result(db_query($sql, $additions->feature->organism_id));
-   $additions->org_nid = $org_nid;
-   $additions->accession =  variable_get('chado_feature_accession_prefix','ID') . $feature->feature_id;
- 
-   // add details about the organism
-   $additions->organism = tripal_feature_load_organism($organism_id);
-   // add the list of synomyms
-   $additions->synonyms = tripal_feature_load_synonyms($feature_id);
+   // find the organism and add in the details
+   $feature_id = chado_get_id_for_node('feature',$node);
+   $values = array('feature_id' => $feature_id);
+   $feature = tripal_core_generate_chado_var('feature',$values);
 
+   $additions->feature = $feature;
    return $additions;
 }
 /**
@@ -1616,12 +1615,18 @@ function tripal_feature_preprocess(&$variables){
    // to add all of our variables.
    if($variables['template_files'][0] == 'node-chado_feature'){
       $feature = $variables['node']->feature;
-      $variables['tripal_feature']['synonyms'] = tripal_feature_load_synonyms($feature->feature_id);
-      $variables['tripal_feature']['object_relationships'] = tripal_feature_get_aggregate_relationships($feature->feature_id,0);
-      $variables['tripal_feature']['subject_relationships'] = tripal_feature_load_relationships($feature->feature_id,'as_subject');
-      $variables['tripal_feature']['featurelocs_as_child'] = tripal_feature_load_featurelocs($feature->feature_id,'as_child',0);
-      $variables['tripal_feature']['featurelocs_as_parent'] = tripal_feature_load_featurelocs($feature->feature_id,'as_parent');
-      $variables['tripal_feature']['references'] = tripal_feature_load_references($feature->feature_id);
+
+//      $variables['tripal_feature']['object_relationships'] = tripal_feature_get_aggregate_relationships($feature->feature_id,0);
+//      $variables['tripal_feature']['subject_relationships'] = tripal_feature_load_relationships($feature->feature_id,'as_subject');
+//      $variables['tripal_feature']['featurelocs_as_child'] = tripal_feature_load_featurelocs($feature->feature_id,'as_child',0);
+//      $variables['tripal_feature']['featurelocs_as_parent'] = tripal_feature_load_featurelocs($feature->feature_id,'as_parent');
+
+      $variables['node']->feature = tripal_core_expand_chado_vars($feature,'table','feature_dbxref');
+      $variables['node']->feature = tripal_core_expand_chado_vars($feature,'table','feature_synonym');
+      $variables['node']->feature = tripal_core_expand_chado_vars($feature,'table','featureloc');
+      $variables['node']->feature = tripal_core_expand_chado_vars($feature,'table','feature_relationship',
+         array('order_by'=>array('rank' => 'ASC')));
+
       $featurelocs = $variables['tripal_feature']['featurelocs_as_child'];
       $variables['tripal_feature']['featureloc_sequences'] = tripal_feature_load_featureloc_sequences ($feature->feature_id,$featurelocs);   
    }
@@ -2252,7 +2257,9 @@ function tripal_feature_job_describe_args($callback,$args){
       $new_args['Relationship Parent Type'] = $args[10];
 
       // add in the database reference arguments
-      $db = tripal_core_chado_select('db',array('name'),array('db_id' => $args[7]));
+      if($args[7]){
+         $db = tripal_core_chado_select('db',array('name'),array('db_id' => $args[7]));
+      }
       $new_args['Database Reference'] = $db[0]->name;
       $new_args['Accession RE'] = $args[6];
       if($args[11]){
@@ -2264,3 +2271,4 @@ function tripal_feature_job_describe_args($callback,$args){
    }
    return $new_args;
 }
+

+ 66 - 96
tripal_organism/tripal_organism.module

@@ -549,63 +549,80 @@ function tripal_organism_cron (){
  */
 function chado_organism_insert($node){
 
-   // If this organism already exists then don't recreate it in chado
-   $o_sql = "SELECT organism_id ".
-            "FROM {Organism} ".
-            "WHERE genus = '%s' ".
-            "AND species = '%s'";
-   $previous_db = tripal_db_set_active('chado');
-   $organism = db_fetch_object(db_query($o_sql, $node->genus,$node->species));
-   tripal_db_set_active($previous_db);
-
-   // if the feature doesn't exist then let's create it in chado.
-   if(!$organism){
-      // First add the item to the chado oganism table
-      $sql = "INSERT INTO {organism} ".
-             " (abbreviation, genus, species,common_name,comment) VALUES ".
-             " ('%s','%s','%s','%s','%s')";
-     $previous_db = tripal_db_set_active('chado');  // use chado database
-     db_query($sql,$node->abbreviation, $node->genus,
-     $node->species,$node->common_name,$node->description);
-
-     // find the newly entered organism_id
-     $organism = db_fetch_object(db_query($o_sql, $node->genus,$node->species));
-     tripal_db_set_active($previous_db);  // switch back to drupal database
+   $values = array(
+      'genus' => $node->genus,
+      'species' => $node->species,
+      'abbreviation' => $node->abbreviation,
+      'common_name' => $node->common_name,
+      'comment' => $node->description
+   );
+   $istatus = tripal_core_chado_insert('organism', $values);
+   if (!$istatus) {
+		drupal_set_message('Unable to add organism.', 'warning');
+		watchdog('tripal_organism', 
+			'Insert Organism: Unable to create organism where values:%values', 
+			array('%values' => print_r($values, TRUE)),
+			WATCHDOG_WARNING
+		);
+	}   
 
-   }
+   // get the newly add organism
+   $values = array(
+      'genus' => $node->genus,
+      'species' => $node->species,
+   );
+   $organism = tripal_core_chado_select('organism',array('organism_id'),$values);
 
-   // Make sure the entry for this feature doesn't already exist in the
-   // chado_feature table if it doesn't exist then we want to add it.
-   $node_check_sql = "SELECT * FROM {chado_organism} ".
-                     "WHERE organism_id = %d";
-   $node_check = db_fetch_object(db_query($node_check_sql,
-                                          $organism->organism_id));
-   if(!$node_check){
+   // Make sure the entry for this organism doesn't already exist in the
+   // chado_organism table if it doesn't exist then we want to add it.
+   $organism_id = chado_get_id_for_node('organism',$node);
+   if(!$organism_id){
       // next add the item to the drupal table
       $sql = "INSERT INTO {chado_organism} (nid, vid, organism_id) ".
              "VALUES (%d, %d, %d)";
-      db_query($sql,$node->nid,$node->vid,$organism->organism_id);
+      chado_query($sql,$node->nid,$node->vid,$organism[0]->organism_id);
    }
 
+   // set the title for the node
    $record = new stdClass();
    $record->title = "$node->genus $node->species";
    $record->nid = $node->nid;
    drupal_write_record('node',$record,'nid');
    drupal_write_record('node_revisions',$record,'nid');
 }
+/*******************************************************************************
+ * Update organisms
+ */
+function chado_organism_update($node){
+   if($node->revision){
+      // TODO -- decide what to do about revisions
+   } else {
+      $match = array(
+         'organism_id' => chado_get_id_for_node('organism',$node),
+      );
+      $values = array(
+         'genus' => $node->genus,
+         'species' => $node->species,
+         'abbreviation' => $node->abbreviation,
+         'common_name' => $node->common_name,
+         'comment' => $node->description
+      );
+      $org_status = tripal_core_chado_update('organism', $match,$values);
+
+      // set the title for the node
+      $record = new stdClass();
+      $record->title = "$node->genus $node->species";
+      $record->nid = $node->nid;
+      drupal_write_record('node',$record,'nid');
+      drupal_write_record('node_revisions',$record,'nid');
+   }
+}
 /*******************************************************************************
  * Delete organism from both drupal and chado databases. Check dependency before
  * deleting from chado.
  */
 function chado_organism_delete($node){
-
-   // Before removing, get organism_id so we can remove it from chado database
-   // later
-   $sql_drupal = "SELECT organism_id ".
-                 "FROM {chado_organism} ".
-                 "WHERE nid = %d ".
-                 "AND vid = %d";
-   $organism_id = db_result(db_query($sql_drupal, $node->nid, $node->vid));
+   $organism_id = chado_get_id_for_node('organism',$node);
 
    // Remove data from the {chado_organism}, {node}, and {node_revisions} tables
    $sql_del = "DELETE FROM {chado_organism} ".
@@ -623,6 +640,7 @@ function chado_organism_delete($node){
 
    // Test dependency before deleting from chado database. If a library or
    // feature depends on this organism, don't delete it
+
    $sql = "SELECT feature_id FROM {feature} WHERE organism_id = %d";
    $previous_db = tripal_db_set_active('chado');
    $check_feature = db_result(db_query($sql, $organism_id));
@@ -630,14 +648,7 @@ function chado_organism_delete($node){
    $check_lib = db_result(db_query($sql, $organism_id));
 
    if ($check_lib == 0 && $check_feature == 0) {
-      // Remove from organism/organism_dbxref/organismprop tables of chado
-      // database as well
-      db_query("DELETE FROM {organism} WHERE organism_id = %d", $organism_id);
-      db_query("DELETE FROM {organism_dbxref} WHERE organism_id = %d",
-               $organism_id);
-      db_query("DELETE FROM {organismprop} WHERE organism_id = %d",
-               $organism_id);
-
+      tripal_core_chado_delete('organism',array('organism_id' => $organism_id));
    } else {
       drupal_set_message("Organism deleted from drupal. Warning: at least one ".
                          "library or feature depends on this organism. It was ".
@@ -665,41 +676,7 @@ function chado_organism_validate($node){
       file_move($file->filepath,$dest . "/".$node->genus."_".$node->species.".jpg",FILE_EXISTS_REPLACE);
    }
 }
-/*******************************************************************************
- * Update organisms
- */
-function chado_organism_update($node){
-   if($node->revision){
-      // TODO -- decide what to do about revisions
-   } else {
-      // get the organism_id for this node:
-      $sql = "SELECT organism_id ".
-             "FROM {chado_organism} ".
-             "WHERE nid = %d";
-      $org = db_fetch_object(db_query($sql, $node->nid));
-
-      $sql = "UPDATE {organism} ".
-             " SET comment = '%s', ".
-             "    abbreviation = '%s', ".
-             "    genus = '%s', ".
-             "    species = '%s', ".
-             "    common_name = '%s' ".
-             "WHERE organism_id = %d ";
 
-      $previous_db = tripal_db_set_active('chado');  // use chado database
-      db_query($sql,$node->description, $node->abbreviation, $node->genus,
-          $node->species,$node->common_name,$org->organism_id);
-      tripal_db_set_active($previous_db);  // now use drupal database
-
-      //$sql = "UPDATE {node} SET title = '$node->genus $node->species' WHERE nid = $node->nid";
-      //db_query($sql);
-      $record = new stdClass();
-      $record->title = "$node->genus $node->species";
-      $record->nid = $node->nid;
-      drupal_write_record('node',$record,'nid');
-      drupal_write_record('node_revisions',$record,'nid');
-   }
-}
 
 /*******************************************************************************
  *  When editing or creating a new node of type 'chado_organism' we need
@@ -745,7 +722,7 @@ function chado_organism_form ($node, $param){
       '#rows' => 15,
       '#title' => t('Description'),
       '#required' => TRUE,
-      '#default_value' => $organism->description,
+      '#default_value' => $organism->comment,
       '#weight' => 5
    );
    $form['organism-image']= array(
@@ -762,22 +739,15 @@ function chado_organism_form ($node, $param){
  *  to add auxiliary data to the node object.
  */
 function chado_organism_load($node){
-   // get the organism_id for this node:
-   $sql = "SELECT organism_id FROM {chado_organism} WHERE vid = %d";
-   $org_node = db_fetch_object(db_query($sql, $node->vid));
+   // find the organism and add in the details
+   $organism_id = chado_get_id_for_node('organism',$node);
+   $values = array('organism_id' => $organism_id);
+   $organism = tripal_core_generate_chado_var('organism',$values);
 
-   // get information about this organism and add it to the items in this node
-   $previous_db = tripal_db_set_active('chado');  // use chado database
-   if ($org_node->organism_id) {
-      $sql = "SELECT O.organism_id,O.genus,O.species, ".
-      		 "  O.common_name, O.comment as description, O.abbreviation ".
-             "FROM {Organism} O ".
-          	 "WHERE O.Organism_id = $org_node->organism_id";
-      $organism = db_fetch_object(db_query($sql));
-      $additions->organism  = $organism;
-   }
-   tripal_db_set_active($previous_db);  // now use drupal database
+   // add in the description field
+   $organism = tripal_core_expand_chado_vars($organism,'field','organism.comment');
 
+   $additions->organism = $organism;
    return $additions;
 }