Browse Source

Added orphaned form items to sync form. Library module is now converted.

Stephen Ficklin 11 years ago
parent
commit
f8f44afa9c
42 changed files with 1982 additions and 2070 deletions
  1. 339 0
      LICENSE.txt
  2. 251 1
      tripal_analysis/includes/tripal_analysis.chado_node.inc
  3. 1 1
      tripal_analysis/includes/tripal_analysis.sync.inc
  4. 1 252
      tripal_analysis/tripal_analysis.module
  5. 1 1
      tripal_contact/includes/contact_sync.inc
  6. 19 1
      tripal_contact/tripal_contact.install
  7. 25 9
      tripal_contact/tripal_contact.module
  8. 5 114
      tripal_core/api/tripal_core_chado.api.inc
  9. 243 76
      tripal_core/api/tripal_core_chado_nodes.api.inc
  10. 26 8
      tripal_core/api/tripal_core_jobs.api.inc
  11. 2 2
      tripal_core/tripal_core.drush.inc
  12. 1 1
      tripal_feature/includes/tripal_feature.sync_features.inc
  13. 7 4
      tripal_feature/theme/tripal_feature/tripal_feature_terms.tpl.php
  14. 1 1
      tripal_featuremap/includes/tripal_featuremap.admin.inc
  15. 4 4
      tripal_library/api/tripal_library.api.inc
  16. 4 565
      tripal_library/includes/tripal_library.admin.inc
  17. 314 0
      tripal_library/includes/tripal_library.chado_node.inc
  18. 0 142
      tripal_library/theme/node--chado-library.tpl.php
  19. 69 0
      tripal_library/theme/tripal_feature/tripal_feature.libraries.tpl.php
  20. 0 57
      tripal_library/theme/tripal_feature/tripal_feature_libraries.tpl.php
  21. 0 4
      tripal_library/theme/tripal_library.help.tpl.php
  22. 1 0
      tripal_library/theme/tripal_library.theme.inc
  23. 105 0
      tripal_library/theme/tripal_library/tripal_library.base.tpl.php
  24. 62 0
      tripal_library/theme/tripal_library/tripal_library.properties.tpl.php
  25. 70 0
      tripal_library/theme/tripal_library/tripal_library.references.tpl.php
  26. 53 0
      tripal_library/theme/tripal_library/tripal_library.synonyms.tpl.php
  27. 19 0
      tripal_library/theme/tripal_library/tripal_library.teaser.tpl.php
  28. 71 0
      tripal_library/theme/tripal_library/tripal_library.terms.tpl.php
  29. 0 54
      tripal_library/theme/tripal_library/tripal_library_base.tpl.php
  30. 0 44
      tripal_library/theme/tripal_library/tripal_library_properties.tpl.php
  31. 0 49
      tripal_library/theme/tripal_library/tripal_library_references.tpl.php
  32. 0 31
      tripal_library/theme/tripal_library/tripal_library_synonyms.tpl.php
  33. 0 54
      tripal_library/theme/tripal_library/tripal_library_teaser.tpl.php
  34. 0 51
      tripal_library/theme/tripal_library/tripal_library_terms.tpl.php
  35. 73 0
      tripal_library/theme/tripal_organism/tripal_organism.libraries.tpl.php
  36. 0 74
      tripal_library/theme/tripal_organism/tripal_organism_libraries.tpl.php
  37. 98 14
      tripal_library/tripal_library.install
  38. 113 452
      tripal_library/tripal_library.module
  39. 1 1
      tripal_organism/includes/organism_sync.inc
  40. 1 1
      tripal_project/includes/tripal_project.admin.inc
  41. 1 1
      tripal_pub/includes/tripal_pub.pub_sync.inc
  42. 1 1
      tripal_stock/includes/tripal_stock.admin.inc

+ 339 - 0
LICENSE.txt

@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.

+ 251 - 1
tripal_analysis/includes/tripal_analysis.form.inc → tripal_analysis/includes/tripal_analysis.chado_node.inc

@@ -95,7 +95,7 @@ function chado_analysis_form($node, &$form_state) {
         are derived from some software package. But, data can also be derived via retreival
         from an external source or an analysis pipeline with multipel software components.
         In these cases, provide values for the fields below that best makes sense
-        '),
+     '),
   );
   $form['analysisname']= array(
     '#type' => 'textfield',
@@ -317,4 +317,254 @@ function tripal_analysis_validate($node, $form, &$form_state) {
       return;
     }
   }
+}
+
+/**
+ *  When a new chado_analysis node is created we also need to add information
+ *  to our chado_analysis table.  This function is called on insert of a new
+ *  node of type 'chado_analysis' and inserts the necessary information.
+ *
+ * @ingroup tripal_analysis
+ */
+function chado_analysis_insert($node) {
+
+  $node->analysisname = trim($node->analysisname);
+  $node->description = trim($node->description);
+  $node->program = trim($node->program);
+  $node->programversion = trim($node->programversion);
+  $node->algorithm = trim($node->algorithm);
+  $node->sourcename = trim($node->sourcename);
+  $node->sourceversion = trim($node->sourceversion);
+  $node->sourceuri = trim($node->sourceuri);
+
+  // if there is an analysis_id in the $node object then this must be a sync so
+  // we can skip adding the analysis as it is already there, although
+  // we do need to proceed with the rest of the insert
+  if (!property_exists($node, 'analysis_id')) {
+
+    // Create a timestamp so we can insert it into the chado database
+    $time  = $node->timeexecuted;
+    $month = $time['month'];
+    $day   = $time['day'];
+    $year  = $time['year'];
+    $timestamp = $month . '/' . $day . '/' . $year;
+
+    // insert and then get the newly inserted analysis record
+    $values = array(
+      'name'           => $node->analysisname,
+      'description'    => $node->description,
+      'program'        => $node->program,
+      'programversion' => $node->programversion,
+      'algorithm'      => $node->algorithm,
+      'sourcename'     => $node->sourcename,
+      'sourceversion'  => $node->sourceversion,
+      'sourceuri'      => $node->sourceuri,
+      'timeexecuted'   => $timestamp
+    );
+    $analysis = tripal_core_chado_insert('analysis', $values);
+    if (!$analysis) {
+      drupal_set_message(t('Unable to add analysis.', 'warning'));
+      watchdog('tripal_analysis', 'Insert analysis: Unable to create analysis where values:%values',
+      array('%values' => print_r($values, TRUE)), WATCHDOG_ERROR);
+      return;
+    }
+    $analysis_id = $analysis['analysis_id'];
+
+    // now add in the properties
+    $properties = tripal_core_properties_form_retreive($node, 'analysis_property');
+    foreach ($properties as $property => $elements) {
+      foreach ($elements as $rank => $value) {
+
+        $status = tripal_analysis_insert_property($analysis_id, $property, $value, FALSE, 'analysis_property');
+        if (!$status) {
+          drupal_set_message("Error cannot add property: $property", "error");
+          watchdog('t_analysis', "Error cannot add property: %prop",
+          array('%property' => $property), WATCHDOG_ERROR);
+        }
+      }
+    }
+  }
+  else {
+    $analysis_id = $node->analysis_id;
+  }
+
+  // Make sure the entry for this analysis doesn't already exist in the
+  // chado_analysis table if it doesn't exist then we want to add it.
+  $check_org_id = chado_get_id_for_node('analysis', $node->nid);
+  if (!$check_org_id) {
+    $record = new stdClass();
+    $record->nid = $node->nid;
+    $record->vid = $node->vid;
+    $record->analysis_id = $analysis_id;
+    drupal_write_record('chado_analysis', $record);
+  }
+
+  // add the analysis to the node object for
+  // use by other analysis modules that may be using this function
+  $node->analysis = $analysis;
+  $node->analysis_id = $analysis_id; // we need to set this for children
+}
+
+/**
+ * Removes analysis from the chado database
+ *
+ * @param $node
+ *   The node object specifying which chado record to delete
+ *
+ * @ingroup tripal_analysis
+ */
+function chado_analysis_delete($node) {
+  $analysis_id = chado_get_id_for_node('analysis', $node->nid);
+
+  // if we don't have an analysis id for this node then this isn't a node of
+  // type chado_analysis or the entry in the chado_analysis table was lost.
+  if (!$analysis_id) {
+    return;
+  }
+
+  // Remove data from the {chado_analysis}, {node}, and {node_revisions} tables
+  $sql_del = "DELETE FROM {chado_analysis} WHERE nid = :nid AND vid = :vid";
+  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
+  $sql_del = "DELETE FROM {node} WHERE nid = :nid AND vid = :vid";
+  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
+  $sql_del = "DELETE FROM {node_revision} WHERE nid = :nid AND vid = :vid";
+  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
+
+  //Remove from analysis and analysisprop tables of chado database as well
+  chado_query("DELETE FROM {analysis} WHERE analysis_id = :analysis_id", array(':analysis_id' => $analysis_id));
+}
+
+/**
+ * Update analyses
+ *
+ * @param $node
+ *   The updated node object
+ *
+ * @ingroup tripal_analysis
+ */
+function chado_analysis_update($node) {
+  $node->analysisname = trim($node->analysisname);
+  $node->description = trim($node->description);
+  $node->program = trim($node->program);
+  $node->programversion = trim($node->programversion);
+  $node->algorithm = trim($node->algorithm);
+  $node->sourcename = trim($node->sourcename);
+  $node->sourceversion = trim($node->sourceversion);
+  $node->sourceuri = trim($node->sourceuri);
+
+  // Create a timestamp so we can insert it into the chado database
+  $time = $node->timeexecuted;
+  $month = $time['month'];
+  $day = $time['day'];
+  $year = $time['year'];
+  $timestamp = $month . '/' . $day . '/' . $year;
+
+  // update the record in Chado
+  $analysis_id = chado_get_id_for_node('analysis', $node->nid);
+  $match = array(
+    'analysis_id' => $node->analysis_id,
+  );
+  $values = array(
+    'name'           => $node->analysisname,
+    'description'    => $node->description,
+    'program'        => $node->program,
+    'programversion' => $node->programversion,
+    'algorithm'      => $node->algorithm,
+    'sourcename'     => $node->sourcename,
+    'sourceversion'  => $node->sourceversion,
+    'sourceuri'      => $node->sourceuri,
+    'timeexecuted'   => $timestamp,
+    'analysis_id'    => $analysis_id
+  );
+  $status = tripal_core_chado_update('analysis', $match, $values);
+  if (!$status) {
+    drupal_set_message(t('Unable to update analysis.', 'warning'));
+    watchdog('tripal_analysis', 'Update analysis: Unable to update analysis where values: %values',
+    array('%values' => print_r($values, TRUE)), WATCHDOG_ERROR);
+  }
+
+  // now add in the properties by first removing any the analysis
+  // already has and adding the ones we have
+  tripal_core_chado_delete('analysisprop', array('analysis_id' => $analysis_id));
+  $properties = tripal_core_properties_form_retreive($node, 'analysis_property');
+  foreach ($properties as $property => $elements) {
+    foreach ($elements as $rank => $value) {
+      $status = tripal_analysis_insert_property($analysis_id, $property, $value, FALSE, 'analysis_property');
+      if (!$status) {
+        drupal_set_message("Error cannot add property: '$property'", "error");
+        watchdog('t_analysis', "Error cannot add property: '%prop'",
+        array('%prop' => $property), WATCHDOG_ERROR);
+      }
+    }
+  }
+}
+/**
+ *  When a node is requested by the user this function is called to allow us
+ *  to add auxiliary data to the node object.
+ *
+ * @ingroup tripal_analysis
+ */
+function chado_analysis_load($nodes) {
+
+  foreach ($nodes as $nid => $node) {
+    // find the analysis and add in the details
+    $analysis_id = chado_get_id_for_node('analysis', $nid);
+
+    // build the analysis variable
+    $values = array('analysis_id' => $analysis_id);
+    $analysis = tripal_core_generate_chado_var('analysis', $values);
+
+    // add in the description field
+    $analysis = tripal_core_expand_chado_vars($analysis, 'field', 'analysis.description');
+    $nodes[$nid]->analysis = $analysis;
+  }
+}
+
+/**
+ * Implement hook_access().
+ *
+ * This hook allows node modules to limit access to the node types they define.
+ *
+ *  @param $node
+ *  The node on which the operation is to be performed, or, if it does not yet exist, the
+ *  type of node to be created
+ *
+ *  @param $op
+ *  The operation to be performed
+ *
+ *  @param $account
+ *  A user object representing the user for whom the operation is to be performed
+ *
+ *  @return
+ *  If the permission for the specified operation is not set then return FALSE. If the
+ *  permission is set then return NULL as this allows other modules to disable
+ *  access.  The only exception is when the $op == 'create'.  We will always
+ *  return TRUE if the permission is set.
+ *
+ * @ingroup tripal_analysis
+ */
+function chado_analysis_node_access($node, $op, $account) {
+
+  if ($op == 'create') {
+    if (!user_access('create chado_analysis content', $account)) {
+      return FALSE;
+    }
+    return TRUE;
+  }
+  if ($op == 'update') {
+    if (!user_access('edit chado_analysis content', $account)) {
+      return FALSE;
+    }
+  }
+  if ($op == 'delete') {
+    if (!user_access('delete chado_analysis content', $account)) {
+      return FALSE;
+    }
+  }
+  if ($op == 'view') {
+    if (!user_access('access chado_analysis content', $account)) {
+      return FALSE;
+    }
+  }
+  return NULL;
 }

+ 1 - 1
tripal_analysis/includes/tripal_analysis.sync.inc

@@ -216,6 +216,6 @@ function tripal_analysis_sync_analyses($analysis_id = NULL, $job_id = NULL) {
  */
 function tripal_analyses_cleanup($dummy = NULL, $job_id = NULL) {
 
-  return tripal_core_clean_orphaned_nodes('analysis', $job_id);
+  return tripal_core_chado_node_cleanup_orphaned('analysis', $job_id);
 
 }

+ 1 - 252
tripal_analysis/tripal_analysis.module

@@ -17,7 +17,7 @@
 require_once 'api/tripal_analysis.api.inc';
 require_once 'includes/tripal_analysis_privacy.inc';
 require_once 'includes/tripal_analysis.admin.inc';
-require_once 'includes/tripal_analysis.form.inc';
+require_once 'includes/tripal_analysis.chado_node.inc';
 require_once 'includes/tripal_analysis.sync.inc';
 require_once "api/tripal_analysis.schema.api.inc";
 
@@ -290,9 +290,6 @@ function tripal_analysis_views_api() {
   );
 }
 
-
-
-
 /**
  * Implementation of hook_form_alter()
  * 
@@ -306,255 +303,7 @@ function tripal_analysis_form_alter(&$form, &$form_state, $form_id) {
     $form['actions']['preview']['#access'] = FALSE;
   }
 }
-/**
- *  When a new chado_analysis node is created we also need to add information
- *  to our chado_analysis table.  This function is called on insert of a new
- *  node of type 'chado_analysis' and inserts the necessary information.
- *
- * @ingroup tripal_analysis
- */
-function chado_analysis_insert($node) {
-
-  $node->analysisname = trim($node->analysisname);
-  $node->description = trim($node->description);
-  $node->program = trim($node->program);
-  $node->programversion = trim($node->programversion);
-  $node->algorithm = trim($node->algorithm);
-  $node->sourcename = trim($node->sourcename);
-  $node->sourceversion = trim($node->sourceversion);
-  $node->sourceuri = trim($node->sourceuri);
-
-  // if there is an analysis_id in the $node object then this must be a sync so
-  // we can skip adding the analysis as it is already there, although
-  // we do need to proceed with the rest of the insert
-  if (!property_exists($node, 'analysis_id')) {
-
-    // Create a timestamp so we can insert it into the chado database
-    $time  = $node->timeexecuted;
-    $month = $time['month'];
-    $day   = $time['day'];
-    $year  = $time['year'];
-    $timestamp = $month . '/' . $day . '/' . $year;
-
-    // insert and then get the newly inserted analysis record
-    $values = array(
-      'name'           => $node->analysisname,
-      'description'    => $node->description,
-      'program'        => $node->program,
-      'programversion' => $node->programversion,
-      'algorithm'      => $node->algorithm,
-      'sourcename'     => $node->sourcename,
-      'sourceversion'  => $node->sourceversion,
-      'sourceuri'      => $node->sourceuri,
-      'timeexecuted'   => $timestamp
-    );
-    $analysis = tripal_core_chado_insert('analysis', $values);
-    if (!$analysis) {
-      drupal_set_message(t('Unable to add analysis.', 'warning'));
-      watchdog('tripal_analysis', 'Insert analysis: Unable to create analysis where values:%values',
-      array('%values' => print_r($values, TRUE)), WATCHDOG_ERROR);
-      return;
-    }
-    $analysis_id = $analysis['analysis_id'];
-    
-    // now add in the properties
-    $properties = tripal_core_properties_form_retreive($node, 'analysis_property');
-    foreach ($properties as $property => $elements) {
-      foreach ($elements as $rank => $value) {
-    
-        $status = tripal_analysis_insert_property($analysis_id, $property, $value, FALSE, 'analysis_property');
-        if (!$status) {
-          drupal_set_message("Error cannot add property: $property", "error");
-          watchdog('t_analysis', "Error cannot add property: %prop",
-          array('%property' => $property), WATCHDOG_ERROR);
-        }
-      }
-    }
-  }
-  else {
-    $analysis_id = $node->analysis_id;
-  }
-
-  // Make sure the entry for this analysis doesn't already exist in the
-  // chado_analysis table if it doesn't exist then we want to add it.
-  $check_org_id = chado_get_id_for_node('analysis', $node->nid);
-  if (!$check_org_id) {
-    $record = new stdClass();
-    $record->nid = $node->nid;
-    $record->vid = $node->vid;
-    $record->analysis_id = $analysis_id;
-    drupal_write_record('chado_analysis', $record);
-  }
-
-  // add the analysis to the node object for
-  // use by other analysis modules that may be using this function
-  $node->analysis = $analysis;
-  $node->analysis_id = $analysis_id; // we need to set this for children
-}
-
-/**
- * Removes analysis from the chado database
- *
- * @param $node
- *   The node object specifying which chado record to delete
- *
- * @ingroup tripal_analysis
- */
-function chado_analysis_delete($node) {
-  $analysis_id = chado_get_id_for_node('analysis', $node->nid);
 
-  // if we don't have an analysis id for this node then this isn't a node of
-  // type chado_analysis or the entry in the chado_analysis table was lost.
-  if (!$analysis_id) {
-    return;
-  }
 
-  // Remove data from the {chado_analysis}, {node}, and {node_revisions} tables
-  $sql_del = "DELETE FROM {chado_analysis} WHERE nid = :nid AND vid = :vid";
-  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
-  $sql_del = "DELETE FROM {node} WHERE nid = :nid AND vid = :vid";
-  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
-  $sql_del = "DELETE FROM {node_revision} WHERE nid = :nid AND vid = :vid";
-  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
-
-  //Remove from analysis and analysisprop tables of chado database as well
-  chado_query("DELETE FROM {analysis} WHERE analysis_id = :analysis_id", array(':analysis_id' => $analysis_id));
-}
 
-/**
- * Update analyses
- *
- * @param $node
- *   The updated node object
- *
- * @ingroup tripal_analysis
- */
-function chado_analysis_update($node) {
-  $node->analysisname = trim($node->analysisname);
-  $node->description = trim($node->description);
-  $node->program = trim($node->program);
-  $node->programversion = trim($node->programversion);
-  $node->algorithm = trim($node->algorithm);
-  $node->sourcename = trim($node->sourcename);
-  $node->sourceversion = trim($node->sourceversion);
-  $node->sourceuri = trim($node->sourceuri);
-
-  // Create a timestamp so we can insert it into the chado database
-  $time = $node->timeexecuted;
-  $month = $time['month'];
-  $day = $time['day'];
-  $year = $time['year'];
-  $timestamp = $month . '/' . $day . '/' . $year;
-
-  // update the record in Chado
-  $analysis_id = chado_get_id_for_node('analysis', $node->nid);
-  $sql = "
-    UPDATE {analysis}
-    SET name = :name, description = :description, program = :program,
-        programversion = :programversion, algorithm = :algorithm, sourcename = :sourcename,
-        sourceversion = :sourceversion, sourceuri = :sourceuri, timeexecuted = :timeexecuted
-    WHERE analysis_id = :analysis_id
-  ";
-  $args = array(
-    ':name' => $node->analysisname,
-    ':description' => $node->description,
-    ':program' => $node->program,
-    ':programversion' => $node->programversion,
-    ':algorithm' => $node->algorithm,
-    ':sourcename' => $node->sourcename,
-    ':sourceversion' => $node->sourceversion,
-    ':sourceuri' => $node->sourceuri,
-    ':timeexecuted' => $timestamp,
-    ':analysis_id' => $analysis_id
-  );
-  chado_query($sql, $args);
-
-  // now update the properties
-  $properties = array(); // stores all of the properties we need to add
-  
-  // now add in the properties by first removing any the analysis
-  // already has and adding the ones we have
-  tripal_core_chado_delete('analysisprop', array('analysis_id' => $analysis_id));
-  $properties = tripal_core_properties_form_retreive($node, 'analysis_property');
-  foreach ($properties as $property => $elements) {
-    foreach ($elements as $rank => $value) {
-      $status = tripal_analysis_insert_property($analysis_id, $property, $value, FALSE, 'analysis_property');
-      if (!$status) {
-        drupal_set_message("Error cannot add property: '$property'", "error");
-        watchdog('t_analysis', "Error cannot add property: '%prop'",
-        array('%prop' => $property), WATCHDOG_ERROR);
-      }
-    }
-  }
-}
- /**
-  *  When a node is requested by the user this function is called to allow us
-  *  to add auxiliary data to the node object.
-  *
-  * @ingroup tripal_analysis
-  */
-function chado_analysis_load($nodes) {
-
-  foreach ($nodes as $nid => $node) {
-    // find the analysis and add in the details
-    $analysis_id = chado_get_id_for_node('analysis', $nid);
-
-    // build the analysis variable
-    $values = array('analysis_id' => $analysis_id);
-    $analysis = tripal_core_generate_chado_var('analysis', $values);
-    
-    // add in the description field
-    $analysis = tripal_core_expand_chado_vars($analysis, 'field', 'analysis.description');
-    $nodes[$nid]->analysis = $analysis;
-  }
-}
-
-/**
- * Implement hook_access().
- *
- * This hook allows node modules to limit access to the node types they define.
- *
- *  @param $node
- *  The node on which the operation is to be performed, or, if it does not yet exist, the
- *  type of node to be created
- *
- *  @param $op
- *  The operation to be performed
- *
- *  @param $account
- *  A user object representing the user for whom the operation is to be performed
- *
- *  @return
- *  If the permission for the specified operation is not set then return FALSE. If the
- *  permission is set then return NULL as this allows other modules to disable
- *  access.  The only exception is when the $op == 'create'.  We will always
- *  return TRUE if the permission is set.
- *
- * @ingroup tripal_analysis
- */
-function chado_analysis_node_access($node, $op, $account) {
-
-  if ($op == 'create') {
-    if (!user_access('create chado_analysis content', $account)) {
-      return FALSE;
-    }
-    return TRUE;
-  }
-  if ($op == 'update') {
-    if (!user_access('edit chado_analysis content', $account)) {
-      return FALSE;
-    }
-  }
-  if ($op == 'delete') {
-    if (!user_access('delete chado_analysis content', $account)) {
-      return FALSE;
-    }
-  }
-  if ($op == 'view') {
-    if (!user_access('access chado_analysis content', $account)) {
-      return FALSE;
-    }
-  }
-  return NULL;
-}
 

+ 1 - 1
tripal_contact/includes/contact_sync.inc

@@ -126,6 +126,6 @@ function tripal_contact_sync_contacts($job_id = NULL) {
  */
 function tripal_contact_cleanup($dummy = NULL, $job_id = NULL) {
 
-  return tripal_core_clean_orphaned_nodes('contact', $job_id);
+  return tripal_core_chado_node_cleanup_orphaned('contact', $job_id);
 
 }

+ 19 - 1
tripal_contact/tripal_contact.install

@@ -58,13 +58,31 @@ function tripal_contact_install() {
   $obo_path = drupal_realpath(drupal_get_path('module', 'tripal_contact') . '/files/tcontact.obo');
   $obo_id = tripal_cv_add_obo_ref('Tripal Contacts', $obo_path);
   tripal_cv_submit_obo_job($obo_id);
+  
+  /*
+  // Install our custom block visibility settings per node type
+  $query = db_insert('block_node_type')
+    ->fields(array('type', 'module', 'delta'))
+    ->values(array(
+      'type'   => 'chado_contact',
+      'module' => 'tripal_contact', // My module name
+      'delta'  => 'contbase', // Same delta used in hook_block_info
+    )
+  )->execute();
+  */
 }
 
 /**
  * Implementation of hook_uninstall().
  */
 function tripal_contact_uninstall() {
-
+  /*
+  // remove our custom block visibility settings per node type
+  db_delete('block_node_type')
+    ->condition('module', 'chado_contact')
+    ->condition('delta', 'contbase')
+    ->execute();
+    */
 }
 
 /**

+ 25 - 9
tripal_contact/tripal_contact.module

@@ -203,16 +203,16 @@ function tripal_contact_theme($existing, $type, $theme, $path) {
 function tripal_contact_block_info() {
 
   $blocks['contbase']['info'] = t('Tripal Contact Details');
-  $blocks['contbase']['cache'] = 'BLOCK_NO_CACHE';
+  $blocks['contbase']['cache'] = 'DRUPAL_NO_CACHE';
 
   $blocks['contprops']['info'] = t('Tripal Contact Properties');
-  $blocks['contprops']['cache'] = 'BLOCK_NO_CACHE';
+  $blocks['contprops']['cache'] = 'DRUPAL_NO_CACHE';
 
   $blocks['contrels']['info'] = t('Tripal Contact Relationships');
-  $blocks['contrels']['cache'] = 'BLOCK_NO_CACHE';
+  $blocks['contrels']['cache'] = 'DRUPAL_NO_CACHE';
 
-  $blocks['contpubs']['info'] = t('Tripal Cotact Publications');
-  $blocks['contpubs']['cache'] = 'BLOCK_NO_CACHE';
+  $blocks['contpubs']['info'] = t('Tripal Contact Publications');
+  $blocks['contpubs']['cache'] = 'DRUPAL_NO_CACHE';
 
   return $blocks;
 }
@@ -229,19 +229,35 @@ function tripal_contact_block_view($delta = '') {
     switch ($delta) {
       case 'contbase':
         $block['subject'] = t('Details');
-        $block['content'] = theme('tripal_contact_base', $node);
+        $block['content'] = array(
+          '#theme' => 'tripal_contact_base', 
+          '#nodes' => $node,
+          '#title' => '',
+        );
         break;
       case 'contprops':
         $block['subject'] = t('Properties');
-        $block['content'] = theme('tripal_contact_properties', $node);
+        $block['content'] = array(
+          '#theme' => 'tripal_contact_properties', 
+          '#nodes' => $node,
+          '#title' => '',
+        );
         break;
       case 'contrels':
         $block['subject'] = t('Relationships');
-        $block['content'] = theme('tripal_contact_relationships', $node);
+        $block['content'] = array(
+          '#theme' => 'tripal_contact_relationships', 
+          '#nodes' => $node,
+          '#title' => '',
+        );
         break;
       case 'contpubs':
         $block['subject'] = t('Publications');
-        $block['content'] = theme('tripal_contact_publications', $node);
+        $block['content'] = array(
+          '#theme' => 'tripal_contact_publications', 
+          '#nodes' => $node,
+          '#title' => '',
+        );
         break;
       default :
     }

+ 5 - 114
tripal_core/api/tripal_core_chado.api.inc

@@ -1818,7 +1818,7 @@ function tripal_core_expand_chado_vars($object, $type, $to_expand, $table_option
       $foreign_table_desc = tripal_core_get_chado_table_schema($foreign_table);
 
       // If it's connected to the base table via a FK constraint
-      if ($foreign_table_desc['foreign keys'][$base_table]) {
+      if (array_key_exists($base_table, $foreign_table_desc['foreign keys'])) {
         foreach ($foreign_table_desc['foreign keys'][$base_table]['columns'] as $left => $right) {
           // if the FK value in the base table is not there then we can't expand it, so just skip it.
           if (!$object->{$right}) {
@@ -1873,7 +1873,10 @@ function tripal_core_expand_chado_vars($object, $type, $to_expand, $table_option
         $did_expansion = 0;
         foreach ((array) $object as $field_name => $field_value) {
           // if we have a nested object ->expand the table in it
-          if (is_object($field_value)) {
+          // check to see if the $field_name is a valid chado table, we don't need
+          // to call tripal_core_expand_chado_vars on fields that aren't tables          
+          $check = tripal_core_get_chado_table_schema($field_name);          
+          if ($check) {
             $did_expansion = 1;
             $object->{$field_name} = tripal_core_expand_chado_vars($field_value, 'table', $foreign_table);
           }
@@ -2439,119 +2442,7 @@ function tripal_core_get_chado_table_schema($table) {
 
   return $table_arr;
 }
-/**
- * This function will delete Drupal nodes for any sync'ed table (e.g.
- * feature, organism, analysis, stock, library) if the chado record has been
- * deleted or the entry in the chado_[table] table has been removed.
- *
- * @param $table
- *   The name of the table that corresonds to the node type we want to clean up.
- * @param $job_id
- *   This should be the job id from the Tripal jobs system.  This function
- *   will update the job status using the provided job ID.
- *
- * @ingroup tripal_core_api
- */
-function tripal_core_clean_orphaned_nodes($table, $job_id) {
-  $count = 0;
-
-  // build the SQL statments needed to check if nodes point to valid analyses
-  $dsql = "SELECT * FROM {node} WHERE type = 'chado_" . $table . "' order by nid";
-  $nsql = "SELECT * FROM {node} WHERE nid = :nid";
-  $csql = "SELECT * FROM {chado_" . $table . "} WHERE nid = :nid ";
-  $clsql= "SELECT * FROM {chado_" . $table . "}";
-  $lsql = "SELECT * FROM {" . $table . "} where " . $table . "_id = :" . $table . "_id ";
-
-  // load into nodes array
-  print "Getting nodes\n";
-  $nodes = array();
-  $res = db_query($dsql);
-  foreach ($res as $node) {
-    $nodes[$count] = $node;
-    $count++;
-  }
-
-  // load the chado_$table into an array
-  print "Getting chado_$table\n";
-  $cnodes = array();
-  $res = db_query($clsql);
-  foreach ($res as $node) {
-    $cnodes[$count] = $node;
-    $count++;
-  }
-  $interval = intval($count * 0.01);
-  if ($interval < 1) {
-    $interval = 1;
-  }
-
-  // iterate through all of the chado_$table entries and remove those
-  // that don't have a node or don't have a $table record in chado.libary
-  print "Verifying all chado_$table Entries\n";
-  $deleted = 0;
-  foreach ($cnodes as $nid) {
-
-    // update the job status every 1% analyses
-    if ($job_id and $i % $interval == 0) {
-      tripal_job_set_progress($job_id, intval(($i / $count) * 100));
-    }
-
-    // see if the node exits, if not remove the entry from the chado_$table table
-    $results = db_query($nsql, array(':nid' => $nid->nid));
-    $node = $results->fetchObject();
-    if (!$node) {
-      $deleted++;
-      db_query("DELETE FROM {chado_" . $table . "} WHERE nid = :nid", array(':nid' => $nid->nid));
-      $message = "chado_$table missing node.... DELETING: $nid->nid";
-      watchdog('tripal_core', $message, array(), WATCHDOG_WARNING);
-    }
 
-    // see if the record in chado exist, if not remove the entry from the chado_$table
-    $table_id = $table . "_id";
-    $results = chado_query($lsql, array(":" . $table . "_id" => $nid->$table_id));
-    $record = $results->fetchObject();
-    if (!$record) {
-      $deleted++;
-      $sql = "DELETE FROM {chado_" . $table . "} WHERE " . $table . "_id = :" . $table . "_id";
-      db_query($sql, array(":" . $table . "_id" => $nid->$table_id));
-      $message = "chado_$table missing $table.... DELETING entry.";
-      watchdog('tripal_core', $message, array(), WATCHDOG_WARNING);
-    }
-    $i++;
-  }
-  print "\t$deleted chado_$table entries missing either a node or chado entry.\n";
-
-  // iterate through all of the nodes and delete those that don't
-  // have a corresponding entry in chado_$table
-  $deleted = 0;
-  foreach ($nodes as $node) {
-
-    // update the job status every 1% libraries
-    if ($job_id and $i % $interval == 0) {
-      tripal_job_set_progress($job_id, intval(($i / $count) * 100));
-    }
-
-    // check to see if the node has a corresponding entry
-    // in the chado_$table table. If not then delete the node.
-    $results = db_query($csql, array(":nid" => $node->nid));
-    $link = $results->fetchObject();
-    if (!$link) {
-      if (node_access('delete', $node)) {
-        $deleted++;
-        $message = "Node missing in chado_$table table.... DELETING node $node->nid";
-        watchdog("tripal_core", $message, array(), WATCHDOG_WARNING);
-        node_delete($node->nid);
-      }
-      else {
-        $message = "Node missing in chado_$table table.... but cannot delete due to improper permissions (node $node->nid)";
-        watchdog("tripal_core", $message, array(), WATCHDOG_WARNING);
-      }
-    }
-    $i++;
-  }
-  print "\t$deleted nodes did not have corresponding chado_$table entries.\n";
-
-  return '';
-}
 /**
  * Check that the Chado schema exists within the local database
  *

+ 243 - 76
tripal_core/api/tripal_core_chado_nodes.api.inc

@@ -43,11 +43,11 @@
         'chado_node_api' => array(
           'base_table' => 'example',            // the name of the chado base table
           'hook_prefix' => 'chado_example',     // usually the name of the node type
-          'title' => array(
+          'record_type_title' => array(
             'singular' => t('Example'),         // Singular human-readable title
             'plural' => t('Examples')           // Plural human-readable title
           ),
-          'select_by' => array(                 // foreign keys present in your table
+          'sync_filters' => array(                 // foreign keys present in your table
             'type_id' => TRUE,                  // TRUE if there is an example.type_id field
             'organism_id' => TRUE               // TRUE if there is an example.organism_id field
           ),
@@ -139,8 +139,14 @@ function tripal_core_chado_node_sync_form($form, &$form_state) {
     $args = $node_info[$linking_table]['chado_node_api'];
     $form_state['chado_node_api'] = $args;
   }
+  
+  // define the fieldsets
+  $form['sync'] = array(
+    '#type' => 'fieldset',
+    '#title' => 'Sync ' . $args['record_type_title']['plural'],
+  );
 
-  $form['description'] = array(
+  $form['sync']['description'] = array(
   '#type' => 'item',
   '#value' => t("%title_plural of the types listed ".
      "below in the %title_singular Types box will be synced (leave blank to sync all types). You may limit the ".
@@ -148,67 +154,86 @@ function tripal_core_chado_node_sync_form($form, &$form_state) {
      "number of %title_plural in the chado database this may take a long ".
      "time to complete. ",
      array(
-      '%title_singular' => $args['title']['singular'],
-      '%title_plural' => $args['title']['plural']
+      '%title_singular' => $args['record_type_title']['singular'],
+      '%title_plural' => $args['record_type_title']['plural']
     )),
   );
 
-  if ($args['select_by']['type_id']) {
-    $form['type_ids'] = array(
+  if ($args['sync_filters']['type_id']) {
+    $form['sync']['type_ids'] = array(
       '#title'       => t('%title_singular Types',
          array(
-          '%title_singular' => $args['title']['singular'],
-          '%title_plural' => $args['title']['plural']
+          '%title_singular' => $args['record_type_title']['singular'],
+          '%title_plural' => $args['record_type_title']['plural']
       )),
       '#type'        => 'textarea',
       '#description' => t("Enter the names of the %title_singular types to sync. " .
          "Leave blank to sync all %title_plural. Pages for these %title_singular ".
          "types will be created automatically for %title_plural that exist in the ".
-         "chado database.  The names listed here should be spearated by ".
-         "spaces or entered separately on new lines. The names must match ".
+         "chado database.  The names listed here should be separated by a comma".
+         "or entered separately on new lines. The names must match ".
          "exactly (spelling and case) with terms in the ontologies",
          array(
-          '%title_singular' => $args['title']['singular'],
-          '%title_plural' => $args['title']['plural']
+          '%title_singular' => $args['record_type_title']['singular'],
+          '%title_plural' => $args['record_type_title']['plural']
         )),
       '#default_value' => (isset($form_state['values']['type_id'])) ? $form_state['values']['type_id'] : '',
     );
   }
 
   // get the list of organisms
-  if ($args['select_by']['organism_id']) {
+  if ($args['sync_filters']['organism_id']) {
     $sql = "SELECT * FROM {organism} ORDER BY genus, species";
     $orgs = tripal_organism_get_synced();
     $organisms[] = '';
     foreach ($orgs as $organism) {
       $organisms[$organism->organism_id] = "$organism->genus $organism->species ($organism->common_name)";
     }
-    $form['organism_id'] = array(
+    $form['sync']['organism_id'] = array(
       '#title'       => t('Organism'),
       '#type'        => t('select'),
       '#description' => t("Choose the organism for which %title_plural types set above will
         be synced. Only organisms which also have been synced will appear in this list.",
          array(
-          '%title_singular' => $args['title']['singular'],
-          '%title_plural' => $args['title']['plural']
+          '%title_singular' => $args['record_type_title']['singular'],
+          '%title_plural' => $args['record_type_title']['plural']
         )),
       '#options'     => $organisms,
       '#default_value' => (isset($form_state['values']['organism_id'])) ? $form_state['values']['organism_id'] : 0,
     );
   }
 
-  $form['max_sync'] = array(
+  $form['sync']['max_sync'] = array(
     '#type' => 'textfield',
     '#title' => t('Maximum number of records to Sync'),
     '#description' => t('Leave this field empty to sync all records, regardless of number'),
     '#default_value' => (isset($form_state['values']['max_sync'])) ? $form_state['values']['max_sync'] : '',
   );
 
-  $form['button'] = array(
+  $form['sync']['button'] = array(
     '#type' => 'submit',
-    '#value' => t('Sync all ' . $args['title']['plural']),
+    '#value' => t('Sync ' . $args['record_type_title']['plural']),
     '#weight' => 3,
   );
+  
+  
+  $form['cleanup'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Clean Up')
+  );
+  $form['cleanup']['description'] = array(
+    '#markup' => t("<p>With Drupal and chado residing in different databases " .
+        "it is possible that nodes in Drupal and " . strtolower($args['record_type_title']['plural']) . " in Chado become " .
+        "\"orphaned\".  This can occur if a node in Drupal is " .
+        "deleted but the corresponding chado records is not and/or vice " .
+        "versa. Click the button below to resolve these discrepancies.</p>"),
+    '#weight' => 1,
+  );
+  $form['cleanup']['button'] = array(
+    '#type' => 'submit',
+    '#value' => 'Clean up orphaned ' . strtolower($args['record_type_title']['plural']),
+    '#weight' => 2,
+  );
 
   // Allow each module to alter this form as needed
   $hook_form_alter = $args['hook_prefix'] . '_chado_node_sync_form';
@@ -226,57 +251,71 @@ function tripal_core_chado_node_sync_form_submit($form, $form_state) {
 
   global $user;
 
-  // get arguments
-  $args = $form_state['chado_node_api'];
-  $module = $form_state['chado_node_api']['hook_prefix'];
-  $base_table = $form_state['chado_node_api']['base_table'];
-
-  // Allow each module to hijack the submit if needed
-  $hook_form_hijack_submit = $args['hook_prefix'] . '_chado_node_sync_form_submit';
-  if (function_exists($hook_form_hijack_submit)) {
-    return call_user_func($hook_form_hijack_submit, $form, $form_state);
-  }
-
-  // Get the types separated into a consistent string
-  if (isset($form_state['values']['type_ids'])) {
-    $types = preg_replace("/[\s\n\r]+/", '|||', $form_state['values']['type_ids']);
-  }
-  else {
-    $types = '';
-  }
-
-  // Job Arguments
-  $job_args = array(
-    'base_table' => $base_table,
-    'max_sync' => (!empty($form_state['values']['max_sync'])) ? $form_state['values']['max_sync'] : FALSE,
-    'organism_id' => FALSE,
-    'types' => $types,
-  );
-
-  // Create Job based on presence of organism
-  if (isset($form_state['values']['organism_id'])) {
-    $organism_id = $form_state['values']['organism_id'];
-    $organism = tripal_core_chado_select('organism', array('genus', 'species'), array('organism_id' => $organism_id));
-    $title = "Sync all " . $args['title']['plural'] . " for " . $organism[0]->genus . " " . $organism[0]->species;
-
-    $job_args['organism_id'] = $organism_id;
-    tripal_add_job($title, $module, 'tripal_core_chado_node_sync_records', $job_args, $user->uid);
+  if (preg_match('/^Sync/', $form_state['values']['op'])) {
+    // get arguments
+    $args = $form_state['chado_node_api'];
+    $module = $form_state['chado_node_api']['hook_prefix'];
+    $base_table = $form_state['chado_node_api']['base_table'];
+  
+    // Allow each module to hijack the submit if needed
+    $hook_form_hijack_submit = $args['hook_prefix'] . '_chado_node_sync_form_submit';
+    if (function_exists($hook_form_hijack_submit)) {
+      return call_user_func($hook_form_hijack_submit, $form, $form_state);
+    }
+  
+    // Get the types separated into a consistent string
+    $types = array();
+    if (isset($form_state['values']['type_ids'])) {
+      // seperate by new line or comma.
+      $temp_types = preg_split("/[,\n\r]+/", $form_state['values']['type_ids']);
+      
+      // remove any extra spacing around the types
+      for($i = 0; $i < count($temp_types); $i++) {
+        // skip empty types
+        if (trim($temp_types[$i]) == '') {
+          continue;
+        }
+        $types[$i] = trim($temp_types[$i]);
+      }
+    }
+      // Job Arguments
+    $job_args = array(
+      'base_table' => $base_table,
+      'max_sync' => (!empty($form_state['values']['max_sync'])) ? $form_state['values']['max_sync'] : FALSE,
+      'organism_id' => FALSE,
+      'types' => $types,
+    );
+    // Create Job based on presence of organism
+    if (array_key_exists('organism_id', $form_state['values']) and 
+        $form_state['values']['organism_id'] != 0) {
+      $organism_id = $form_state['values']['organism_id'];
+      $organism = tripal_core_chado_select('organism', array('genus', 'species'), array('organism_id' => $organism_id));
+      $title = "Sync all " . $args['record_type_title']['plural'] . " for " . $organism[0]->genus . " " . $organism[0]->species;
+  
+      $job_args['organism_id'] = $organism_id;
+      tripal_add_job($title, $module, 'tripal_core_chado_node_sync_records', $job_args, $user->uid);
+    }
+    else {
+      $title = t('Sync all ' . $args['record_type_title']['plural']);
+      tripal_add_job($title, $module, 'tripal_core_chado_node_sync_records', $job_args, $user->uid);
+    }
   }
-  else {
-    $title = t('Sync all ' . $args['title']['plural'] . ' for all synced organisms');
-    tripal_add_job($title, $module, 'tripal_core_chado_node_sync_records', $job_args, $user->uid);
+  if (preg_match('/^Clean up orphaned/', $form_state['values']['op'])) {
+    $module = $form_state['chado_node_api']['hook_prefix'];
+    $base_table = $form_state['chado_node_api']['base_table'];
+    $job_args = array($base_table);
+    tripal_add_job($form_state['values']['op'], $module, 'tripal_core_chado_node_cleanup_orphaned', $job_args, $user->uid);
   }
 }
 
 /**
  * Actual Sync Function. Works on a group of records
  */
-function tripal_core_chado_node_sync_records($base_table, $max_sync = FALSE, $organism_id = FALSE, $types = '') {
-
+function tripal_core_chado_node_sync_records($base_table, $max_sync = FALSE, $organism_id = FALSE, $types = array(), $job_id = NULL) {
   global $user;
   $base_table_id = $base_table . '_id';
 
-  print "\nSync'ing records from $base_table restricted to\n";
+  print "\nSync'ing $base_table records.  ";
 
   // START BUILDING QUERY TO GET ALL RECORD FROM BASE TABLE THAT MATCH
   $select = array("$base_table.*");
@@ -285,24 +324,26 @@ function tripal_core_chado_node_sync_records($base_table, $max_sync = FALSE, $or
   $where_args = array();
 
   // If types are supplied then handle them
-  if (!empty($types)) {
-    $types = explode('|||',$types);
-    print "  Types: " . implode(', ',$types) . "\n";
+  $restrictions = '';
+  if (count($types) > 0) {
+    $restrictions .= "  Type(s): " . implode(', ',$types) . "\n";
 
     $select[] = 'cvterm.name as cvtname';
     $joins[] = "LEFT JOIN {cvterm} cvterm ON $base_table.type_id = cvterm.cvterm_id";
     if (sizeof($types) == 1) {
       $where_clauses[] = 'cvterm.name = :type_name';
       $where_args[':type_name'] = $types[0];
-    } elseif (sizeof($types) > 1) {
+    } 
+    elseif (sizeof($types) > 1) {
       $where_clauses[] = "cvterm.name IN ('" . implode("', '", $types) . "')";
     }
   }
 
   // If Organism is supplied
   if ($organism_id) {
-    print "  Organism ID: $organism_id\n";
-
+    $organism = tripal_core_chado_select('organism', array('*'), array('organism_id' => $organism_id));
+    $restrictions .= "  Organism: " . $organism[0]->genus . " " . $organism[0]->species . "\n";
+    
     $select[] = 'organism.*';
     $joins[] = "LEFT JOIN {organism} organism ON organism.organism_id = $base_table.organism_id";
     $where_clauses[] = 'organism.organism_id = :organism_id';
@@ -316,20 +357,29 @@ function tripal_core_chado_node_sync_records($base_table, $max_sync = FALSE, $or
   }
 
   // Build Query
-  $query = "SELECT " . implode(', ',$select)
-    . ' FROM {' . $base_table . '} ' . $base_table . ' '
-    . implode(' ', $joins)
-    . " WHERE " . implode(' AND ', $where_clauses)
-    . " ORDER BY " . $base_table_id;
+  $query = "SELECT " . implode(', ',$select) . ' FROM {' . $base_table . '} ' . $base_table . ' ' . implode(' ', $joins);
+  if (count($where_clauses) > 0) {
+    $query .= " WHERE " . implode(' AND ', $where_clauses);
+  }
+  $query .- " ORDER BY " . $base_table_id;
 
   // If Maximum number to Sync is supplied
   if ($max_sync) {
     $query .= " LIMIT $max_sync";
+    $restrictions .= "  Limited to $max_sync records.\n";
   }
 
-  print "\nQuery: " . preg_replace(array("/FROM/","/LEFT/","/WHERE/"), array("\nFROM","\nLEFT","\nWHERE"), $query) . "\n";
+  if ($restrictions) {
+    print "Records matching these criteria will be synced: \n$restrictions";
+  }
+  else {
+    print "\n";
+  } 
+    
+  
+  //print "\nQuery: " . preg_replace(array("/FROM/","/LEFT/","/WHERE/"), array("\nFROM","\nLEFT","\nWHERE"), $query) . "\n";
 
-  print "Executing Query...\n";
+  //print "Executing Query...\n";
   $results = chado_query($query, $where_args);
 
   // Iterate through features that need to be synced
@@ -339,7 +389,7 @@ function tripal_core_chado_node_sync_records($base_table, $max_sync = FALSE, $or
     $interval = 1;
   }
 
-  print "\n$count $base_table records found.\nLoading...\n";
+  print "\n$count $base_table records found.\n";
 
   $i = 0;
   $transaction = db_transaction();
@@ -372,10 +422,14 @@ function tripal_core_chado_node_sync_records($base_table, $max_sync = FALSE, $or
         $new_node->type = 'chado_' . $base_table;
         $new_node->uid = $user->uid;
         $new_node->{$base_table_id} = $record->{$base_table_id};
+        $new_node->library = $record;
 
+        // TODO: should we get rid of this hook and use hook_node_presave() instead?
         // allow base module to set additional fields as needed
         $hook_create_new_node = 'chado_' . $base_table . '_chado_node_sync_create_new_node';
-        $new_node = call_user_func($hook_create_new_node, $new_node, $record);
+        if (function_exists($hook_create_new_node)) {
+          $new_node = call_user_func($hook_create_new_node, $new_node, $record);
+        }
 
         // Validate and Save New Node
         $form = array();
@@ -402,4 +456,117 @@ function tripal_core_chado_node_sync_records($base_table, $max_sync = FALSE, $or
     print "FAILED: Rolling back database changes...\n";
   }
 
+}
+/**
+ * This function will delete Drupal nodes for any sync'ed table (e.g.
+ * feature, organism, analysis, stock, library) if the chado record has been
+ * deleted or the entry in the chado_[table] table has been removed.
+ *
+ * @param $table
+ *   The name of the table that corresonds to the node type we want to clean up.
+ * @param $job_id
+ *   This should be the job id from the Tripal jobs system.  This function
+ *   will update the job status using the provided job ID.
+ *
+ * @ingroup tripal_core_api
+ */
+function tripal_core_chado_node_cleanup_orphaned($table, $job_id = NULL) {
+  $count = 0;
+
+  // build the SQL statments needed to check if nodes point to valid analyses
+  $dsql = "SELECT * FROM {node} WHERE type = 'chado_" . $table . "' order by nid";
+  $nsql = "SELECT * FROM {node} WHERE nid = :nid";
+  $csql = "SELECT * FROM {chado_" . $table . "} WHERE nid = :nid ";
+  $clsql= "SELECT * FROM {chado_" . $table . "}";
+  $lsql = "SELECT * FROM {" . $table . "} where " . $table . "_id = :" . $table . "_id ";
+
+  // load into nodes array
+  print "Getting nodes\n";
+  $nodes = array();
+  $res = db_query($dsql);
+  foreach ($res as $node) {
+    $nodes[$count] = $node;
+    $count++;
+  }
+
+  // load the chado_$table into an array
+  print "Getting chado_$table\n";
+  $cnodes = array();
+  $res = db_query($clsql);
+  foreach ($res as $node) {
+    $cnodes[$count] = $node;
+    $count++;
+  }
+  $interval = intval($count * 0.01);
+  if ($interval < 1) {
+    $interval = 1;
+  }
+
+  // iterate through all of the chado_$table entries and remove those
+  // that don't have a node or don't have a $table record in chado.libary
+  print "Verifying all chado_$table Entries\n";
+  $deleted = 0;
+  foreach ($cnodes as $nid) {
+
+    // update the job status every 1% analyses
+    if ($job_id and $i % $interval == 0) {
+      tripal_job_set_progress($job_id, intval(($i / $count) * 100));
+    }
+
+    // see if the node exits, if not remove the entry from the chado_$table table
+    $results = db_query($nsql, array(':nid' => $nid->nid));
+    $node = $results->fetchObject();
+    if (!$node) {
+      $deleted++;
+      db_query("DELETE FROM {chado_" . $table . "} WHERE nid = :nid", array(':nid' => $nid->nid));
+      $message = "chado_$table missing node.... DELETING: $nid->nid";
+      watchdog('tripal_core', $message, array(), WATCHDOG_WARNING);
+    }
+
+    // see if the record in chado exist, if not remove the entry from the chado_$table
+    $table_id = $table . "_id";
+    $results = chado_query($lsql, array(":" . $table . "_id" => $nid->$table_id));
+    $record = $results->fetchObject();
+    if (!$record) {
+      $deleted++;
+      $sql = "DELETE FROM {chado_" . $table . "} WHERE " . $table . "_id = :" . $table . "_id";
+      db_query($sql, array(":" . $table . "_id" => $nid->$table_id));
+      $message = "chado_$table missing $table.... DELETING entry.";
+      watchdog('tripal_core', $message, array(), WATCHDOG_WARNING);
+    }
+    $i++;
+  }
+  print "\t$deleted chado_$table entries missing either a node or chado entry.\n";
+
+  // iterate through all of the nodes and delete those that don't
+  // have a corresponding entry in chado_$table
+  $deleted = 0;
+  foreach ($nodes as $node) {
+
+    // update the job status every 1% libraries
+    if ($job_id and $i % $interval == 0) {
+      tripal_job_set_progress($job_id, intval(($i / $count) * 100));
+    }
+
+    // check to see if the node has a corresponding entry
+    // in the chado_$table table. If not then delete the node.
+    $results = db_query($csql, array(":nid" => $node->nid));
+    $link = $results->fetchObject();
+    if (!$link) {
+      if (node_access('delete', $node)) {
+        $deleted++;
+        $message = "Node missing in chado_$table table.... DELETING node $node->nid";
+        watchdog("tripal_core", $message, array(), WATCHDOG_WARNING);
+        node_delete($node->nid);
+      }
+      else {
+        $message = "Node missing in chado_$table table.... but cannot delete due to improper permissions (node $node->nid)";
+        watchdog("tripal_core", $message, array(), WATCHDOG_WARNING);
+      }
+    }
+    $i++;
+  }
+  print "\t$deleted nodes did not have corresponding chado_$table entries.\n";
+
+  return '';
 }

+ 26 - 8
tripal_core/api/tripal_core_jobs.api.inc

@@ -34,7 +34,7 @@
  * @param $callback
  *    The name of a function to be called when the job is executed
  * @param $arguments
- *    An array of arguements to be passed on to the callback
+ *    An array of arguments to be passed on to the callback
  * @param $uid
  *    The uid of the user adding the job
  * @param $priority
@@ -64,7 +64,11 @@
 function tripal_add_job($job_name, $modulename, $callback, $arguments, $uid, $priority = 10) {
 
   // convert the arguments into a string for storage in the database
-  $args = implode("::", $arguments);
+  $args = array();
+  if (is_array($arguments)) {
+    $args = serialize($arguments);
+  }
+  
   $record = new stdClass();
   $record->job_name = $job_name;
   $record->modulename = $modulename;
@@ -73,9 +77,8 @@ function tripal_add_job($job_name, $modulename, $callback, $arguments, $uid, $pr
   $record->submit_date = REQUEST_TIME;
   $record->uid = $uid;
   $record->priority = $priority;  # the lower the number the higher the priority
-  if ($args) {
-    $record->arguments = $args;
-  }
+  $record->arguments = $args;
+
   if (drupal_write_record('tripal_jobs', $record)) {
     $jobs_url = url("admin/tripal/tripal_jobs");
     drupal_set_message(t("Job '%job_name' submitted.  Check the <a href='!jobs_url'>jobs page</a> for status", array('%job_name' => $job_name, '!jobs_url' => $jobs_url)));
@@ -192,8 +195,15 @@ function tripal_jobs_rerun($job_id, $goto_jobs_page = TRUE) {
 
   $sql = "SELECT * FROM {tripal_jobs} WHERE job_id = :job_id";
   $results = db_query($sql, array(':job_id' => $job_id));
-  $job = $results->fetchObject();
-  $args = explode("::", $job->arguments);
+  $job = $results->fetchObject(); 
+  // arguments for jobs used to be stored as plain string with a double colon
+  // separating them.  But as of Tripal v2.0 the arguments are stored as 
+  // a serialized array.  To be backwards compatible, we should check for serialization
+  // and if not then we will use the old style
+  $args = unserialize($job->arguments);
+  if (!$args) {
+    $args = explode("::", $job->arguments);
+  }
   $job_id = tripal_add_job($job->job_name, $job->modulename, $job->callback, $args, $user_id, $job->priority);
 
   if ($goto_jobs_page) {
@@ -285,7 +295,15 @@ function tripal_jobs_launch($do_parallel = 0, $job_id = NULL) {
     // Add the job_id as the last item in the list of arguments. All
     // callback functions should support this argument.
     $callback = $job->callback;
-    $args = split("::", $job->arguments);
+    
+    // arguments for jobs used to be stored as plain string with a double colon
+    // separating them.  But as of Tripal v2.0 the arguments are stored as
+    // a serialized array.  To be backwards compatible, we should check for serialization
+    // and if not then we will use the old style
+    $args = unserialize($job->arguments);
+    if (!$args) {
+      $args = explode("::", $job->arguments);
+    }
     $args[] = $job->job_id;
     print "Calling: $callback(" . implode(", ", $args) . ")\n";
     call_user_func_array($callback, $args);

+ 2 - 2
tripal_core/tripal_core.drush.inc

@@ -187,7 +187,7 @@ function drush_tripal_core_set_user($username) {
   }
   else {
     drush_print('ERROR: Please provide a username for running this job.');
-    return;
+    exit;
   }
 }
 
@@ -368,5 +368,5 @@ function drush_tripal_core_tripal_node_sync($module) {
  *  The name of a module with nodes associated with it. For example, feature
  */
 function drush_tripal_core_tripal_node_clean($module) {
-  tripal_core_clean_orphaned_nodes($module, 0);
+  tripal_core_chado_node_cleanup_orphaned($module, 0);
 }

+ 1 - 1
tripal_feature/includes/tripal_feature.sync_features.inc

@@ -444,6 +444,6 @@ function tripal_feature_sync_features($max_sync = 0, $organism_id = NULL,
  */
 function tripal_features_cleanup($dummy = NULL, $job_id = NULL) {
 
-  return tripal_core_clean_orphaned_nodes('feature', $job_id);
+  return tripal_core_chado_node_cleanup_orphaned('feature', $job_id);
 
 }

+ 7 - 4
tripal_feature/theme/tripal_feature/tripal_feature_terms.tpl.php

@@ -1,14 +1,17 @@
 <?php
 
-$feature = $node->feature;
+$feature = $variables['node']->feature;
+
 $options = array('return_array' => 1);
 $feature = tripal_core_expand_chado_vars($feature, 'table', 'feature_cvterm', $options);
 $terms = $feature->feature_cvterm;
 
 // order the terms by CV
 $s_terms = array();
-foreach ($terms as $term) {
-  $s_terms[$term->cvterm_id->cv_id->name][] = $term;  
+if ($terms) {
+  foreach ($terms as $term) {
+    $s_terms[$term->cvterm_id->cv_id->name][] = $term;  
+  }
 }
 
 if (count($s_terms) > 0) { ?>
@@ -56,7 +59,7 @@ if (count($s_terms) > 0) { ?>
           'id' => "tripal_feature-table-terms-$i",
         ),
         'sticky' => FALSE,
-        'caption' => ucwords(preg_replace('/_/', ' ', $cv)),
+        'caption' => '<b>Vocabulary: ' . ucwords(preg_replace('/_/', ' ', $cv)) . '</b>',
         'colgroups' => array(),
         'empty' => '',
       );

+ 1 - 1
tripal_featuremap/includes/tripal_featuremap.admin.inc

@@ -401,7 +401,7 @@ function tripal_featuremap_sync_featuremaps($featuremap_id = NULL, $job_id = NUL
  */
 function tripal_featuremap_cleanup($dummy = NULL, $job_id = NULL) {
 
-  return tripal_core_clean_orphaned_nodes('featuremap', $job_id);
+  return tripal_core_chado_node_cleanup_orphaned('featuremap', $job_id);
 
 }
 /**

+ 4 - 4
tripal_library/api/tripal_library.api.inc

@@ -21,7 +21,7 @@
  * @ingroup tripal_library_api
  */
 function tripal_library_get_property($library_id, $property) {
-  return tripal_core_get_property('library', $library_id, $property, 'tripal');
+  return tripal_core_get_property('library', $library_id, $property, 'library_property');
 }
 
 /**
@@ -42,7 +42,7 @@ function tripal_library_get_property($library_id, $property) {
  * @ingroup tripal_library_api
  */
 function tripal_library_insert_property($library_id, $property, $value, $update_if_present = 0) {
-  return tripal_core_insert_property('library', $library_id, $property, 'tripal', $value, $update_if_present);
+  return tripal_core_insert_property('library', $library_id, $property, 'library_property', $value, $update_if_present);
 }
 
 /**
@@ -66,7 +66,7 @@ function tripal_library_insert_property($library_id, $property, $value, $update_
  * @ingroup tripal_library_api
  */
 function tripal_library_update_property($library_id, $property, $value, $insert_if_missing = 0) {
-  return tripal_core_update_property('library', $library_id, $property, 'tripal', $value, $insert_if_missing);
+  return tripal_core_update_property('library', $library_id, $property, 'library_property', $value, $insert_if_missing);
 }
 /**
  * Delete a given property
@@ -85,5 +85,5 @@ function tripal_library_update_property($library_id, $property, $value, $insert_
  * @ingroup tripal_library_api
  */
 function tripal_library_delete_property($library_id, $property) {
-  return tripal_core_delete_property('library', $library_id, $property, 'tripal');
+  return tripal_core_delete_property('library', $library_id, $property, 'library_property');
 }

+ 4 - 565
tripal_library/includes/tripal_library.admin.inc

@@ -38,581 +38,20 @@ function tripal_library_admin_libraries_listing() {
 function tripal_library_admin() {
   $form = array();
 
-  // before proceeding check to see if we have any
-  // currently processing jobs. If so, we don't want
-  // to give the opportunity to sync libraries
-  $active_jobs = FALSE;
-  if (tripal_get_module_active_jobs('tripal_library')) {
-    $active_jobs = TRUE;
-  }
-
-  // add the field set for syncing libraries
-  if (!$active_jobs) {
-    get_tripal_library_admin_form_sync_set($form);
-    get_tripal_library_admin_form_reindex_set($form);
-    get_tripal_library_admin_form_taxonomy_set($form);
-    get_tripal_library_admin_form_cleanup_set($form);
-  }
-  else {
-    $form['notice'] = array(
-     '#type' => 'fieldset',
-     '#title' => t('Library Management Temporarily Unavailable')
-    );
-    $form['notice']['message'] = array(
-        '#value' => t('Currently, library management jobs are waiting or are running. . Managemment features have been hidden until these jobs complete.  Please check back later once these jobs have finished.  You can view the status of pending jobs in the Tripal jobs page.'),
-    );
-  }
-
-  return system_settings_form($form);
-}
-
-
-/**
- *
- *
- * @ingroup tripal_library
- */
-function get_tripal_library_admin_form_cleanup_set(&$form) {
-  $form['cleanup'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Clean Up')
-  );
-  $form['cleanup']['description'] = array(
-     '#type' => 'item',
-     '#value' => t("With Drupal and chado residing in different databases ".
-        "it is possible that nodes in Drupal and libraries in Chado become ".
-        "\"orphaned\".  This can occur if an library node in Drupal is ".
-        "deleted but the corresponding chado library is not and/or vice ".
-        "versa. Click the button below to resolve these discrepancies."),
-     '#weight' => 1,
-  );
-  $form['cleanup']['button'] = array(
-    '#type' => 'submit',
-    '#value' => t('Clean up orphaned libraries'),
-    '#weight' => 2,
-  );
-}
-
-/**
- *
- *
- * @ingroup tripal_library
- */
-function get_tripal_library_admin_form_taxonomy_set(&$form) {
-  $form['taxonify'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Assign Drupal Taxonomy to Library Features')
-  );
-
-  // get the list of libraries
-  $sql = "SELECT * FROM {library} ORDER BY uniquename";
-  $lib_rset = chado_query($sql);
-
-  // iterate through all of the libraries
-  $lib_boxes = array();
-  foreach ($lib_rset as $library) {
-    $lib_boxes[$library->library_id] = "$library->name";
-  }
-
-  $form['taxonify']['description'] = array(
-     '#type' => 'item',
-     '#value' => t("Drupal allows for assignment of \"taxonomy\" or catagorical terms to " .
-                   "nodes. These terms allow for advanced filtering during searching. This option allows ".
-                   "for setting taxonomy only for features that belong to the selected libraries below.  All other features will be unaffected.  To set taxonomy for all features in the site see the Feature Administration page."),
-   '#weight' => 1,
-  );
-
-  $form['taxonify']['tx-libraries'] = array(
-   '#title'       => t('Libraries'),
-   '#type'        => t('checkboxes'),
-   '#description' => t("Check the libraries whose features you want to reset taxonomy.  Note: this list contains all libraries, even those that may not be synced."),
-   '#required'    => FALSE,
-   '#prefix'      => '<div id="lib_boxes">',
-   '#suffix'      => '</div>',
-   '#options'     => $lib_boxes,
-   '#weight'      => 2
-  );
-  $form['taxonify']['tx-button'] = array(
-    '#type' => 'submit',
-    '#value' => t('Set Feature Taxonomy'),
-    '#weight'      => 3
-  );
-}
-/**
- *
- * @ingroup tripal_library
- */
-function get_tripal_library_admin_form_reindex_set(&$form) {
-   // define the fieldsets
-  $form['reindex'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Reindex Library Features')
+  $form['nothing'] = array(
+    '#markup' => t('There are currently no settings to configure.')
   );
 
-  // get the list of libraries
-  $sql = "SELECT * FROM {Library} ORDER BY uniquename";
-  $lib_rset = chado_query($sql);
-
-  // iterate through all of the libraries
-  $lib_boxes = array();
-  while ($library = $lib_rset->fetchObject()) {
-    $lib_boxes[$library->library_id] = "$library->name";
-  }
-  $form['reindex']['description'] = array(
-     '#type' => 'item',
-     '#value' => t("This option allows for reindexing of only those features that belong to the selected libraries below. All other features will be unaffected.  To reindex all features in the site see the Feature Administration page."),
-   '#weight' => 1,
-  );
-
-  $form['reindex']['re-libraries'] = array(
-   '#title'       => t('Libraries'),
-   '#type'        => t('checkboxes'),
-   '#description' => t("Check the libraries whoee features you want to reindex. Note: this list contains all libraries, even those that may not be synced."),
-   '#required'    => FALSE,
-   '#prefix'      => '<div id="lib_boxes">',
-   '#suffix'      => '</div>',
-   '#options'     => $lib_boxes,
-   '#weight' => 2,
-  );
-  $form['reindex']['re-button'] = array(
-    '#type' => 'submit',
-    '#value' => t('Reindex Features'),
-    '#weight' => 3,
-  );
+  return system_settings_form($form);
 }
-/**
- *
- * @ingroup tripal_library
- */
-function get_tripal_library_admin_form_sync_set(&$form) {
-   // define the fieldsets
-  $form['sync'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Sync Libraries')
-  );
-
-
-  // get the list of libraries
-  $sql = "SELECT * FROM {library} ORDER BY uniquename";
-  $lib_rset = chado_query($sql);
-
-  // if we've added any libraries to the list that can be synced
-  // then we want to build the form components to allow the user
-  // to select one or all of them.  Otherwise, just present
-  // a message stating that all libraries are currently synced.
-  $lib_boxes = array();
-  $added = 0;
-  foreach ($lib_rset as $libary) {
-    // check to see if the library is already present as a node in drupal.
-    // if so, then skip it.
-    $sql = "SELECT * FROM {chado_library} WHERE library_id = :library_id";
-    $chado_library = db_query($sql, array(':library_id' => $library->library_id))->fetchObject();
-    if (!$chado_library) {
-      $lib_boxes[$library->library_id] = "$library->name";
-      $added++;
-    }
-  }
-
-  // if we have libraries we need to add to the checkbox then
-  // build that form element
-  if ($added > 0) {
-    $lib_boxes['all'] = "All Libraries";
 
-    $form['reindex']['description'] = array(
-     '#type' => 'item',
-     '#value' => t("This option allows for the creation of Drupal content for libraries in chado. Only the selected libraries will be synced."),
-   '#weight' => 1,
-    );
 
 
-    $form['sync']['libraries'] = array(
-      '#title'       => t('Available Libraries'),
-      '#type'        => t('checkboxes'),
-      '#description' => t("Check the libraries you want to sync.  Drupal content will be created for each of the libraries listed above.  Select 'All Libraries' to sync all of them."),
-      '#required'    => FALSE,
-      '#prefix'      => '<div id="lib_boxes">',
-      '#suffix'      => '</div>',
-      '#options'     => $lib_boxes,
-    '#weight' => 2,
-    );
-    $form['sync']['button'] = array(
-       '#type' => 'submit',
-       '#value' => t('Sync Libraries'),
-     '#weight' => 3,
-    );
-  }
-   // we don't have any libraries to select from
-  else {
-    $form['sync']['value'] = array(
-       '#value' => t('All libraries in Chado are currently synced with Drupal.')
-    );
-  }
-}
 /**
  *
  * @ingroup tripal_library
  */
 function tripal_library_admin_validate($form, &$form_state) {
-  global $user;  // we need access to the user info
-  $job_args = array();
-
-  // Submit the Sync Job if selected
-  if ($form_state['values']['op'] == t('Sync Libraries')) {
-
-    // check to see if the user wants to sync chado and drupal.  If
-    // so then we need to register a job to do so with tripal
-    $libraries = $form_state['values']['libraries'];
-    $do_all = FALSE;
-    $to_sync = array();
-
-  foreach ($libraries as $library_id) {
-    if (preg_match("/^all$/i", $library_id)) {
-      $do_all = TRUE;
-    }
-    if ($library_id and preg_match("/^\d+$/i", $library_id)) {
-      // get the library info
-      $sql = "SELECT * FROM {library} WHERE library_id = :library_id";
-      $library = chado_query($sql, array(':library_id' => $library_id))->fetchObject();
-      $to_sync[$library_id] = $library->name;
-    }
-  }
-
-  // submit the job to the tripal job manager
-  if ($do_all) {
-    tripal_add_job('Sync all libraries', 'tripal_library', 'tripal_library_sync_libraries', $job_args, $user->uid);
-  }
-  else{
-    foreach ($to_sync as $library_id => $name) {
-      $job_args[0] = $library_id;
-      tripal_add_job("Sync library: $name", 'tripal_library', 'tripal_library_sync_libraries', $job_args, $user->uid);
-      }
-    }
-  }
-
-  // -------------------------------------
-  // Submit the Reindex Job if selected
-  if ($form_state['values']['op'] == t('Reindex Features')) {
-    $libraries = $form_state['values']['re-libraries'];
-    foreach ($libraries as $library_id) {
-      if ($library_id and preg_match("/^\d+$/i", $library_id)) {
-        // get the library info
-        $sql = "SELECT * FROM {Library} WHERE library_id = :library_id";
-        $library = chado_query($sql, array(':library_id' => $library_id))->fetchObject();
-        $job_args[0] = $library_id;
-        tripal_add_job("Reindex features for library: $library->name", 'tripal_library',
-         'tripal_library_reindex_features', $job_args, $user->uid);
-      }
-    }
-  }
-
-  // -------------------------------------
-  // Submit the Taxonomy Job if selected
-  if ($form_state['values']['op'] == t('Set Feature Taxonomy')) {
-    $libraries = $form_state['values']['tx-libraries'];
-    foreach ($libraries as $library_id) {
-      if ($library_id and preg_match("/^\d+$/i", $library_id)) {
-        // get the library info
-        $sql = "SELECT * FROM {Library} WHERE library_id = :libary_id";
-        $library = chado_query($sql, array(':library_id' => $library_id))->fetchObject();
-        $job_args[0] = $library_id;
-        tripal_add_job("Set taxonomy for features in library: $library->name", 'tripal_library',
-         'tripal_library_taxonify_features', $job_args, $user->uid);
-      }
-    }
-  }
-    // -------------------------------------
-    // Submit the Cleanup Job if selected
-    if ($form_state['values']['op'] == t('Clean up orphaned libraries')) {
-      tripal_add_job('Cleanup orphaned libraries', 'tripal_library',
-         'tripal_library_cleanup', $job_args, $user->uid);
-    }
-}
-
-
-/**
- * Add the library as a taxonomy term for associating with library_features
- *
- * @ingroup tripal_library
- */
-function tripal_library_add_taxonomy($node, $library_id) {
-
-  //include the file containing the required functions.  We only have to
-  // do this because Drupal 6 fails to do this globally for us and
-  // the drupal_execute function below won't work
-  module_load_include('inc', 'taxonomy', 'taxonomy.admin');
-
-   // add the vocabulary
-  $vocab_form['values']['name'] = 'DNA Libraries';
-  $vocab_form['values']['description'] = 'Allows for associating/searching of library features by library name';
-  $vocab_form['values']['help'] = '';
-  $vocab_form['values']['module'] = 'taxonomy';
-  drupal_form_submit('taxonomy_form_vocabulary', $vocab_form);
-  return;
-
-   // make sure this term doesn't already exist.  If it doesn't then add it
-  if ($vid) {
-    $tree = taxonomy_get_tree($vid);
-    $found = 0;
-    foreach ($tree as $term) {
-      if ($term->name == $node->title) {
-        $found = 1;
-      }
-    }
-
-      // add the term to the vocabulary
-    if (!$found) {
-      $form_state = array();
-      $form_state['values']['name'] = $node->title;
-      $form_state['values']['description'] = $library_id;
-      drupal_form_submit('taxonomy_form_term', $form_state, $vid);
-    }
-  }
-}
-
-
-/**
- *
- *
- * @ingroup tripal_library
- */
-function tripal_library_sync_libraries($library_id = NULL, $job_id = NULL) {
-
-  global $user;
-  $page_content = '';
-
-  // get the list of libraries and create new nodes
-  if (!$library_id) {
-    $sql = "SELECT * FROM {library} L";
-    $results = chado_query($sql);
-  }
-  else {
-    $sql = "SELECT * FROM {library} L WHERE library_id = :library_id";
-    $results = chado_query($sql, array(':library_id' => $library_id));
-  }
-
-  // We'll use the following SQL statement for checking if the library
-  // already exists as a drupal node.
-  $sql = "SELECT * FROM {chado_library} ".
-        "WHERE library_id = :libary_id";
-
-  while ($library = $results->fetchObject()) {
-
-    // check if this library already exists in the drupal database. if it
-    // does then skip this library and go to the next one.
-    if (!db_query($sql, array(':libary_id' => $library->library_id))->fetchObject()) {
-
-    $new_node = new stdClass();
-    $new_node->type = 'chado_library';
-    $new_node->uid = $user->uid;
-    $new_node->title = "$library->name";
-    $new_node->library_id = $library->library_id;
-    $new_node->organism_id = $library->organism_id;
-    $new_node->uniquename = $library->uniquename;
-    $new_node->type_id = $library->type_id;
-
-    node_validate($new_node);
-    $errors = form_get_errors();
-    if (!$errors) {
-      $node = node_submit($new_node);
-      node_save($node);
-      if ($node->nid) {
-        print "Added " . $library->name . "\n";
-      }
-      else {
-        print "ERROR: Unable to create " . $library->name . "\n";
-      }
-    }
-    else {
-      print "ERROR: Unable to create " . $library->name . "\n" . print_r($errors, TRUE) . "\n";
-    }
-    }
-    else {
-      print "Skipped " . $library->name . "\n";
-    }
-  }
-  return $page_content;
-}
-
-
-/**
- *
- * @ingroup tripal_library
- */
-function tripal_library_feature_set_taxonomy($library_id = NULL) {
-
-   //TO DO : return usable error if vocabs don't exist
-   // get the list of vocabularies and find our two vocabularies of interest
-  $vocabularies = taxonomy_get_vocabularies();
-  $vid = NULL;
-  foreach ($vocabularies as $vocab) {
-    if ($vocab->name == 'Library') {
-      $vid = $vocab->vid;
-    }
-  }
-  if (!$vid) {
-    return;
-  }
-
-  // We'll use the following SQL statement for getting the node info
-  if ($library_id) {
-    print "Finding features for library with ID: $library_id\n";
-    $sql = "
-      SELECT LF.feature_id, L.library_id, L.name as libname
-      FROM {library_feature} LF
-        INNER JOIN {library} L ON LF.library_id = L.library_id
-      WHERE L.library_id = :library_id
-      ORDER BY LF.feature_id
-    ";
-    $features = chado_query($sql, array(':library_id' => $library_id));
-  }
-  else {
-    print "Finding features for all libraries\n";
-    $sql = "
-      SELECT LF.feature_id, L.library_id, L.name as libname
-      FROM {library_feature} LF
-        INNER JOIN {library} L ON LF.library_id = L.library_id
-      ORDER BY LF.feature_id
-    ";
-    $features = chado_query($sql);
-  }
-
-  $node_sql = "
-    SELECT *
-    FROM {chado_feature} CF
-      INNER JOIN {node} N ON CF.nid = N.nid
-    WHERE feature_id = :feature_id
-  ";
-  // iterate through the features and add the taxonomy
-  while ($feature = $features->fetchObject()) {
-    $node = db_query($node_sql, array(':feature_id' => $feature->feature_id))->fetchObject();
-    $tags["$vid"] = $feature->libname;
-    $terms['tags'] = $tags;
-    taxonomy_node_save($node, $terms);
-    print "Updated $feature->feature_id as $feature->libname\n";
-  }
-}
-/**
- *
- * @ingroup tripal_library
- */
-function tripal_library_reindex_features($library_id = NULL, $job_id = NULL) {
-  $i = 0;
-
-  // if the caller provided a library_id then get all of the features
-  // associated with the library. Otherwise get all sequences assoicated
-  // with all libraries.
-  if ($library_id) {
-    $sql = "
-      SELECT LF.feature_id, L.library_id, L.name as libname
-      FROM {library_feature} LF
-        INNER JOIN {library} L ON LF.library_id = L.library_id
-      WHERE L.library_id = :library_id
-      ORDER BY LF.feature_id
-    ";
-    $results = chado_query($sql, array(':library_id' => $library_id));
-  }
-  else {
-    $sql = "
-      SELECT LF.feature_id, L.library_id, L.name as libname
-      FROM {library_feature} LF
-        INNER JOIN {library} L ON LF.library_id = L.library_id
-      ORDER BY LF.feature_id
-    ";
-    $results = chado_query($sql);
-  }
-
-   // load into ids array
-  $count = 0;
-  $ids = array();
-  while ($id = $results->fetchObject()) {
-    $ids[$count] = $id->feature_id;
-    $count++;
-  }
-
-  $interval = intval($count * 0.01);
-  foreach ($ids as $feature_id) {
-    // update the job status every 1% features
-    if ($job_id and $i % interval == 0) {
-      tripal_job_set_progress($job_id, intval(($i/$count)*100));
-    }
-    $i++;
-  }
-}
-/**
- *
- * @ingroup tripal_library
- */
-function tripal_library_taxonify_features($library_id = NULL, $job_id = NULL) {
-  $i = 0;
-
-  // if the caller provided a library_id then get all of the features
-  // associated with the library. Otherwise get all sequences assoicated
-  // with all libraries.
-  if ($library_id) {
-    $sql = "
-      SELECT LF.feature_id, L.library_id, L.name as libname
-      FROM {library_feature} LF
-        INNER JOIN {library} L ON LF.library_id = L.library_id
-      WHERE L.library_id = :library_id
-      ORDER BY LF.feature_id
-    ";
-    $results = chado_query($sql, array(':library_id' => $library_id));
-  }
-  else {
-    $sql = "
-      SELECT LF.feature_id, L.library_id, L.name as libname
-      FROM {library_feature} LF
-        INNER JOIN {library} L ON LF.library_id = L.library_id
-      ORDER BY LF.feature_id
-    ";
-    $results = chado_query($sql);
-  }
-
-  // load into ids array
-  $count = 0;
-  $ids = array();
-  while ($id = $results->fetchObject()) {
-    $ids[$count] = $id->feature_id;
-    $count++;
-  }
-
-  // make sure our vocabularies are set before proceeding
-  tripal_feature_set_vocabulary();
-
-  // use this SQL for getting the nodes
-  $nsql =  "
-    SELECT *
-    FROM {chado_feature} CF
-      INNER JOIN {node} N ON N.nid = CF.nid
-    WHERE feature_id = :feature_id
-  ";
-   // iterate through the features and set the taxonomy
-  $interval = intval($count * 0.01);
-  foreach ($ids as $feature_id) {
-    // update the job status every 1% features
-    if ($job_id and $i % interval == 0) {
-      tripal_job_set_progress($job_id, intval(($i/$count)*100));
-    }
-      $node = db_query($nsql, array(':feature_id' => $feature_id))->fetchObject();
-      tripal_feature_set_taxonomy($node, $feature_id);
-      $i++;
-  }
-}
-
-
-/**
- * Remove orphaned drupal nodes
- *
- * @param $dummy
- *   Not Used -kept for backwards compatibility
- * @param $job_id
- *   The id of the tripal job executing this function
- *
- * @ingroup tripal_library
- */
-function tripal_library_cleanup($dummy = NULL, $job_id = NULL) {
-
-  return tripal_core_clean_orphaned_nodes('library', $job_id);
-
+  
 }
 

+ 314 - 0
tripal_library/includes/tripal_library.chado_node.inc

@@ -0,0 +1,314 @@
+<?php
+/**
+ *  When editing or creating a new node of type 'chado_library' we need
+ *  a form.  This function creates the form that will be used for this.
+ *
+ * @ingroup tripal_library
+ */
+function chado_library_form($node, &$form_state) {
+  $form = array();
+
+  // Default values can come in the following ways:
+  //
+  // 1) as elements of the $node object.  This occurs when editing an existing library
+  // 2) in the $form_state['values'] array which occurs on a failed validation or
+  //    ajax callbacks from non submit form elements
+  // 3) in the $form_state['input'[ array which occurs on ajax callbacks from submit
+  //    form elements and the form is being rebuilt
+  //
+  // set form field defaults
+  $library_id = NULL;
+  $title = '';
+  $uniquename = '';
+  $library_type = '';
+  $organism_id = '';
+  $description = '';
+  
+  // if we are editing an existing node then the library is already part of the node
+  if (property_exists($node, 'library')) {
+    $library = $node->library;
+    $library_id = $library->library_id;
+    
+    $title        = $library->name;
+    $uniquename   = $library->uniquename;
+    $library_type = $library->type_id->cvterm_id;
+    $organism_id  = $library->organism_id->organism_id;
+    
+    $libprop = tripal_library_get_property($library->library_id, 'Library Description');
+    $description = $libprop->value;
+    
+    // keep track of the library id if we have.  If we do have one then
+    // this is an update as opposed to an insert.
+    $form['library_id'] = array(
+      '#type' => 'value',
+      '#value' => $library_id,
+    );
+  }
+  // if we are re constructing the form from a failed validation or ajax callback
+  // then use the $form_state['values'] values
+  if (array_key_exists('values', $form_state)) {
+    $title        = $form_state['values']['title'];
+    $uniquename   = $form_state['values']['uniquename'];
+    $library_type = $form_state['values']['library_type'];
+    $organism_id  = $form_state['values']['organism_id'];
+    $description  = $form_state['values']['description'];
+  }
+  // if we are re building the form from after submission (from ajax call) then
+  // the values are in the $form_state['input'] array
+  if (array_key_exists('input', $form_state) and !empty($form_state['input'])) {
+    $title        = $form_state['input']['title'];
+    $uniquename   = $form_state['input']['uniquename'];
+    $library_type = $form_state['input']['library_type'];
+    $organism_id  = $form_state['input']['organism_id'];
+    $description  = $form_state['input']['description'];
+  }
+
+  $form['title']= array(
+    '#type'          => 'textfield',
+    '#title'         => t('Library Name'),
+    '#description'   => t('Please enter the name for this library. Library names should be recognizable but do not need to be unique.'),
+    '#required'      => TRUE,
+    '#default_value' => $title,
+    '#weight'        => 1
+  );
+
+  $form['uniquename']= array(
+    '#type'          => 'textfield',
+    '#title'         => t('Unique Name'),
+    '#description'   => t('Please enter a unique name for this library. This can be any value used to uniquely identify a library.'),
+    '#required'      => TRUE,
+    '#default_value' => $uniquename,
+    '#weight'        => 2
+  );
+
+  // get the list of library types
+  $values = array(
+    'cv_id' => array(
+      'name' => 'library_type',
+    )
+  );
+  $columns = array('cvterm_id','name');
+  $options = array('order_by' => array('name' => 'ASC'));
+  $lib_types = tripal_core_chado_select('cvterm', $columns, $values, $options);
+  $types = array();
+  $types[''] = '';
+  foreach($lib_types as $type) {
+    $types[$type->cvterm_id] = $type->name;
+  }
+
+  $form['library_type'] = array(
+    '#title'       => t('Library Type'),
+    '#type'        => t('select'),
+    '#description' => t("Choose the library type."),
+    '#required'    => TRUE,
+    '#default_value' => $library_type,
+    '#options'     => $types,
+    '#weight'      => 3
+  );
+
+  // get the list of organisms
+  $sql = "SELECT * FROM {organism}";
+  $org_rset = chado_query($sql);
+
+  $organisms = array();
+  $organisms[''] = '';
+  while ($organism = $org_rset->fetchObject()) {
+    $organisms[$organism->organism_id] =
+    "$organism->genus $organism->species ($organism->common_name)";
+  }
+
+  $form['organism_id'] = array(
+    '#title'       => t('Organism'),
+    '#type'        => t('select'),
+    '#description' => t("Choose the organism with which this library is associated."),
+    '#required'    => TRUE,
+    '#default_value' => $organism_id,
+    '#options'     => $organisms,
+    '#weight'      => 4,
+  );
+
+  $form['description']= array(
+    '#type'          => 'textarea',
+    '#title'         => t('Library Description'),
+    '#description'   => t('A brief description of the library'),
+    '#required'      => TRUE,
+    '#default_value' => $description,
+    '#weight'        => 5
+  );
+
+  return $form;
+}
+/**
+ *  validates submission of form when adding or updating a library node
+ *
+ * @ingroup tripal_library
+ */
+function chado_library_validate($node, $form, &$form_state) {
+  
+  $node->title       = trim($node->title);
+  $node->uniquename  = trim($node->uniquename);
+  $node->description = trim($node->description);
+  
+  $lib = 0;
+  // check to make sure the unique name on the library is unique
+  // before we try to insert into chado.
+  if ($node->library_id) {
+    $sql = "
+      SELECT *
+      FROM {library}
+      WHERE uniquename = :uname AND NOT library_id = :library_id
+    ";
+    $lib = chado_query($sql, array(':uname' => $node->uniquename, ':library_id' => $node->library_id))->fetchObject();
+  }
+  else {
+    $sql = "SELECT * FROM {library} WHERE uniquename = :uname";
+    $lib = chado_query($sql, array(':uname' => $node->uniquename))->fetchObject();
+  }
+  if ($lib) {
+    form_set_error('uniquename', t('The unique library name already exists. Please choose another'));
+  }
+}
+/**
+ *  When a new chado_library node is created we also need to add information
+ *  to our chado_library table.  This function is called on insert of a new node
+ *  of type 'chado_library' and inserts the necessary information.
+ *
+ * @ingroup tripal_library
+ */
+function chado_library_insert($node) {
+  
+  $node->title       = trim($node->title);
+  $node->uniquename  = trim($node->uniquename);
+  $node->description = trim($node->description);
+
+  // if there is an library_id in the $node object then this must be a sync so
+  // we can skip adding the library as it is already there, although
+  // we do need to proceed with the rest of the insert
+  if (!property_exists($node, 'library_id')) {
+    $values = array(
+      'name' => $node->title,
+      'uniquename' => $node->uniquename,
+      'organism_id' => $node->organism_id,
+      'type_id' => $node->library_type,
+    );
+    $library = tripal_core_chado_insert('library', $values);
+    if (!$library) {
+      drupal_set_message(t('Unable to add library.', 'warning'));
+      watchdog('tripal_library', 'Insert library: Unable to create library where values: %values',
+        array('%values' => print_r($values, TRUE)), WATCHDOG_ERROR);
+      return;
+    }
+    $library_id = $library['library_id'];
+    
+    // add the description property
+    tripal_library_insert_property($library_id, 'Library Description', $node->description);
+    
+  }
+  else {
+    $library_id = $node->library_id;
+  }
+
+  // Make sure the entry for this library doesn't already exist in the
+  // chado_library table if it doesn't exist then we want to add it.
+  $check_org_id = chado_get_id_for_node('library', $node->nid);
+  if (!$check_org_id) {
+    $record = new stdClass();
+    $record->nid = $node->nid;
+    $record->vid = $node->vid;
+    $record->library_id = $library_id;
+    drupal_write_record('chado_library', $record);
+  }
+}
+/**
+ * Update nodes
+ *
+ * @ingroup tripal_library
+ */
+function chado_library_update($node) {
+  
+  $node->title       = trim($node->title);
+  $node->uniquename  = trim($node->uniquename);
+  $node->description = trim($node->description);
+
+  // update the library record
+  $library_id = chado_get_id_for_node('library', $node->nid);
+  $match = array(
+    'library_id' => $library_id,
+  );
+  $values = array(
+    'name'        => $node->title,
+    'uniquename'  => $node->uniquename,
+    'organism_id' => $node->organism_id,
+    'type_id'     => $node->library_type,
+  );
+  $status = tripal_core_chado_update('library', $match, $values);
+  if (!$status) {
+    drupal_set_message(t('Unable to update library.', 'warning'));
+    watchdog('tripal_library', 'Update library: Unable to update library where values: %values',
+    array('%values' => print_r($values, TRUE)), WATCHDOG_ERROR);
+  }
+  
+  // add in the library description as a property
+  tripal_library_update_property($library_id, 'Library Description', $node->description, 1);
+}
+/**
+ *  When a node is requested by the user this function is called to allow us
+ *  to add auxiliary data to the node object.
+ *
+ * @ingroup tripal_library
+ */
+function chado_library_load($nodes) {
+  
+  foreach ($nodes as $nid => $node) {
+    // get the feature details from chado
+    $library_id = chado_get_id_for_node('library', $node->nid);
+  
+    $values = array('library_id' => $library_id);
+    $library = tripal_core_generate_chado_var('library', $values);
+  
+    // the uniquename field is a text field so we need to expand it
+    $library = tripal_core_expand_chado_vars($library, 'field', 'library.uniquename');
+    
+    $nodes[$nid]->library = $library;
+  }
+}
+
+/**
+ * Delete data from drupal and chado databases when a node is deleted
+ * @ingroup tripal_library
+ */
+function chado_library_delete(&$node) {
+
+  $library_id = chado_get_id_for_node('library', $node->nid);
+
+  // if we don't have a library id for this node then this isn't a node of
+  // type chado_library or the entry in the chado_library table was lost.
+  if (!$library_id) {
+    return;
+  }
+
+  // Remove data from {chado_library}, {node} and {node_revisions} tables of
+  // drupal database
+  $sql_del = "DELETE FROM {chado_library} WHERE nid = :nid AND vid = :vid";
+  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
+  $sql_del = "DELETE FROM {node_revision} WHERE nid = :nid AND vid = :vid";
+  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
+  $sql_del = "DELETE FROM {node} WHERE nid = :nid AND vid = :vid";
+  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
+
+  // Remove data from library and libraryprop tables of chado database as well
+  chado_query("DELETE FROM {libraryprop} WHERE library_id = :library_id", array(':library_id' => $library_id));
+  chado_query("DELETE FROM {library} WHERE library_id = :library_id", array(':library_id' => $library_id));
+}
+
+/**
+ * 
+ * @param unknown $node
+ */
+function tripal_library_node_presave($node) {
+  // if this is a chado_library and the $node->library object is set then we 
+  // are syncing and we want to set the node title to be the same as the node name
+  if ($node->type == 'chado_library' and property_exists($node, 'library')) {
+    $node->title = $node->library->name;
+  }
+}

+ 0 - 142
tripal_library/theme/node--chado-library.tpl.php

@@ -1,142 +0,0 @@
-<?php
-// Purpose: This template provides the layout of the library node (page)
-//   using the same templates used for the various library content blocks.
-//
-// To Customize the Libray Node Page:
-//   - This Template: customize basic layout and which elements are included
-//   - Using Panels: Override the node page using Panels3 and place the blocks
-//       of content as you please. This method requires no programming. See
-//       the Tripal User Guide for more details
-//   - Block Templates: customize the content/layout of each block of stock 
-//       content. These templates are found in the tripal_stock subdirectory
-//
-// Variables Available:
-//   - $node: a standard object which contains all the fields associated with
-//       nodes including nid, type, title, taxonomy. It also includes stock
-//       specific fields such as stock_name, uniquename, stock_type, synonyms,
-//       properties, db_references, object_relationships, subject_relationships,
-//       organism, etc.
-//   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
-
-$library  = $variables['node']->library;
-
-// get the template settings
-$template_settings = theme_get_setting('tripal');
-
-// toggle the sidebar if desired
-$no_sidebar = 0;
-if (is_array($template_settings['tripal_no_sidebar']) and 
-   $template_settings['tripal_no_sidebar']['library']) {
-  $no_sidebar = 1;
-}
-
-if ($teaser) { 
-  print theme('tripal_library_teaser',$variables); 
-} 
-else { ?>
-
-<script type="text/javascript">
-(function ($) {
-  Drupal.behaviors.libraryBehavior = {
-	attach: function (context, settings){ <?php 
-	  if ($no_sidebar) { ?>    
-        // hide the resource side bar and strech the details section    
-        $(".tripal_toc").hide();
-        $(".tripal_details").addClass("tripal_details_full");
-        $(".tripal_details_full").removeClass("tripal_details"); <?php
-      } else { ?>
-        // use default resource sidebar
-        $(".tripal-info-box").hide(); <?php
-      } ?>
- 
-      // iterate through all of the info boxes and add their titles
-      // to the table of contents
-      $(".tripal-info-box-title").each(function(){
-        var parent = $(this).parent();
-        var id = $(parent).attr('id');
-        var title = $(this).text();
-        $('#tripal_library_toc_list').append('<li><a href="#'+id+'" class="tripal_library_toc_item">'+title+'</a></li>');
-      });
-
-      // when a title in the table of contents is clicked, then
-      // show the corresponding item in the details box
-      $(".tripal_library_toc_item").click(function(){
-         $(".tripal-info-box").hide();
-         href = $(this).attr('href');
-         $(href).fadeIn('slow');
-         // we want to make sure our table of contents and the details
-         // box stay the same height
-         $("#tripal_library_toc").height($(href).parent().height());
-         return false;
-      }); 
-
-      // we want the base details to show up when the page is first shown 
-      // unless the user specified a specific block
-      var block = window.location.href.match(/[\?|\&]block=(.+?)\&/)
-      if(block == null){
-         block = window.location.href.match(/[\?|\&]block=(.+)/)
-      }
-      if(block != null){
-         $("#tripal_library-"+block[1]+"-box").show();
-      } else {
-         $("#tripal_library-base-box").show();
-      }
-
-      $("#tripal_library_toc").height($("#tripal_library-base-box").parent().height());
-    }     
-  };
-})(jQuery);
-</script>
-
-<div id="tripal_library_details" class="tripal_details">
-
-   <!-- Basic Details Theme -->
-   <?php print theme('tripal_library_base',$node); ?>
-
-   <!-- External References -->
-   <?php print theme('tripal_library_references',$node); ?>
-
-   <!-- Properties -->
-   <?php print theme('tripal_library_properties',$node); ?>
-   
-   <!-- Terms -->
-   <?php print theme('tripal_library_terms',$node); ?>
-
-   <!-- Synonyms -->
-   <?php print theme('tripal_library_synonyms',$node); ?>
-
-   <!-- Resource Blocks CCK elements --><?php
-   for($i = 0; $i < count($node->field_resource_titles); $i++){
-     if($node->field_resource_titles[$i]['value']){ ?>
-       <div id="tripal_library-resource_<?php print $i?>-box" class="tripal_library-info-box tripal-info-box">
-         <div class="tripal_library-info-box-title tripal-info-box-title"><?php print $node->field_resource_titles[$i]['value'] ?></div>
-         <?php print $node->field_resource_blocks[$i]['value']; ?>
-       </div><?php
-     }
-   }?>
-   
-   <!-- Let modules add more content -->
-
-   <?php print $content ?>
-</div>
-
-<!-- Table of contents -->
-<div id="tripal_library_toc" class="tripal_toc">
-   <div id="tripal_library_toc_title" class="tripal_toc_title">Resources</div>
-   <ul id="tripal_library_toc_list" class="tripal_toc_list">
-   
-     <!-- Resource Links CCK elements --><?php
-     for($i = 0; $i < count($node->field_resource_links); $i++){
-       if($node->field_resource_links[$i]['value']){
-         $matches = preg_split("/\|/",$node->field_resource_links[$i]['value']);?>
-         <li><a href="<?php print $matches[1] ?>" target="_blank"><?php print $matches[0] ?></a></li><?php
-       }
-     }?>
-     
-     <?php // ADD CUSTOMIZED <li> LINKS HERE ?>
-   </ul>
-</div>
-
-<?php } ?>

+ 69 - 0
tripal_library/theme/tripal_feature/tripal_feature.libraries.tpl.php

@@ -0,0 +1,69 @@
+<?php
+$feature = $variables['node']->feature;
+
+// expand the feature object to include the libraries from the library
+// table in chado.
+$options = array('return_array' => 1);
+$feature = tripal_core_expand_chado_vars($feature, 'table', 'library_feature', $options);
+$library_features = $feature->library_feature;
+
+
+if (count($library_features) > 0) {?>
+  <div id="tripal_feature-library_list-box" class="tripal_feature-info-box tripal-info-box">
+    <div class="tripal_feature-info-box-title tripal-info-box-title">Libraries</div>
+    <div class="tripal_feature-info-box-desc tripal-info-box-desc">The following libraries are associated with this feature.</div> <?php 
+    
+    // the $headers array is an array of fields to use as the colum headers. 
+    // additional documentation can be found here 
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    // This table for the analysis has a vertical header (down the first column)
+    // so we do not provide headers here, but specify them in the $rows array below.
+    $headers = array('Library Name', 'Type');
+    
+    // the $rows array contains an array of rows where each row is an array
+    // of values for each column of the table in that row.  Additional documentation
+    // can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7 
+    $rows = array();
+    foreach ($library_features as $library_feature){ 
+      
+      $libname = $library_feature->library_id->name;
+      if ($library_feature->library_id->nid) {
+        $libname = l($libname, "node/" . $library_feature->library_id->nid, array('attributes' => array('target' => '_blank')));
+      }
+      
+      $typename = $library_feature->library_id->type_id->name;
+      if ($typename == 'cdna_library') {
+        $typename = 'cDNA';
+      }
+      else if ($typename == 'bac_library') {
+        $typename = 'BAC';
+      }
+      
+      $rows[] = array(
+        $libname,
+        $typename
+      );      
+    }
+    
+    // the $table array contains the headers and rows array as well as other
+    // options for controlling the display of the table.  Additional
+    // documentation can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $table = array(
+      'header' => $headers,
+      'rows' => $rows,
+      'attributes' => array(
+        'id' => 'tripal_feature-table-libraries',
+      ),
+      'sticky' => FALSE,
+      'caption' => '',
+      'colgroups' => array(),
+      'empty' => '',
+    );
+    
+    // once we have our table array structure defined, we call Drupal's theme_table()
+    // function to generate the table.
+    print theme_table($table); ?>  
+  </div><?php
+}

+ 0 - 57
tripal_library/theme/tripal_feature/tripal_feature_libraries.tpl.php

@@ -1,57 +0,0 @@
-<?php
-$feature = $variables['node']->feature;
-
-// expand the feature object to include the libraries from the library_feature
-// table in chado.
-$feature = tripal_core_expand_chado_vars($feature,'table','library_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
-$library_features = $feature->library_feature;
-if (!$library_features) {
-   $library_features = array();
-} 
-elseif (!is_array($library_features)) { 
-   $library_features = array($library_features); 
-}
-
-// don't show this page if there are no libraries
-if (count($library_features) > 0) { ?>
-  <div id="tripal_feature-libraries-box" class="tripal_feature-info-box tripal-info-box">
-    <div class="tripal_feature-info-box-title tripal-info-box-title">Libraries</div>
-    <div class="tripal_feature-info-box-desc tripal-info-box-desc">This <?php print $feature->type_id->name ?> is derived, or can be located in the following libraries</div>
-    <table id="tripal_feature-libraries-table" class="tripal_feature-table tripal-table tripal-table-horz">
-      <tr>
-        <th>Library Name</th>
-        <th>Type</th>
-      </tr> <?php
-      $i = 0; 
-      foreach ($library_features as $library_feature) {
-        $class = 'tripal-table-odd-row';
-        if ($i % 2 == 0 ) {
-           $class = 'tripal-table-even-row';
-        } ?>
-        <tr class="<?php print $class ?>">
-          <td><?php 
-            if ($library_feature->library_id->nid) {
-               print "<a href=\"". url("node/".$library_feature->library_id->nid) . "\">".$library_feature->library_id->name."</a>";
-            } else {
-               print $library_feature->library_id->name;
-            } ?>
-          </td>
-          <td> <?php 
-              if ($library_feature->library_id->type_id->name == 'cdna_library') {
-                 print 'cDNA';
-              } else if ($library_feature->library_id->type_id->name == 'bac_library') {
-                 print 'BAC';
-              } else {
-                 print $library_feature->library_id->type_id->name;
-              } ?>
-          </td>
-        </tr> <?php
-        $i++;  
-      } ?>
-    </table> 
-  </div><?php 
-} 
-

+ 0 - 4
tripal_library/theme/tripal_library_admin.tpl.php → tripal_library/theme/tripal_library.help.tpl.php

@@ -1,7 +1,3 @@
-<h3>Tripal Library Administrative Tools Quick Links:</h3>
-<ul>
- <li><a href="<?php print url("admin/tripal/tripal_library/configuration") ?>">Library Configuration</a></li>
-</ul>
 <h3>Module Description:</h3>
 <p>The Tripal Library module is an interface for the Chado Library module which groups features (sequences) into genetic libraries.
     This module provides support for visualization of "library" pages, editing and updating.</p>

+ 1 - 0
tripal_library/theme/tripal_library.theme.inc

@@ -0,0 +1 @@
+<?php

+ 105 - 0
tripal_library/theme/tripal_library/tripal_library.base.tpl.php

@@ -0,0 +1,105 @@
+<?php
+
+$library  = $variables['node']->library;
+
+// get the library description. IT uses a tern name of 'Library Description'
+$libprop = tripal_library_get_property($library->library_id, 'Library Description');
+$description = $libprop->value;
+
+
+?>
+<div id="tripal_library-base-box" class="tripal_library-info-box tripal-info-box">
+  <div class="tripal_library-info-box-title tripal-info-box-title">Library Details</div>
+  <div class="tripal_library-info-box-desc tripal-info-box-desc"></div> <?php 
+  
+  // the $headers array is an array of fields to use as the colum headers. 
+  // additional documentation can be found here 
+  // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+  // This table for the library has a vertical header (down the first column)
+  // so we do not provide headers here, but specify them in the $rows array below.
+  $headers = array();
+  
+  // the $rows array contains an array of rows where each row is an array
+  // of values for each column of the table in that row.  Additional documentation
+  // can be found here:
+  // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7 
+  $rows = array();
+
+  // Name row
+  $rows[] = array(
+    array(
+      'data' => 'Library Name',
+      'header' => TRUE
+    ),
+    $library->name
+  );
+
+  // Unique row
+  $rows[] = array(
+    array(
+      'data' => 'Unique Name',
+      'header' => TRUE
+    ),
+    $library->uniquename
+  );
+  
+  // Organism row
+  $organism = $library->organism_id->genus ." " . $library->organism_id->species ." (" .$library->organism_id->common_name .")";
+  if ($library->organism_id->nid) {
+    $organism = l("<i>" . $library->organism_id->genus . " " . $library->organism_id->species . "</i> (" .$library->organism_id->common_name .")", "node/".$library->organism_id->nid, array('html' => TRUE));
+  } 
+  $rows[] = array(
+    array(
+      'data' => 'Organism',
+      'header' => TRUE
+    ),
+    $organism
+  );
+
+  // Library Type row
+  $rows[] = array(
+    array(
+      'data' => 'Type',
+      'header' => TRUE
+    ),
+    $library->type_id->name,
+  );
+  
+  // allow site admins to see the library ID
+  if (user_access('access administration pages')) {
+    // Library ID
+    $rows[] = array(
+      array(
+        'data' => 'Library ID',
+        'header' => TRUE
+      ),
+      $library->library_id,
+    );
+  }
+  
+  // the $table array contains the headers and rows array as well as other
+  // options for controlling the display of the table.  Additional
+  // documentation can be found here:
+  // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+  $table = array(
+    'header' => $headers,
+    'rows' => $rows,
+    'attributes' => array(
+      'id' => 'tripal_library-table-base',
+    ),
+    'sticky' => FALSE,
+    'caption' => '',
+    'colgroups' => array(),
+    'empty' => '',
+  );
+  
+  // once we have our table array structure defined, we call Drupal's theme_table()
+  // function to generate the table.
+  print theme_table($table); 
+  
+  // now add in the description below the table if one exists
+  if ($description) { ?>
+    <div style="text-align: justify"><?php print $description; ?></div> <?php  
+  }
+  ?>
+</div>

+ 62 - 0
tripal_library/theme/tripal_library/tripal_library.properties.tpl.php

@@ -0,0 +1,62 @@
+<?php
+
+$library = $variables['node']->library;
+$options = array('return_array' => 1);
+$library = tripal_core_expand_chado_vars($library, 'table', 'libraryprop', $options);
+$props = $library->libraryprop;
+
+// iterate through the properties and remove the 'library_description' as it is
+// already displayed on the base template.
+$properties = array();
+foreach ($props as $prop) {
+  if ($prop->type_id->name == 'Library Description') {
+    continue;
+  }
+  $properties[] = $prop;
+}
+
+if(count($properties) > 0){ ?>
+
+  <div id="tripal_library-properties-box" class="tripal_library-info-box tripal-info-box">
+    <div class="tripal_library-info-box-title tripal-info-box-title">Properties</div> <?php
+
+    // the $headers array is an array of fields to use as the colum headers.
+    // additional documentation can be found here
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $headers = array('Property Name', 'Value');
+    
+    // the $rows array contains an array of rows where each row is an array
+    // of values for each column of the table in that row.  Additional documentation
+    // can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $rows = array();
+    
+    foreach ($properties as $property){
+      $property = tripal_core_expand_chado_vars($property,'field','libraryprop.value');
+      $rows[] = array(
+        ucfirst(preg_replace('/_/', ' ', $property->type_id->name)),
+        urldecode($property->value)
+      );
+    }
+     
+    // the $table array contains the headers and rows array as well as other
+    // options for controlling the display of the table.  Additional
+    // documentation can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $table = array(
+      'header' => $headers,
+      'rows' => $rows,
+      'attributes' => array(
+        'id' => 'tripal_library-table-properties',
+      ),
+      'sticky' => FALSE,
+      'caption' => '',
+      'colgroups' => array(),
+      'empty' => '',
+    );
+    
+    // once we have our table array structure defined, we call Drupal's theme_table()
+    // function to generate the table.
+    print theme_table($table); ?>
+  </div> <?php
+}

+ 70 - 0
tripal_library/theme/tripal_library/tripal_library.references.tpl.php

@@ -0,0 +1,70 @@
+<?php
+$library = $variables['node']->library;
+$references = array();
+
+// Second, expand the library object to include the records from the library_dbxref table
+$options = array('return_array' => 1);
+$library = tripal_core_expand_chado_vars($library, 'table', 'library_dbxref', $options);
+$library_dbxrefs = $library->library_dbxref;
+if (count($library_dbxrefs) > 0 ) {
+  foreach ($library_dbxrefs as $library_dbxref) {    
+    $references[] = $library_dbxref->dbxref_id;
+  }
+}
+
+
+if(count($references) > 0){ ?>
+  <div id="tripal_library-references-box" class="tripal_library-info-box tripal-info-box">
+    <div class="tripal_library-info-box-title tripal-info-box-title">Cross References</div>
+    <div class="tripal_library-info-box-desc tripal-info-box-desc">External references for this <?php print $library->type_id->name ?></div><?php
+     
+    // the $headers array is an array of fields to use as the colum headers.
+    // additional documentation can be found here
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $headers = array('Dababase', 'Accession');
+    
+    // the $rows array contains an array of rows where each row is an array
+    // of values for each column of the table in that row.  Additional documentation
+    // can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $rows = array();
+ 
+    foreach ($references as $dbxref){
+     
+      $dbname = $dbxref->db_id->name; 
+      if ($dbxref->db_id->url) { 
+        $dbname = l($dbname, $dbxref->db_id->url, array('attributes' => array('target' => '_blank')));
+      } 
+      
+      $accession = $dbxref->accession; 
+      if ($dbxref->db_id->urlprefix) { 
+        $accession = l($accession, $dbxref->db_id->urlprefix . $dbxref->accession, array('attributes' => array('target' => '_blank')));
+      } 
+      $rows[] = array(
+        $dbname,
+        $accession
+      );
+    } 
+    
+    // the $table array contains the headers and rows array as well as other
+    // options for controlling the display of the table.  Additional
+    // documentation can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $table = array(
+      'header' => $headers,
+      'rows' => $rows,
+      'attributes' => array(
+        'id' => 'tripal_library-table-references',
+      ),
+      'sticky' => FALSE,
+      'caption' => '',
+      'colgroups' => array(),
+      'empty' => '',
+    );
+    
+    // once we have our table array structure defined, we call Drupal's theme_table()
+    // function to generate the table.
+    print theme_table($table); ?>
+  </div><?php 
+}?>
+

+ 53 - 0
tripal_library/theme/tripal_library/tripal_library.synonyms.tpl.php

@@ -0,0 +1,53 @@
+<?php
+$library = $variables['node']->library;
+
+// expand the library object to include the synonyms from the library_synonym 
+// table in chado.
+$options = array('return_array' => 1);
+$library = tripal_core_expand_chado_vars($library, 'table', 'library_synonym', $options);
+$synonyms = $library->library_synonym;
+
+if(count($synonyms) > 0){ ?>
+  <div id="tripal_library-synonyms-box" class="tripal_library-info-box tripal-info-box">
+    <div class="tripal_library-info-box-title tripal-info-box-title">Synonyms</div>
+    <div class="tripal_library-info-box-desc tripal-info-box-desc">The library '<?php print $library->name ?>' has the following synonyms</div><?php
+    
+    // the $headers array is an array of fields to use as the colum headers. 
+    // additional documentation can be found here 
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    // This table for the analysis has a vertical header (down the first column)
+    // so we do not provide headers here, but specify them in the $rows array below.
+    $headers = array('Synonym');
+    
+    // the $rows array contains an array of rows where each row is an array
+    // of values for each column of the table in that row.  Additional documentation
+    // can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7 
+    $rows = array();
+    foreach ($synonyms as $library_synonym){
+      $rows[] = array(
+        $library_synonym->synonym_id->name
+      );
+    } 
+    
+    // the $table array contains the headers and rows array as well as other
+    // options for controlling the display of the table.  Additional
+    // documentation can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $table = array(
+      'header' => $headers,
+      'rows' => $rows,
+      'attributes' => array(
+        'id' => 'tripal_library-table-synonyms',
+      ),
+      'sticky' => FALSE,
+      'caption' => '',
+      'colgroups' => array(),
+      'empty' => '',
+    );
+    
+    // once we have our table array structure defined, we call Drupal's theme_table()
+    // function to generate the table.
+      print theme_table($table); ?>
+  </div><?php
+}

+ 19 - 0
tripal_library/theme/tripal_library/tripal_library.teaser.tpl.php

@@ -0,0 +1,19 @@
+<?php
+$node    = $variables['node'];
+$library = $variables['node']->library;
+
+// get the library description. IT uses a tern name of 'Library Description'
+$libprop = tripal_library_get_property($library->library_id, 'Library Description');
+$description = $libprop->value; ?>
+
+<div class="tripal_library-teaser tripal-teaser"> 
+  <div class="tripal-library-teaser-title tripal-teaser-title"><?php 
+    print l($node->title, "node/$node->nid", array('html' => TRUE));?>
+  </div>
+  <div class="tripal-library-teaser-text tripal-teaser-text"><?php 
+    print substr($description, 0, 650);
+    if (strlen($description) > 650) {
+      print "... " . l("[more]", "node/$node->nid");
+    } ?>
+  </div>
+</div>

+ 71 - 0
tripal_library/theme/tripal_library/tripal_library.terms.tpl.php

@@ -0,0 +1,71 @@
+<?php
+
+$library = $variables['node']->library;
+
+$options = array('return_array' => 1);
+$library = tripal_core_expand_chado_vars($library, 'table', 'library_cvterm', $options);
+$terms = $library->library_cvterm;
+
+// order the terms by CV
+$s_terms = array();
+foreach ($terms as $term) {
+  $s_terms[$term->cvterm_id->cv_id->name][] = $term;  
+}
+
+if (count($s_terms) > 0) { ?>
+  <div id="tripal_library-terms-box" class="tripal_library-info-box tripal-info-box">
+    <div class="tripal_library-info-box-title tripal-info-box-title">Annotated Terms</div>
+    <div class="tripal_library-info-box-desc tripal-info-box-desc">The following terms have been associated with this <?php print $node->library->type_id->name ?>:</div>  <?php
+    
+    // iterate through each term
+    $i = 0;
+    foreach ($s_terms as $cv => $terms) {  
+      // the $headers array is an array of fields to use as the colum headers.
+      // additional documentation can be found here
+      // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+      $headers = array('Term', 'Definition');
+      
+      // the $rows array contains an array of rows where each row is an array
+      // of values for each column of the table in that row.  Additional documentation
+      // can be found here:
+      // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+      $rows = array();
+      
+      foreach ($terms as $term) { 
+
+        $accession = $term->cvterm_id->dbxref_id->accession;
+        if (is_numeric($term->cvterm_id->dbxref_id->accession)) {
+          $accession = $term->cvterm_id->dbxref_id->db_id->name . ":" . $term->cvterm_id->dbxref_id->accession;
+        }
+        if ($term->cvterm_id->dbxref_id->db_id->urlprefix) {
+          $accession = l($accession, $term->cvterm_id->dbxref_id->db_id->urlprefix . $accession, array('attributes' => array("target" => '_blank')));
+        } 
+        
+        $rows[] = array(
+          $accession,
+          $term->cvterm_id->name
+        );
+      } 
+      // the $table array contains the headers and rows array as well as other
+      // options for controlling the display of the table.  Additional
+      // documentation can be found here:
+      // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+      $table = array(
+        'header' => $headers,
+        'rows' => $rows,
+        'attributes' => array(
+          'id' => "tripal_library-table-terms-$i",
+        ),
+        'sticky' => FALSE,
+        'caption' => '<b>Vocabulary: ' . ucwords(preg_replace('/_/', ' ', $cv)) . '</b>',
+        'colgroups' => array(),
+        'empty' => '',
+      );
+      
+      // once we have our table array structure defined, we call Drupal's theme_table()
+      // function to generate the table.
+      print theme_table($table);
+      $i++;
+    } ?>
+  </div> <?php
+} ?>

+ 0 - 54
tripal_library/theme/tripal_library/tripal_library_base.tpl.php

@@ -1,54 +0,0 @@
-<?php
-
-$library  = $variables['node']->library;
-
-// expand the library to include the properties so that we can get the description
-$library = tripal_core_expand_chado_vars($library,'table','libraryprop', array('return_array' => 1));  
-$libraryprops = $library->libraryprop;
-if (count($libraryprops) > 0){ 
-  foreach ($libraryprops as $property) {
-    if($property->type_id->name == 'library_description') {
-      $property = tripal_core_expand_chado_vars($property,'field','libraryprop.value');
-      $library_description = $property->value;      
-    }
-  }
-}
-
-?>
-<div id="tripal_library-base-box" class="tripal_library-info-box tripal-info-box">
-  <div class="tripal_library-info-box-title tripal-info-box-title">Library Details</div>
-  <div class="tripal_library-info-box-desc tripal-info-box-desc"></div>
-
-   <?php if(strcmp($library->is_obsolete,'t')==0){ ?>
-      <div class="tripal_library-obsolete">This library is obsolete</div>
-   <?php }?>
-   <table id="tripal_library-base-table" class="tripal_library-table tripal-table tripal-table-vert">
-      <tr class="tripal_library-table-even-row tripal-table-even-row">
-        <th nowrap>Unique Name</th>
-        <td><?php print $library->uniquename; ?></td>
-      </tr>
-      <tr class="tripal_library-table-odd-row tripal-table-odd-row">
-        <th>Internal ID</th>
-        <td><?php print $library->library_id; ?></td>
-      </tr>
-      <tr class="tripal_library-table-even-row tripal-table-even-row">
-        <th>Organism</th>
-        <td>
-          <?php if ($library->organism_id->nid) { 
-      	   print "<a href=\"".url("node/".$library->organism_id->nid)."\">".$library->organism_id->genus ." " . $library->organism_id->species ." (" .$library->organism_id->common_name .")</a>";      	 
-          } else { 
-            print $library->organism_id->genus ." " . $library->organism_id->species ." (" .$library->organism_id->common_name .")";
-          } ?>
-        </td>
-      </tr>      
-      <tr class="tripal_library-table-odd-row tripal-table-odd-row">
-        <th>Type</th>
-        <td><?php print $library->type_id->definition ?></td>
-      </tr>
-      <tr class="tripal_library-table-even-row tripal-table-even-row">
-        <th>Description</th>
-        <td><?php print $library_description ?>
-        </td>
-     	</tr>           	                                
-   </table>
-</div>

+ 0 - 44
tripal_library/theme/tripal_library/tripal_library_properties.tpl.php

@@ -1,44 +0,0 @@
-<?php
-$library = $node->library;
-
-// expand the library to include the properties.
-$library = tripal_core_expand_chado_vars($library, 'table', 'libraryprop', array('return_array' => 1));
-$libraryprops = $library->libraryprop;
-$properties = array();
-
-if (count($libraryprops) > 0) {
-  foreach ($libraryprops as $property) {
-    // we want to keep all properties but the library_description as that
-    // property is shown on the base template page.
-    if($property->type_id->name != 'library_description') {
-      $property = tripal_core_expand_chado_vars($property,'field','libraryprop.value');
-      $properties[] = $property;
-    }
-  }
-}
-
-if (count($properties) > 0) { ?>
-  <div id="tripal_library-properties-box" class="tripal_library-info-box tripal-info-box">
-    <div class="tripal_library-info-box-title tripal-info-box-title">Properties</div>
-    <div class="tripal_library-info-box-desc tripal-info-box-desc">Properties for this library include:</div>
-    <table class="tripal_library-table tripal-table tripal-table-horz">
-      <tr>
-        <th>Property Name</th>
-        <th>Value</th>
-      </tr> <?php
-      $i = 0;
-      foreach ($properties as $property) {
-        $class = 'tripal_library-table-odd-row tripal-table-odd-row';
-        if ($i % 2 == 0 ) {
-           $class = 'tripal_library-table-odd-row tripal-table-even-row';
-        }
-        $i++; 
-        ?>
-        <tr class="<?php print $class ?>">
-          <td><?php print ucfirst(preg_replace('/_/', ' ', $property->type_id->name)) ?></td>
-          <td><?php print $property->value ?></td>
-        </tr><?php 
-      } ?>
-    </table>
-  </div> <?php
-}

+ 0 - 49
tripal_library/theme/tripal_library/tripal_library_references.tpl.php

@@ -1,49 +0,0 @@
-<?php
-$library = $variables['node']->library;
-
-// expand the library object to include the external references stored
-// in the library_dbxref table
-$options = array('return_array' => 1);
-$library = tripal_core_expand_chado_vars($library,'table','library_dbxref', $options);
-$references = $library->library_dbxref;
-
-
-if(count($references) > 0){ ?>
-  <div id="tripal_library-references-box" class="tripal_library-info-box tripal-info-box">
-    <div class="tripal_library-info-box-title tripal-info-box-title">Cross References</div>
-    <div class="tripal_library-info-box-desc tripal-info-box-desc">External references for this <?php print $library->type_id->name ?> library</div>
-    <table id="tripal_library-references-table" class="tripal_library-table tripal-table tripal-table-horz">
-      <tr>
-        <th>Dababase</th>
-        <th>Accession</th>
-      </tr> <?php
-      $i = 0; 
-      foreach ($references as $library_dbxref) { 
-        $dbxref = $library_dbxref->dbxref_id;
-        $class = 'tripal_library-table-odd-row tripal-table-odd-row';
-        if ($i % 2 == 0 ) {
-           $class = 'tripal_library-table-odd-row tripal-table-even-row';
-        } ?>
-        <tr class="<?php print $class ?>">
-          <td> <?php 
-            if ($dbxref->db_id->url) { 
-              print l($dbxref->db_id->name, $dbxref->db_id->url);
-            } 
-            else { 
-              print $dbxref->db_id->name; 
-            } ?>
-          </td>
-          <td> <?php 
-            if ($dbxref->db_id->urlprefix) { 
-              print l($dbxref->accession, $dbxref->db_id->urlprefix.$dbxref->accession);
-            } 
-            else { 
-              print $dbxref->accession; 
-            } ?>
-          </td>
-        </tr> <?php
-        $i++;  
-      } ?>
-    </table>
-  </div><?
-}

+ 0 - 31
tripal_library/theme/tripal_library/tripal_library_synonyms.tpl.php

@@ -1,31 +0,0 @@
-<?php
-$library = $variables['node']->library;
-
-// expand the library object to include the synonyms from the library_synonym 
-// table in chado.
-$options = array('return_array' => 1); 
-$library = tripal_core_expand_chado_vars($library,'table','library_synonym', $options);
-$synonyms = $library->library_synonym;
-
-if (count($synonyms) > 0) { ?>
-  <div id="tripal_library-synonyms-box" class="tripal_library-info-box tripal-info-box">
-    <div class="tripal_library-info-box-title tripal-info-box-title">Synonyms</div>
-    <div class="tripal_library-info-box-desc tripal-info-box-desc">The library '<?php print $library->name ?>' has the following synonyms</div>
-    <table id="tripal_library-synonyms-table" class="tripal_library-table tripal-table tripal-table-horz">
-      <tr>
-        <th>Synonym</th>
-      </tr> <?php
-      $i = 0; 
-      foreach ($synonyms as $library_synonym) {
-        $class = 'tripal-table-odd-row';
-        if ($i % 2 == 0 ) {
-          $class = 'tripal-table-even-row';
-        }?>
-        <tr class="<?php print $class ?>">
-          <td> <?php print $library_synonym->synonym_id->name?></td>
-        </tr> <?php
-        $i++;  
-      } ?>
-    </table>
-  </div> <?php 
-}

+ 0 - 54
tripal_library/theme/tripal_library/tripal_library_teaser.tpl.php

@@ -1,54 +0,0 @@
-<?php
-
-$library  = $variables['node']->library;
-
-// expand the library to include the properties so that we can get the description
-$library = tripal_core_expand_chado_vars($library,'table','libraryprop', array('return_array' => 1));  
-$libraryprops = $library->libraryprop;
-if (count($libraryprops) > 0){ 
-  foreach ($libraryprops as $property) {
-    if($property->type_id->name == 'library_description') {
-      $property = tripal_core_expand_chado_vars($property,'field','libraryprop.value');
-      $library_description = $property->value;      
-    }
-  }
-}
-
-?>
-<div id="tripal_library-base-box" class="tripal_library-info-box tripal-info-box">
-  <div class="tripal_library-info-box-title tripal-info-box-title">Library Details</div>
-  <div class="tripal_library-info-box-desc tripal-info-box-desc"></div>
-
-   <?php if(strcmp($library->is_obsolete,'t')==0){ ?>
-      <div class="tripal_library-obsolete">This library is obsolete</div>
-   <?php }?>
-   <table id="tripal_library-base-table" class="tripal_library-table tripal-table tripal-table-vert">
-      <tr class="tripal_library-table-even-row tripal-table-even-row">
-        <th nowrap>Unique Name</th>
-        <td><?php print $library->uniquename; ?></td>
-      </tr>
-      <tr class="tripal_library-table-odd-row tripal-table-odd-row">
-        <th>Internal ID</th>
-        <td><?php print $library->library_id; ?></td>
-      </tr>
-      <tr class="tripal_library-table-even-row tripal-table-even-row">
-        <th>Organism</th>
-        <td>
-          <?php if ($library->organism_id->nid) { 
-           print "<a href=\"".url("node/".$library->organism_id->nid)."\">".$library->organism_id->genus ." " . $library->organism_id->species ." (" .$library->organism_id->common_name .")</a>";         
-          } else { 
-            print $library->organism_id->genus ." " . $library->organism_id->species ." (" .$library->organism_id->common_name .")";
-          } ?>
-        </td>
-      </tr>      
-      <tr class="tripal_library-table-odd-row tripal-table-odd-row">
-        <th>Type</th>
-        <td><?php print $library->type_id->definition ?></td>
-      </tr>
-      <tr class="tripal_library-table-even-row tripal-table-even-row">
-        <th>Description</th>
-        <td><?php print $library_description ?>
-        </td>
-      </tr>                                             
-   </table>
-</div>

+ 0 - 51
tripal_library/theme/tripal_library/tripal_library_terms.tpl.php

@@ -1,51 +0,0 @@
-<?php
-
-$library = $node->library;
-
-// expand the library object to inlucde the records from the library_cvterm table
-$options = array('return_array' => 1);
-$library = tripal_core_expand_chado_vars($library, 'table', 'library_cvterm', $options);
-$terms = $library->library_cvterm;
-
-// re-organize the terms by CV
-$s_terms = array();
-if (count($terms) > 0) {
-  foreach ($terms as $term) {
-    $s_terms[$term->cvterm_id->cv_id->name][] = $term;  
-  }
-}
-
-if (count($s_terms) > 0) { ?>
-  <div id="tripal_library-terms-box" class="tripal_library-info-box tripal-info-box">
-    <div class="tripal_library-info-box-title tripal-info-box-title">Annotated Terms</div>
-    <div class="tripal_library-info-box-desc tripal-info-box-desc">The following terms have been associated with this <?php print $node->library->type_id->name ?>:</div>  <?php
-    // iterate through each term
-    foreach ($s_terms as $cv => $terms) {  ?>
-      <p><?php print ucwords(preg_replace('/_/', ' ', $cv)) ?></p>
-      <table class="tripal_library-table tripal-table tripal-table-horz">
-        <tr>
-          <th>Term</th>
-          <th>Definition</th>
-        </tr> <?php
-        $i = 0;
-        foreach ($terms as $term) { 
-          $class = 'tripal_library-table-odd-row tripal-table-odd-row';
-          if($i % 2 == 0 ){
-            $class = 'tripal_library-table-even-row tripal-table-even-row';
-          }
-          $accession = $term->cvterm_id->dbxref_id->accession;
-          if (is_numeric($term->cvterm_id->dbxref_id->accession)) {
-            $accession = $term->cvterm_id->dbxref_id->db_id->name . ":" . $term->cvterm_id->dbxref_id->accession;
-          }
-          if ($term->cvterm_id->dbxref_id->db_id->urlprefix) {
-            $accession =  "<a href=\"" . $term->cvterm_id->dbxref_id->db_id->urlprefix . "$accession\" target=\"_blank\">$accession</a>";
-          } ?>
-          <tr class="<?php print $class ?>">
-            <td><?php print $accession ?></td>
-            <td><?php print $term->cvterm_id->name ?></td>
-          </tr> <?php
-        } ?>
-      </table> <?php
-  } ?>
-  </div> <?php
-} ?>

+ 73 - 0
tripal_library/theme/tripal_organism/tripal_organism.libraries.tpl.php

@@ -0,0 +1,73 @@
+<?php
+$organism = $variables['node']->organism;
+
+// expand the organism object to include the libraries from the library
+// table in chado.
+$options = array('return_array' => 1);
+$organism = tripal_core_expand_chado_vars($organism, 'table', 'library', $options);
+$libraries = $organism->library;
+
+
+if (count($libraries) > 0) {?>
+  <div id="tripal_organism-library_list-box" class="tripal_organism-info-box tripal-info-box">
+    <div class="tripal_organism-info-box-title tripal-info-box-title">Libraries</div>
+    <div class="tripal_organism-info-box-desc tripal-info-box-desc">The following libraries are associated with this organism.</div> <?php 
+    
+    // the $headers array is an array of fields to use as the colum headers. 
+    // additional documentation can be found here 
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    // This table for the analysis has a vertical header (down the first column)
+    // so we do not provide headers here, but specify them in the $rows array below.
+    $headers = array('Library Name', 'Type');
+    
+    // the $rows array contains an array of rows where each row is an array
+    // of values for each column of the table in that row.  Additional documentation
+    // can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7 
+    $rows = array();
+    foreach ($libraries as $library){ 
+      
+      $libname = $library->name;
+      if ($library->nid) {
+        $libname = l($libname, "node/".$library->nid, array('attributes' => array('target' => '_blank')));
+      }
+      
+      $typename = $library->type_id->name;
+      if ($typename == 'cdna_library') {
+        $typename = 'cDNA';
+      }
+      else if ($typename == 'bac_library') {
+        $typename = 'BAC';
+      }
+      
+      $rows[] = array(
+        $libname,
+        $typename
+      );      
+    }
+    
+    // the $table array contains the headers and rows array as well as other
+    // options for controlling the display of the table.  Additional
+    // documentation can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $table = array(
+      'header' => $headers,
+      'rows' => $rows,
+      'attributes' => array(
+        'id' => 'tripal_organism-table-libraries',
+      ),
+      'sticky' => FALSE,
+      'caption' => '',
+      'colgroups' => array(),
+      'empty' => '',
+    );
+    
+    // once we have our table array structure defined, we call Drupal's theme_table()
+    // function to generate the table.
+    print theme_table($table); ?>  
+  </div><?php
+}
+
+
+
+

+ 0 - 74
tripal_library/theme/tripal_organism/tripal_organism_libraries.tpl.php

@@ -1,74 +0,0 @@
-<?php
-$organism = $variables['node']->organism;
-
-// expand the organism object to include the libraries from the library
-// table in chado.
-$organism = tripal_core_expand_chado_vars($organism,'table','library');
-
-
-// get the references. if only one reference exists then we want to convert
-// the object into an array, otherwise the value is an array
-$libraries = $organism->library;
-if (!$libraries) {
-   $libraries = array();
-} 
-elseif (!is_array($libraries)) { 
-   $libraries = array($libraries); 
-}
-
-if (count($libraries) > 0) {?>
-  <div id="tripal_organism-library_list-box" class="tripal_organism-info-box tripal-info-box">
-    <div class="tripal_organism-info-box-title tripal-info-box-title">Libraries</div>
-    <div class="tripal_organism-info-box-desc tripal-info-box-desc">The following libraries are associated with this organism.</div>
-    <table id="tripal_organism-table-library_list" class="tripal_organism-table tripal-table tripal-table-horz">     
-      <tr class="tripal_organism-table-odd-row tripal-table-even-row">
-        <th>Library Name</th>
-        <th>Description</th>
-        <th>Type</th>
-      </tr> <?php
-      foreach ($libraries as $library){ 
-        // expand the library to include the properties.
-        $library = tripal_core_expand_chado_vars($library,'table','libraryprop');
-        $library = tripal_core_expand_chado_vars($library,'field','libraryprop.value');
-        $class = 'tripal_organism-table-odd-row tripal-table-odd-row';
-        if($i % 2 == 0 ){
-          $class = 'tripal_organism-table-odd-row tripal-table-even-row';
-        } ?>
-        <tr class="<?php print $class ?>">
-          <td><?php 
-            if($library->nid){    
-              $link =  url("node/$library->nid");        
-              print "<a href=\"$link\">$library->name</a>";
-            } 
-            else {
-              print $library->name;
-            } ?>
-          </td>
-          <td><?php 
-            // right now we only have one property for libraries. So we can just
-            // refernece it directly.  If we had more than one property
-            // we would need to convert this to an if statment and loop
-            // until we found the right one.
-            print $library->libraryprop->value?>
-          </td>
-          <td> <?php 
-            if ($library->type_id->name == 'cdna_library') {
-              print 'cDNA';
-            } 
-            else if ($library->type_id->name == 'bac_library') {
-              print 'BAC';
-            } 
-            else {
-              print $library->type_id->name;
-            }?>
-          </td>
-        </tr> <?php
-        $i++; 
-      }?>  
-    </table> 
-  </div><?php
-}
-
-
-
-

+ 98 - 14
tripal_library/tripal_library.install

@@ -49,6 +49,7 @@ function tripal_library_install() {
   tripal_library_add_mview_library_feature_count();
 
   // add cvterms
+  tripal_library_add_cvs();
   tripal_library_add_cvterms();
 }
 
@@ -152,6 +153,13 @@ function tripal_library_add_mview_library_feature_count(){
   tripal_add_mview($view_name, 'tripal_library', $schema, $sql, $comment);
 }
 
+/**
+ * Adds new CV's used by this module
+ */
+function tripal_library_add_cvs(){
+  tripal_cv_add_cv('library_property', 'Contains properties for libraries');
+  tripal_cv_add_cv('library_type', 'Contains terms for types of libraries (e.g. BAC, cDNA, FOSMID, etc).');
+}
 /**
  * @ingroup tripal_library
  */
@@ -160,20 +168,96 @@ function tripal_library_add_cvterms() {
   // Insert cvterm 'library_description' into cvterm table of chado
   // database. This CV term is used to keep track of the library
   // description in the libraryprop table.
-  tripal_cv_add_cvterm(array('name' => 'library_description', 'def' => 'Description of a library'),
-    'tripal', 0, 1, 'tripal');
+  tripal_cv_add_cvterm(
+     array(
+       'name' => 'Library Description', 
+       'def' => 'Description of a library'
+     ),
+    'library_property', 0, 1, 'tripal'
+   );
 
   // add cvterms for the map unit types
-  tripal_cv_add_cvterm(array('name' => 'cdna_library','def' => 'cDNA library'),
-    'tripal_library_types', 0, 1, 'tripal');
-  tripal_cv_add_cvterm(array('name' => 'bac_library','def' => 'Bacterial Artifical Chromsome (BAC) library'),
-    'tripal_library_types', 0, 1, 'tripal');
-  tripal_cv_add_cvterm(array('name' => 'fosmid_library','def' => 'Fosmid library'),
-    'tripal_library_types', 0, 1, 'tripal');
-  tripal_cv_add_cvterm(array('name' => 'cosmid_library','def' => 'Cosmid library'),
-    'tripal_library_types', 0, 1, 'tripal');
-  tripal_cv_add_cvterm(array('name' => 'yac_library','def' => 'Yeast Artificial Chromosome (YAC) library'),
-    'tripal_library_types', 0, 1, 'tripal');
-  tripal_cv_add_cvterm(array('name' => 'genomic_library','def' => 'Genomic Library'),
-    'tripal_library_types', 0, 1, 'tripal');
+  tripal_cv_add_cvterm(
+    array(
+      'name' => 'cdna_library',
+      'def' => 'cDNA library'
+    ),
+    'library_type', 0, 1, 'tripal'
+  );
+  tripal_cv_add_cvterm(
+    array(
+      'name' => 'bac_library',
+      'def' => 'Bacterial Artifical Chromsome (BAC) library'
+    ),
+    'library_type', 0, 1, 'tripal'
+  );
+  tripal_cv_add_cvterm(
+    array(
+      'name' => 'fosmid_library',
+      'def' => 'Fosmid library'
+    ),
+    'library_type', 0, 1, 'tripal'
+  );
+  tripal_cv_add_cvterm(
+    array(
+      'name' => 'cosmid_library',
+      'def' => 'Cosmid library'
+    ),
+    'library_type', 0, 1, 'tripal'
+  );
+  tripal_cv_add_cvterm(
+    array(
+      'name' => 'yac_library',
+      'def' => 'Yeast Artificial Chromosome (YAC) library'
+    ),
+    'library_type', 0, 1, 'tripal'
+  );
+  tripal_cv_add_cvterm(
+    array(
+      'name' => 'genomic_library',
+      'def' => 'Genomic Library'),
+    'library_type', 0, 1, 'tripal'
+  );
+}
+
+/**
+ * This is the required update for tripal_library when upgrading from Drupal core API 6.x. 
+ */
+function tripal_library_update_7000() {
+  
+  // the library types were formerly in a vocabulary named 'tripal_library_types'.
+  // rename that to just be 'library_type'
+  $cv = tripal_cv_get_cv_by_name('tripal_library_types');
+  $match = array(
+    'cv_id' => $cv->cv_id
+  );
+  $values = array(
+    'name' => 'library_type'
+  );
+  $success = tripal_core_chado_update('cv', $match, $values);
+  if (!$success) {
+    throw new DrupalUpdateException('Failed to rename tripal_library_types CV.');
+  }
+  
+  
+  // For Tripal in Drupal 6 the library_description cvterm was stored in the 
+  // 'tripal' CV.  It should be stored in the new library_property CV that
+  // is added by this module for Tripal 2.0 and Drupal 7.  So, we need to 
+  // reset the CV ID for that term and rename the term to 'Library Description'
+  tripal_library_add_cvs();
+  $cv = tripal_cv_get_cv_by_name('library_property');
+  $cvterm = tripal_cv_get_cvterm_by_name('library_description');
+  $match = array(
+    'cvterm_id' => $cvterm->cvterm_id,
+  );
+  $values = array(
+    'cv_id' => $cv->cv_id,
+    'name' => 'Library Description',
+  );
+  tripal_core_chado_update('cvterm', $match, $values);
+  if (!$success) {
+    throw new DrupalUpdateException('Failed to move library properties to new library_property CV.');
+  }
+
+  
 }

+ 113 - 452
tripal_library/tripal_library.module

@@ -9,7 +9,9 @@
  */
 
 require('api/tripal_library.api.inc');
+require('theme/tripal_library.theme.inc');
 require('includes/tripal_library.admin.inc');
+require('includes/tripal_library.chado_node.inc');
 
 /**
  * Provide information to drupal about the node types that we're creating
@@ -26,11 +28,24 @@ function tripal_library_node_info() {
     'has_title' => FALSE,
     'title_label' => t('Library'),
     'has_body' => FALSE,
-    'locked' => TRUE
+    'locked' => TRUE,
+    'chado_node_api' => array(
+      'base_table' => 'library',
+      'hook_prefix' => 'chado_library',
+      'record_type_title' => array(
+        'singular' => t('Library'),
+        'plural' => t('Libraries')
+      ),
+      'sync_filters' => array(
+        'type_id' => TRUE,
+        'organism_id' => TRUE
+      ),
+    )
   );
   return $nodes;
 }
 
+
 /**
  * Set the permission types that the chado module uses.  Essentially we
  * want permissionis that protect creation, editing and deleting of chado
@@ -121,21 +136,20 @@ function tripal_library_menu() {
   // The administative settings menu
   $items['admin/tripal/chado/tripal_library'] = array(
     'title' => 'Libraries',
-    'description' => 'A grouping of genetic data',
+    'description' => 'Any biological library. Examples of genomic libraries include BAC, cDNA, FOSMID, etc.',
     'page callback' => 'tripal_library_admin_libraries_listing',
     'access arguments' => array('administer tripal libraries'),
     'type' => MENU_NORMAL_ITEM,
-    'weight' => 0
   );
 
   $items['admin/tripal/chado/tripal_library/help'] = array(
     'title' => 'Help',
     'description' => 'Basic Description of Tripal Library Module Functionality',
     'page callback' => 'theme',
-    'page arguments' => array('tripal_library_admin'),
+    'page arguments' => array('tripal_library.help'),
     'access arguments' => array('administer tripal libraries'),
     'type' => MENU_LOCAL_TASK,
-    'weight' => 4
+    'weight' => 10
   );
 
   $items['admin/tripal/chado/tripal_library/configuration'] = array(
@@ -145,8 +159,18 @@ function tripal_library_menu() {
     'page arguments' => array('tripal_library_admin'),
     'access arguments' => array('administer tripal libraries'),
     'type' => MENU_LOCAL_TASK,
-    'weight' => 2
+    'weight' => 5
+  );
+  $items['admin/tripal/chado/tripal_library/sync'] = array(
+    'title' => ' Sync',
+    'description' => 'Create pages on this site for libraries stored in Chado',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('tripal_core_chado_node_sync_form', 'tripal_library', 'chado_library'),
+    'access arguments' => array('administer tripal libraries'),
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 0
   );
+  return $items;
 
   // Synchronizing libraries from Chado to Drupal
   $items['chado_sync_libraries'] = array(
@@ -184,20 +208,45 @@ function tripal_library_views_api() {
 /**
  * @ingroup tripal_library
  */
-function tripal_library_node_view(&$node, $view_mode, $langcode) {
+function tripal_library_node_view($node, $view_mode, $langcode) {
 
   switch ($node->type) {
+    case 'chado_library':
+      if ($view_mode == 'full') {
+        $node->content['tripal_library.base'] = array(
+          '#value' => theme('tripal_library.base', array('node' => $node)),
+        );      
+        $node->content['tripal_library.properties'] = array(
+          '#value' => theme('tripal_library.properties', array('node' => $node)),
+        );
+        
+        $node->content['tripal_library.references'] = array(
+          '#value' => theme('tripal_library.references', array('node' => $node)),
+        );      
+        $node->content['tripal_library.synonyms'] = array(
+          '#value' => theme('tripal_library.synonyms', array('node' => $node)),
+        );
+        $node->content['tripal_library.terms'] = array(
+          '#value' => theme('tripal_library.terms', array('node' => $node)),
+        );
+      }
+      if ($view_mode == 'teaser') {
+        $node->content['tripal_library.teaser'] = array(
+          '#value' => theme('tripal_library.teaser', array('node' => $node)),
+        );
+      }
+      break;
     case 'chado_organism':
       if ($view_mode == 'full') {
-        $node->content['tripal_organism_libraries'] = array(
-          '#value' => theme('tripal_organism_libraries', $node),
+        $node->content['tripal_organism.libraries'] = array(
+          '#value' => theme('tripal_organism.libraries', array('node' => $node)),
         );
       }
       break;
     case 'chado_feature':
       if ($view_mode == 'full') {
-        $node->content['tripal_feature_libraries'] = array(
-          '#value' => theme('tripal_feature_libraries', $node),
+        $node->content['tripal_feature.libraries'] = array(
+          '#value' => theme('tripal_feature.libraries', array('node' => $node)),
         );
       }
       break;
@@ -210,63 +259,70 @@ function tripal_library_node_view(&$node, $view_mode, $langcode) {
  *
  * @ingroup tripal_library
  */
-function tripal_library_theme() {
-  $theme_path = drupal_get_path('module', 'tripal_library') . '/theme';
+function tripal_library_theme($existing, $type, $theme, $path) {
+  $core_path = drupal_get_path('module', 'tripal_core');
+  
   $items = array(
-    // themed functions
-    'tripal_library_library_table' => array(
-      'arguments' => array('libraries'),
-    ),
-    'tripal_library_search_index' => array(
-      'arguments' => array('node'),
+    'node__chado_library' => array(
+      'template' => 'node--chado-generic',
+      'render element' => 'node',
+      'base hook' => 'node',
+      'path' => "$core_path/theme",
     ),
-    'tripal_library_search_result' => array(
-      'arguments' => array('node'),
+
+    // tripal_library templates
+    'tripal_library.base' => array(
+      'variables' => array('node' => NULL),
+      'template' => 'tripal_library.base',
+      'path' => "$path/theme/tripal_library",
     ),
-    // tripal_organism templates
-    'tripal_organism_libraries' => array(
-      'arguments' => array('node' => NULL),
-      'template' => 'tripal_organism_libraries',
-      'path' => "$theme_path/tripal_organism",
+    'tripal_library.properties' => array(
+      'variables' => array('node' => NULL),
+      'template' => 'tripal_library.properties',
+      'path' => "$path/theme/tripal_library",
     ),
-    // tripal_feature templates
-    'tripal_feature_libraries' => array(
-      'arguments' => array('node' => NULL),
-      'template' => 'tripal_feature_libraries',
-      'path' => "$theme_path/tripal_feature",
+    'tripal_library.references' => array(
+      'variables' => array('node' => NULL),
+      'template' => 'tripal_library.references',
+      'path' => "$path/theme/tripal_library",
     ),
-    // tripal_library templates
-    'tripal_library_base' => array(
-      'arguments' => array('node' => NULL),
-      'template' => 'tripal_library_base',
-      'path' => "$theme_path/tripal_library",
+    'tripal_library.synonyms' => array(
+      'variables' => array('node' => NULL),
+      'template' => 'tripal_library.synonyms',
+      'path' => "$path/theme/tripal_library",
     ),
-    'tripal_library_synonyms' => array(
-      'arguments' => array('node' => NULL),
-      'template' => 'tripal_library_synonyms',
-      'path' => "$theme_path/tripal_library",
+    'tripal_library.terms' => array(
+      'variables' => array('node' => NULL),
+      'template' => 'tripal_library.terms',
+      'path' => "$path/theme/tripal_library",
     ),
-    'tripal_library_references' => array(
-      'arguments' => array('node' => NULL),
-      'template' => 'tripal_library_references',
-      'path' => "$theme_path/tripal_library",
+    'tripal_library.help' => array(
+      'template' => 'tripal_library.help',
+      'variables' =>  array(NULL),
+      'path' => "$path/theme",
     ),
-    'tripal_library_properties' => array(
-      'arguments' => array('node' => NULL),
-      'template' => 'tripal_library_properties',
-      'path' => "$theme_path/tripal_library",
+    
+    // teaser
+    'tripal_library.teaser' => array(
+      'variables' => array('node' => NULL),
+      'template' => 'tripal_library.teaser',
+      'path' => "$path/theme/tripal_library",
     ),
-    'tripal_library_terms' => array(
-      'arguments' => array('node' => NULL),
-      'template' => 'tripal_library_terms',
-      'path' => "$theme_path/tripal_library",
+    
+    // tripal_organism templates
+    'tripal_organism.libraries' => array(
+      'variables' => array('node' => NULL),
+      'template' => 'tripal_organism.libraries',
+      'path' => "$path/theme/tripal_organism",
     ),
-    // help template
-    'tripal_library_admin' => array(
-      'template' => 'tripal_library_admin',
-      'arguments' =>  array(NULL),
-      'path' => $theme_path,
+    
+    // tripal_feature templates
+    'tripal_feature.libraries' => array(
+      'variables' => array('node' => NULL),
+      'template' => 'tripal_feature.libraries',
+      'path' => "$path/theme/tripal_feature",
     ),
+    
   );
   return $items;
 }
@@ -352,117 +408,6 @@ function tripal_library_block_view($delta = '') {
     return $block;
   }
 }
-/**
- * This function is an extension of the chado_feature_view and
- * chado_organism_view by providing the markup for the library object
- * THAT WILL BE INDEXED.
- *
- * @ingroup tripal_library
- */
-function theme_tripal_library_search_index($node) {
-
-  if ($node->type == 'chado_organism') {
-    $content = "";
-    // get the libraries for the organism
-    $sql = "SELECT * FROM {library} L WHERE L.organism_id = :organism_id";
-    $libraries = array();
-    $results = chado_query($sql, array(':organism_id' => $node->organism->organism_id));
-    while ($library = $results->fetchObject()) {
-      // get the description
-      $sql = "
-        SELECT *
-        FROM {libraryprop} LP
-          INNER JOIN {cvterm} CVT ON CVT.cvterm_id = LP.type_id
-        WHERE LP.library_id = :library_id
-          AND CVT.name = 'library_description'
-      ";
-      $desc = chado_query($sql, array(':library_id' => $library->library_id))->fetchObject();
-      $library->description = $desc->value;
-      $libraries[] = $library;
-    }
-    if (count($libraries) > 0) {
-      foreach ($libraries as $library) {
-        $content .= "$library->name ";
-        $content .= "$library->description";
-      };
-    }
-    // Provide library names to show in a feature page
-  }
-  elseif ($node->type == 'chado_feature') {
-    $content = "";
-    $organism_id = $node->feature->organism_id;
-    $sql = "
-      SELECT *
-      FROM {library} L
-        INNER JOIN {library_feature} LF ON L.library_id = LF.library_id
-      WHERE LF.feature_id = :feature_id
-    ";
-    $libraries = array();
-    $results = chado_query($sql, array(':feature_id' => $node->feature->feature_id));
-    while ($library = $results->fetchObject()) {
-      $libraries[] = $library;
-    }
-    if (count($libraries) > 0) {
-      $lib_additions = array();
-      foreach ($libraries as $library) {
-        $content .= $library->name;
-      };
-    }
-  }
-  return $content;
-}
-
-/**
- * This function shows library information on an organism/feature node
- *
- * @ingroup tripal_library
- */
-function theme_tripal_library_node_libraries($node) {
-  $content = "";
-
-  // Show library information in a expandable box for a organism page.
-  // Make sure we have $node->organism_id. In the case of creating a new
-  // organism, the organism_id is not created until we save. This will cause
-  // an error when users preview the creation without a $node->organism_id
-  if ($node->type == 'chado_organism' && $node->organism_id) {
-    $box_status = variable_get("tripal_library-box-libraries", "menu_off");
-
-    if (strcmp($box_status, "menu_off")==0) {
-      return get_tripal_library_organism_libraries($node->nid);
-    }
-  }
-  // Provide library names to show in a feature page.
-  // Make sure we have $node->feature->feature_id or there will be an error
-  // when a feature is previewed at its creation
-  elseif ($node->type == 'chado_feature' && $node->feature->feature_id) {
-    $organism_id = $node->feature->organism_id;
-    $sql = "
-      SELECT *
-      FROM {library} L
-        INNER JOIN Library_feature LF ON L.library_id = LF.library_id
-      WHERE LF.feature_id = :feature_id
-    ";
-    $libraries = array();
-    $results = chado_query($sql, array(':feature_id' => $node->feature->feature_id));
-    while ($library = $results->fetchObject()) {
-      $libraries[] = $library;
-  }
-  if (count($libraries) > 0) {
-    $lib_additions = array();
-    foreach ($libraries as $library) {
-      $sql = "SELECT nid FROM {chado_library} WHERE library_id = :library_id";
-      $lib_nid = db_query($sql, array(':library_id' => $library->library_id))->fetchField();
-      if ($lib_nid) {
-        $lib_url = url("node/$lib_nid");
-      }
-      $lib_additions[$lib_url] = $library->name;
-    };
-    $node->lib_additions = $lib_additions;
-  }
-  }
-  return $content;
-}
-
 
 /**
  *
@@ -473,290 +418,6 @@ function tripal_library_cron() {
 }
 
 
-/**
- *  When editing or creating a new node of type 'chado_library' we need
- *  a form.  This function creates the form that will be used for this.
- *
- * @ingroup tripal_library
- */
-function chado_library_form($node) {
-  $form = array();
-
-  $library = $node->library;
-
-  // get the default values
-  $uniquename = $node->uniquename;
-  if (!$uniquename) {
-    $uniquename = $library->uniquename;
-  }
-  $library_type = $node->library_type;
-  if (!$library_type) {
-    $library_type = $library->type_id->cvterm_id;
-  }
-  $organism_id = $node->organism_id;
-  if (!$organism_id) {
-    $organism_id = $library->organism_id->organism_id;
-  }
-  $library_description = $node->library_description;
-  if (!$library_description) {
-    $libprop = tripal_library_get_property($library->library_id, 'library_description');
-    $library_description = $libprop->value;
-  }
-
-  // keep track of the library id if we have.  If we do have one then
-  // this is an update as opposed to an insert.
-  $form['library_id'] = array(
-    '#type' => 'value',
-    '#value' => $library->library_id,
-  );
-
-  $form['title']= array(
-    '#type'          => 'textfield',
-    '#title'         => t('Library Title'),
-    '#description'   => t('Please enter the title for this library. '.
-                          'This appears at the top of the library page.'),
-    '#required'      => TRUE,
-    '#default_value' => $node->title,
-    '#weight'        => 1
-  );
-
-  $form['uniquename']= array(
-    '#type'          => 'textfield',
-    '#title'         => t('Unique Library Name'),
-    '#description'   => t('Please enter a unique name for this library'),
-    '#required'      => TRUE,
-    '#default_value' => $uniquename,
-    '#weight'        => 2
-  );
-
-  // get the list of library types
-  $values = array(
-    'cv_id' => array(
-      'name' => 'tripal_library_types',
-    )
-  );
-  $columns = array('cvterm_id','name');
-  $options = array('order_by' => array('name' => 'ASC'));
-  $lib_types = tripal_core_chado_select('cvterm', $columns, $values, $options);
-  $types = array();
-  $types[''] = '';
-  foreach($lib_types as $type) {
-    $types[$type->cvterm_id] = $type->name;
-  }
-
-  $form['library_type'] = array(
-    '#title'       => t('Library Type'),
-    '#type'        => t('select'),
-    '#description' => t("Choose the library type."),
-    '#required'    => TRUE,
-    '#default_value' => $library_type,
-    '#options'     => $types,
-    '#weight'      => 3
-  );
-
-  // get the list of organisms
-  $sql = "SELECT * FROM {organism}";
-  $org_rset = chado_query($sql);
-
-  $organisms = array();
-  $organisms[''] = '';
-  while ($organism = $org_rset->fetchObject()) {
-    $organisms[$organism->organism_id] =
-    "$organism->genus $organism->species ($organism->common_name)";
-  }
-
-  $form['organism_id'] = array(
-   '#title'       => t('Organism'),
-   '#type'        => t('select'),
-   '#description' => t("Choose the organism with which this library is ".
-                       "associated."),
-   '#required'    => TRUE,
-   '#default_value' => $organism_id,
-   '#options'     => $organisms,
-   '#weight'      => 4,
-  );
-
-  $form['library_description']= array(
-    '#type'          => 'textarea',
-    '#title'         => t('Library Description'),
-    '#description'   => t('A brief description of the library'),
-    '#required'      => TRUE,
-    '#default_value' => $library_description,
-    '#weight'        => 5
-  );
-
-  return $form;
-}
-/**
- *  validates submission of form when adding or updating a library node
- *
- * @ingroup tripal_library
- */
-function chado_library_validate($node, $form, &$form_state) {
-  $lib = 0;
-  // check to make sure the unique name on the library is unique
-  // before we try to insert into chado.
-  if ($node->library_id) {
-    $sql = "
-      SELECT *
-      FROM {library}
-      WHERE uniquename = :uname AND NOT library_id = :library_id
-    ";
-    $lib = chado_query($sql, array(':uname' => $node->uniquename, ':library_id' => $node->library_id))->fetchObject();
-  }
-  else {
-    $sql = "SELECT * FROM {library} WHERE uniquename = :uname";
-    $lib = chado_query($sql, array(':uname' => $node->uniquename))->fetchObject();
-  }
-  if ($lib) {
-    form_set_error('uniquename', t('The unique library name already exists. Please choose another'));
-  }
-}
-/**
- *  When a new chado_library node is created we also need to add information
- *  to our chado_library table.  This function is called on insert of a new node
- *  of type 'chado_library' and inserts the necessary information.
- *
- * @ingroup tripal_library
- */
-function chado_library_insert($node) {
-
-  if ($node->library_id) {
-    $library['library_id'] = $node->library_id;
-  }
-  else {
-    $values = array(
-      'name' => $node->title,
-      'uniquename' => $node->uniquename,
-      'organism_id' => $node->organism_id,
-      'type_id' => $node->library_type,
-    );
-    $library = tripal_core_chado_insert('library', $values);
-  }
-
-  if ($library) {
-     // add the description property
-    tripal_library_insert_property($library['library_id'], 'library_description',
-      $node->library_description);
-
-    // make sure the entry for this feature doesn't already exist in the chado_library table
-    // if it doesn't exist then we want to add it.
-    $library_id = chado_get_id_for_node('library', $node->nid) ;
-    if (!$library_id) {
-       // next add the item to the drupal table
-      $sql = "
-        INSERT INTO {chado_library} (nid, vid, library_id)
-        VALUES (:nid, :vid, :library_id)
-      ";
-      db_query($sql, array(':nid' => $node->nid, ':vid' => $node->vid, ':library_id' => $library['library_id']));
-    }
-  }
-  else {
-    drupal_set_message(t('Unable to add library.', 'warning'));
-    watchdog('tripal_library', 'Insert feature: Unable to create library where values: %values',
-      array('%values' => print_r($values, TRUE)), WATCHDOG_WARNING);
-  }
-}
-/**
- * Update nodes
- *
- * @ingroup tripal_library
- */
-function chado_library_update($node) {
-  if ($node->revision) {
-    // there is no way to handle revisions in Chado but leave
-    // this here just to make not we've addressed it.
-  }
-
-  $library_id = chado_get_id_for_node('library', $node->nid);
-  // update the library record
-  $match = array(
-     'library_id' => $library_id,
-  );
-  $values = array(
-     'name' => $node->title,
-     'uniquename' => $node->uniquename,
-     'organism_id' => $node->organism_id,
-     'type_id' => $node->library_type,
-  );
-  $status = tripal_core_chado_update('library', $match, $values);
-
-  tripal_library_update_property($library_id, 'library_description', $node->library_description, 1);
-
-}
-/**
- *  When a node is requested by the user this function is called to allow us
- *  to add auxiliary data to the node object.
- *
- * @ingroup tripal_library
- */
-function chado_library_load($node) {
-  // get the feature details from chado
-  $library_id = chado_get_id_for_node('library', $node->nid);
-
-  $values = array('library_id' => $library_id);
-  $library = tripal_core_generate_chado_var('library', $values);
-
-  $additions = new stdClass();
-  $additions->library = $library;
-  return $additions;
-
-}
-/**
- *  This function customizes the view of the chado_library node.  It allows
- *  us to generate the markup. This function is required for node [Preview]
- *
- * @ingroup tripal_library
- */
-function chado_library_view($node, $teaser = FALSE, $page = FALSE) {
-   // use drupal's default node view:
-  if (!$teaser) {
-
-    $node = node_prepare($node, $teaser);
-
-    // If Hook_view() is called by Hook_form(), we'll only have orgnism_id
-    // but not genus/species/common_name. We need to get those from chado
-    // database so they will show up in preview
-    if (!$node->genus) {
-      $sql = "SELECT * FROM {organism} WHERE organism_id = :organism_id";
-      $data = chado_query($sql, array(':organism_id' => $node->organism_id))->fetchObject();
-      $node->genus = $data->genus;
-      $node->species = $data->species;
-      $node->common_name = $data->common_name;
-    }
-  }
-  return $node;
-}
-
-/**
- * Delete data from drupal and chado databases when a node is deleted
- * @ingroup tripal_library
- */
-function chado_library_delete(&$node) {
-
-  $library_id = chado_get_id_for_node('library', $node->nid);
-
-  // if we don't have a library id for this node then this isn't a node of
-  // type chado_library or the entry in the chado_library table was lost.
-  if (!$library_id) {
-    return;
-  }
-
-  // Remove data from {chado_library}, {node} and {node_revisions} tables of
-  // drupal database
-  $sql_del = "DELETE FROM {chado_library} WHERE nid = :nid AND vid = :vid";
-  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
-  $sql_del = "DELETE FROM {node_revision} WHERE nid = :nid AND vid = :vid";
-  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
-  $sql_del = "DELETE FROM {node} WHERE nid = :nid AND vid = :vid";
-  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
-
-  // Remove data from library and libraryprop tables of chado database as well
-  chado_query("DELETE FROM {libraryprop} WHERE library_id = :library_id", array(':library_id' => $library_id));
-  chado_query("DELETE FROM {library} WHERE library_id = :library_id", array(':library_id' => $library_id));
-}
-
-
 /**
  * Implementation of hook_form_alter()
  *

+ 1 - 1
tripal_organism/includes/organism_sync.inc

@@ -207,5 +207,5 @@ function tripal_organism_sync_organisms($organism_id = NULL, $job_id = NULL) {
  */
 function tripal_organism_cleanup($dummy = NULL, $job_id = NULL) {
 
-  return tripal_core_clean_orphaned_nodes('organism', $job_id);
+  return tripal_core_chado_node_cleanup_orphaned('organism', $job_id);
 }

+ 1 - 1
tripal_project/includes/tripal_project.admin.inc

@@ -380,5 +380,5 @@ function tripal_project_sync_all_projects() {
  */
 function tripal_project_cleanup($dummy = NULL, $job_id = NULL) {
 
-  return tripal_core_clean_orphaned_nodes('project', $job_id);
+  return tripal_core_chado_node_cleanup_orphaned('project', $job_id);
 }

+ 1 - 1
tripal_pub/includes/tripal_pub.pub_sync.inc

@@ -132,6 +132,6 @@ function tripal_pub_sync_pubs($job_id = NULL) {
  */
 function tripal_pub_cleanup($dummy = NULL, $job_id = NULL) {
 
-  return tripal_core_clean_orphaned_nodes('pub', $job_id);
+  return tripal_core_chado_node_cleanup_orphaned('pub', $job_id);
 
 }

+ 1 - 1
tripal_stock/includes/tripal_stock.admin.inc

@@ -291,6 +291,6 @@ function get_tripal_stock_admin_form_cleanup_set(&$form) {
  */
 function tripal_stock_cleanup($dummy = NULL, $job_id = NULL) {
 
-  return tripal_core_clean_orphaned_nodes('stock', $job_id);
+  return tripal_core_chado_node_cleanup_orphaned('stock', $job_id);
 
 }