Parcourir la source

Nightly checkin... working on pub module. Fixed bugs in other modules and consistency issues

Stephen Ficklin il y a 11 ans
Parent
commit
30aa5f6cad

+ 35 - 34
tripal_analysis/includes/tripal_analysis.form.inc

@@ -213,7 +213,7 @@ function chado_analysis_form($node, &$form_state) {
  *
  * @ingroup tripal_analysis
  */
-function chado_analysis_validate($node, &$form_state) {
+function chado_analysis_validate($node, $form, &$form_state) {
   // use the analysis parent to validate the node
   tripal_analysis_validate($node, $form_state);
 }
@@ -226,7 +226,7 @@ function chado_analysis_validate($node, &$form_state) {
  *
  * @ingroup tripal_analysis
  */
-function tripal_analysis_validate($node, &$form_state) {
+function tripal_analysis_validate($node, $form, &$form_state) {
   // remove surrounding white-space on submitted values
   $node->analysisname = trim($node->analysisname);
   $node->description = trim($node->description);
@@ -237,10 +237,20 @@ function tripal_analysis_validate($node, &$form_state) {
   $node->sourceversion = trim($node->sourceversion);
   $node->sourceuri = trim($node->sourceuri);
  
-  // Only nodes being updated will have an nid already
+  // 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 analysis_id. We don't
+  // need to validate during syncing so just skip it.
+  if (is_null($node->nid) and property_exists($node, 'analysis_id') and $node->analysis_id != 0) {
+    return;
+  }
+  
+  // Validating for an update
   if (!is_null($node->nid)) {    
-    // CASE A: We are validating a form for updating an existing node
-    
+   
     // get the existing node    
     $values = array('analysis_id' => $node->analysis_id);      
     $result = tripal_core_chado_select('analysis', array('*'), $values);
@@ -282,37 +292,28 @@ function tripal_analysis_validate($node, &$form_state) {
       }  
     }
   }
+  // Validating for an insert
   else {
-    // To differentiate if we are syncing or creating a new analysis altogther, see if an
-    // analysis_id already exists
-    if (property_exists($node, 'analysis_id') and $node->analysis_id != 0) {
-      // CASE B: Synchronizing a node from chado to drupal
-      // we don't need to do anything.
+    $values = array(
+      'program' => $node->program,
+      'programversion' => $node->programversion,
+      'sourcename' => $node->sourcename,
+    );
+    $analysis = tripal_core_chado_select('analysis', array('analysis_id'), $values);
+    if ($analysis and count($analysis) > 0) {
+      form_set_error('program', 'Cannot add the analysis with this program,
+        program version and source name. An analysis with these values already exists.');
+      return;
     }
-    else {
-      // CASE C: We are validating a form for inserting a new node
-      // The unique constraint for the chado analysis table is: program, programversion, sourcename
-      $values = array(
-        'program' => $node->program,
-        'programversion' => $node->programversion,
-        'sourcename' => $node->sourcename,
-      );
-      $analysis = tripal_core_chado_select('analysis', array('analysis_id'), $values);
-      if ($analysis and count($analysis) > 0) {
-        form_set_error('program', 'Cannot add the analysis with this program,
-          program version and source name. An analysis with these values already exists.');
-        return;
-      }
-      
-      // make sure we have a unique analysis name. This is not a requirement 
-      // for the analysis table but we use the analysis name for the Drupal node
-      // title, so it should be unique      
-      $values = array('name' => $node->analysisname);
-      $result = tripal_core_chado_select('analysis', array('analysis_id'), $values);
-      if ($result and count($result) > 0) {
-        form_set_error('analysisname', 'Cannot add the analysis with this analysis name. An analysis with this name already exists.');
-        return;
-      }
+    
+    // make sure we have a unique analysis name. This is not a requirement 
+    // for the analysis table but we use the analysis name for the Drupal node
+    // title, so it should be unique      
+    $values = array('name' => $node->analysisname);
+    $result = tripal_core_chado_select('analysis', array('analysis_id'), $values);
+    if ($result and count($result) > 0) {
+      form_set_error('analysisname', 'Cannot add the analysis with this analysis name. An analysis with this name already exists.');
+      return;
     }
   }
 }

+ 24 - 22
tripal_contact/includes/tripal_contact.form.inc

@@ -44,7 +44,7 @@ function chado_contact_form(&$node, $form_state) {
     // the contact description was incorrectly stored in the $node->body field.
     // It is better to store it in the Chado tables.  However, the 'description'
     // field of the contact table is only 255 characters.  So, we are going
-    // to follow the same as the analysis module and store the description in
+    // to follow the same as the contact module and store the description in
     // the contactprop table and leave the contact.description field blank.
     // however, for backwards compatibitily, we check to see if the description
     // is in the $node->body field. If it is we'll use that.  When the node is
@@ -162,15 +162,25 @@ function chado_contact_form(&$node, $form_state) {
  *
  * @ingroup tripal_contact
  */
-function chado_contact_validate($node, &$form) {
+function chado_contact_validate($node, $form, &$form_state) {
   // remove surrounding white-space on submitted values
   $node->title          = trim($node->title);
   $node->description    = trim($node->description);
  
-  // Only nodes being updated will have an nid already
+  
+  // 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 contact_id. We don't
+  // need to validate during syncing so just skip it.
+  if (is_null($node->nid) and property_exists($node, 'contact_id') and $node->contact_id != 0) {
+    return;
+  }
+  
+  // Validating for an update
   if (!property_exists($node,'nid')) {    
-    // CASE A: We are validating a form for updating an existing node
-    
     // get the existing node    
     $values = array('contact_id' => $node->contact_id);      
     $result = tripal_core_chado_select('contact', array('*'), $values);
@@ -186,24 +196,16 @@ function chado_contact_validate($node, &$form) {
       }  
     }
   }
+  // Validating for an insert
   else {
-    // To differentiate if we are syncing or creating a new contact altogther, see if an
-    // contact_id already exists
-    if (property_exists($node, 'contact_id') and $node->contact_id != 0) {
-      // CASE B: Synchronizing a node from chado to drupal
-      // we don't need to do anything.
-    }
-    else {
-      // CASE C: We are validating a form for inserting a new node
-      // The unique constraint for the chado contact table is: name
-      $values = array(
-        'name' => $node->title,
-      );
-      $contact = tripal_core_chado_select('contact', array('contact_id'), $values);
-      if ($contact and count($contact) > 0) {
-        form_set_error('title', 'Cannot add the contact with this name. An contact with these values already exists.');
-        return;
-      }
+    // The unique constraint for the chado contact table is: name
+    $values = array(
+      'name' => $node->title,
+    );
+    $contact = tripal_core_chado_select('contact', array('contact_id'), $values);
+    if ($contact and count($contact) > 0) {
+      form_set_error('title', 'Cannot add the contact with this name. An contact with these values already exists.');
+      return;
     }
   }
 }

+ 35 - 32
tripal_feature/includes/tripal_feature.form.inc

@@ -201,17 +201,27 @@ function chado_feature_form($node, &$form_state) {
  *
  * @ingroup tripal_feature
  */
-function chado_feature_validate($node, &$form_state) {
+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);
   
-  $result = 0;
+  // 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;
+  }
 
-  // CASE A: if the nid exists then this is an update
+  // 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) {
@@ -240,37 +250,30 @@ function chado_feature_validate($node, &$form_state) {
       }
     }
   }
+  // Validating for an insert
   else {
-    // To differentiate if we are syncing or creating a new feature altogther, see if a feature_id already exists
-    if (property_exists($node, 'feature_id') and $node->feature_id != 0) {
-      // CASE B: Synchronizing a node from chado to drupal
-      // we don't need to do anything.
-    }
-    else {
-      // CASE C: We are validating a form for inserting a new node
-      
-      // 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."));
-      }
+    // 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."));
     }
   }
 }

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

@@ -112,7 +112,7 @@ function chado_featuremap_form($node) {
  *
  * @ingroup tripal_featuremap
  */
-function chado_featuremap_validate($node, &$form) {
+function chado_featuremap_validate($node, $form, &$form_state) {
   $name          = trim($node->title);
   $featuremap_id = trim($node->featuremap_id);
   $unittype_id   = trim($node->unittype_id);

+ 1 - 1
tripal_library/tripal_library.module

@@ -592,7 +592,7 @@ function chado_library_form($node) {
  *
  * @ingroup tripal_library
  */
-function chado_library_validate($node) {
+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.

+ 14 - 3
tripal_organism/tripal_organism.module

@@ -355,9 +355,20 @@ function chado_organism_validate($node, $form, &$form_state) {
   $node->abbreviation = trim($node->abbreviation);
   $node->common_name  = trim($node->common_name);
   $node->description  = trim($node->description);
+  
+  
+  // 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 organism_id. We don't
+  // need to validate during syncing so just skip it.
+  if (is_null($node->nid) and property_exists($node, 'organism_id') and $node->organism_id != 0) {
+    return;
+  }
 
-  // if this is an update, we want to make sure that a different organism doesn't
-  // already have this genus and speces
+  // Validating for an update
   if (property_exists($node, 'organism_id')) {
     $sql = "
       SELECT *
@@ -378,7 +389,7 @@ function chado_organism_validate($node, $form, &$form_state) {
         WATCHDOG_WARNING);
     }
   }
-  // if this is an insert then check to make sure the genus and species are unique
+  // Validating for an insert
   else {
     $values = array(
       'genus' => $node->genus,

+ 1 - 1
tripal_project/tripal_project.module

@@ -314,7 +314,7 @@ function chado_project_form(&$node, $form_state) {
  *
  * @ingroup tripal_project
  */
-function chado_project_validate($node) {
+function chado_project_validate($node, $form, &$form_state) {
   $project = 0;
   // check to make sure the name on the project is unique
   // before we try to insert into chado.

+ 229 - 683
tripal_pub/includes/pub_form.inc

@@ -6,126 +6,149 @@
  */
 
 function chado_pub_form($node, $form_state) {
-  tripal_core_ahah_init_form();
   $form = array();
-
-  $pub = $node->pub;
-  $pub_id = $pub->pub_id;
-
-  $d_title        = $form_state['values']['pubtitle']     ? $form_state['values']['pubtitle']    : $pub->title;
-  $d_uniquename   = $form_state['values']['uniquename']   ? $form_state['values']['uniquename']  : $pub->uniquename;
-  $d_type_id      = $form_state['values']['type_id']      ? $form_state['values']['type_id']     : $pub->type_id->cvterm_id;
-  $d_volume       = $form_state['values']['volume']       ? $form_state['values']['volume']      : $pub->volume;
-  $d_volumetitle  = $form_state['values']['volumetitle']  ? $form_state['values']['volumetitle'] : $pub->volumetitle;
-  $d_series_name  = $form_state['values']['series_name']  ? $form_state['values']['series_name'] : $pub->series_name;
-  $d_issue        = $form_state['values']['issue']        ? $form_state['values']['issue']       : $pub->issue;
-  $d_pyear        = $form_state['values']['pyear']        ? $form_state['values']['pyear']       : $pub->pyear;
-  $d_pages        = $form_state['values']['pages']        ? $form_state['values']['pages']       : $pub->pages;
-  $d_miniref      = $form_state['values']['miniref']      ? $form_state['values']['miniref']     : $pub->miniref;
-  $d_publisher    = $form_state['values']['publisher']    ? $form_state['values']['publisher']   : $pub->publisher;
-  $d_pubplace     = $form_state['values']['pubplace']     ? $form_state['values']['pubplace']    : $pub->pubplace;
-  $d_is_obsolete  = $form_state['values']['is_obsolete']  ? $form_state['values']['is_obsolete'] : $pub->is_obsolete;
-
-  // if the obsolete value is set by the database then it is in the form of
-  // 't' or 'f', we need to convert to 1 or 0
-  $d_is_obsolete = $d_is_obsolete == 't' ? 1 : $d_is_obsolete;
-  $d_is_obsolete = $d_is_obsolete == 'f' ? 0 : $d_is_obsolete;
-
-  // on AHAH callbacks we want to keep a list of all the properties that have been removed
-  // we'll store this info in a hidden field and retrieve it here
-  $d_removed = $form_state['values']['removed'];
-
-  // get the number of new fields that have been aded via AHAH callbacks
-  $num_new = $form_state['values']['num_new'] ? $form_state['values']['num_new'] : 0;
-
-  // initialze default properties array. This is where we store the property defaults
-  $d_properties = array();
-
+  
+  // Default values can come in the following ways:
+  //
+  // 1) as elements of the $node object.  This occurs when editing an existing pub
+  // 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
+  $pub_id      = null;
+  $title       = '';
+  $volumetitle = '';
+  $volume      = '';
+  $series_name = '';
+  $issue       = '';
+  $pyear       = '';
+  $pages       = '';
+  $miniref     = '';
+  $uniquename  = '';
+  $type_id     = '';
+  $is_obsolete = '';
+  $publisher   = '';
+  $pubplace    = '';
+  
+  
+  // if we are editing an existing node then the pub is already part of the node
+  if (property_exists($node, 'pub')) {
+    $pub = $node->pub;
+    $pub = tripal_core_expand_chado_vars($pub, 'field', 'pub.title');
+    $pub = tripal_core_expand_chado_vars($pub, 'field', 'pub.volumetitle');
+    $pub = tripal_core_expand_chado_vars($pub, 'field', 'pub.uniquename');
+    $pub_id = $pub->pub_id;
+    
+    $title       = $node->title;
+    $volumetitle = $node->volumetitle;
+    $volume      = $node->volume;
+    $series_name = $node->series_name;
+    $issue       = $node->issue;
+    $pyear       = $node->pyear;
+    $pages       = $node->pages;
+    $miniref     = $node->miniref;
+    $uniquename  = $node->uniquename;
+    $type_id     = $node->type_id;
+    $is_obsolete = $node->is_obsolete;
+    $publisher   = $node->publisher;
+    $pubplace    = $node->pubplace;
+    
+    // if the obsolete value is set by the database then it is in the form of
+    // 't' or 'f', we need to convert to 1 or 0
+    $is_obsolete = $is_obsolete == 't' ? 1 : $is_obsolete;
+    $is_obsolete = $is_obsolete == 'f' ? 0 : $is_obsolete;
+    
+    // set the organism_id in the form
+    $form['pub_id'] = array(
+      '#type' => 'value',
+      '#value' => $pub->pub_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']['pubtitle'];
+    $volumetitle  = $form_state['values']['volumetitle'];
+    $volume       = $form_state['values']['volume'];
+    $series_name  = $form_state['values']['series_name'];
+    $issue        = $form_state['values']['issue'];
+    $pyear        = $form_state['values']['pyear'];
+    $pages        = $form_state['values']['pages'];
+    $miniref      = $form_state['values']['miniref'];
+    $uniquename   = $form_state['values']['uniquename'];
+    $type_id      = $form_state['values']['type_id'];
+    $is_obsolete  = $form_state['values']['is_obsolete'];
+    $publisher    = $form_state['values']['publisher'];
+    $pubplace     = $form_state['values']['pubplace'];
+  }
+  // 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']['pubtitle'];
+    $volumetitle  = $form_state['input']['volumetitle'];
+    $volume       = $form_state['input']['volume'];
+    $series_name  = $form_state['input']['series_name'];
+    $issue        = $form_state['input']['issue'];
+    $pyear        = $form_state['input']['pyear'];
+    $pages        = $form_state['input']['pages'];
+    $miniref      = $form_state['input']['miniref'];
+    $uniquename   = $form_state['input']['uniquename'];
+    $type_id      = $form_state['input']['type_id'];
+    $is_obsolete  = $form_state['input']['is_obsolete'];
+    $publisher    = $form_state['input']['publisher'];
+    $pubplace     = $form_state['input']['pubplace'];
+  }
+ 
+  // a drupal title can only be 255 characters, but the Chado title can be much longer.
+  // we use the publication title as the drupal title, but we'll need to truncate it.
+  $form['title'] = array(
+    '#type' => 'hidden',
+    '#value' => substr($title, 0, 255),
+  );
+  $form['pubtitle'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Publication Title'),
+    '#default_value' => $title,
+    '#required' => TRUE,
+  );
   // get the list of publication types.  In the Tripal publication
   // ontologies these are all grouped under the term 'Publication Type'
   // we want the default to be 'Journal Article'
   $sql = "
-    SELECT 
+    SELECT
       CVTS.cvterm_id, CVTS.name
     FROM {cvtermpath} CVTP
       INNER JOIN {cvterm} CVTS ON CVTP.subject_id = CVTS.cvterm_id
       INNER JOIN {cvterm} CVTO ON CVTP.object_id  = CVTO.cvterm_id
       INNER JOIN {cv}          ON CVTO.cv_id      = CV.cv_id
-    WHERE 
-      CV.name = 'tripal_pub' AND CVTO.name = 'Publication Type' AND 
+    WHERE
+      CV.name = 'tripal_pub' AND CVTO.name = 'Publication Type' AND
       NOT CVTS.is_obsolete = 1
-    ORDER BY CVTS.name ASC 
+    ORDER BY CVTS.name ASC
   ";
   $results = chado_query($sql);
   $pub_types = array();
   while ($pub_type = $results->fetchObject()) {
     $pub_types[$pub_type->cvterm_id] = $pub_type->name;
     // if we don't have a default type then set the default to be 'Journal Article'
-    if (strcmp($pub_type->name,"Journal Article") == 0 and !$d_type_id) {
-      $d_type_id = $pub_type->cvterm_id;
+    if (strcmp($pub_type->name,"Journal Article") == 0 and !$type_id) {
+      $type_id = $pub_type->cvterm_id;
     }
   }
   
-  // reset the default to use the stored variable if one exists
-  $d_type_id = variable_get('tripal_pub_default_type', $d_type_id);
-
-  // get publication properties list
-  $properties_select = array();
-  $properties_select[] = 'Select a Property';
-  $properties_list = array();
-  $sql = "
-    SELECT 
-      DISTINCT CVTS.cvterm_id, CVTS.name, CVTS.definition
-    FROM {cvtermpath} CVTP
-      INNER JOIN {cvterm} CVTS ON CVTP.subject_id = CVTS.cvterm_id
-      INNER JOIN {cvterm} CVTO ON CVTP.object_id  = CVTO.cvterm_id
-      INNER JOIN {cv}          ON CVTO.cv_id      = CV.cv_id
-    WHERE CV.name = 'tripal_pub' and 
-      (CVTO.name = 'Publication Details' OR CVTS.name = 'Publication Type') AND 
-      NOT CVTS.is_obsolete = 1
-    ORDER BY CVTS.name ASC 
-  ";
-  $prop_types = chado_query($sql);
-  while ($prop = $prop_types->fetchObject()) {
-    // the 'Citation' term is special because it serves
-    // both as a property and as the uniquename for the publiation table
-    if ($prop->name != "Citation") {
-      $properties_select[$prop->cvterm_id] = $prop->name;
-    }
-    $properties_list[$prop->cvterm_id] = $prop;
-  }
-
-  $form['pub_id'] = array(
-    '#type' => 'hidden',
-    '#value' => $pub_id,
-  );
-
-  // a drupal title can only be 255 characters, but the Chado title can be much longer.
-  // we use the publication title as the drupal title, but we'll need to truncate it.
-  $form['title'] = array(
-    '#type' => 'hidden',
-    '#value' => substr($d_title, 0, 255),
-  );
-
-  $form['pubtitle'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Publication Title'),
-    '#default_value' => $d_title,
-    '#required' => TRUE,
-  );
-
   $form['type_id'] = array(
     '#type' => 'select',
     '#title' => t('Publication Type'),
     '#options' => $pub_types,
     '#required' => TRUE,
-    '#default_value' => $d_type_id,
+    '#default_value' => $type_id,
   );
-
   $form['pyear'] = array(
     '#type' => 'textfield',
     '#title' => t('Publication Year'),
-    '#default_value' => $d_pyear,
+    '#default_value' => $pyear,
     '#required' => TRUE,
     '#size' => 5,
     '#description' => t('Enter the year of publication. Also, if available, please add a <b>Publication Date</b> property to specify the full date of publication.'),
@@ -133,7 +156,7 @@ function chado_pub_form($node, $form_state) {
   $form['uniquename'] = array(
     '#type' => 'textarea',
     '#title' => t('Citation'),
-    '#default_value' => $d_uniquename,
+    '#default_value' => $uniquename,
     '#description' => t('All publications must have a unique citation. 
       <b>Please enter the full citation for this publication or leave blank and one will be generated 
       automatically if possible</b>.  For PubMed style citations list 
@@ -142,76 +165,71 @@ function chado_pub_form($node, $form_state) {
       Below is an example: <pre>Medeiros PM, Ladio AH, Santos AM, Albuquerque UP. <a href="http://www.ncbi.nlm.nih.gov/pubmed/23462414" target="_blank">Does the selection of medicinal plants by Brazilian local populations 
         suffer taxonomic influence?</a> J Ethnopharmacol. 2013 Apr 19; 146(3):842-52.</pre>'),
   );
-
-
-  // add in the properties that are actually stored in the pub table fields.
-  $num_properties = chado_pub_node_form_add_pub_table_props($form, $form_state, $properties_list,
-  $d_properties, $d_removed, $d_volume, $d_volumetitle, $d_issue, $d_pages, $d_series_name);
-
-  // add in the properties from the pubprop table
-  $num_properties += chado_pub_node_form_add_pubprop_table_props($form, $form_state, $pub_id, $d_properties, $d_removed);
-
-  // add in any new properties that have been added by the user through an AHAH callback
-  $num_new = chado_pub_node_form_add_new_props($form, $form_state, $d_properties, $d_removed);
-
-  // add an empty row of field to allow for addition of a new property
-  chado_pub_node_form_add_new_empty_props($form, $properties_select);
-
-
-  $form['removed'] = array(
-    '#type' => 'hidden',
-    '#value' => $d_removed,
-  );
-
-  $form['num_new'] = array(
-    '#type' => 'hidden',
-    '#value' => $num_new,
-  );
-  $form['num_properties'] = array(
-    '#type' => 'hidden',
-    '#value' => $num_properties,
-  );
-
   $form['is_obsolete'] = array(
     '#type' => 'checkbox',
     '#title' => t('Is Obsolete? (Check for Yes)'),
-    '#required' => TRUE,
-    '#default_value' => $d_is_obsolete,
+    '#default_value' => $is_obsolete,
   );
+ 
+  // get publication properties list
+  $properties_select = array();
+  $properties_select[] = 'Select a Property';
+  $sql = "
+    SELECT
+      DISTINCT CVTS.cvterm_id, CVTS.name, CVTS.definition
+    FROM {cvtermpath} CVTP
+      INNER JOIN {cvterm} CVTS ON CVTP.subject_id = CVTS.cvterm_id
+      INNER JOIN {cvterm} CVTO ON CVTP.object_id  = CVTO.cvterm_id
+      INNER JOIN {cv}          ON CVTO.cv_id      = CV.cv_id
+    WHERE CV.name = 'tripal_pub' and
+      (CVTO.name = 'Publication Details' OR CVTS.name = 'Publication Type') AND
+      NOT CVTS.is_obsolete = 1
+    ORDER BY CVTS.name ASC
+  ";
+  $prop_types = chado_query($sql);
+  while ($prop = $prop_types->fetchObject()) {
+    // add all properties except the Citation. That property is set via the uniquename field
+    if ($prop->name != 'Citation') {
+      $properties[$prop->cvterm_id] = $prop->name;
+    }
+  }
+  
+  // add in the properties fields. The 'Citation' term is special because it serves
+  // both as a property and as the uniquename for the publiation table so we exclude it
+  // as it shouldn't be selected as a property
+  $exclude = array("Citation");
+  $instructions = '';
+  tripal_core_properties_form($form, $form_state, 'pubprop', 'pub_id', 'tripal_pub',
+    $properties, $pub_id, $exclude, $instructions);
+
   return $form;
 
 }
 /*
  *
  */
-function chado_pub_validate($node, &$form) {
+function chado_pub_validate($node, $form, &$form_state) {
 
   // get the submitted values
   $title        = trim($node->pubtitle);
-  $uniquename   = trim($node->uniquename);
-  $type_id      = trim($node->type_id);
-  $volume       = trim($node->volume);
-  $volumetitle  = trim($node->volumetitle);
-  $series_name  = trim($node->series_name);
-  $issue        = trim($node->issue);
   $pyear        = trim($node->pyear);
-  $pages        = trim($node->pages);
-  $miniref      = trim($node->miniref);
-  $publisher    = trim($node->publisher);
-  $pubplace     = trim($node->pubplace);
+  $uniquename   = trim($node->uniquename);
   $is_obsolete  = $node->is_obsolete;
-  $pub_id       = $node->pub_id;
-  $num_properties = $node->num_properties;
-  $num_new = $node->num_new;
-  
-  $pub = array();
+  $type_id      = $node->type_id;  
 
   // 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 pub_id. We don't
+  // need to validate during syncing so just skip it.
+  if (is_null($node->nid) and property_exists($node, 'pub_id') and $node->pub_id != 0) {
+    return;
+  }
+  
+  $pub = array();
+  
   // make sure the year is four digits
   if(!preg_match('/^\d{4}$/', $pyear)){
     form_set_error('pyear', t('The publication year should be a 4 digit year.'));
@@ -228,7 +246,8 @@ function chado_pub_validate($node, &$form) {
     return;
   }  
 
-  // get the media name looking at the properties  
+  // get the media name looking at the properties
+  $series_name = '';
   foreach ($node as $element => $value) {
     // if this is an existing property (either previously in the database or
     // added via AHAH/AJAX callback)
@@ -244,7 +263,7 @@ function chado_pub_validate($node, &$form) {
       $pub[$prop_type->name] = $value;
     }
     // if this is a new property (added by this submit of the form)
-    elseif ($element == 'new_id') {    	 
+    elseif ($element == 'new_id') {       
       $prop_type = tripal_cv_get_cvterm_by_id($value);
       if($prop_type->name == 'Conference Name' or $prop_type->name == 'Journal Name') {
         $series_name = $node->new_value;
@@ -274,12 +293,14 @@ function chado_pub_validate($node, &$form) {
     $skip_duplicate_check = 1;
   }
 
-  // on an update ($pub_id is set), check to see if there have been  changes to fields that
-  // are used to check for duplicates. If not, then no need to check for duplicates
-  if ($pub_id) {
+  // Validating for an update
+  if (!is_null($node->nid)) { 
+    
+    $pub_id = $node->pub_id;
+    
     // first get the original title, type and year before it was changed
     $values = array('pub_id' => $pub_id);
-    $columns =  array('title', 'pyear', 'type_id', 'series_name');
+    $columns = array('title', 'pyear', 'type_id', 'series_name');
     $options = array('statement_name' => 'sel_pub_id');
     $pub = tripal_core_chado_select('pub', $columns, $values, $options);
 
@@ -291,561 +312,86 @@ function chado_pub_validate($node, &$form) {
        ($pub[0]->year == $pyear)) {
       $skip_duplicate_check = 1;
     }
-  }
-
-  // check to see if a duplicate publication already exists
-  if (!$skip_duplicate_check) {
 
-    // make sure the publication is unique using the prefereed import duplication check
-    $import_dups_check = variable_get('tripal_pub_import_duplicate_check', 'title_year_media');
-    switch ($import_dups_check) {
-      case 'title_year':
-        $results = tripal_pub_get_pubs_by_title_type_pyear_series($title, NULL, $pyear, NULL);
-        // make sure we don't capture our pub_id in the list (remove it)
-        foreach ($results as $index => $found_pub_id) {
-          if($found_pub_id == $pub_id){
-            unset($results[$index]);
-          }
-        }
-        if (count($results) > 0) {
-          $message = t('A publication with this title and publication year, already exists.');
-          form_set_error('pyear', $message);
-        }
-        break;
-      case 'title_year_type':
-        $results = tripal_pub_get_pubs_by_title_type_pyear_series($title, $cvterm[0]->name, $pyear, NULL);
-
-        // make sure we don't capture our pub_id in the list (remove it)
-        foreach ($results as $index => $found_pub_id) {
-          if($found_pub_id == $pub_id){
-            unset($results[$index]);
-          }
-        }
-        if (count($results) > 0) {
-          $message = t('A publication with this title, type and publication year, already exists.');
-          form_set_error('pyear', $message);
-        }
-        break;
-      case 'title_year_media':
-        $results = tripal_pub_get_pubs_by_title_type_pyear_series($title, NULL, $pyear, $series_name);
-
-        // make sure we don't capture our pub_id in the list (remove it)
-        foreach ($results as $index => $found_pub_id) {
-          if($found_pub_id == $pub_id){
-            unset($results[$index]);
-          }
-        }
-        if (count($results) > 0) {
-          $message = t('A publication with this title, media name (e.g. Journal Name) and publication year, already exists.');
-          form_set_error('pyear', $message);
-        }
-        break;
+    // check to see if a duplicate publication already exists
+    if (!$skip_duplicate_check) {
+      chado_pub_validate_check_duplicate($title, $pyear, $series_name, $cvterm, $pub_id); 
     }
+    chado_pub_validate_check_uniquename($uniquename, $pub_id);
   }
-  // even though we are skipping the duplication checks above we must make sure the uniquename is unique
-  // as that is the offical table constraint
+  // Validating for an insert
   else {
-    $results = tripal_pub_get_pub_by_uniquename($uniquename);
-    // make sure we don't capture our pub_id in the list (remove it)
-    foreach ($results as $index => $found_pub_id) {
-      if($found_pub_id == $pub_id){
-        unset($results[$index]);
-      }
-    }
-    if (count($results) > 0) {
-      $message = t('A publication with this unique citation already exists.');
-      form_set_error('uniquename', $message);
-    }
+    chado_pub_validate_check_duplicate($title, $pyear, $series_name, $cvterm);
+    chado_pub_validate_check_uniquename($uniquename);
   }
 }
-/*
- *
- */
-function chado_pub_node_form_add_new_empty_props(&$form, $properties_select) {
-
-  // add one more blank set of property fields
-  $form['properties']['new']["new_id"] = array(
-    '#type'          => 'select',
-    '#options'       => $properties_select,
-    '#ahah' => array(
-      'path'    => "tripal_pub/properties/description",
-      'wrapper' => 'tripal-pub-new_value-desc',
-      'event'   => 'change',
-      'method'  => 'replace',          
-  ),
-  );
-  $form['properties']['new']["new_value"] = array(
-    '#type'          => 'textarea',
-    '#default_value' => '',
-    '#cols'          => 5,
-    '#rows'          => $rows,
-    '#description'   => '<div id="tripal-pub-new_value-desc"></div>'
-    );
-    $form['properties']['new']["add"] = array(
-    '#type'         => 'image_button',      
-    '#value'        => t('Add'),
-    '#src'          => drupal_get_path('theme', 'tripal') . '/images/add.png',
-    '#ahah' => array(
-      'path'    => "tripal_pub/properties/add",
-      'wrapper' => 'tripal-pub-edit-properties-table',
-      'event'   => 'click',
-      'method'  => 'replace',          
-    ),
-    '#attributes' => array('onClick' => 'return false;'),
-    );
-}
-/*
- *
+/**
+ * 
+ * @param unknown $uniquename
  */
-function chado_pub_node_form_add_new_props(&$form, $form_state, &$d_properties, &$d_removed) {
-   
-  // first, add in all of the new properties that were added through a previous AHAH callback
-  $j = 0;
-  $num_properties++;
-
-  // we need to find the
-  if ($form_state['values']) {
-    foreach ($form_state['values'] as $element_name => $value) {
-      if (preg_match('/new_value-(\d+)-(\d+)/', $element_name, $matches)) {
-        $new_id = $matches[1];
-        $rank = $matches[2];
-
-        // skip any properties that the user requested to delete through a previous
-        // AHAH callback or through the current AHAH callback
-        if($d_removed["$new_id-$rank"]) {
-          continue;
-        }
-        if($form_state['post']['remove-' . $new_id . '-' . $rank]) {
-          $d_removed["$new_id-$rank"] = 1;
-          continue;
-        }
-
-        // get this new_id information
-        $cvterm = tripal_core_chado_select('cvterm', array('name', 'definition'), array('cvterm_id' => $new_id));
-
-        // add it to the $d_properties array
-        $d_properties[$new_id][$rank]['name']  = $cvterm->name;
-        $d_properties[$new_id][$rank]['id']    = $new_id;
-        $d_properties[$new_id][$rank]['value'] = $value;
-        $d_properties[$new_id][$rank]['definition']  = $cvterm->definition;
-        $num_properties++;
-
-        // determine how many rows we need in the textarea
-        $rows = 1;
-        if (preg_match('/Abstract/', $cvterm[0]->name)) {
-          $rows = 10;
-        }
-        if ($cvterm[0]->name == 'Authors') {
-          $rows = 2;
-        }
-
-        // add the new fields
-        $form['properties']['new'][$new_id][$rank]["new_id-$new_id-$rank"] = array(
-          '#type'          => 'item',
-          '#value'         => $cvterm[0]->name
-        );
-        $form['properties']['new'][$new_id][$rank]["new_value-$new_id-$rank"] = array(
-          '#type'          => 'textarea',
-          '#default_value' => $value,
-          '#cols'          => 50,
-          '#rows'          => $rows,
-          '#description'   => $cvterm->definition,
-        );
-
-        $form['properties']['new'][$new_id][$rank]["remove-$new_id-$rank"] = array(
-          '#type'         => 'image_button',
-          '#value'        => t('Remove'),
-          '#src'          => drupal_get_path('theme', 'tripal') . '/images/minus.png',
-          '#ahah' => array(
-            'path'    => "tripal_pub/properties/minus/$new_id/$rank",
-            'wrapper' => 'tripal-pub-edit-properties-table',
-            'event'   => 'click',
-            'method'  => 'replace',
-        ),
-          '#attributes' => array('onClick' => 'return false;'),
-        );
-      }
+function chado_pub_validate_check_uniquename($uniquename, $pub_id = NULL) {
+  
+  $results = tripal_pub_get_pub_by_uniquename($uniquename);
+  // make sure we don't capture our pub_id in the list (remove it)
+  foreach ($results as $index => $found_pub_id) {
+    if($found_pub_id == $pub_id){
+      unset($results[$index]);
     }
   }
-
-
-  // second add in any new properties added during this callback
-  if($form_state['post']['add']) {
-    $new_id = $form_state['values']['new_id'];
-    $new_value = $form_state['values']['new_value'];
-
-    // get the rank by counting the number of entries
-    $rank = count($d_properties[$new_id]);
-
-    // get this new_id information
-    $cvterm = tripal_core_chado_select('cvterm', array('name', 'definition'), array('cvterm_id' => $new_id));
-
-    // add it to the $d_properties array
-    $d_properties[$new_id][$rank]['name']  = $cvterm->name;
-    $d_properties[$new_id][$rank]['id']    = $new_id;
-    $d_properties[$new_id][$rank]['value'] = $value;
-    $d_properties[$new_id][$rank]['definition']  = $cvterm->definition;
-    $num_properties++;
-
-    // determine how many rows we need in the textarea
-    $rows = 1;
-    if (preg_match('/Abstract/', $cvterm[0]->name)) {
-      $rows = 10;
-    }
-    if ($cvterm[0]->name == 'Authors') {
-      $rows = 2;
-    }
-
-    // add the new fields
-    $form['properties']['new'][$new_id][$rank]["new_id-$new_id-$rank"] = array(
-      '#type'          => 'item',
-      '#value'         => $cvterm[0]->name
-    );
-    $form['properties']['new'][$new_id][$rank]["new_value-$new_id-$rank"] = array(
-      '#type'          => 'textarea',
-      '#default_value' => $new_value,
-      '#cols'          => 50,
-      '#rows'          => $rows,
-      '#description'   => $cvterm->definition,
-    );
-
-    $form['properties']['new'][$new_id][$rank]["remove-$new_id-$rank"] = array(
-      '#type'         => 'image_button',
-      '#value'        => t('Remove'),
-      '#src'          => drupal_get_path('theme', 'tripal') . '/images/minus.png',
-      '#ahah' => array(
-        'path'    => "tripal_pub/properties/minus/$new_id/$rank",
-        'wrapper' => 'tripal-pub-edit-properties-table',
-        'event'   => 'click',
-        'method'  => 'replace',
-    ),
-      '#attributes' => array('onClick' => 'return false;'),
-    );
-
+  if (count($results) > 0) {
+    $message = t('A publication with this unique citation already exists.');
+    form_set_error('uniquename', $message);
   }
-
-  return $num_properties;
 }
-/*
- *
- */
-function chado_pub_node_form_add_pubprop_table_props(&$form, $form_state, $pub_id, &$d_properties, &$d_removed) {
-
-  // get the properties for this publication
-  $num_properties = 0;
-
-  if(!$pub_id) {
-    return $num_properties;
-  }
-
-  $sql = "
-    SELECT CVT.cvterm_id, CVT.name, CVT.definition, PP.value, PP.rank
-    FROM {pubprop} PP
-      INNER JOIN {cvterm} CVT on CVT.cvterm_id = PP.type_id
-    WHERE PP.pub_id = :pub_id
-    ORDER BY CVT.name, PP.rank
-  ";
-  $pub_props = chado_query($sql, array(':pub_id' => $pub_id));
-  while ($prop = $pub_props->fetchObject()) {
-
-    $type_id = $prop->cvterm_id;
-    $rank = count($d_properties[$type_id]);
-
-    // skip properties that are found in the pub table
-    if($prop->name == "Volume" or $prop->name == "Volume Title" or
-    $prop->name == "Issue"  or $prop->name == "Pages" or
-    $prop->name == "Citation" or $prop->name == "Journal Name") {
-      continue;
-    }
-
-    // skip any properties that the user requested to delete through a previous
-    // AHAH callback or through the current AHAH callback
-    if($d_removed["$type_id-$rank"]) {
-      continue;
-    }
-    if($form_state['post']['remove-' . $type_id . '-' . $rank]) {
-      $d_removed["$type_id-$rank"] = 1;
-      continue;
-    }
-
-    $d_properties[$type_id][$rank]['name']  = $prop->name;
-    $d_properties[$type_id][$rank]['id']    = $type_id;
-    $d_properties[$type_id][$rank]['value'] = $prop->value;
-    $d_properties[$type_id][$rank]['definition']  = $prop->definition;
-    $num_properties++;
-
-    // determine how many rows we need in the textarea
-    $rows = 1;
-    if (preg_match('/Abstract/', $prop->name)) {
-      $rows = 10;
-    }
-    if ($prop->name == 'Authors') {
-      $rows = 2;
-    }
-
-    $form['properties'][$type_id][$rank]["prop_id-$type_id-$rank"] = array(
-      '#type'          => 'item',
-      '#value'         => $prop->name,
-    );
-    $form['properties'][$type_id][$rank]["prop_value-$type_id-$rank"] = array(
-      '#type'          => 'textarea',
-      '#default_value' => $prop->value,
-      '#cols'          => 50,
-      '#rows'          => $rows,
-      '#description'   => $prop->definition,
-    );
-
-    $form['properties'][$type_id][$rank]["remove-$type_id-$rank"] = array(
-      '#type'         => 'image_button',
-      '#value'        => t('Remove'),
-      '#src'          => drupal_get_path('theme', 'tripal') . '/images/minus.png',
-      '#ahah' => array(
-        'path'    => "tripal_pub/properties/minus/$type_id/$rank",
-        'wrapper' => 'tripal-pub-edit-properties-table',
-        'event'   => 'click',
-        'method'  => 'replace',
-    ),
-      '#attributes' => array('onClick' => 'return false;'),
-    );
-  }
-  return $num_properties;
-}
-/*
- *
+/**
+ * 
  */
-function chado_pub_node_form_add_pub_table_props(&$form, $form_state, $properties_list,
-&$d_properties, &$d_removed, $d_volume, $d_volumetitle, $d_issue, $d_pages, $d_series_name) {
-
-  $num_properties = 0;
-  $rank = 0;
-
-  // add properties that are actually part of the pub table
-  foreach($properties_list as $type_id => $prop) {
-
-    // skip any properties that the user requested to delete through a previous
-    // AHAH callback or through the current AHAH callback
-    if($d_removed["$type_id-$rank"]) {
-      continue;
-    }
-    if($form_state['post']["remove-$type_id-$rank"]) {
-      $d_removed["$type_id-$rank"] = 1;
-      continue;
-    }
-
-    // if any of the properties match the fields in the pub table then we
-    // want to include those automatically
-    if (($prop->name == 'Volume' and $d_volume) or
-    ($prop->name == 'Issue' and $d_issue) or
-    ($prop->name == 'Pages' and $d_pages) or
-    ($prop->name == 'Volume Title' and $d_volumetitle) or
-    ($prop->name == 'Journal Name' and $d_series_name)) {
-
-      $d_properties[$type_id][$rank]['name']  = $prop->name;
-      $d_properties[$type_id][$rank]['id']    = $type_id;
-      $d_properties[$type_id][$rank]['definition']  = $prop->definition;
-      $num_properties++;
-
-      if ($prop->name == 'Volume') {
-        $d_properties[$type_id][$rank]['value'] = $d_volume;
-      }
-      if ($prop->name == 'Issue') {
-        $d_properties[$type_id][$rank]['value'] = $d_issue;
-      }
-      if ($prop->name == 'Pages') {
-        $d_properties[$type_id][$rank]['value'] = $d_pages;
-      }
-      if ($prop->name == 'Volume Title') {
-        $d_properties[$type_id][$rank]['value'] = $d_volumetitle;
+function chado_pub_validate_check_duplicate($title, $pyear, $series_name, $cvterm, $pub_id = NULL) {
+  
+  // make sure the publication is unique using the prefereed import duplication check
+  $import_dups_check = variable_get('tripal_pub_import_duplicate_check', 'title_year_media');
+  switch ($import_dups_check) {
+    case 'title_year':
+      $results = tripal_pub_get_pubs_by_title_type_pyear_series($title, NULL, $pyear, NULL);
+      // make sure we don't capture our pub_id in the list (remove it)
+      foreach ($results as $index => $found_pub_id) {
+        if($found_pub_id == $pub_id){
+          unset($results[$index]);
+        }
       }
-      if ($prop->name == 'Journal Name') {
-        $d_properties[$type_id][$rank]['value'] = $d_series_name;
+      if (count($results) > 0) {
+        $message = t('A publication with this title and publication year, already exists.');
+        form_set_error('pyear', $message);
       }
-
-      // determine how many rows we need in the textarea
-      $rows = 1;
-      if (preg_match('/Abstract/', $prop->name)) {
-        $rows = 10;
+      break;
+    case 'title_year_type':
+      $results = tripal_pub_get_pubs_by_title_type_pyear_series($title, $cvterm[0]->name, $pyear, NULL);
+  
+      // make sure we don't capture our pub_id in the list (remove it)
+      foreach ($results as $index => $found_pub_id) {
+        if($found_pub_id == $pub_id){
+          unset($results[$index]);
+        }
       }
-      if ($prop->name == 'Authors') {
-        $rows = 2;
+      if (count($results) > 0) {
+        $message = t('A publication with this title, type and publication year, already exists.');
+        form_set_error('pyear', $message);
       }
-
-      // add in the fields
-      $form['properties'][$type_id][$rank]["prop_id-$type_id-$rank"] = array(
-        '#type'          => 'item',
-        '#value'         => $prop->name
-      );
-      $form['properties'][$type_id][$rank]["prop_value-$type_id-$rank"] = array(
-        '#type'          => 'textarea',
-        '#default_value' => $d_properties[$type_id][$rank]['value'],
-        '#cols'          => 50,
-        '#rows'          => $rows,
-        '#description'   => $description,
-      );
-
-      $form['properties'][$type_id][$rank]["remove-$type_id-$rank"] = array(
-        '#type'         => 'image_button',
-        '#value'        => t('Remove'),
-        '#src'          => drupal_get_path('theme', 'tripal') . '/images/minus.png',
-        '#ahah' => array(
-          'path'    => "tripal_pub/properties/minus/$type_id/$rank",
-          'wrapper' => 'tripal-pub-edit-properties-table',
-          'event'   => 'click',
-          'method'  => 'replace',
-      ),
-        '#attributes' => array('onClick' => 'return false;'),
-      );
-    }
-  }
-  return $num_properties;
-}
-/*
- *
- */
-function theme_chado_pub_node_form($form) {
-
-  $properties_table = tripal_pub_theme_node_form_properties($form);
-
-  $markup  = drupal_render($form['pub_id']);
-  $markup .= drupal_render($form['pubtitle']);
-  $markup .= drupal_render($form['type_id']);
-  $markup .= drupal_render($form['series_name']);
-  $markup .= drupal_render($form['pyear']);
-  $markup .= drupal_render($form['uniquename']);
-  $markup .= "<b>Include Additional Details</b><br>You may add additional properties to this publication by scrolling to the bottom of this table, selecting a property type from the dropdown and adding text.  You may add as many properties as desired by clicking the plus button on the right.  To remove a property, click the minus button";
-  $markup .= $properties_table;
-  $markup .= drupal_render($form['is_obsolete']);
-
-  $form['properties'] = array(
-    '#type' => 'markup',
-    '#value' =>  $markup,
-  );
-  return drupal_render($form);
-}
-
-/*
- *
- */
-function tripal_pub_theme_node_form_properties($form) {
-  $rows = array();
-
-  if ($form['properties']) {
-
-    // first add in the properties derived from the pub and pubprop tables
-    // the array tree for these properties looks like this:
-    // $form['properties'][$type_id][$rank]["prop_id-$type_id-$rank"]
-    foreach ($form['properties'] as $type_id => $elements) {
-      // there are other fields in the properties array so we only
-      // want the numeric ones those are our type_id
-      if (is_numeric($type_id)) {
-        foreach ($elements as $rank => $element) {
-          if (is_numeric($rank)) {
-            $rows[] = array(
-            drupal_render($element["prop_id-$type_id-$rank"]),
-            drupal_render($element["prop_value-$type_id-$rank"]),
-            drupal_render($element["remove-$type_id-$rank"]),
-            );
-          }
+      break;
+    case 'title_year_media':
+      $results = tripal_pub_get_pubs_by_title_type_pyear_series($title, NULL, $pyear, $series_name);
+  
+      // make sure we don't capture our pub_id in the list (remove it)
+      foreach ($results as $index => $found_pub_id) {
+        if($found_pub_id == $pub_id){
+          unset($results[$index]);
         }
       }
-    }
-
-    // second, add in any new properties added by the user through AHAH callbacks
-    // the array tree for these properties looks like this:
-    // $form['properties']['new'][$type_id][$rank]["new_id-$new_id-$rank"]
-    foreach ($form['properties']['new'] as $type_id => $elements) {
-      if (is_numeric($type_id)) {
-        foreach ($elements as $rank => $element) {
-          if (is_numeric($rank)) {
-            $rows[] = array(
-            drupal_render($element["new_id-$type_id-$rank"]),
-            drupal_render($element["new_value-$type_id-$rank"]),
-            drupal_render($element["remove-$type_id-$rank"]),
-            );
-          }
-        }
+      if (count($results) > 0) {
+        $message = t('A publication with this title, media name (e.g. Journal Name) and publication year, already exists.');
+        form_set_error('pyear', $message);
       }
-    }
-
-    // finally add in a set of blank field for adding a new property
-    $rows[] = array(
-    drupal_render($form['properties']['new']['new_id']),
-    drupal_render($form['properties']['new']['new_value']),
-    drupal_render($form['properties']['new']['add']),
-    );
+      break;
   }
-
-  $headers = array('Property Type','Value', '');
-  return theme('table', $headers, $rows, array('id'=> "tripal-pub-edit-properties-table"));
 }
 
-/*
- *
- */
-function tripal_pub_property_add() {
-  $status = TRUE;
-
-  // prepare and render the form
-  $form = tripal_core_ahah_prepare_form();
-
-  // we only want to return the properties as that's all we'll replace with this AHAh callback
-  $data = tripal_pub_theme_node_form_properties($form);
-
-  // bind javascript events to the new objects that will be returned
-  // so that AHAH enabled elements will work.
-  $settings = tripal_core_ahah_bind_events();
-
-  // return the updated JSON
-  drupal_json(
-  array(
-      'status'   => $status, 
-      'data'     => $data,
-      'settings' => $settings,
-  )
-  );
-}
-/*
- *
- */
-function tripal_pub_property_delete() {
-  $status = TRUE;
-
-  // prepare and render the form
-  $form = tripal_core_ahah_prepare_form();
-
-  // we only want to return the properties as that's all we'll replace with this AHAh callback
-  $data = tripal_pub_theme_node_form_properties($form);
-
-  // bind javascript events to the new objects that will be returned
-  // so that AHAH enabled elements will work.
-  $settings = tripal_core_ahah_bind_events();
-
-  // return the updated JSON
-  drupal_json(
-  array(
-      'status'   => $status, 
-      'data'     => $data,
-      'settings' => $settings,
-  )
-  );
-}
-/*
- *
- */
-function tripal_pub_property_get_description() {
-  $new_id = $_POST['new_id'];
-
-  $values = array('cvterm_id' => $new_id);
-  $cvterm = tripal_core_chado_select('cvterm', array('definition'), $values);
-
-  $description = '&nbsp;';
-  if ($cvterm[0]->definition) {
-    $description = $cvterm[0]->definition;
-  }
-  drupal_json(
-  array(
-      'status' => TRUE,
-      'data'   => '<div id="tripal-pub-new_value-desc">' . $description . '</div>',
-  )
-  );
-}

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

@@ -260,7 +260,7 @@ function tripal_pub_set_pub_url($node, $pub_id) {
   $url_alias = "pub/$pub_id";
 
   // remove any previous alias
-  db_query("DELETE FROM {url_alias} WHERE src = :src", array(':src' => $node_url));
+  db_query("DELETE FROM {url_alias} WHERE source = :source", array(':source' => $node_url));
   // add the new alias
   $path_alias = array("source" => $node_url, "alias" => $url_alias);
   path_save($path_alias);

+ 0 - 161
tripal_pub/theme/node--chado-pub.tpl.php

@@ -1,161 +0,0 @@
-<?php
-// Purpose: This template provides the layout of the pub node (page)
-//   using the same templates used for the various pub 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
-
-$pub  = $variables['node']->pub;
-
-// 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']['pub']) {
-  $no_sidebar = 1;
-}
-
-if ($teaser) { 
-  print theme('tripal_pub_teaser',$node); 
-} 
-else { ?>
-
-<script type="text/javascript">
-// hide the node title. It is not informative to the viewer
-$(".title").hide();
-   
-(function ($) {
-  Drupal.behaviors.pubBehavior = {
-    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_pub_toc_list').append('<li><a href="#'+id+'" class="tripal_pub_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_pub_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_pub_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_pub-"+block[1]+"-box").show();
-      } else {
-         $("#tripal_pub-base-box").show();
-      }
-
-      $("#tripal_pub_toc").height($("#tripal_pub-base-box").parent().height());
-    }     
-  };
-})(jQuery);
-</script>
-
-<div id="tripal_pub_details" class="tripal_details">
-
-   <!-- Basic Details Theme -->   
-   <?php print theme('tripal_pub_base', $node); ?>
-   
-   <!-- Properties Theme -->
-   <?php print theme('tripal_pub_properties', $node); ?>
-   
-   <!-- Authors Theme -->
-   <?php print theme('tripal_pub_authors', $node); ?>   
-   
-   <!-- References Theme -->
-   <?php print theme('tripal_pub_references', $node); ?>
-        
-   <!-- Relationships Theme -->
-   <?php print theme('tripal_pub_relationships', $node); ?>
-
-   <!-- FeatureMaps Theme -->
-   <?php print theme('tripal_pub_featuremaps', $node); ?>
-
-   <!-- Features Theme -->
-   <?php print theme('tripal_pub_features', $node); ?>
-
-   <!-- Libraries Theme -->
-   <?php print theme('tripal_pub_libraries', $node); ?>
-
-   <!-- Projects Theme -->
-   <?php print theme('tripal_pub_projects', $node); ?>
-
-   <!-- Stocks Theme -->
-   <?php print theme('tripal_pub_stocks', $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_pub-resource_<?php print $i?>-box" class="tripal_pub-info-box tripal-info-box">
-         <div class="tripal_pub-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_pub_toc" class="tripal_toc">
-   <div id="tripal_pub_toc_title" class="tripal_toc_title">Resources</div>
-   <ul id="tripal_pub_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 } ?>

+ 137 - 56
tripal_pub/theme/tripal_pub/tripal_pub_base.tpl.php

@@ -1,5 +1,4 @@
 <?php
-$node = $variables['node'];
 $pub = $variables['node']->pub;
 
 // expand the title
@@ -25,6 +24,10 @@ $values = array(
 );
 $abstract = tripal_core_generate_chado_var('pubprop', $values); 
 $abstract = tripal_core_expand_chado_vars($abstract, 'field', 'pubprop.value');
+$abstract_text = 'N/A';
+if ($abstract) {
+  $abstract_text = htmlspecialchars($abstract->value);
+}
 
 // get the author list
 $values = array(
@@ -35,10 +38,15 @@ $values = array(
 );
 $authors = tripal_core_generate_chado_var('pubprop', $values); 
 $authors = tripal_core_expand_chado_vars($authors, 'field', 'pubprop.value');
+$authors_list = 'N/A';
+if ($authors) {
+  $authors_list = $authors->value;
+} 
 
 // get the first database cross-reference with a url
 $options = array('return_array' => 1);
 $pub = tripal_core_expand_chado_vars($pub, 'table', 'pub_dbxref', $options);
+$dbxref = NULL;
 if ($pub->pub_dbxref) { 
   foreach ($pub->pub_dbxref as $index => $pub_dbxref) {
     if ($pub_dbxref->dbxref_id->db_id->urlprefix) {
@@ -58,9 +66,11 @@ $values = array(
 $options = array('return_array' => 1);
 $urls = tripal_core_generate_chado_var('pubprop', $values, $options); 
 $urls = tripal_core_expand_chado_vars($urls, 'field', 'pubprop.value');
-$url = $urls[0]->value;
+$url = '';
+if (count($urls) > 0) {
+  $url = $urls[0]->value; 
+}?>
 
-?>
 <div id="tripal_pub-base-box" class="tripal_pub-info-box tripal-info-box">
   <div class="tripal_pub-info-box-title tripal-info-box-title">Publication Details</div>
   <!-- <div class="tripal_pub-info-box-desc tripal-info-box-desc"></div> -->
@@ -78,58 +88,129 @@ $url = $urls[0]->value;
   if (file_exists($inc_path)) {
     require_once "pub_types/$inc_name";  
   } 
-  else { ?>
-    <table id="tripal_pub-table-base" class="tripal_pub-table tripal-table tripal-table-vert">
-      <tr class="tripal_pub-table-even-row tripal-table-even-row">
-        <th>Title</th>
-        <td><?php
-          if ($url) {
-            print l(htmlspecialchars($pub->title), $url, array('attributes' => array('target' => '_blank')));          
-          }
-          elseif ($dbxref->db_id->urlprefix) { 
-            print l(htmlspecialchars($pub->title), $dbxref->db_id->urlprefix . $dbxref->accession, array('attributes' => array('target' => '_blank')));             
-          } 
-          else {
-            print htmlspecialchars($pub->title); 
-          }?>
-        </td>
-      </tr>
-      <tr class="tripal_pub-table-odd-row tripal-table-odd-row">
-        <th>Authors</th>
-        <td><?php print $authors->value ? $authors->value : 'N/A'; ?></td>
-      </tr>
-      <tr class="tripal_pub-table-even-row tripal-table-even-row">
-        <th>Type</th>
-        <td><?php print $pub->type_id->name; ?></td>
-      </tr>
-      <tr class="tripal_pub-table-odd-row tripal-table-odd-row">
-        <th nowrap>Media Title</th>
-        <td><?php print $pub->series_name; ?></td>
-      </tr>
-      <tr class="tripal_pub-table-even-row tripal-table-even-row">
-        <th>Volume</th>
-        <td><?php print $pub->volume ? $pub->volume : 'N/A'; ?></td>
-      </tr>
-      <tr class="tripal_pub-table-odd-row tripal-table-odd-row">
-        <th>Issue</th>
-        <td><?php print $pub->issue ? $pub->issue : 'N/A'; ?></td>
-      </tr>
-      <tr class="tripal_pub-table-even-row tripal-table-even-row">    
-        <th>Year</th>
-        <td><?php print $pub->pyear; ?></td>
-      </tr>
-      <tr class="tripal_pub-table-odd-row tripal-table-odd-row">
-        <th>Page(s)</th>
-        <td><?php print $pub->pages ? $pub->pages : 'N/A'; ?></td>
-      </tr>
-      <tr class="tripal_pub-table-even-row tripal-table-even-row">
-        <th>Citation</th>
-        <td><?php print htmlspecialchars($citation->value); ?></td>
-      </tr>
-      <tr class="tripal_pub-table-odd-row tripal-table-odd-row">
-        <th>Abstract</th>
-        <td style="text-align:justify;"><?php print htmlspecialchars($abstract->value) ? $abstract->value : 'N/A'; ?></td>
-      </tr>
-    </table> <?php
+  else { 
+    // 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();
+    
+    // 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();
+  
+    // Title row
+    $title = '';
+    if ($url) {
+      $title =  l(htmlspecialchars($pub->title), $url, array('attributes' => array('target' => '_blank')));
+    }
+    elseif ($dbxref and $dbxref->db_id->urlprefix) {
+      $title =  l(htmlspecialchars($pub->title), $dbxref->db_id->urlprefix . $dbxref->accession, array('attributes' => array('target' => '_blank')));
+    }
+    else {
+      $title =  htmlspecialchars($pub->title);
+    }
+    $rows[] = array(
+      array(
+        'data' => 'Title',
+        'header' => TRUE
+      ),
+      $title,
+    );
+    // Authors row
+    $rows[] = array(
+      array(
+        'data' => 'Authors',
+        'header' => TRUE
+      ),
+      $authors_list,
+    );
+    // Type row
+    $rows[] = array(
+      array(
+        'data' => 'Type',
+        'header' => TRUE
+      ),
+      $pub->type_id->name,
+    );
+    // Media Title
+    $rows[] = array(
+      array(
+        'data' => 'Type',
+        'header' => TRUE
+      ),
+      $pub->series_name,
+    );
+    // Volume
+    $rows[] = array(
+      array(
+        'data' => 'Volume',
+        'header' => TRUE
+      ),
+      $pub->volume ? $pub->volume : 'N/A',
+    );
+    // Issue
+    $rows[] = array(
+      array(
+        'data' => 'Issue',
+        'header' => TRUE
+      ),
+      $pub->issue ? $pub->issue : 'N/A'
+    );
+    // Year
+    $rows[] = array(
+      array(
+        'data' => 'Year',
+        'header' => TRUE
+      ),
+      $pub->pyear
+    );
+    // Pages
+    $rows[] = array(
+      array(
+        'data' => 'Page(s)',
+        'header' => TRUE
+      ),
+      $pub->pages ? $pub->pages : 'N/A'
+    );
+    // Citation row
+    $rows[] = array(
+      array(
+        'data' => 'Citation',
+        'header' => TRUE
+      ),
+      htmlspecialchars($citation->value)
+    );
+    // Abstract
+    $rows[] = array(
+      array(
+        'data' => 'Abstract',
+        'header' => TRUE
+      ),
+      $abstract_text
+    );
+
+    // 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_pub-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);
   } ?>
 </div>

+ 135 - 126
tripal_pub/tripal_pub.module

@@ -207,66 +207,73 @@ function tripal_pub_menu() {
  *   An array of themeing functions to register
  *
  */
-function tripal_pub_theme() {
-  $theme_path = drupal_get_path('module', 'tripal_pub') . '/theme';
+function tripal_pub_theme($existing, $type, $theme, $path) {
+  $core_path = drupal_get_path('module', 'tripal_core');
+  
   $items = array(
+    'node__chado_pub' => array(
+      'template' => 'node--chado-generic',
+      'render element' => 'node',
+      'base hook' => 'node',
+      'path' => "$core_path/theme",
+    ),
     // node templates
     'tripal_pub_base' => array(
       'arguments' => array('node' => NULL),
-      'template' => 'tripal_project_base',
-      'path' => "$theme_path/tripal_pub",
+      'template' => 'tripal_pub_base',
+      'path' => "$path/theme/tripal_pub",
     ),
     'tripal_pub_properties' => array(
       'arguments' => array('node' => NULL),
-      'template' => 'tripal_project_base',
-      'path' => "$theme_path/tripal_pub",
+      'template' => 'tripal_pub_properties',
+      'path' => "$path/theme/tripal_pub",
     ),
     'tripal_pub_authors' => array(
       'arguments' => array('node' => NULL),
-      'template' => 'tripal_project_base',
-      'path' => "$theme_path/tripal_pub",
+      'template' => 'tripal_pub_authors',
+      'path' => "$path/theme/tripal_pub",
     ),
     'tripal_pub_references' => array(
       'arguments' => array('node' => NULL),
-      'template' => 'tripal_project_base',
-      'path' => "$theme_path/tripal_pub",
+      'template' => 'tripal_pub_references',
+      'path' => "$path/theme/tripal_pub",
     ),
     'tripal_pub_relationships' => array(
       'arguments' => array('node' => NULL),
-      'template' => 'tripal_project_base',
-      'path' => "$theme_path/tripal_pub",
+      'template' => 'tripal_pub_relationships',
+      'path' => "$path/theme/tripal_pub",
     ),
     'tripal_pub_featuremaps' => array(
       'arguments' => array('node' => NULL),
-      'template' => 'tripal_project_base',
-      'path' => "$theme_path/tripal_pub",
+      'template' => 'tripal_pub_featuremaps',
+      'path' => "$path/theme/tripal_pub",
     ),
     'tripal_pub_features' => array(
       'arguments' => array('node' => NULL),
-      'template' => 'tripal_project_base',
-      'path' => "$theme_path/tripal_pub",
+      'template' => 'tripal_pub_features',
+      'path' => "$path/theme/tripal_pub",
     ),
     'tripal_pub_libraries' => array(
       'arguments' => array('node' => NULL),
-      'template' => 'tripal_project_base',
-      'path' => "$theme_path/tripal_pub",
+      'template' => 'tripal_pub_libraries',
+      'path' => "$path/theme/tripal_pub",
     ),
     'tripal_pub_projects' => array(
       'arguments' => array('node' => NULL),
-      'template' => 'tripal_project_base',
-      'path' => "$theme_path/tripal_pub",
+      'template' => 'tripal_pub_projects',
+      'path' => "$path/theme/tripal_pub",
     ),
     'tripal_pub_stocks' => array(
       'arguments' => array('node' => NULL),
-      'template' => 'tripal_project_base',
-      'path' => "$theme_path/tripal_pub",
+      'template' => 'tripal_pub_stocks',
+      'path' => "$path/theme/tripal_pub",
     ),
 
     // instructions page for the pub module
     'tripal_pub_help' => array(
       'template' => 'tripal_pub_help',
       'arguments' =>  array(NULL),
-      'path' => $theme_path,
+      'path' => $path,
     ),
 
     // themed forms
@@ -276,9 +283,6 @@ function tripal_pub_theme() {
     'tripal_pub_search_form' => array(
       'arguments' => array('form'),
     ),
-    'chado_pub_node_form' => array(
-      'arguments' => array('form'),
-    ),
   );
 
   return $items;
@@ -402,20 +406,27 @@ function chado_pub_node_access($node, $op, $account ) {
  */
 function chado_pub_insert($node) {
 
-	// we need an array suitable for the tripal_pub_create_citation() function
-	// to automatically generate a citation if a uniquename doesn't already exist
-	$pub_arr = array();
-
-  // if a pub_id already exists for this node then it already exists in Chado and
-  // we get here because we are syncing the node.  Therefore, we can skip the insert
-  // but we always want to set the URL path alias to be the Chado pub ID
-  if ($node->pub_id) {
-    $pub['pub_id'] = $node->pub_id;
-  }
-  else {
+  $title        = trim($node->pubtitle);
+  $pyear        = trim($node->pyear);
+  $uniquename   = trim($node->uniquename);
+  $is_obsolete  = $node->is_obsolete;
+  $type_id      = $node->type_id;
+  
+  // we need an array suitable for the tripal_pub_create_citation() function
+  // to automatically generate a citation if a uniquename doesn't already exist
+  $pub_arr = array();
+  
+  // if there is an pub_id in the $node object then this must be a sync so
+  // we can skip adding the pub as it is already there, although
+  // we do need to proceed with the rest of the insert
+  if (!property_exists($node, 'pub_id')) {
+  
     $properties = array(); // stores all of the properties we need to add
     $cross_refs = array(); // stores any cross references for this publication
 
+    // get the properties from the form
+    $properties = tripal_core_properties_form_retreive($node, 'tripal_pub');
+    
     // get the list of properties for easy lookup (without doing lots of database queries
     $properties_list = array();
     $sql = "
@@ -439,32 +450,22 @@ function chado_pub_insert($node) {
       }
     }
 
-    // get the properties that should be added. Properties are in one of two forms:
-    //  1) prop_value-[type id]-[index]
-    //  2) new_value-[type id]-[index]
-    //  3) new_id, new_value
-    foreach ($node as $name => $value) {
-      if (preg_match('/^new_value-(\d+)-(\d+)/', $name, $matches)) {
-        $type_id = $matches[1];
-        $index = $matches[2];
-        $name = $properties_list[$type_id];
-        $properties[$name][$index] = trim($value);
-      }
-    }
-    if ($node->new_id and $node->new_value) {
-      $type_id = $node->new_id;
-      $index = count($properties[$name]);
-      $name = $properties_list[$type_id];
-      $properties[$name][$index] = trim($node->new_value);
-    }
-
     // iterate through all of the properties and remove those that really are
     // part of the pub table fields
+    $volume = '';
+    $volumetitle = '';
+    $issue = '';
+    $pages = '';
+    $publisher = '';
+    $series_name = '';
+    $pubplace = '';
+    $miniref = '';
+    $cross_refs = array();
     foreach ($properties as $name => $element) {
       $value = trim($element[0]);
 
-    	// populate our $pub_array for building a citation
-    	$pub_arr[$name] = $value;
+      // populate our $pub_array for building a citation
+      $pub_arr[$name] = $value;
 
       // remove properties that are stored in the pub table
       if ($name == "Volume") {
@@ -488,7 +489,7 @@ function chado_pub_insert($node) {
         unset($properties[$name]);
       }
       elseif ($name == "Journal Name" or $name == "Conference Name") {
-        $node->series_name = $value;
+        $series_name = $value;
         unset($properties[$name]);
       }
       elseif ($name == "Journal Country" or $name == "Published Location") {
@@ -503,8 +504,8 @@ function chado_pub_insert($node) {
     }
     // generate a citation for this pub if one doesn't already exist
     if (!$node->uniquename and array_key_exists('Citation', $properties)) {
-    	$pub_type = tripal_cv_get_cvterm_by_id($node->type_id);
-    	$pub_arr['Title'] = $node->pubtitle;
+      $pub_type = tripal_cv_get_cvterm_by_id($node->type_id);
+      $pub_arr['Title'] = $node->pubtitle;
       $pub_arr['Publication Type'][0] = $pub_type->name;
       $pub_arr['Year'] = $node->pyear;
       $node->uniquename = tripal_pub_create_citation($pub_arr);
@@ -513,12 +514,12 @@ function chado_pub_insert($node) {
 
     // insert the pub record
     $values = array(
-      'title'       => trim($node->pubtitle),
-      'series_name' => substr(trim($node->series_name), 0, 255),
-      'type_id'     => trim($node->type_id),
-      'pyear'       => trim($node->pyear),
+      'title'       => $node->pubtitle,
+      'series_name' => substr($series_name, 0, 255),
+      'type_id'     => $node->type_id,
+      'pyear'       => $node->pyear,
       'is_obsolete' => $node->is_obsolete ? 'true' : 'false',
-      'uniquename'  => trim($node->uniquename),
+      'uniquename'  => $node->uniquename,
       'volumetitle' => $volumetitle,
       'volume'      => $volume,
       'issue'       => $issue,
@@ -533,6 +534,7 @@ function chado_pub_insert($node) {
       watchdog('tripal_pub', "Error inserting publication", array(), WATCHDOG_ERROR);
       return;
     }
+    $pub_id = $pub['pub_id'];
 
     // now add in the properties
     foreach ($properties as $property => $elements) {
@@ -556,24 +558,22 @@ function chado_pub_insert($node) {
         array('%ref' => $ref), WATCHDOG_ERROR);
       }
     }
-  } // if ($node->pub_id) {} else
-
-  if ($pub) {
-    // make sure the entry for this feature doesn't already exist in the chado_pub table
-    // if it doesn't exist then we want to add it.
-    $pub_id = chado_get_id_for_node('pub', $node->nid) ;
-    if (!$pub_id) {
-      // next add the item to the drupal table
-      $sql = "INSERT INTO {chado_pub} (nid, vid, pub_id) ".
-             "VALUES (:nid, :vid, :pub_id)";
-      db_query($sql, array(':nid' => $node->nid, ':vid' => $node->vid, ':pub_id' => $pub['pub_id']));
-    }
   }
   else {
-    drupal_set_message(t('Unable to add publication.', 'warning'));
-    watchdog('tripal_pub', 'Insert publication: Unable to create pub where values: %values',
-      array('%values' => print_r($values, TRUE)), WATCHDOG_WARNING);
+    $pub_id = $node->pub_id;
   }
+
+  // Make sure the entry for this pub doesn't already exist in the
+  // chado_pub table if it doesn't exist then we want to add it.
+  $check_org_id = chado_get_id_for_node('pub', $node->nid);
+  if (!$check_org_id) {
+    $record = new stdClass();
+    $record->nid = $node->nid;
+    $record->vid = $node->vid;
+    $record->pub_id = $pub_id;
+    drupal_write_record('chado_pub', $record);
+  }
+  
 }
 
 /*
@@ -590,10 +590,11 @@ function chado_pub_insert($node) {
  * @ingroup tripal_pub
  */
 function chado_pub_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.
-  }
+  $title        = trim($node->pubtitle);
+  $pyear        = trim($node->pyear);
+  $uniquename   = trim($node->uniquename);
+  $is_obsolete  = $node->is_obsolete;
+  $type_id      = $node->type_id;
 
   // we need an array suitable for the tripal_pub_create_citation() function
   // to automatically generate a citation if a uniquename doesn't already exist
@@ -605,6 +606,9 @@ function chado_pub_update($node) {
   $properties = array(); // stores all of the properties we need to add
   $cross_refs = array(); // stores any cross references for this publication
 
+  // get the properties from the form
+  $properties = tripal_core_properties_form_retreive($node, 'tripal_pub');
+  
   // get the list of properties for easy lookup (without doing lots of database queries
   $properties_list = array();
   $sql = "
@@ -629,37 +633,20 @@ function chado_pub_update($node) {
     }
   }
 
-  // get the properties that should be added. Properties are in one of three forms:
-  //  1) prop_value-[type id]-[index]
-  //  2) new_value-[type id]-[index]
-  //  3) new_id, new_value
-  //  dpm($node);
-  foreach ($node as $key => $value) {
-    if (preg_match('/^prop_value-(\d+)-(\d+)/', $key, $matches)) {
-      $type_id = $matches[1];
-      $index = $matches[2];
-      $name = $properties_list[$type_id];
-      $properties[$name][$index] = trim($value);
-    }
-    if (preg_match('/^new_value-(\d+)-(\d+)/', $key, $matches)) {
-      $type_id = $matches[1];
-      $index = $matches[2];
-      $name = $properties_list[$type_id];
-      $properties[$name][$index] = trim($value);
-    }
-  }
-  if ($node->new_id and $node->new_value) {
-    $type_id = $node->new_id;
-    $name = $properties_list[$type_id];
-    $index = count($properties[$name]);
-    $properties[$name][$index] = trim($node->new_value);
-  }
-
   // iterate through all of the properties and remove those that really are
   // part of the pub table fields
+  $volume = '';
+  $volumetitle = '';
+  $issue = '';
+  $pages = '';
+  $publisher = '';
+  $series_name = '';
+  $pubplace = '';
+  $miniref = '';
+  $cross_refs = array();
   foreach ($properties as $name => $element) {
     foreach ($element as $index => $value) {
-    	// populate our $pub_array for building a citation
+      // populate our $pub_array for building a citation
       $pub_arr[$name] = $value;
 
       // remove properties that are stored in the pub table
@@ -684,7 +671,7 @@ function chado_pub_update($node) {
         unset($properties[$name]);
       }
       elseif ($name == "Journal Name" or $name == "Conference Name") {
-        $node->series_name = $value;
+        $series_name = $value;
         unset($properties[$name]);
       }
       elseif ($name == "Journal Country" or $name == "Published Location") {
@@ -713,19 +700,19 @@ function chado_pub_update($node) {
     'pub_id' => $pub_id,
   );
   $values = array(
-    'title'       => trim($node->pubtitle),
-    'type_id'     => trim($node->type_id),
-    'pyear'       => trim($node->pyear),
+    'title'       => $node->pubtitle,
+    'type_id'     => $node->type_id,
+    'pyear'       => $node->pyear,
     'is_obsolete' => $node->is_obsolete ? 'true' : 'false',
-    'uniquename'  => trim($node->uniquename),
-    'series_name' => trim($node->series_name),
+    'uniquename'  => $node->uniquename,
+    'series_name' => substr($series_name, 0, 255),
     'volumetitle' => $volumetitle,
     'volume'      => $volume,
     'issue'       => $issue,
     'pages'       => $pages,
-    'miniref'     => $miniref,
-    'publisher'   => $publisher,
-    'pubplace'    => $pubplace,
+    'miniref'     => substr($miniref, 0, 255),
+    'publisher'   => substr($publisher, 0, 255),
+    'pubplace'    => substr($pubplace, 0, 255),
   );
   $status = tripal_core_chado_update('pub', $match, $values);
   if (!$status) {
@@ -790,7 +777,7 @@ function chado_pub_load($nodes) {
     
     // set the URL path
     $nodes[$nid]->path = "pub/$pub_id";
-    $nodes[$nid]->pub = $pug;
+    $nodes[$nid]->pub = $pub;
   }
 }
 
@@ -922,7 +909,27 @@ 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_base'] = array(
+          '#value' => theme('tripal_pub_base', array('node' => $node)),
+        );
+      }
+      if ($view_mode == 'teaser') {
+        $node->content['tripal_pub_teaser'] = array(
+          '#value' => theme('tripal_pub_teaser', array('node' => $node)),
+        );
+      }
+      break;
+  }
+}
 /**
  *
  * @param $node
@@ -953,9 +960,11 @@ function tripal_pub_node_load($nodes, $types) {
   // 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))) {
-    if (!$node->path) {
-      $pub_id = chado_get_id_for_node('pub', $node->nid);
-      $path = tripal_pub_set_pub_url($node, $pub_id);
+    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);
+      }
     }
   }
 }

+ 1 - 1
tripal_stock/tripal_stock.module

@@ -610,7 +610,7 @@ function chado_stock_form($node, $form_state) {
  *
  * @ingroup tripal_stock
  */
-function chado_stock_validate($node, &$form) {
+function chado_stock_validate($node, $node, $form, &$form_state) {
 
   $int_in_chado_sql = "SELECT count(*) as count FROM {:table} WHERE :column = :value";
   $string_in_chado_sql = "SELECT count(*) as count FROM {:table} WHERE :column = :value";