Browse Source

Fixes to templates and update to GFF3 loader

spficklin 14 năm trước cách đây
mục cha
commit
94ef4739bb
23 tập tin đã thay đổi với 906 bổ sung555 xóa
  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;
 }