Browse Source

Added an example module to serve as a template for anyone who wants to create an extension module. It will eventually have stubs for all functions

Stephen Ficklin 11 years ago
parent
commit
996d6c0c1d

+ 1 - 0
tripal_example/api/tripal_example.api.inc

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

+ 1 - 0
tripal_example/includes/tripal_example.admin.inc

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

+ 1 - 0
tripal_example/includes/tripal_example.blocks.inc

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

+ 1 - 0
tripal_example/includes/tripal_example.chado_node.inc

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

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

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

+ 1 - 0
tripal_example/theme/tripal_example_help.tpl.php

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

+ 0 - 0
tripal_example/tripal_example.info


+ 1 - 0
tripal_example/tripal_example.install

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

+ 1 - 0
tripal_example/tripal_example.module

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

+ 114 - 0
tripal_feature/includes/tripal_feature.blocks.inc

@@ -0,0 +1,114 @@
+<?php
+
+/**
+ *
+ *
+ * @ingroup tripal_feature
+ */
+function tripal_feature_block_info() {
+
+  $blocks['references']['info'] = t('Tripal Feature References');
+  $blocks['references']['cache'] = 'BLOCK_NO_CACHE';
+
+  $blocks['base']['info'] = t('Tripal Feature Details');
+  $blocks['base']['cache'] = 'BLOCK_NO_CACHE';
+
+  $blocks['sequence']['info'] = t('Tripal Feature Sequence');
+  $blocks['sequence']['cache'] = 'BLOCK_NO_CACHE';
+
+  $blocks['featureloc_sequences']['info'] = t('Tripal Feature Annotated Sequence');
+  $blocks['featureloc_sequences']['cache'] = 'BLOCK_NO_CACHE';
+
+  $blocks['synonyms']['info'] = t('Tripal Feature Synonyms');
+  $blocks['synonyms']['cache'] = 'BLOCK_NO_CACHE';
+
+  $blocks['properties']['info'] = t('Tripal Feature Properties');
+  $blocks['properties']['cache'] = 'BLOCK_NO_CACHE';;
+
+  $blocks['terms']['info'] = t('Tripal Annotated Terms');
+  $blocks['terms']['cache'] = 'BLOCK_NO_CACHE';;
+
+  $blocks['alignments']['info'] = t('Tripal Feature Alignments');
+  $blocks['alignments']['cache'] = 'BLOCK_NO_CACHE';
+
+  $blocks['relationships']['info'] = t('Tripal Feature Relationships');
+  $blocks['relationships']['cache'] = 'BLOCK_NO_CACHE';
+
+  $blocks['org_feature_counts']['info'] = t('Tripal Organism Feature Counts');
+  $blocks['org_feature_counts']['cache'] = 'BLOCK_NO_CACHE';
+
+  $blocks['org_feature_browser']['info'] = t('Tripal Organism Feature Browser');
+  $blocks['org_feature_browser']['cache'] = 'BLOCK_NO_CACHE';
+
+  return $blocks;
+}
+/**
+ *
+ *
+ * @ingroup tripal_feature
+ */
+function tripal_feature_block_view($delta = '') {
+
+  if (user_access('access chado_feature content') and arg(0) == 'node' and is_numeric(arg(1))) {
+    $nid = arg(1);
+    $node = node_load($nid);
+
+    $block = array();
+    switch ($delta) {
+    	case 'references':
+    	  $block['subject'] = t('References');
+    	  $block['content'] = theme('tripal_feature_references', $node);
+    	  break;
+    	case 'base':
+    	  $block['subject'] = t('Feature Details');
+    	  $block['content'] = theme('tripal_feature_base', $node);
+    	  break;
+    	case 'synonyms':
+    	  $block['subject'] = t('Synonyms');
+    	  $block['content'] = theme('tripal_feature_synonyms', $node);
+    	  break;
+    	case 'properties':
+    	  $block['subject'] = t('Properties');
+    	  $block['content'] = theme('tripal_feature_properties', $node);
+    	  break;
+    	case 'terms':
+    	  $block['subject'] = t('Annotated Terms');
+    	  $block['content'] = theme('tripal_feature_terms', $node);
+    	  break;
+    	case 'sequence':
+    	  $block['subject'] = t('Sequence');
+    	  $block['content'] = theme('tripal_feature_sequence', $node);
+    	  break;
+    	case 'featureloc_sequences':
+    	  $block['subject'] = t('Formatted Sequences');
+    	  $block['content'] = theme('tripal_feature_featureloc_sequences', $node);
+    	  break;
+    	case 'alignments':
+    	  $block['subject'] = t('Alignments');
+    	  $block['content'] = theme('tripal_feature_alignments', $node);
+    	  break;
+    	case 'relationships':
+    	  $block['subject'] = t('Relationships');
+    	  $block['content'] = theme('tripal_feature_relationships', $node);
+    	  break;
+    	case 'org_feature_counts':
+    	  $block['subject'] = t('Feature Type Summary');
+    	  $block['content'] = theme('tripal_organism_feature_counts', array('node' => $node));
+    	  break;
+    	case 'org_feature_browser':
+    	  $block['subject'] = t('Feature Browser');
+    	  $block['content'] = theme('tripal_organism_feature_browser', array('node' => $node));
+    	  break;
+    	case 'library_feature_browser':
+    	  $block['subject'] = t('Library Feature Browser');
+    	  $block['content'] = theme('tripal_library_feature_browser', $node);
+    	  break;
+    	case 'analysis_feature_browser':
+    	  $block['subject'] = t('Analysis Feature Browser');
+    	  $block['content'] = theme('tripal_analysis_feature_browser', $node);
+    	  break;
+    	default :
+    }
+    return $block;
+  }
+}

+ 754 - 0
tripal_feature/includes/tripal_feature.chado_node.inc

@@ -0,0 +1,754 @@
+<?php 
+
+/**
+ * Implementation of hook_form
+ * 
+ * @param  $node
+ * @param  $param
+ * 
+ * @return 
+ *   Drupal form array
+ *   
+ * @ingroup tripal_feature
+ */
+function chado_feature_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 feature
+  // 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
+  $feature      = null;
+  $feature_id   = null;
+  $uniquename   = '';
+  $fname        = '';
+  $feature_type = '';
+  $organism_id  = '';  
+  $residues     = '';
+  $is_obsolete  = '';
+  $analyses     = '';
+  $references   = '';
+  $synonyms     = '';
+  
+  // if we are editing an existing node then the feature is already part of the node
+  if (property_exists($node, 'feature')) {
+    $feature = $node->feature;
+    $feature = tripal_core_expand_chado_vars($feature, 'field', 'feature.residues');
+    $feature_id   = $feature->feature_id;
+    $uniquename   = $feature->uniquename;
+    $fname        = $feature->name;
+    $feature_type = $feature->type_id->name;
+    $organism_id  = $feature->organism_id->organism_id;
+    $residues     = $feature->residues;
+    $is_obsolete  = $feature->is_obsolete;
+    
+    // get the synonyms from a previous post
+    $synonyms = '';
+    if(property_exists($node, 'synonyms')) {
+      $synonyms = $node->synonyms;
+    }
+    
+    // get synonyms from the database if we don't already have them
+    if (!$synonyms) {
+      $options = array('return_array' => 1);
+      $feature = tripal_core_expand_chado_vars($feature, 'table', 'feature_synonym', $options);
+      $feature_synonyms = $feature->feature_synonym;      
+      foreach ($feature_synonyms as $index => $synonym) {
+        $synonyms .= $synonym->synonym_id->name . "\n";
+      }
+    }
+  }
+  // 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)) {
+    $uniquename   = $form_state['values']['uniquename'];
+    $fname        = $form_state['values']['fname'];
+    $feature_type = $form_state['values']['feature_type'];
+    $organism_id  = $form_state['values']['organism_id'];
+    $residues     = $form_state['values']['residues'];
+    $is_obsolete  = $form_state['values']['is_obsolete'];
+    $synonyms     = $form_state['values']['synonyms'];
+  }
+  // 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'])) {
+    $uniquename   = $form_state['input']['uniquename'];
+    $fname        = $form_state['input']['fname'];
+    $feature_type = $form_state['input']['feature_type'];
+    $organism_id  = $form_state['input']['organism_id'];
+    $residues     = $form_state['input']['residues'];
+    $is_obsolete  = array_key_exists('is_obsolete', $form_state['input']) ? $form_state['input']['is_obsolete'] : FALSE;
+    $synonyms     = $form_state['input']['synonyms'];
+  }
+
+  // We need to pass above variables for preview to show
+  $form['feature'] = array(
+    '#type' => 'value',
+    '#value' => $feature
+  );
+
+  // keep track of the feature id if we have one.  If we do have one then
+  // this would indicate an update as opposed to an insert.
+  $form['feature_id'] = array(
+    '#type' => 'value',
+    '#value' => $feature_id,
+  );
+  $form['fname']= array(
+    '#type' => 'textfield',
+    '#title' => t('Feature Name'),
+    '#required' => TRUE,
+    '#default_value' => $fname,
+    '#description' => t('Enter the name used by humans to refer to this feature.'),
+    '#maxlength' => 255
+  );
+  $form['uniquename']= array(
+    '#type' => 'textfield',
+    '#title' => t('Unique Feature Name'),
+    '#required' => TRUE,
+    '#default_value' => $uniquename,
+    '#description' => t('Enter a unique name for this feature.  This name must be unique for the organism and feature type.'),
+    '#maxlength' => 255
+  );
+  // get the sequence ontology CV ID
+  $values = array('name' => 'sequence');
+  $cv = tripal_core_chado_select('cv', array('cv_id'), $values);
+  $cv_id = $cv[0]->cv_id;
+
+  $form['feature_type'] = array(
+   '#title'       => t('Feature Type'),
+   '#type'        => 'textfield',
+   '#description' => t("Choose the feature type."),
+   '#required'    => TRUE,
+   '#default_value' => $feature_type,
+   '#autocomplete_path' => "admin/tripal/tripal_cv/cvterm/auto_name/$cv_id",
+  );
+
+  // get the list of organisms
+  $sql = "SELECT * FROM {Organism} ORDER BY genus, species";
+  $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 feature is associated"),
+    '#required'    => TRUE,
+    '#default_value' => $organism_id,
+    '#options'     => $organisms,
+  );
+
+  // Get synonyms
+  $syn_text = '';
+  if ($synonyms) {
+    if (is_array($synonyms)) {
+      foreach ($synonyms as $synonym) {
+        $syn_text .= "$synonym->name\n";
+      }
+    }
+    else {
+      $syn_text = $synonyms;
+    }
+  }
+  $form['synonyms']= array(
+    '#type' => 'textarea',
+    '#title' => t('Synonyms'),
+    '#required' => FALSE,
+    '#default_value' => $syn_text,
+    '#description' => t('Enter alternate names (synonmys) for this feature to help in searching and identification. You may enter as many alternate names as needed each on different lines.'),
+  );
+
+  $form['residues']= array(
+    '#type' => 'textarea',
+    '#title' => t('Residues'),
+    '#required' => FALSE,
+    '#default_value' => $residues,
+    '#description' => t('Enter the nucelotide sequences for this feature'),
+  );
+
+  $checked = '';
+  if ($is_obsolete == 't') {
+    $checked = '1';
+  }
+  $form['is_obsolete']= array(
+    '#type' => 'checkbox',
+    '#title' => t('Is Obsolete'),
+    '#required' => FALSE,
+    '#default_value' => $checked,
+    '#description' => t('Check this box if this sequence should be retired'),
+  );
+  return $form;
+}
+
+/**
+ * Implementation of hook_validate
+ * 
+ * This validation is being used for three activities:
+ *   CASE A: Update a node that exists in both drupal and chado
+ *   CASE B: Synchronizing a node from chado to drupal
+ *   CASE C: Inserting a new node that exists in niether drupal nor chado
+ *
+ * @param $node
+ *  
+ *
+ * @ingroup tripal_feature
+ */
+function chado_feature_validate($node, $form, &$form_state) {
+  // remove surrounding white-space on submitted values
+  $node->uniquename   = trim($node->uniquename);
+  $node->fname        = trim($node->fname);
+  $node->feature_type = trim($node->feature_type); 
+  $node->residues     = trim($node->residues);
+  
+  // if this is a delete then don't validate
+  if($node->op == 'Delete') {
+    return;
+  }
+  
+  // we are syncing if we do not have a node ID but we do have a feature_id. We don't
+  // need to validate during syncing so just skip it.
+  if (is_null($node->nid) and property_exists($node, 'feature_id') and $node->feature_id != 0) {
+    return;
+  }
+
+  // Validating for an update
+  if (property_exists($node, 'nid')) {
+    
+    // make sure the feature type is a real sequence ontology term
+    $type = tripal_cv_get_cvterm_by_name($node->feature_type, NULL, 'sequence');
+    if (!$type) {
+      form_set_error('feature_type', t("The feature type is not a valid name from the Sequence Ontology."));
+    }
+    
+    // if this is an update, we want to make sure that a different feature for
+    // the organism doesn't already have this uniquename. We don't want to give
+    // two sequences the same uniquename
+    if (property_exists($node, 'feature_id') and $node->feature_id != 0) {
+      $sql = "
+        SELECT *
+        FROM {feature} F
+          INNER JOIN {cvterm} CVT ON F.type_id = CVT.cvterm_id
+        WHERE
+          F.uniquename     = :uname AND
+          F.organism_id    = :organism_id AND
+          CVT.name         = :cvtname AND
+          NOT f.feature_id = :feature_id
+      ";
+      $args = array(':uname' => $node->uniquename, ':organism_id' => $node->organism_id,
+        ':cvtname' => $node->feature_type, ':feature_id' => $node->feature_id);
+      $result = chado_query($sql, $args)->fetchObject();
+      if ($result) {
+        form_set_error('uniquename', t("Feature update cannot proceed. The feature name '$node->uniquename' is not unique for this organism. Please provide a unique name for this feature."));
+      }
+    }
+  }
+  // Validating for an insert
+  else {
+      
+    // make sure the feature type is a real sequence ontology term
+    $type = tripal_cv_get_cvterm_by_name($node->feature_type, NULL, 'sequence');
+    if (!$type) {
+      form_set_error('feature_type', t("The feature type is not a valid name from the Sequence Ontology."));
+    }
+    
+    // if this is an insert then we just need to make sure this name doesn't
+    // already exist for this organism if it does then we need to throw an error
+    $sql = "
+      SELECT *
+      FROM {feature} F
+        INNER JOIN {cvterm} CVT ON F.type_id = CVT.cvterm_id
+      WHERE
+        F.uniquename  = :name AND
+        F.organism_id = :organism_id AND
+        CVT.name      = :cvtname
+    ";
+    $args = array(':name' => $node->uniquename, ':organism_id' => $node->organism_id, ':cvtname' => $node->feature_type);
+    $result = chado_query($sql, $args)->fetchObject();
+    if ($result) {
+      form_set_error('uniquename', t("Feature insert cannot proceed. The feature name '$node->uniquename' already exists for this organism. Please provide a unique name for this feature."));
+    }
+  }
+}
+
+
+/**
+ * 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_feature
+ */
+function chado_feature_node_access($node, $op, $account) {
+  if ($op == 'create') {
+    if (!user_access('create chado_feature content', $account)) {
+      return FALSE;
+    }
+    return TRUE;
+  }
+
+  if ($op == 'update') {
+    if (!user_access('edit chado_feature content', $account)) {
+      return FALSE;
+    }
+  }
+  if ($op == 'delete') {
+    if (!user_access('delete chado_feature content', $account)) {
+      return FALSE;
+    }
+  }
+  if ($op == 'view') {
+    if (!user_access('access chado_feature content', $account)) {
+      return FALSE;
+    }
+  }
+  return NULL;
+}
+/**
+ *  When a new chado_feature node is created we also need to add information
+ *  to our chado_feature table.  This function is called on insert of a new node
+ *  of type 'chado_feature' and inserts the necessary information.
+ *
+ * @ingroup tripal_feature
+ */
+function chado_feature_insert($node) {
+
+  $node->uniquename   = trim($node->uniquename);
+  $node->fname        = trim($node->fname);
+  $node->feature_type = trim($node->feature_type);
+  $node->residues     = trim($node->residues);
+
+  // remove spaces, newlines from residues
+  $residues = preg_replace("/[\n\r\s]/", "", $node->residues);
+  $obsolete = 'FALSE';
+  if ($node->is_obsolete) {
+    $obsolete = 'TRUE';
+  }
+
+  $feature_id = '';
+
+  // if there is an feature_id in the $node object then this must be a sync so
+  // we can skip adding the feature as it is already there, although
+  // we do need to proceed with the rest of the insert
+  if (!property_exists($node, 'feature_id')) {
+    $values = array(
+      'organism_id' => $node->organism_id,
+      'name' => $node->fname,
+      'uniquename' => $node->uniquename,
+      'residues' => $residues,
+      'seqlen' => drupal_strlen($residues),
+      'is_obsolete' => $obsolete,
+      'type_id' => $type[0]->cvterm_id,
+      'md5checksum' => md5($residues)
+    );
+    $feature = tripal_core_chado_select('feature', array('*'), $values);
+    if (!$feature) {
+      drupal_set_message(t('Unable to add feature.'), 'warning');
+      watchdog('tripal_feature', 'Insert feature: Unable to create feature where values: %values',
+      array('%values' => print_r($values, TRUE)), WATCHDOG_WARNING);
+      return;
+    }
+    $feature_id = $feature->feature_id;
+
+    // add the genbank accession and synonyms
+    chado_feature_add_synonyms($node->synonyms, $node->feature_id);
+  }
+  else {
+    $feature_id = $node->feature_id;
+  }
+
+  // Make sure the entry for this feature doesn't already exist in the
+  // chado_feature table if it doesn't exist then we want to add it.
+  $check_org_id = chado_get_id_for_node('feature', $node->nid);
+  if (!$check_org_id) {
+    $record = new stdClass();
+    $record->nid = $node->nid;
+    $record->vid = $node->vid;
+    $record->feature_id = $feature_id;
+    drupal_write_record('chado_feature', $record);
+  }
+}
+
+/**
+ *
+ *
+ * @ingroup tripal_feature
+ */
+function chado_feature_update($node) {
+
+  $node->uniquename   = trim($node->uniquename);
+  $node->fname        = trim($node->fname);
+  $node->feature_type = trim($node->feature_type);
+  $node->residues     = trim($node->residues);
+
+  if ($node->revision) {
+    // there is no way to handle revisions in Chado but leave
+    // this here just to make not we've addressed it.
+  }
+
+  $residues = preg_replace("/[\n\r\s]/", "", $node->residues);
+  $obsolete = 'FALSE';
+  if ($node->is_obsolete) {
+    $obsolete = 'TRUE';
+  }
+
+  // get the feature type id
+  $values = array(
+    'cv_id' => array(
+      'name' => 'sequence'
+    ),
+    'name' => $node->feature_type
+  );
+  $type = tripal_core_chado_select('cvterm', array('cvterm_id'), $values);
+
+  $feature_id = chado_get_id_for_node('feature', $node->nid) ;
+
+  if (sizeof($type) > 0) {
+    $match = array(
+      'feature_id' => $feature_id,
+    );
+    $values = array(
+      'organism_id' => $node->organism_id,
+      'name' => $node->fname,
+      'uniquename' => $node->uniquename,
+      'residues' => $residues,
+      'seqlen' => drupal_strlen($residues),
+      'is_obsolete' => $obsolete,
+      'type_id' => $type[0]->cvterm_id,
+      'md5checksum' => md5($residues)
+    );
+    $options = array('return_record' => TRUE);
+    $status = tripal_core_chado_update('feature', $match, $values, $options);
+
+    // add the genbank synonyms
+    chado_feature_add_synonyms($node->synonyms, $feature_id);
+  }
+  else {
+    drupal_set_message(t('Unable to update feature.'), 'warning');
+    watchdog('tripal_feature',
+    'Update feature: Unable to update feature where values: %values',
+    array('%values' => print_r($values, TRUE)),
+    WATCHDOG_WARNING
+    );
+  }
+
+
+}
+/**
+ *
+ *
+ * @ingroup tripal_feature
+ */
+function chado_feature_delete($node) {
+
+  $feature_id  = chado_get_id_for_node('feature', $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 (!$feature_id) {
+    return;
+  }
+
+  // remove the drupal content
+  $sql_del = "DELETE FROM {chado_feature} 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 data from feature tables of chado database.  This will
+  // cause a cascade delete and remove all data in referencing tables
+  // for this feature
+  chado_query("DELETE FROM {feature} WHERE feature_id = :feature_id", array(':feature_id' => $feature_id));
+
+  drupal_set_message(t("The feature and all associated data were removed from") .
+  "chado");
+
+}
+
+/**
+ *
+ *
+ * @ingroup tripal_feature
+ */
+function chado_feature_add_synonyms($synonyms, $feature_id) {
+
+  // separate synomys by carriage returns
+  $synonyms = preg_replace("/[\n\r]+/", " ", $synonyms);
+  // split the synonyms into an array based on a space as the delimieter
+  $syn_array = array();
+  $syn_array = explode(" ", $synonyms);
+
+
+  // remove any old synonyms
+  $feature_syn_dsql = "DELETE FROM {feature_synonym} WHERE feature_id = :feature_id";
+  if (!chado_query($feature_syn_dsql, array(':feature_id' => $feature_id))) {
+    watchdog('tripal_feature', "Could not remove synonyms from feature. ", array(), WATCHDOG_ERROR);
+    return;
+  }
+
+  // return if we don't have any synonmys to add
+  if (!$synonyms) {
+    return;
+  }
+  // iterate through each synonym and add it to the database
+  foreach ($syn_array as $syn) {
+    // skip this item if it's empty
+    if (!$syn) {
+      break;
+    }
+
+    // check to see if we have this accession number already in the database
+    // if so then don't add it again. it messes up drupal if the insert fails.
+    // It is possible for the accession number to be present and not the feature
+    $synonym_sql = "SELECT synonym_id FROM {synonym} WHERE name = :name";
+    $synonym = chado_query($synonym_sql, array(':name' => $syn))->fetchObject();
+    if (!$synonym) {
+      $synonym_isql = "
+        INSERT INTO {synonym} (name, synonym_sgml, type_id)
+        VALUES (:name, :synonym_sgml,
+          (SELECT cvterm_id
+           FROM {cvterm} CVT
+             INNER JOIN {cv} ON CVT.cv_id = CV.cv_id
+           WHERE CV.name = 'feature_property' and CVT.name = 'synonym')
+          )
+      ";
+      if (!chado_query($synonym_isql, array(':name' => $syn, ':synonym_sgml' => $syn))) {
+        watchdog('tripal_feature', "Could not add synonym. ", array(), WATCHDOG_WARNING);
+        return;
+      }
+      // now get the synonym we just added
+      $synonym_sql = "SELECT synonym_id FROM {synonym} WHERE name = :name";
+      $synonym = chado_query($synonym_sql, array(':name' => $syn))->fetchObject();
+    }
+
+    // now add in our new sysnonym
+    $feature_syn_isql = "
+      INSERT INTO {feature_synonym} (synonym_id,feature_id,pub_id)
+      VALUES (:synonym_id, :feature_id, :pub_id)";
+    $args = array(':synonym_id' => $synonym->synonym_id, ':feature_id' => $feature_id, ':pub_id'=> 1);
+    if (!chado_query($feature_syn_isql, $args)) {
+      watchdog('tripal_feature', "Could not associate synonym with feature. ", array(), WATCHDOG_WARNING);
+      return;
+    }
+  }
+}
+
+/**
+ *  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_feature
+ */
+function chado_feature_load($nodes) {
+
+  foreach ($nodes as $nid => $node) {
+    // find the feature and add in the details
+    $feature_id = chado_get_id_for_node('feature', $nid);
+
+    // build the feature variable
+    $values = array('feature_id' => $feature_id);
+    $feature = tripal_core_generate_chado_var('feature', $values);
+    $nodes[$nid]->feature = $feature;
+
+    // by default, the titles are saved using the unique constraint.  We will
+    // keep it the same, but remove the duplicate name if the unique name and name
+    // are identical. This doesn't change the title saved in the database, just what is shown
+    // to the user on the page
+    $title_type = variable_get('chado_feature_title', 'unique_constraint');
+    if ($title_type == 'unique_constraint') {
+      if (strcmp($feature->name, $feature->uniquename)==0) {
+        $node->title = $feature->name . " (" . $feature->type_id->name . ") " . $feature->organism_id->genus . " " . $feature->organism_id->species ;
+      }
+      // in previous version of Tripal, the feature title was simply the unique name.
+      // so, we recreate the title just to be sure all of our feature pages are consistent
+      else {
+        $node->title = $feature->name . ", " . $feature->uniquename . " (" . $feature->type_id->name . ") " . $feature->organism_id->genus . " " . $feature->organism_id->species ;
+      }
+    }
+    // set the title to be the feature name or uniquename as configured
+    if ($title_type == 'feature_name') {
+      $node->title = $feature->name;
+    }
+    if ($title_type == 'feature_unique_name') {
+      $node->title = $feature->uniquename;
+    }
+  }
+}
+/**
+ *  Provide information to drupal about the node types that we're creating
+ *  in this module
+ *
+ * @ingroup tripal_feature
+ */
+function tripal_feature_node_info() {
+  $nodes = array();
+
+  $nodes['chado_feature'] = array(
+    'name'        => t('Feature'),
+    'base'        => 'chado_feature',
+    'description' => t('A feature from the chado database'),
+    'has_title'   => FALSE,
+    'title_label' => t('Feature'),
+    'has_body'    => FALSE,
+    'body_label'  => t('Feature Description'),
+    'locked'      => TRUE
+  );
+  return $nodes;
+}
+/**
+ *
+ * @ingroup tripal_feature
+ */
+function tripal_feature_node_presave($node) {
+
+  // set the title to ensure it is always unique
+  switch ($node->type) {
+  	case 'chado_feature':
+  	  $values = array('organism_id' => $node->organism_id);
+  	  $organism = tripal_core_chado_select('organism', array('genus', 'species'), $values);
+  	  $node->title = $node->fname . ', ' . $node->uniquename . ' (' . $node->feature_type . ') ' . $organism[0]->genus . ' ' . $organism[0]->species;
+  	  break;
+  }
+}
+
+/**
+ *
+ * @ingroup tripal_feature
+ */
+function tripal_feature_node_insert($node) {
+
+  // set the URL path after inserting.  We do it here because we do not
+  // know the feature_id in the presave
+  switch ($node->type) {
+  	case 'chado_feature':
+  	  if (!$node->feature_id) {
+  	    $sql = "SELECT * FROM {chado_feature} WHERE nid = :nid";
+  	    $chado_feature = db_query($sql, array(':nid' => $node->nid))->fetchObject();
+  	    $node->feature_id = $chado_feature->feature_id;
+  	  }
+
+  	  // remove any previous alias
+  	  db_query("DELETE FROM {url_alias} WHERE source = :source", array(':source' => "node/$node->nid"));
+
+  	  // set the URL for this feature page
+  	  $url_alias = tripal_feature_get_feature_url($node);
+  	  $path_alias = array("source" => "node/$node->nid", "alias" => $url_alias);
+  	  path_save($path_alias);
+  	  break;
+  }
+}
+
+/**
+ *
+ * @ingroup tripal_feature
+ */
+function tripal_feature_node_view($node, $view_mode, $langcode) {
+  switch ($node->type) {
+  	case 'chado_feature':
+  	  // Show feature browser and counts
+  	  if ($view_mode == 'full') {
+  	    $node->content['tripal_feature_alignments'] = array(
+  	      '#value' => theme('tripal_feature_alignments', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_feature_analyses'] = array(
+  	      '#value' => theme('tripal_feature_analyses', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_feature_base'] = array(
+  	      '#value' => theme('tripal_feature_base', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_feature_featurepos'] = array(
+  	      '#value' => theme('tripal_feature_featurepos', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_feature_properties'] = array(
+  	      '#value' => theme('tripal_feature_properties', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_feature_publications'] = array(
+  	      '#value' => theme('tripal_feature_publications', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_feature_references'] = array(
+  	      '#value' => theme('tripal_feature_references', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_feature_relationships'] = array(
+  	      '#value' => theme('tripal_feature_relationships', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_feature_seqence'] = array(
+  	      '#value' => theme('tripal_feature_sequence', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_feature_synonyms'] = array(
+  	      '#value' => theme('tripal_feature_synonyms', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_feature_terms'] = array(
+  	      '#value' => theme('tripal_feature_terms', array('node' => $node)),
+  	    );
+  	  }
+  	  if ($view_mode == 'teaser') {
+  	    $node->content['tripal_feature_teaser'] = array(
+  	      '#value' => theme('tripal_feature_teaser', array('node' => $node)),
+  	    );
+  	  }
+  	  break;
+  	case 'chado_organism':
+  	  // Show feature browser and counts
+  	  if ($view_mode == 'full') {
+  	    $node->content['tripal_organism_feature_counts'] = array(
+  	      '#value' => theme('tripal_organism_feature_counts', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_organism_feature_browser'] = array(
+  	      '#value' => theme('tripal_organism_feature_browser', array('node' => $node)),
+  	    );
+  	  }
+  	  break;
+  	  // TODO: handle these node types. Should we also have a feature browser?
+  	case 'chado_library':
+  	  break;
+  	case 'chado_stock':
+  	  break;
+  	case 'chado_analysis':
+  	  break;
+  }
+}
+/**
+ *
+ * @ingroup tripal_feature
+ */
+function tripal_feature_node_update($node) {
+
+  // add items to other nodes, build index and search results
+  switch ($node->type) {
+  	case 'chado_feature':
+  	  // remove any previous alias
+  	  db_query("DELETE FROM {url_alias} WHERE source = :source", array(':source' => "node/$node->nid"));
+
+  	  // set the URL for this feature page
+  	  $url_alias = tripal_feature_get_feature_url($node);
+  	  $path_alias = array("source" => "node/$node->nid", "alias" => $url_alias);
+  	  path_save($path_alias);
+  	  break;
+  }
+}

+ 0 - 279
tripal_feature/includes/tripal_feature.form.inc

@@ -1,279 +0,0 @@
-<?php 
-
-/**
- * Implementation of hook_form
- * 
- * @param  $node
- * @param  $param
- * 
- * @return 
- *   Drupal form array
- *   
- * @ingroup tripal_feature
- */
-function chado_feature_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 feature
-  // 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
-  $feature      = null;
-  $feature_id   = null;
-  $uniquename   = '';
-  $fname        = '';
-  $feature_type = '';
-  $organism_id  = '';  
-  $residues     = '';
-  $is_obsolete  = '';
-  $analyses     = '';
-  $references   = '';
-  $synonyms     = '';
-  
-  // if we are editing an existing node then the feature is already part of the node
-  if (property_exists($node, 'feature')) {
-    $feature = $node->feature;
-    $feature = tripal_core_expand_chado_vars($feature, 'field', 'feature.residues');
-    $feature_id   = $feature->feature_id;
-    $uniquename   = $feature->uniquename;
-    $fname        = $feature->name;
-    $feature_type = $feature->type_id->name;
-    $organism_id  = $feature->organism_id->organism_id;
-    $residues     = $feature->residues;
-    $is_obsolete  = $feature->is_obsolete;
-    
-    // get the synonyms from a previous post
-    $synonyms = '';
-    if(property_exists($node, 'synonyms')) {
-      $synonyms = $node->synonyms;
-    }
-    
-    // get synonyms from the database if we don't already have them
-    if (!$synonyms) {
-      $options = array('return_array' => 1);
-      $feature = tripal_core_expand_chado_vars($feature, 'table', 'feature_synonym', $options);
-      $feature_synonyms = $feature->feature_synonym;      
-      foreach ($feature_synonyms as $index => $synonym) {
-        $synonyms .= $synonym->synonym_id->name . "\n";
-      }
-    }
-  }
-  // 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)) {
-    $uniquename   = $form_state['values']['uniquename'];
-    $fname        = $form_state['values']['fname'];
-    $feature_type = $form_state['values']['feature_type'];
-    $organism_id  = $form_state['values']['organism_id'];
-    $residues     = $form_state['values']['residues'];
-    $is_obsolete  = $form_state['values']['is_obsolete'];
-    $synonyms     = $form_state['values']['synonyms'];
-  }
-  // 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'])) {
-    $uniquename   = $form_state['input']['uniquename'];
-    $fname        = $form_state['input']['fname'];
-    $feature_type = $form_state['input']['feature_type'];
-    $organism_id  = $form_state['input']['organism_id'];
-    $residues     = $form_state['input']['residues'];
-    $is_obsolete  = array_key_exists('is_obsolete', $form_state['input']) ? $form_state['input']['is_obsolete'] : FALSE;
-    $synonyms     = $form_state['input']['synonyms'];
-  }
-
-  // We need to pass above variables for preview to show
-  $form['feature'] = array(
-    '#type' => 'value',
-    '#value' => $feature
-  );
-
-  // keep track of the feature id if we have one.  If we do have one then
-  // this would indicate an update as opposed to an insert.
-  $form['feature_id'] = array(
-    '#type' => 'value',
-    '#value' => $feature_id,
-  );
-  $form['fname']= array(
-    '#type' => 'textfield',
-    '#title' => t('Feature Name'),
-    '#required' => TRUE,
-    '#default_value' => $fname,
-    '#description' => t('Enter the name used by humans to refer to this feature.'),
-    '#maxlength' => 255
-  );
-  $form['uniquename']= array(
-    '#type' => 'textfield',
-    '#title' => t('Unique Feature Name'),
-    '#required' => TRUE,
-    '#default_value' => $uniquename,
-    '#description' => t('Enter a unique name for this feature.  This name must be unique for the organism and feature type.'),
-    '#maxlength' => 255
-  );
-  // get the sequence ontology CV ID
-  $values = array('name' => 'sequence');
-  $cv = tripal_core_chado_select('cv', array('cv_id'), $values);
-  $cv_id = $cv[0]->cv_id;
-
-  $form['feature_type'] = array(
-   '#title'       => t('Feature Type'),
-   '#type'        => 'textfield',
-   '#description' => t("Choose the feature type."),
-   '#required'    => TRUE,
-   '#default_value' => $feature_type,
-   '#autocomplete_path' => "admin/tripal/tripal_cv/cvterm/auto_name/$cv_id",
-  );
-
-  // get the list of organisms
-  $sql = "SELECT * FROM {Organism} ORDER BY genus, species";
-  $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 feature is associated"),
-    '#required'    => TRUE,
-    '#default_value' => $organism_id,
-    '#options'     => $organisms,
-  );
-
-  // Get synonyms
-  $syn_text = '';
-  if ($synonyms) {
-    if (is_array($synonyms)) {
-      foreach ($synonyms as $synonym) {
-        $syn_text .= "$synonym->name\n";
-      }
-    }
-    else {
-      $syn_text = $synonyms;
-    }
-  }
-  $form['synonyms']= array(
-    '#type' => 'textarea',
-    '#title' => t('Synonyms'),
-    '#required' => FALSE,
-    '#default_value' => $syn_text,
-    '#description' => t('Enter alternate names (synonmys) for this feature to help in searching and identification. You may enter as many alternate names as needed each on different lines.'),
-  );
-
-  $form['residues']= array(
-    '#type' => 'textarea',
-    '#title' => t('Residues'),
-    '#required' => FALSE,
-    '#default_value' => $residues,
-    '#description' => t('Enter the nucelotide sequences for this feature'),
-  );
-
-  $checked = '';
-  if ($is_obsolete == 't') {
-    $checked = '1';
-  }
-  $form['is_obsolete']= array(
-    '#type' => 'checkbox',
-    '#title' => t('Is Obsolete'),
-    '#required' => FALSE,
-    '#default_value' => $checked,
-    '#description' => t('Check this box if this sequence should be retired'),
-  );
-  return $form;
-}
-
-/**
- * Implementation of hook_validate
- * 
- * This validation is being used for three activities:
- *   CASE A: Update a node that exists in both drupal and chado
- *   CASE B: Synchronizing a node from chado to drupal
- *   CASE C: Inserting a new node that exists in niether drupal nor chado
- *
- * @param $node
- *  
- *
- * @ingroup tripal_feature
- */
-function chado_feature_validate($node, $form, &$form_state) {
-  // remove surrounding white-space on submitted values
-  $node->uniquename   = trim($node->uniquename);
-  $node->fname        = trim($node->fname);
-  $node->feature_type = trim($node->feature_type); 
-  $node->residues     = trim($node->residues);
-  
-  // if this is a delete then don't validate
-  if($node->op == 'Delete') {
-    return;
-  }
-  
-  // we are syncing if we do not have a node ID but we do have a feature_id. We don't
-  // need to validate during syncing so just skip it.
-  if (is_null($node->nid) and property_exists($node, 'feature_id') and $node->feature_id != 0) {
-    return;
-  }
-
-  // Validating for an update
-  if (property_exists($node, 'nid')) {
-    
-    // make sure the feature type is a real sequence ontology term
-    $type = tripal_cv_get_cvterm_by_name($node->feature_type, NULL, 'sequence');
-    if (!$type) {
-      form_set_error('feature_type', t("The feature type is not a valid name from the Sequence Ontology."));
-    }
-    
-    // if this is an update, we want to make sure that a different feature for
-    // the organism doesn't already have this uniquename. We don't want to give
-    // two sequences the same uniquename
-    if (property_exists($node, 'feature_id') and $node->feature_id != 0) {
-      $sql = "
-        SELECT *
-        FROM {feature} F
-          INNER JOIN {cvterm} CVT ON F.type_id = CVT.cvterm_id
-        WHERE
-          F.uniquename     = :uname AND
-          F.organism_id    = :organism_id AND
-          CVT.name         = :cvtname AND
-          NOT f.feature_id = :feature_id
-      ";
-      $args = array(':uname' => $node->uniquename, ':organism_id' => $node->organism_id,
-        ':cvtname' => $node->feature_type, ':feature_id' => $node->feature_id);
-      $result = chado_query($sql, $args)->fetchObject();
-      if ($result) {
-        form_set_error('uniquename', t("Feature update cannot proceed. The feature name '$node->uniquename' is not unique for this organism. Please provide a unique name for this feature."));
-      }
-    }
-  }
-  // Validating for an insert
-  else {
-      
-    // make sure the feature type is a real sequence ontology term
-    $type = tripal_cv_get_cvterm_by_name($node->feature_type, NULL, 'sequence');
-    if (!$type) {
-      form_set_error('feature_type', t("The feature type is not a valid name from the Sequence Ontology."));
-    }
-    
-    // if this is an insert then we just need to make sure this name doesn't
-    // already exist for this organism if it does then we need to throw an error
-    $sql = "
-      SELECT *
-      FROM {feature} F
-        INNER JOIN {cvterm} CVT ON F.type_id = CVT.cvterm_id
-      WHERE
-        F.uniquename  = :name AND
-        F.organism_id = :organism_id AND
-        CVT.name      = :cvtname
-    ";
-    $args = array(':name' => $node->uniquename, ':organism_id' => $node->organism_id, ':cvtname' => $node->feature_type);
-    $result = chado_query($sql, $args)->fetchObject();
-    if ($result) {
-      form_set_error('uniquename', t("Feature insert cannot proceed. The feature name '$node->uniquename' already exists for this organism. Please provide a unique name for this feature."));
-    }
-  }
-}

+ 3 - 582
tripal_feature/tripal_feature.module

@@ -22,7 +22,8 @@ require_once "includes/tripal_feature.fasta_loader.inc";
 require_once "includes/tripal_feature.gff_loader.inc";
 require_once "includes/tripal_feature.seq_extract.inc";
 require_once "includes/tripal_feature.delete.inc";
-require_once "includes/tripal_feature.form.inc";
+require_once "includes/tripal_feature.chado_node.inc";
+require_once "includes/tripal_feature.blocks.inc";
 
 
 /**
@@ -72,27 +73,7 @@ function tripal_feature_help($path, $arg) {
   return $output;
 }
 
-/**
- *  Provide information to drupal about the node types that we're creating
- *  in this module
- *
- * @ingroup tripal_feature
- */
-function tripal_feature_node_info() {
-  $nodes = array();
-
-  $nodes['chado_feature'] = array(
-    'name'        => t('Feature'),
-    'base'        => 'chado_feature',
-    'description' => t('A feature from the chado database'),
-    'has_title'   => FALSE,
-    'title_label' => t('Feature'),
-    'has_body'    => FALSE,
-    'body_label'  => t('Feature Description'),
-    'locked'      => TRUE
-  );
-  return $nodes;
-}
+
 
 /**
  *  Set the permission types that the chado module uses.  Essentially we
@@ -126,54 +107,7 @@ function tripal_feature_permissions() {
   );
 }
 
-/**
- * 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_feature
- */
-function chado_feature_node_access($node, $op, $account) {
-  if ($op == 'create') {
-    if (!user_access('create chado_feature content', $account)) {
-      return FALSE;
-    }
-    return TRUE;
-  }
 
-  if ($op == 'update') {
-    if (!user_access('edit chado_feature content', $account)) {
-      return FALSE;
-    }
-  }
-  if ($op == 'delete') {
-    if (!user_access('delete chado_feature content', $account)) {
-      return FALSE;
-    }
-  }
-  if ($op == 'view') {
-    if (!user_access('access chado_feature content', $account)) {
-      return FALSE;
-    }
-  }
-  return NULL;
-}
 /**
  *  Menu items are automatically added for the new node types created
  *  by this module to the 'Create Content' Navigation menu item.  This function
@@ -393,390 +327,8 @@ function tripal_feature_theme($existing, $type, $theme, $path) {
 
   return $items;
 }
-/**
- *
- *
- * @ingroup tripal_feature
- */
-function tripal_feature_block_info() {
-
-  $blocks['references']['info'] = t('Tripal Feature References');
-  $blocks['references']['cache'] = 'BLOCK_NO_CACHE';
-
-  $blocks['base']['info'] = t('Tripal Feature Details');
-  $blocks['base']['cache'] = 'BLOCK_NO_CACHE';
-
-  $blocks['sequence']['info'] = t('Tripal Feature Sequence');
-  $blocks['sequence']['cache'] = 'BLOCK_NO_CACHE';
-
-  $blocks['featureloc_sequences']['info'] = t('Tripal Feature Annotated Sequence');
-  $blocks['featureloc_sequences']['cache'] = 'BLOCK_NO_CACHE';
-
-  $blocks['synonyms']['info'] = t('Tripal Feature Synonyms');
-  $blocks['synonyms']['cache'] = 'BLOCK_NO_CACHE';
-
-  $blocks['properties']['info'] = t('Tripal Feature Properties');
-  $blocks['properties']['cache'] = 'BLOCK_NO_CACHE';;
-
-  $blocks['terms']['info'] = t('Tripal Annotated Terms');
-  $blocks['terms']['cache'] = 'BLOCK_NO_CACHE';;
-
-  $blocks['alignments']['info'] = t('Tripal Feature Alignments');
-  $blocks['alignments']['cache'] = 'BLOCK_NO_CACHE';
-
-  $blocks['relationships']['info'] = t('Tripal Feature Relationships');
-  $blocks['relationships']['cache'] = 'BLOCK_NO_CACHE';
-
-  $blocks['org_feature_counts']['info'] = t('Tripal Organism Feature Counts');
-  $blocks['org_feature_counts']['cache'] = 'BLOCK_NO_CACHE';
-
-  $blocks['org_feature_browser']['info'] = t('Tripal Organism Feature Browser');
-  $blocks['org_feature_browser']['cache'] = 'BLOCK_NO_CACHE';
-
-  return $blocks;
-}
-/**
- *
- *
- * @ingroup tripal_feature
- */
-function tripal_feature_block_view($delta = '') {
-
-  if (user_access('access chado_feature content') and arg(0) == 'node' and is_numeric(arg(1))) {
-    $nid = arg(1);
-    $node = node_load($nid);
-
-    $block = array();
-    switch ($delta) {
-      case 'references':
-        $block['subject'] = t('References');
-        $block['content'] = theme('tripal_feature_references', $node);
-        break;
-      case 'base':
-        $block['subject'] = t('Feature Details');
-        $block['content'] = theme('tripal_feature_base', $node);
-        break;
-      case 'synonyms':
-        $block['subject'] = t('Synonyms');
-        $block['content'] = theme('tripal_feature_synonyms', $node);
-        break;
-      case 'properties':
-        $block['subject'] = t('Properties');
-        $block['content'] = theme('tripal_feature_properties', $node);
-        break;
-      case 'terms':
-        $block['subject'] = t('Annotated Terms');
-        $block['content'] = theme('tripal_feature_terms', $node);
-        break;
-      case 'sequence':
-        $block['subject'] = t('Sequence');
-        $block['content'] = theme('tripal_feature_sequence', $node);
-        break;
-      case 'featureloc_sequences':
-        $block['subject'] = t('Formatted Sequences');
-        $block['content'] = theme('tripal_feature_featureloc_sequences', $node);
-        break;
-      case 'alignments':
-        $block['subject'] = t('Alignments');
-        $block['content'] = theme('tripal_feature_alignments', $node);
-        break;
-      case 'relationships':
-        $block['subject'] = t('Relationships');
-        $block['content'] = theme('tripal_feature_relationships', $node);
-        break;
-      case 'org_feature_counts':
-        $block['subject'] = t('Feature Type Summary');
-        $block['content'] = theme('tripal_organism_feature_counts', array('node' => $node));
-        break;
-      case 'org_feature_browser':
-        $block['subject'] = t('Feature Browser');
-        $block['content'] = theme('tripal_organism_feature_browser', array('node' => $node));
-        break;
-      case 'library_feature_browser':
-        $block['subject'] = t('Library Feature Browser');
-        $block['content'] = theme('tripal_library_feature_browser', $node);
-        break;
-      case 'analysis_feature_browser':
-        $block['subject'] = t('Analysis Feature Browser');
-        $block['content'] = theme('tripal_analysis_feature_browser', $node);
-        break;
-      default :
-    }
-    return $block;
-  }
-}
-/**
- *  When a new chado_feature node is created we also need to add information
- *  to our chado_feature table.  This function is called on insert of a new node
- *  of type 'chado_feature' and inserts the necessary information.
- *
- * @ingroup tripal_feature
- */
-function chado_feature_insert($node) {
-
-  $node->uniquename   = trim($node->uniquename);
-  $node->fname        = trim($node->fname);
-  $node->feature_type = trim($node->feature_type);
-  $node->residues     = trim($node->residues);
-
-  // remove spaces, newlines from residues
-  $residues = preg_replace("/[\n\r\s]/", "", $node->residues);
-  $obsolete = 'FALSE';
-  if ($node->is_obsolete) {
-    $obsolete = 'TRUE';
-  }
-
-  $feature_id = '';
-
-  // if there is an feature_id in the $node object then this must be a sync so
-  // we can skip adding the feature as it is already there, although
-  // we do need to proceed with the rest of the insert
-  if (!property_exists($node, 'feature_id')) {
-    $values = array(
-      'organism_id' => $node->organism_id,
-      'name' => $node->fname,
-      'uniquename' => $node->uniquename,
-      'residues' => $residues,
-      'seqlen' => drupal_strlen($residues),
-      'is_obsolete' => $obsolete,
-      'type_id' => $type[0]->cvterm_id,
-      'md5checksum' => md5($residues)
-    );
-    $feature = tripal_core_chado_select('feature', array('*'), $values);
-    if (!$feature) {
-      drupal_set_message(t('Unable to add feature.'), 'warning');
-      watchdog('tripal_feature', 'Insert feature: Unable to create feature where values: %values',
-        array('%values' => print_r($values, TRUE)), WATCHDOG_WARNING);
-      return;
-    }
-    $feature_id = $feature->feature_id;
-
-    // add the genbank accession and synonyms
-    chado_feature_add_synonyms($node->synonyms, $node->feature_id);
-  }
-  else {
-    $feature_id = $node->feature_id;
-  }
-
-  // Make sure the entry for this feature doesn't already exist in the
-  // chado_feature table if it doesn't exist then we want to add it.
-  $check_org_id = chado_get_id_for_node('feature', $node->nid);
-  if (!$check_org_id) {
-    $record = new stdClass();
-    $record->nid = $node->nid;
-    $record->vid = $node->vid;
-    $record->feature_id = $feature_id;
-    drupal_write_record('chado_feature', $record);
-  }
-}
-
-/**
- *
- *
- * @ingroup tripal_feature
- */
-function chado_feature_update($node) {
-
-  $node->uniquename   = trim($node->uniquename);
-  $node->fname        = trim($node->fname);
-  $node->feature_type = trim($node->feature_type);
-  $node->residues     = trim($node->residues);
-
-  if ($node->revision) {
-    // there is no way to handle revisions in Chado but leave
-    // this here just to make not we've addressed it.
-  }
-
-  $residues = preg_replace("/[\n\r\s]/", "", $node->residues);
-  $obsolete = 'FALSE';
-  if ($node->is_obsolete) {
-    $obsolete = 'TRUE';
-  }
-
-  // get the feature type id
-  $values = array(
-    'cv_id' => array(
-      'name' => 'sequence'
-      ),
-    'name' => $node->feature_type
-  );
-  $type = tripal_core_chado_select('cvterm', array('cvterm_id'), $values);
-
-  $feature_id = chado_get_id_for_node('feature', $node->nid) ;
 
-  if (sizeof($type) > 0) {
-    $match = array(
-      'feature_id' => $feature_id,
-    );
-    $values = array(
-      'organism_id' => $node->organism_id,
-      'name' => $node->fname,
-      'uniquename' => $node->uniquename,
-      'residues' => $residues,
-      'seqlen' => drupal_strlen($residues),
-      'is_obsolete' => $obsolete,
-      'type_id' => $type[0]->cvterm_id,
-      'md5checksum' => md5($residues)
-    );
-    $options = array('return_record' => TRUE);
-    $status = tripal_core_chado_update('feature', $match, $values, $options);
 
-    // add the genbank synonyms
-    chado_feature_add_synonyms($node->synonyms, $feature_id);
-  }
-  else {
-    drupal_set_message(t('Unable to update feature.'), 'warning');
-    watchdog('tripal_feature',
-    'Update feature: Unable to update feature where values: %values',
-    array('%values' => print_r($values, TRUE)),
-    WATCHDOG_WARNING
-    );
-  }
-
-
-}
-/**
- *
- *
- * @ingroup tripal_feature
- */
-function chado_feature_delete($node) {
-
-  $feature_id  = chado_get_id_for_node('feature', $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 (!$feature_id) {
-    return;
-  }
-
-  // remove the drupal content
-  $sql_del = "DELETE FROM {chado_feature} 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 data from feature tables of chado database.  This will
-  // cause a cascade delete and remove all data in referencing tables
-  // for this feature
-  chado_query("DELETE FROM {feature} WHERE feature_id = :feature_id", array(':feature_id' => $feature_id));
-
-  drupal_set_message(t("The feature and all associated data were removed from") .
-  "chado");
-
-}
-/**
- *
- *
- * @ingroup tripal_feature
- */
-function chado_feature_add_synonyms($synonyms, $feature_id) {
-
-  // separate synomys by carriage returns
-  $synonyms = preg_replace("/[\n\r]+/", " ", $synonyms);
-  // split the synonyms into an array based on a space as the delimieter
-  $syn_array = array();
-  $syn_array = explode(" ", $synonyms);
-
-
-  // remove any old synonyms
-  $feature_syn_dsql = "DELETE FROM {feature_synonym} WHERE feature_id = :feature_id";
-  if (!chado_query($feature_syn_dsql, array(':feature_id' => $feature_id))) {
-    watchdog('tripal_feature', "Could not remove synonyms from feature. ", array(), WATCHDOG_ERROR);
-    return;
-  }
-
-  // return if we don't have any synonmys to add
-  if (!$synonyms) {
-    return;
-  }
-  // iterate through each synonym and add it to the database
-  foreach ($syn_array as $syn) {
-    // skip this item if it's empty
-    if (!$syn) {
-      break;
-    }
-
-    // check to see if we have this accession number already in the database
-    // if so then don't add it again. it messes up drupal if the insert fails.
-    // It is possible for the accession number to be present and not the feature
-    $synonym_sql = "SELECT synonym_id FROM {synonym} WHERE name = :name";
-    $synonym = chado_query($synonym_sql, array(':name' => $syn))->fetchObject();
-    if (!$synonym) {
-      $synonym_isql = "
-        INSERT INTO {synonym} (name, synonym_sgml, type_id)
-        VALUES (:name, :synonym_sgml,
-          (SELECT cvterm_id
-           FROM {cvterm} CVT
-             INNER JOIN {cv} ON CVT.cv_id = CV.cv_id
-           WHERE CV.name = 'feature_property' and CVT.name = 'synonym')
-          )
-      ";
-      if (!chado_query($synonym_isql, array(':name' => $syn, ':synonym_sgml' => $syn))) {
-        watchdog('tripal_feature', "Could not add synonym. ", array(), WATCHDOG_WARNING);
-        return;
-      }
-      // now get the synonym we just added
-      $synonym_sql = "SELECT synonym_id FROM {synonym} WHERE name = :name";
-      $synonym = chado_query($synonym_sql, array(':name' => $syn))->fetchObject();
-    }
-
-    // now add in our new sysnonym
-    $feature_syn_isql = "
-      INSERT INTO {feature_synonym} (synonym_id,feature_id,pub_id)
-      VALUES (:synonym_id, :feature_id, :pub_id)";
-    $args = array(':synonym_id' => $synonym->synonym_id, ':feature_id' => $feature_id, ':pub_id'=> 1);
-    if (!chado_query($feature_syn_isql, $args)) {
-      watchdog('tripal_feature', "Could not associate synonym with feature. ", array(), WATCHDOG_WARNING);
-      return;
-    }
-  }
-}
-
-/**
- *  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_feature
- */
-function chado_feature_load($nodes) {
-
-  foreach ($nodes as $nid => $node) {
-    // find the feature and add in the details
-    $feature_id = chado_get_id_for_node('feature', $nid);
-
-    // build the feature variable
-    $values = array('feature_id' => $feature_id);
-    $feature = tripal_core_generate_chado_var('feature', $values);
-    $nodes[$nid]->feature = $feature;
-
-    // by default, the titles are saved using the unique constraint.  We will
-    // keep it the same, but remove the duplicate name if the unique name and name
-    // are identical. This doesn't change the title saved in the database, just what is shown
-    // to the user on the page
-    $title_type = variable_get('chado_feature_title', 'unique_constraint');
-    if ($title_type == 'unique_constraint') {
-      if (strcmp($feature->name, $feature->uniquename)==0) {
-        $node->title = $feature->name . " (" . $feature->type_id->name . ") " . $feature->organism_id->genus . " " . $feature->organism_id->species ;
-      }
-      // in previous version of Tripal, the feature title was simply the unique name.
-      // so, we recreate the title just to be sure all of our feature pages are consistent
-      else {
-        $node->title = $feature->name . ", " . $feature->uniquename . " (" . $feature->type_id->name . ") " . $feature->organism_id->genus . " " . $feature->organism_id->species ;
-      }
-    }
-    // set the title to be the feature name or uniquename as configured
-    if ($title_type == 'feature_name') {
-      $node->title = $feature->name;
-    }
-    if ($title_type == 'feature_unique_name') {
-      $node->title = $feature->uniquename;
-    }
-  }
-}
 /**
  *
  *
@@ -1321,136 +873,7 @@ function tripal_feature_color_sequence($sequence, $parts, $defline) {
   return $newseq;
 }
 
-/**
- *
- * @ingroup tripal_feature
- */
-function tripal_feature_node_presave($node) {
-
-  // set the title to ensure it is always unique
-  switch ($node->type) {
-    case 'chado_feature':
-      $values = array('organism_id' => $node->organism_id);
-      $organism = tripal_core_chado_select('organism', array('genus', 'species'), $values);
-      $node->title = $node->fname . ', ' . $node->uniquename . ' (' . $node->feature_type . ') ' . $organism[0]->genus . ' ' . $organism[0]->species;
-      break;
-  }
-}
 
-/**
- *
- * @ingroup tripal_feature
- */
-function tripal_feature_node_insert($node) {
-
-  // set the URL path after inserting.  We do it here because we do not
-  // know the feature_id in the presave
-  switch ($node->type) {
-    case 'chado_feature':
-      if (!$node->feature_id) {
-        $sql = "SELECT * FROM {chado_feature} WHERE nid = :nid";
-        $chado_feature = db_query($sql, array(':nid' => $node->nid))->fetchObject();
-        $node->feature_id = $chado_feature->feature_id;
-      }
-
-      // remove any previous alias
-      db_query("DELETE FROM {url_alias} WHERE source = :source", array(':source' => "node/$node->nid"));
-
-      // set the URL for this feature page
-      $url_alias = tripal_feature_get_feature_url($node);
-      $path_alias = array("source" => "node/$node->nid", "alias" => $url_alias);
-      path_save($path_alias);
-      break;
-  }
-}
-/**
- *
- * @ingroup tripal_feature
- */
-function tripal_feature_node_view($node, $view_mode, $langcode) {
-  switch ($node->type) {
-    case 'chado_feature':
-      // Show feature browser and counts
-      if ($view_mode == 'full') {
-        $node->content['tripal_feature_alignments'] = array(
-          '#value' => theme('tripal_feature_alignments', array('node' => $node)),
-        );
-        $node->content['tripal_feature_analyses'] = array(
-          '#value' => theme('tripal_feature_analyses', array('node' => $node)),
-        );
-        $node->content['tripal_feature_base'] = array(
-          '#value' => theme('tripal_feature_base', array('node' => $node)),
-        );
-        $node->content['tripal_feature_featurepos'] = array(
-          '#value' => theme('tripal_feature_featurepos', array('node' => $node)),
-        );
-        $node->content['tripal_feature_properties'] = array(
-          '#value' => theme('tripal_feature_properties', array('node' => $node)),
-        );
-        $node->content['tripal_feature_publications'] = array(
-          '#value' => theme('tripal_feature_publications', array('node' => $node)),
-        );
-        $node->content['tripal_feature_references'] = array(
-          '#value' => theme('tripal_feature_references', array('node' => $node)),
-        );
-        $node->content['tripal_feature_relationships'] = array(
-          '#value' => theme('tripal_feature_relationships', array('node' => $node)),
-        );
-        $node->content['tripal_feature_seqence'] = array(
-          '#value' => theme('tripal_feature_sequence', array('node' => $node)),
-        );
-        $node->content['tripal_feature_synonyms'] = array(
-          '#value' => theme('tripal_feature_synonyms', array('node' => $node)),
-        );
-        $node->content['tripal_feature_terms'] = array(
-          '#value' => theme('tripal_feature_terms', array('node' => $node)),
-        );
-      }
-      if ($view_mode == 'teaser') {
-        $node->content['tripal_feature_teaser'] = array(
-          '#value' => theme('tripal_feature_teaser', array('node' => $node)),
-        );
-      }
-      break;
-    case 'chado_organism':
-      // Show feature browser and counts
-      if ($view_mode == 'full') {
-        $node->content['tripal_organism_feature_counts'] = array(
-          '#value' => theme('tripal_organism_feature_counts', array('node' => $node)),
-        );
-        $node->content['tripal_organism_feature_browser'] = array(
-          '#value' => theme('tripal_organism_feature_browser', array('node' => $node)),
-        );
-      }
-      break;
-    // TODO: handle these node types. Should we also have a feature browser?
-    case 'chado_library':
-      break;
-    case 'chado_stock':
-      break;
-    case 'chado_analysis':
-      break;
-  }
-}
-/**
- *
- * @ingroup tripal_feature
- */
-function tripal_feature_node_update($node) {
-
-  // add items to other nodes, build index and search results
-  switch ($node->type) {
-    case 'chado_feature':
-      // remove any previous alias
-      db_query("DELETE FROM {url_alias} WHERE source = :source", array(':source' => "node/$node->nid"));
-
-      // set the URL for this feature page
-      $url_alias = tripal_feature_get_feature_url($node);
-      $path_alias = array("source" => "node/$node->nid", "alias" => $url_alias);
-      path_save($path_alias);
-      break;
-  }
-}
 
 
 /**
@@ -1517,8 +940,6 @@ function tripal_feature_cv_tree($tree_id) {
   return $options;
 }
 
-
-
 /**
  *
  *

+ 124 - 0
tripal_pub/includes/tripal_pub.chado_node.inc

@@ -887,4 +887,128 @@ function chado_pub_delete(&$node) {
   // Remove data from pub and pubprop tables of chado database as well
   chado_query("DELETE FROM {pubprop} WHERE pub_id = :pub_id", array(':pub_id' => $pub_id));
   chado_query("DELETE FROM {pub} WHERE pub_id = :pub_id", array(':pub_id' => $pub_id));
+}
+
+/**
+ * Implementation of hook_tripal_pub_node_info().
+ *
+ * This node_info, is a simple node that describes the functionallity of the module.
+ *
+ */
+function tripal_pub_node_info() {
+
+  return array(
+    'chado_pub' => array(
+      'name' => t('Publication'),
+      'base' => 'chado_pub',
+      'description' => t('A publication from the Chado database'),
+      'title_label' => t('Article Title'),
+      'body_label' => t('Abstract'),
+      'has_title' => TRUE,
+      'has_body' => FALSE,
+    ),
+  );
+}
+
+/**
+ *
+ * @ingroup tripal_feature
+ */
+function tripal_pub_node_view($node, $view_mode, $langcode) {
+  switch ($node->type) {
+  	case 'chado_pub':
+  	  // Show feature browser and counts
+  	  if ($view_mode == 'full') {
+  	    $node->content['tripal_pub_authors'] = array(
+  	      '#value' => theme('tripal_pub_authors', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_pub_base'] = array(
+  	      '#value' => theme('tripal_pub_base', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_pub_featuremaps'] = array(
+  	      '#value' => theme('tripal_pub_featuremaps', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_pub_features'] = array(
+  	      '#value' => theme('tripal_pub_features', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_pub_libraries'] = array(
+  	      '#value' => theme('tripal_pub_libraries', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_pub_projects'] = array(
+  	      '#value' => theme('tripal_pub_projects', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_pub_properties'] = array(
+  	      '#value' => theme('tripal_pub_properties', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_pub_references'] = array(
+  	      '#value' => theme('tripal_pub_references', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_pub_relationships'] = array(
+  	      '#value' => theme('tripal_pub_relationships', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_pub_stocks'] = array(
+  	      '#value' => theme('tripal_pub_stocks', array('node' => $node)),
+  	    );
+  	  }
+  	  if ($view_mode == 'teaser') {
+  	    $node->content['tripal_pub_teaser'] = array(
+  	      '#value' => theme('tripal_pub_teaser', array('node' => $node)),
+  	    );
+  	  }
+  	  break;
+  }
+}
+/**
+ *
+ * @param $node
+ */
+function tripal_pub_node_insert($node) {
+  // we want the publications to always have a URL of http://[base url]/pub/[pub id]
+  // where [pub id] is the Chado publication ID.  This will allow for easy linking
+  // into the publication without needing to know the node.  Of course if you know the
+  // node that will still work too (e.g. http://[base url]/node/[node id]
+  // so the nodeapi function ensures that the URL path is set after insert or update
+  // of the node and when the node is loaded if it hasn't yet been set.
+  if ($node->type == 'chado_pub') {
+    $pub_id = chado_get_id_for_node('pub', $node->nid);
+    tripal_pub_set_pub_url($node, $pub_id);
+  }
+}
+/**
+ *
+ * @param $node
+ * @param $types
+ */
+function tripal_pub_node_load($nodes, $types) {
+
+  // we want the publications to always have a URL of http://[base url]/pub/[pub id]
+  // where [pub id] is the Chado publication ID.  This will allow for easy linking
+  // into the publication without needing to know the node.  Of course if you know the
+  // node that will still work too (e.g. http://[base url]/node/[node id]
+  // so the nodeapi function ensures that the URL path is set after insert or update
+  // of the node and when the node is loaded if it hasn't yet been set.
+  if (count(array_intersect(array('chado_pub'), $types))) {
+    foreach ($nodes as $nid => $node) {
+      if ($node->type == 'chado_pub' and !property_exists($node, 'path')) {
+        $pub_id = chado_get_id_for_node('pub', $node->nid);
+        $path = tripal_pub_set_pub_url($node, $pub_id);
+      }
+    }
+  }
+}
+/**
+ *
+ * @param $node
+ */
+function tripal_pub_node_update($node) {
+  // we want the publications to always have a URL of http://[base url]/pub/[pub id]
+  // where [pub id] is the Chado publication ID.  This will allow for easy linking
+  // into the publication without needing to know the node.  Of course if you know the
+  // node that will still work too (e.g. http://[base url]/node/[node id]
+  // so the nodeapi function ensures that the URL path is set after insert or update
+  // of the node and when the node is loaded if it hasn't yet been set.
+  if ($node->type == 'chado_pub') {
+    $pub_id = chado_get_id_for_node('pub', $node->nid);
+    tripal_pub_set_pub_url($node, $pub_id);
+  }
 }

+ 1 - 124
tripal_pub/tripal_pub.module

@@ -30,28 +30,6 @@ function tripal_pub_init() {
   drupal_add_js(drupal_get_path('module', 'tripal_pub') . '/theme/js/tripal_pub.js');
 }
 
-
-/**
- * Implementation of hook_tripal_pub_node_info().
- *
- * This node_info, is a simple node that describes the functionallity of the module.
- *
- */
-function tripal_pub_node_info() {
-
-  return array(
-    'chado_pub' => array(
-      'name' => t('Publication'),
-      'base' => 'chado_pub',
-      'description' => t('A publication from the Chado database'),
-      'title_label' => t('Article Title'),
-      'body_label' => t('Abstract'),
-      'has_title' => TRUE,
-      'has_body' => FALSE,
-  ),
-  );
-}
-
 /**
  * Tripal-Publication-Menu
  *
@@ -390,108 +368,7 @@ function tripal_pub_mail($key, &$message, $params) {
         break;
   }
 }
-/**
- *
- * @ingroup tripal_feature
- */
-function tripal_pub_node_view($node, $view_mode, $langcode) {
-  switch ($node->type) {
-    case 'chado_pub':
-      // Show feature browser and counts
-      if ($view_mode == 'full') {
-        $node->content['tripal_pub_authors'] = array(
-          '#value' => theme('tripal_pub_authors', array('node' => $node)),
-        );
-        $node->content['tripal_pub_base'] = array(
-          '#value' => theme('tripal_pub_base', array('node' => $node)),
-        );
-        $node->content['tripal_pub_featuremaps'] = array(
-          '#value' => theme('tripal_pub_featuremaps', array('node' => $node)),
-        );
-        $node->content['tripal_pub_features'] = array(
-          '#value' => theme('tripal_pub_features', array('node' => $node)),
-        );
-        $node->content['tripal_pub_libraries'] = array(
-          '#value' => theme('tripal_pub_libraries', array('node' => $node)),
-        );
-        $node->content['tripal_pub_projects'] = array(
-          '#value' => theme('tripal_pub_projects', array('node' => $node)),
-        );
-        $node->content['tripal_pub_properties'] = array(
-          '#value' => theme('tripal_pub_properties', array('node' => $node)),
-        );
-        $node->content['tripal_pub_references'] = array(
-          '#value' => theme('tripal_pub_references', array('node' => $node)),
-        );
-        $node->content['tripal_pub_relationships'] = array(
-          '#value' => theme('tripal_pub_relationships', array('node' => $node)),
-        );
-        $node->content['tripal_pub_stocks'] = array(
-          '#value' => theme('tripal_pub_stocks', array('node' => $node)),
-        );
-      }
-      if ($view_mode == 'teaser') {
-        $node->content['tripal_pub_teaser'] = array(
-          '#value' => theme('tripal_pub_teaser', array('node' => $node)),
-        );
-      }
-      break;
-  }
-}
-/**
- *
- * @param $node
- */
-function tripal_pub_node_insert($node) {
-  // we want the publications to always have a URL of http://[base url]/pub/[pub id]
-  // where [pub id] is the Chado publication ID.  This will allow for easy linking
-  // into the publication without needing to know the node.  Of course if you know the
-  // node that will still work too (e.g. http://[base url]/node/[node id]
-  // so the nodeapi function ensures that the URL path is set after insert or update
-  // of the node and when the node is loaded if it hasn't yet been set.
-  if ($node->type == 'chado_pub') {
-    $pub_id = chado_get_id_for_node('pub', $node->nid);
-    tripal_pub_set_pub_url($node, $pub_id);
-  }
-}
-/**
- *
- * @param $node
- * @param $types
- */
-function tripal_pub_node_load($nodes, $types) {
-
-  // we want the publications to always have a URL of http://[base url]/pub/[pub id]
-  // where [pub id] is the Chado publication ID.  This will allow for easy linking
-  // into the publication without needing to know the node.  Of course if you know the
-  // node that will still work too (e.g. http://[base url]/node/[node id]
-  // so the nodeapi function ensures that the URL path is set after insert or update
-  // of the node and when the node is loaded if it hasn't yet been set.
-  if (count(array_intersect(array('chado_pub'), $types))) {
-    foreach ($nodes as $nid => $node) {
-      if ($node->type == 'chado_pub' and !property_exists($node, 'path')) {
-        $pub_id = chado_get_id_for_node('pub', $node->nid);
-        $path = tripal_pub_set_pub_url($node, $pub_id);
-      }
-    }
-  }
-}
-/**
- *
- * @param $node
- */
-function tripal_pub_node_update($node) {
-  // we want the publications to always have a URL of http://[base url]/pub/[pub id]
-  // where [pub id] is the Chado publication ID.  This will allow for easy linking
-  // into the publication without needing to know the node.  Of course if you know the
-  // node that will still work too (e.g. http://[base url]/node/[node id]
-  // so the nodeapi function ensures that the URL path is set after insert or update
-  // of the node and when the node is loaded if it hasn't yet been set.
-  if ($node->type == 'chado_pub') {
-    $pub_id = chado_get_id_for_node('pub', $node->nid);
-    tripal_pub_set_pub_url($node, $pub_id);
-  }
-}
+
 
 /**
  * Implementation of hook_form_alter()