Browse Source

Merge branch '7.x-2.x' of git.drupal.org:sandbox/spficklin/1337878 into 7.x-2.x

Lacey Sanderson 11 years ago
parent
commit
2d7cb2ab22
44 changed files with 2559 additions and 2401 deletions
  1. 38 36
      tripal_analysis/includes/tripal_analysis.form.inc
  2. 74 123
      tripal_analysis/includes/tripal_analysis.sync.inc
  3. 2 2
      tripal_analysis/theme/tripal_analysis/tripal_analysis_base.tpl.php
  4. 34 23
      tripal_contact/includes/contact_sync.inc
  5. 1 1
      tripal_contact/includes/tripal_contact.admin.inc
  6. 27 25
      tripal_contact/includes/tripal_contact.form.inc
  7. 13 2
      tripal_contact/theme/tripal_contact/tripal_contact_base.tpl.php
  8. 0 6
      tripal_contact/theme/tripal_contact_help.tpl.php
  9. 11 8
      tripal_core/api/tripal_core_chado.api.inc
  10. 63 24
      tripal_core/api/tripal_core_properties.api.inc
  11. 4 14
      tripal_cv/api/tripal_cv.api.inc
  12. 35 32
      tripal_feature/includes/tripal_feature.form.inc
  13. 4 5
      tripal_feature/includes/tripal_feature.sync_features.inc
  14. 2 2
      tripal_feature/theme/tripal_feature/tripal_feature_relationships.tpl.php
  15. 0 10
      tripal_feature/theme/tripal_feature_help.tpl.php
  16. 1 1
      tripal_feature/theme/tripal_organism/tripal_organism_feature_browser.tpl.php
  17. 1 1
      tripal_featuremap/includes/tripal_featuremap.form.inc
  18. 1 1
      tripal_library/tripal_library.module
  19. 4 4
      tripal_organism/includes/organism_sync.inc
  20. 5 2
      tripal_organism/includes/tripal_organism.admin.inc
  21. 38 23
      tripal_organism/tripal_organism.module
  22. 1 1
      tripal_project/tripal_project.module
  23. 246 684
      tripal_pub/includes/pub_form.inc
  24. 291 246
      tripal_pub/includes/pub_importers.inc
  25. 89 59
      tripal_pub/includes/pub_sync.inc
  26. 63 142
      tripal_pub/includes/tripal_pub.admin.inc
  27. 0 161
      tripal_pub/theme/node--chado-pub.tpl.php
  28. 140 52
      tripal_pub/theme/tripal_pub/pub_types/conference_proceedings.inc
  29. 140 52
      tripal_pub/theme/tripal_pub/pub_types/journal_article.inc
  30. 116 36
      tripal_pub/theme/tripal_pub/pub_types/patent.inc
  31. 76 58
      tripal_pub/theme/tripal_pub/tripal_pub_authors.tpl.php
  32. 178 62
      tripal_pub/theme/tripal_pub/tripal_pub_base.tpl.php
  33. 72 36
      tripal_pub/theme/tripal_pub/tripal_pub_featuremaps.tpl.php
  34. 74 38
      tripal_pub/theme/tripal_pub/tripal_pub_features.tpl.php
  35. 77 40
      tripal_pub/theme/tripal_pub/tripal_pub_libraries.tpl.php
  36. 76 36
      tripal_pub/theme/tripal_pub/tripal_pub_projects.tpl.php
  37. 59 49
      tripal_pub/theme/tripal_pub/tripal_pub_properties.tpl.php
  38. 54 38
      tripal_pub/theme/tripal_pub/tripal_pub_references.tpl.php
  39. 138 69
      tripal_pub/theme/tripal_pub/tripal_pub_relationships.tpl.php
  40. 74 38
      tripal_pub/theme/tripal_pub/tripal_pub_stocks.tpl.php
  41. 41 0
      tripal_pub/theme/tripal_pub/tripal_pub_teaser.tpl.php
  42. 0 9
      tripal_pub/theme/tripal_pub_help.tpl.php
  43. 195 149
      tripal_pub/tripal_pub.module
  44. 1 1
      tripal_stock/tripal_stock.module

+ 38 - 36
tripal_analysis/includes/tripal_analysis.form.inc

@@ -202,9 +202,10 @@ function chado_analysis_form($node, &$form_state) {
   }
   
   $exclude = array();
+  $include = array();
   $instructions = t('To add additional properties to the drop down. ' . l("Add terms to the analysis_property vocabulary", "admin/tripal/chado/tripal_cv/cvterm/add") . ".");
   tripal_core_properties_form($form, $form_state, 'analysisprop', 'analysis_id', 'analysis_property',
-    $properties, $analysis_id, $exclude, $instructions);
+    $properties, $analysis_id, $exclude, $include, $instructions, 'Properties');
 
   return $form;
 }
@@ -213,9 +214,9 @@ 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);
+  tripal_analysis_validate($node, $form, $form_state);
 }
 
 /**
@@ -226,7 +227,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 +238,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 +293,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;
     }
   }
 }

+ 74 - 123
tripal_analysis/includes/tripal_analysis.sync.inc

@@ -6,15 +6,83 @@
 function tripal_analysis_sync_form () {
   $form = array();
   
-  get_tripal_analysis_admin_form_sync_set($form);
-  get_tripal_analysis_admin_form_cleanup_set($form);
+  // define the fieldsets
+  $form['sync'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Sync Analyses')
+  );
+
+  // get the list of analyses
+  $sql = "SELECT * FROM {analysis} ORDER BY name";
+  $ana_rset = chado_query($sql);
+
+  // if we've added any analyses to the list that can be synced
+  // then we want to build the form components to allow the user
+  // to select one or all of them.  Otherwise, just present
+  // a message stating that all analyses are currently synced.
+  $ana_boxes = array();
+  $added = 0;
+  while ($analysis = $ana_rset->fetchObject()) {
+    // check to see if the analysis is already present as a node in drupal.
+    // if so, then skip it.
+    $sql = "SELECT * FROM {chado_analysis} WHERE analysis_id = :analysis_id";
+    if (!db_query($sql, array(':analysis_id' => $analysis->analysis_id))->fetchObject()) {
+      $ana_boxes[$analysis->analysis_id] = "$analysis->name";
+      $added++;
+    }
+  }
+
+  // if we have analyses we need to add to the checkbox then
+  // build that form element
+  if ($added > 0) {
+    $ana_boxes['all'] = "All analyses";
+
+    $form['sync']['analyses'] = array(
+      '#title'       => t('Available analyses'),
+      '#type'        => t('checkboxes'),
+      '#description' => t("Check the analyses you want to sync.  Drupal " .
+          "content will be created for each of the analyses listed above. " .
+          "Select 'All analyses' to sync all of them."),
+      '#required'    => FALSE,
+      '#prefix'      => '<div id="ana_boxes">',
+      '#suffix'      => '</div>',
+      '#options'     => $ana_boxes,
+    );
+    $form['sync']['button'] = array(
+      '#type' => 'submit',
+      '#value' => t('Submit Sync Job')
+    );
+  }
+  // we don't have any analyses to select from
+  else {
+    $form['sync']['value'] = array(
+      '#markup' => t('All analyses in Chado are currently synced with Drupal.')
+    );
+  }
+  
+  $form['cleanup'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Clean Up')
+  );
+  $form['cleanup']['description'] = array(
+    '#markup' => t("With Drupal and chado residing in different databases " .
+        "it is possible that nodes in Drupal and analyses in Chado become " .
+        "\"orphaned\".  This can occur if an analysis node in Drupal is " .
+        "deleted but the corresponding chado analysis is not and/or vice " .
+        "versa. Click the button below to resolve these discrepancies."),
+    '#weight' => 1,
+  );
+  $form['cleanup']['button'] = array(
+    '#type' => 'submit',
+    '#value' => t('Clean up orphaned analyses'),
+    '#weight' => 2,
+  );
   
   return $form;
 }
 
 /**
  * Validate the administrative form
- * @todo Stephen: Why is validate used rather then submit?
  *
  * @param $form
  *   The form API array of the form to be validated
@@ -65,121 +133,6 @@ function tripal_analysis_sync_form_submit($form, &$form_state) {
     'tripal_analyses_cleanup', $job_args, $user->uid);
   }
 }
-/**
- * The "Clean-up orphaned analysis & nodes" Form
- *
- * @param $form
- *  The administrative form as it is currently
- *
- * @return
- *  A form API array describing an administrative form
- *
- * @ingroup tripal_analysis
- */
-function get_tripal_analysis_admin_form_cleanup_set(&$form) {
-  $form['cleanup'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Clean Up')
-  );
-  $form['cleanup']['description'] = array(
-    '#markup' => t("With Drupal and chado residing in different databases " .
-        "it is possible that nodes in Drupal and analyses in Chado become " .
-        "\"orphaned\".  This can occur if an analysis node in Drupal is " .
-        "deleted but the corresponding chado analysis is not and/or vice " .
-        "versa. Click the button below to resolve these discrepancies."),
-    '#weight' => 1,
-  );
-  $form['cleanup']['button'] = array(
-    '#type' => 'submit',
-    '#value' => t('Clean up orphaned analyses'),
-    '#weight' => 2,
-  );
-}
-
-/**
- * The "sync Analysis in chado with drupal" form
- *
- * @param $form
- *  The administrative form as it is currently
- *
- * @return
- *  A form API array describing an administrative form
- *
- * @ingroup tripal_analysis
- */
-function get_tripal_analysis_admin_form_sync_set(&$form) {
-  // define the fieldsets
-  $form['sync'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Sync Analyses')
-  );
-
-  // before proceeding check to see if we have any
-  // currently processing jobs. If so, we don't want
-  // to give the opportunity to sync analyses
-  $active_jobs = FALSE;
-  if (tripal_get_module_active_jobs('tripal_analysis')) {
-    $active_jobs = TRUE;
-  }
-
-  if (!$active_jobs) {
-
-    // get the list of analyses
-    $sql = "SELECT * FROM {analysis} ORDER BY name";
-    $ana_rset = chado_query($sql);
-
-    // if we've added any analyses to the list that can be synced
-    // then we want to build the form components to allow the user
-    // to select one or all of them.  Otherwise, just present
-    // a message stating that all analyses are currently synced.
-    $ana_boxes = array();
-    $added = 0;
-    while ($analysis = $ana_rset->fetchObject()) {
-      // check to see if the analysis is already present as a node in drupal.
-      // if so, then skip it.
-      $sql = "SELECT * FROM {chado_analysis} WHERE analysis_id = :analysis_id";
-      if (!db_query($sql, array(':analysis_id' => $analysis->analysis_id))->fetchObject()) {
-        $ana_boxes[$analysis->analysis_id] = "$analysis->name";
-        $added++;
-      }
-    }
-
-    // if we have analyses we need to add to the checkbox then
-    // build that form element
-    if ($added > 0) {
-      $ana_boxes['all'] = "All analyses";
-
-      $form['sync']['analyses'] = array(
-        '#title'       => t('Available analyses'),
-        '#type'        => t('checkboxes'),
-        '#description' => t("Check the analyses you want to sync.  Drupal " .
-            "content will be created for each of the analyses listed above. " .
-            "Select 'All analyses' to sync all of them."),
-        '#required'    => FALSE,
-        '#prefix'      => '<div id="ana_boxes">',
-        '#suffix'      => '</div>',
-        '#options'     => $ana_boxes,
-      );
-      $form['sync']['button'] = array(
-        '#type' => 'submit',
-        '#value' => t('Submit Sync Job')
-      );
-    }
-    // we don't have any analyses to select from
-    else {
-      $form['sync']['value'] = array(
-        '#markup' => t('All analyses in Chado are currently synced with Drupal.')
-      );
-    }
-  }
-  // we don't want to present a form since we have an active job running
-  else {
-    $form['sync']['value'] = array(
-      '#markup' => t('Currently, jobs exist related to chado analyses. Please check back later for analyses that can by synced once these jobs have finished.  You can view the status of pending jobs in the Tripal jobs page.')
-    );
-  }
-}
-
 /**
  * Synchronize analyses from chado to drupal
  *
@@ -244,13 +197,11 @@ function tripal_analysis_sync_analyses($analysis_id = NULL, $job_id = NULL) {
       }
       else {
         print "Failed to insert analysis $analysis->name\n";
+        watchdog('tanalysis_sync', "Unable to create analysis node. ID: %analysis_id, Name: %name.",
+         array('%analysis_id' => $analysis->analysis_id, '%name' => $analysis->name), WATCHDOG_WARNING);
       }
     }
-    else {
-      $page_content .= "Skipped $new_node->title<br />";
-    }
   }
-  return $page_content;
 }
 
 /**
@@ -267,4 +218,4 @@ function tripal_analyses_cleanup($dummy = NULL, $job_id = NULL) {
 
   return tripal_core_clean_orphaned_nodes('analysis', $job_id);
 
-}
+}

+ 2 - 2
tripal_analysis/theme/tripal_analysis/tripal_analysis_base.tpl.php

@@ -91,7 +91,7 @@ $analysis = tripal_core_expand_chado_vars($analysis,'field','analysis.descriptio
   // once we have our table array structure defined, we call Drupal's theme_table()
   // function to generate the table.
   print theme_table($table); 
-  if (property_exists($analysis, 'description')) {  
-    print $analysis->description; 
+  if (property_exists($analysis, 'description')) { ?>
+    <div style="text-align: justify"><?php print $analysis->description; ?></div> <?php  
   } ?>
 </div>

+ 34 - 23
tripal_contact/includes/contact_sync.inc

@@ -73,34 +73,45 @@ function tripal_contact_sync_contacts($job_id = NULL) {
     SELECT C.*
     FROM chado.contact C
       LEFT JOIN {chado_contact} CP ON CP.contact_id = C.contact_id
-    WHERE CP.contact_id IS NULL
+    WHERE CP.contact_id IS NULL and NOT C.name = 'null'
   ";
   $results = db_query($sql);
+  
+  // We'll use the following SQL statement for checking if the contact
+  // already exists as a drupal node.
+  $sql = "SELECT * FROM {chado_contact} WHERE contact_id = :contact_id";
 
   while ($contact = $results->fetchObject()) {
-    $new_node = new stdClass();
-    $new_node->uid = $user->uid;
-    $new_node->contact_id = $contact->contact_id;
-    $new_node->type = 'chado_contact';
-    $new_node->title = $contact->name;
-    $new_node->description = $contact->description;
-    $new_node->type_id = $contact->type_id;
-  
-    $form = array(); // dummy variable
-    $form_state = array(); // dummy variable
-    node_validate($new_node, $form, $form_state);
-    if (!form_get_errors()) {
-      $node = node_submit($new_node);
-      node_save($node);
-      if ($node->nid) {
-        print "Added contact: $new_node->title\n";
+    
+    // check if this contact already exists in the drupal database. if it
+    // does then skip this contact and go to the next one.
+    if (!db_query($sql, array(':contact_id' => $contact->contact_id))->fetchObject()) {
+    
+      $new_node = new stdClass();
+      $new_node->uid = $user->uid;
+      $new_node->contact_id = $contact->contact_id;
+      $new_node->type = 'chado_contact';
+      $new_node->title = $contact->name;
+      $new_node->description = $contact->description;
+      $new_node->type_id = $contact->type_id;
+    
+      $form = array(); // dummy variable
+      $form_state = array(); // dummy variable
+      node_validate($new_node, $form, $form_state);
+      if (!form_get_errors()) {
+        $node = node_submit($new_node);
+        node_save($node);
+        if ($node->nid) {
+          print "Added contact: $new_node->title\n";
+        }
       }
-    }
-    else {
-      print "ERROR: Unable to create " . $contact->name . "\n" . print_r($errors, TRUE) . "\n";
-      return FALSE;
-    }
-  } 
+      else {
+        watchdog('tcontact_sync', "Unable to create contact node. ID: %contact_id, Name: %name.",
+          array('%contact_id' => $contact->contact_id, '%name' => $contact->name), WATCHDOG_WARNING);      
+        
+      }
+    } 
+  }
 }
 
 /**

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

@@ -43,7 +43,7 @@ function tripal_contact_admin() {
   $form = array();
 
   $form['nothing'] = array(
-    '#markup' => t('There are currently no settings to configure. .')
+    '#markup' => t('There are currently no settings to configure.')
   );
 
   return system_settings_form($form);

+ 27 - 25
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
@@ -151,8 +151,9 @@ function chado_contact_form(&$node, $form_state) {
   }
   
   $exclude = array('contact_description');
+  $include = array();
   tripal_core_properties_form($form, $form_state, 'contactprop', 'contact_id', 'tripal_contact',
-    $properties, $contact_id, $exclude, '');
+    $properties, $contact_id, $exclude, $include, '', 'Properties');
    
   return $form;
 }
@@ -162,15 +163,24 @@ 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 (!property_exists($node,'nid')) {    
-    // CASE A: We are validating a form for updating an existing node
-    
+  // 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')) {    
     // get the existing node    
     $values = array('contact_id' => $node->contact_id);      
     $result = tripal_core_chado_select('contact', array('*'), $values);
@@ -181,29 +191,21 @@ function chado_contact_validate($node, &$form) {
       $values = array('name' => $node->title);
       $result = tripal_core_chado_select('contact', array('contact_id'), $values);
       if ($result and count($result) > 0) {
-        form_set_error('title', 'Cannot update the contact with this contact name. An contact with this name already exists.');
+        form_set_error('title', 'Cannot update the contact with this contact name. A contact with this name already exists.');
         return;
       }  
     }
   }
+  // 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. A contact with these values already exists.');
+      return;
     }
   }
 }

+ 13 - 2
tripal_contact/theme/tripal_contact/tripal_contact_base.tpl.php

@@ -34,6 +34,17 @@ $contact = $variables['node']->contact; ?>
     ),
     $contact->type_id->name,
   );
+  // allow site admins to see the contact ID
+  if (user_access('access administration pages')) {
+    // Pub ID
+    $rows[] = array(
+      array(
+        'data' => 'Contact ID',
+        'header' => TRUE
+      ),
+      $contact->contact_id
+    );
+  }
   
   // the $table array contains the headers and rows array as well as other
   // options for controlling the display of the table.  Additional
@@ -54,7 +65,7 @@ $contact = $variables['node']->contact; ?>
   // once we have our table array structure defined, we call Drupal's theme_table()
   // function to generate the table.
   print theme_table($table);
-  if (property_exists($contact, 'description')) {
-    print $contact->description;
+  if (property_exists($contact, 'description')) { ?>
+    <div style="text-align: justify"><?php print $contact->description; ?></div> <?php 
   } ?>
 </div>

+ 0 - 6
tripal_contact/theme/tripal_contact_help.tpl.php

@@ -1,9 +1,3 @@
-<h3>Tripal Contact Quick Links:</h3>
-<ul>
-  <li><a href="<?php print url('admin/tripal/tripal_contact/configuration') ?>">Contact Configuration</a></li>
-  <li><a href="<?php print url('admin/tripal/tripal_contact/sync') ?>">Sync Contacts</a></li>
-</ul>
-
 <h3>Module Description:</h3>
 <p>The Tripal Contact module is an interface for the Chado Contact module which provides information about
    people or organizations.  This module provides support for visualization of "contact" pages, editing and updating.

+ 11 - 8
tripal_core/api/tripal_core_chado.api.inc

@@ -892,7 +892,7 @@ function tripal_core_chado_delete($table, $match, $options = NULL) {
  *     should specify the number of records to return and 'element' is a
  *     unique integer to differentiate between pagers when more than one
  *     appear on a page.  The 'element' should start with zero and increment by
- *     one for each pager.  
+ *     one for each pager.    
  *
  * @return
  *  An array of results, FALSE if the query was not executed
@@ -1223,7 +1223,8 @@ function tripal_core_chado_select($table, $columns, $values, $options = NULL) {
     return array('sql' => $sql, 'args' => $args);
   }
   if (array_key_exists('limit', $pager)) {
-    $resource = chado_pager_query($sql, $args, $pager['limit'], $pager['element']);
+    $total_records = 0;
+    $resource = chado_pager_query($sql, $args, $pager['limit'], $pager['element'], NULL, $total_records);
   }
   else {
     $resource = chado_query($sql, $args);
@@ -1941,7 +1942,7 @@ function tripal_core_expand_chado_vars($object, $type, $to_expand, $table_option
   //try again becasue now we might have moved it down
   if (property_exists($object, 'expanded')) {
     $expandable_name = 'expandable_' . $type . 's';
-    if ($object->{$expandable_name}) {
+    if (property_exists($object, $expandable_name) and $object->{$expandable_name}) {
       $key_to_remove = array_search($object->expanded, $object->{$expandable_name});
       unset($object->{$expandable_name}[$key_to_remove]);
       unset($object->expanded);
@@ -2034,7 +2035,7 @@ function tripal_core_exclude_field_from_feature_by_default() {
  *   An optional integer to distinguish between multiple pagers on one page.
  * @param $count_query
  *   An SQL query used to count matching records.
- *   
+ *
  * @returns
  *   A database query result resource or FALSE if the query was not
  *   executed correctly
@@ -2042,8 +2043,9 @@ function tripal_core_exclude_field_from_feature_by_default() {
  * @ingroup tripal_chado_api
  */
 function chado_pager_query($query, $args, $limit, $element, $count_query = NULL) {
-
-  $page = pager_find_page();
+  
+  // get the page and offset for the pager
+  $page = pager_find_page($element);
   $offset = $limit * $page;
 
   // Construct a count query if none was given.
@@ -2053,9 +2055,10 @@ function chado_pager_query($query, $args, $limit, $element, $count_query = NULL)
   }
 
   // We calculate the total of pages as ceil(items / limit).
-  $pager_total_items = chado_query($count_query, $args)->fetchField();
+  $total_records = chado_query($count_query, $args)->fetchField();
+  $_SESSION['chado_pager'][$element]['total_records'] = $total_records;
   
-  pager_default_initialize($pager_total_items, $limit, $element);
+  pager_default_initialize($total_records, $limit, $element);
   
   $query .= ' LIMIT ' . (int) $limit . ' OFFSET ' . (int) $offset;
   $results = chado_query($query, $args);

+ 63 - 24
tripal_core/api/tripal_core_properties.api.inc

@@ -355,19 +355,31 @@ function tripal_core_delete_property_by_id($basetable, $record_id) {
  *   value should be that of the contact_id.  This is the record from which currently assigned
  *   properties will be retrieved.
  * @param $exclude
- *   An array of cvterms to exclude when retreiving terms already saved in the database.
+ *   An optional array of cvterms to exclude when retreiving terms already saved in the database.
  *   Use this array when properties are present but should be handled elsewhere.
  *   For example, for contacts, the description field is stored as a property because 
  *   the actual field is only 255 characters. The 'contact_description' therefore should
  *   not be shown in the list of properties, even if present, because it is handled by
  *   a different form element.
+ * @param $include
+ *   An optional array of terms to pre-populate in the form.  This argument can be used to
+ *   add a default set of pre-populated properties regardless if they exist in the database
+ *   or not.  The array should be of the following form:
+ *     array(
+ *       array('cvterm' => $obj1, 'value' => $val1),
+ *       array('cvterm' => $obj2, 'value' => $val2),
+ *       ... etc
+ *     );
+ *   The 'cvterm' key should have as a value an object with these properties: 'name', 'cvterm_id', 'definition'. 
  * @param $instructions
- *   An additional set of instructions for the form properties.
- *   
+ *   An optional additional set of instructions for the form properties.
+ * @param $fset_title
+ *   A title for the property field set.  The default is 'Additional Details'.
  * @ingroup tripal_properties_api
  */
 function tripal_core_properties_form(&$form, &$form_state, $prop_table, $id_field, $cv_name,
-    $available_props, $id = NULL, $exclude = array(), $instructions = '') {
+    $available_props, $id = NULL, $exclude = array(), $include = array(), $instructions = '', 
+    $fset_title = 'Additional Details') {
   
   $d_removed      = array(); // lists removed properties
   $num_new        = 0;  // the number of new rows
@@ -387,7 +399,7 @@ function tripal_core_properties_form(&$form, &$form_state, $prop_table, $id_fiel
   
   $form['properties'] = array(
     '#type' => 'fieldset',
-    '#title' => t('Additional Details'),
+    '#title' => t($fset_title),
     '#description' => t('You may add additional properties by
       selecting a property type from the dropdown and adding text.  You may add
       as many properties as desired by clicking the add button on the right.  To
@@ -407,7 +419,7 @@ function tripal_core_properties_form(&$form, &$form_state, $prop_table, $id_fiel
   // add in the properties from the Chado prop table (only pertains to existing analyses)
   if ($id) {
     tripal_core_properties_form_add_prop_table_props($prop_table, $id_field, $cv_name,
-      $form, $form_state, $id, $ranks, $d_removed, $exclude);
+      $form, $form_state, $id, $ranks, $d_removed, $exclude, $include);
   }
   
   // add in any new properties that have been added by the user through an AHAH callback
@@ -462,7 +474,7 @@ function  tripal_core_properties_form_add_new_empty_props(&$form, &$form_state,
     '#cols'           => 50,
     '#rows'           => $rows,
     '#prefix'         => '<div id="tripal-properties-new_value">',
-    '#description'    => $description,
+    '#description'    => '<span style="white-space: normal">' . $description . '</span>',
     '#suffix'         => '</div>',
   );
 
@@ -558,6 +570,11 @@ function tripal_core_properties_form_add_new_props(&$form, &$form_state, &$ranks
 
       // determine how many rows we need in the textarea
       $rows = 1;
+      $rows = strlen($value) / 80 + 1;
+      if ($rows > 10) {
+        $rows = 10;
+      }
+      
       // add the new fields
       $form['properties']['table']['new'][$new_id][$rank]["new_id-$new_id-$rank"] = array(
         '#markup' => $cvterm[0]->name
@@ -567,7 +584,7 @@ function tripal_core_properties_form_add_new_props(&$form, &$form_state, &$ranks
         '#default_value' => $value,
         '#cols'          => 50,
         '#rows'          => $rows,
-        '#description'   => $cvterm[0]->definition,
+        '#description'   => '<span style="white-space: normal">' . $cvterm[0]->definition . '</span>',
       );
 
       $form['properties']['table']['new'][$new_id][$rank]["remove-$new_id-$rank"] = array(
@@ -659,11 +676,14 @@ function tripal_core_properties_form_add_new_props(&$form, &$form_state, &$ranks
 
   return $num_properties;
 }
-/*
+/**
+ * This function queries the proper xxxprop table to look for existing values for the given
+ * $id.  It then adds these properties to the form for editing.  It also will incorporate
+ * extra properties that were specified manually by the caller.
  *
-*/
+ */
 function  tripal_core_properties_form_add_prop_table_props($prop_table, $id_field, $cv_name, 
-    &$form, $form_state, $id, &$ranks, &$d_removed, $exclude = array()) {
+    &$form, $form_state, $id, &$ranks, &$d_removed, $exclude = array(), $include = array()) {
 
   // get the existing properties
   $num_properties = 0;
@@ -672,21 +692,36 @@ function  tripal_core_properties_form_add_prop_table_props($prop_table, $id_fiel
     return;
   }
 
+  // create an array of properties so we can merge those in the database with those provided by the caller
+  $all_props = array();
+  foreach ($include as $prop) {
+    $all_props[] = $prop;
+  }
+  
+  // now merge in properties saved in the database
   $sql = "
     SELECT CVT.cvterm_id, CVT.name, CVT.definition, PP.value, PP.rank
     FROM {" . $prop_table . "} PP
       INNER JOIN {cvterm} CVT ON CVT.cvterm_id = PP.type_id
       INNER JOIN {cv} CV      ON CVT.cv_id     = CV.cv_id
-    WHERE 
-      PP.$id_field = :id AND 
+      WHERE
+      PP.$id_field = :id AND
       CV.name = '$cv_name'
-    ORDER BY CVT.name, PP.rank
-  ";
+      ORDER BY CVT.name, PP.rank
+      ";
   $props = chado_query($sql, array(':id' => $id));
   while ($prop = $props->fetchObject()) {
+    $all_props[] = array('cvterm' => $prop, 'value' => $prop->value);
+  }
 
-    $type_id = $prop->cvterm_id;
-    $rank = 0;
+  // iterate through the properties
+  foreach ($all_props as $prop) {
+
+    $type_id    = $prop['cvterm']->cvterm_id;
+    $value      = $prop['value'];
+    $name       = $prop['cvterm']->name;
+    $definition = $prop['cvterm']->definition;
+    $rank       = 0;
     if(array_key_exists($type_id, $ranks)) {
       $rank = count($ranks[$type_id]);
     }
@@ -697,7 +732,7 @@ function  tripal_core_properties_form_add_prop_table_props($prop_table, $id_fiel
       continue;
     }
     // skip any properties that should be excluded
-    if (count(array_intersect(array($prop->name), $exclude)) == 1) {
+    if (count(array_intersect(array($name), $exclude)) == 1) {
       continue;
     }
     if (array_key_exists('triggering_element', $form_state) and
@@ -706,22 +741,26 @@ function  tripal_core_properties_form_add_prop_table_props($prop_table, $id_fiel
       continue;
     }
 
-    $ranks[$type_id][$rank]['name']  = $prop->name;
+    $ranks[$type_id][$rank]['name']  = $name;
     $ranks[$type_id][$rank]['id']    = $type_id;
-    $ranks[$type_id][$rank]['value'] = $prop->value;
-    $ranks[$type_id][$rank]['definition']  = $prop->definition;
+    $ranks[$type_id][$rank]['value'] = $value;
     $num_properties++;
     $rows = 1;
+    $rows = strlen($value) / 80 + 1;
+    if ($rows > 10) {
+      $rows = 10;
+    }
+    
 
     $form['properties']['table'][$type_id][$rank]["prop_id-$type_id-$rank"] = array(
-      '#markup'        => $prop->name,
+      '#markup'        => $name,
     );
     $form['properties']['table'][$type_id][$rank]["prop_value-$type_id-$rank"] = array(
       '#type'          => 'textarea',
-      '#default_value' => $prop->value,
+      '#default_value' => $value,
       '#cols'          => 50,
       '#rows'          => $rows,
-      '#description'   => $prop->definition,
+      '#description'   => '<span style="white-space: normal">' . $definition . '</span>',
     );
 
     $form['properties']['table'][$type_id][$rank]["remove-$type_id-$rank"] = array(

+ 4 - 14
tripal_cv/api/tripal_cv.api.inc

@@ -226,7 +226,6 @@ function tripal_cv_get_cvterm_by_name($name, $cv_id = NULL, $cv_name = 'tripal')
        'cv_id' => $cv_id,
     );
     $options = array(
-      'statement_name' => 'sel_cvterm_nacv',
       'case_insensitive_columns' => array('name')
     );
     $r = tripal_core_chado_select('cvterm', array('*'), $values, $options);
@@ -237,22 +236,13 @@ function tripal_cv_get_cvterm_by_name($name, $cv_id = NULL, $cv_name = 'tripal')
       'cv_id' => array(
         'name' => $cv_name,
       ),
-    );    
-
-    $options = array(
-      'statement_name' => 'sel_cvterm_nacv',
-      'case_insensitive_columns' => array('name')
     );
-    $r = tripal_core_chado_select('cvterm', array('*'), $values, $options);      
+    $options = array('case_insensitive_columns' => array('name'));
+    $r = tripal_core_chado_select('cvterm', array('*'), $values, $options);
   }
   else {
-    $values = array(
-      'name' => $name,
-    );
-    $options = array(
-      'statement_name' => 'sel_cvterm_na',
-      'case_insensitive_columns' => array('name')
-    );
+    $values = array('name' => $name);
+    $options = array('case_insensitive_columns' => array('name'));
     $r = tripal_core_chado_select('cvterm', array('*'), $values, $options);
   }
 

+ 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."));
     }
   }
 }

+ 4 - 5
tripal_feature/includes/tripal_feature.sync_features.inc

@@ -407,18 +407,17 @@ function tripal_feature_sync_features($max_sync = 0, $organism_id = NULL,
       $new_node->uniquename = $feature->uniquename;
       $new_node->feature_type = $feature->cvtname;
       
+      $form = array(); // dummy variable
+      $form_state = array(); // dummy variable
       node_validate($new_node, $form, $form_state);
       if (!form_get_errors()) {
         $node = node_submit($new_node);
         node_save($node);
       }
       else {
-        watchdog('trp-fsync', "Failed to insert feature: %title", array('%title' => $new_node->title), WATCHDOG_ERROR);
+        watchdog('tfeature_sync', "Unable to create feature node. ID: %feature_id, Name: %name.",
+          array('%feature_id' => $feature->feature_id, '%name' => $feature->uniquename), WATCHDOG_WARNING);      
       }
-      
-      // set the taxonomy for this node
-      //  tripal_feature_set_taxonomy($node, $feature_id);
-      
       $i++;
     }
   }

+ 2 - 2
tripal_feature/theme/tripal_feature/tripal_feature_relationships.tpl.php

@@ -46,7 +46,7 @@ if (count($object_rels) > 0 or count($subject_rels) > 0) { ?>
           // link the feature to it's node
           $feature_name = $object->record->object_id->name;
           if (property_exists($object->record, 'nid')) {
-            $feature_name = "<a href=\"" . url("node/" . $object->record->nid) . "\" target=\"_blank\">" . $object->record->object_id->name . "</a>";
+            $feature_name = l($feature_name, "node/" . $object->record->nid, array('attributes' => array('target' => "_blank")));
           }
           // link the organism to it's node
           $organism = $object->record->object_id->organism_id;
@@ -104,7 +104,7 @@ if (count($object_rels) > 0 or count($subject_rels) > 0) { ?>
           // link the feature to it's node
           $feature_name = $subject->record->subject_id->name;
           if (property_exists($subject->record, 'nid')) {
-            $feature_name = "<a href=\"" . url("node/" . $subject->record->nid) . "\" target=\"_blank\">" . $subject->record->subject_id->name . "</a>";
+            $feature_name = l($feature_name, "node/" . $subject->record->nid, array('attributes' => array('target' => "_blank")));
           }
           // link the organism to it's node
           $organism = $subject->record->subject_id->organism_id;

+ 0 - 10
tripal_feature/theme/tripal_feature_help.tpl.php

@@ -1,13 +1,3 @@
- <h3>Tripal Feature Quick Links:</h3>
-  <ul>
-   <li><a href="<?php print url("find/sequences") ?>">Retrieve Sequences</a></li>
-   <li><a href="<?php print url("admin/tripal/tripal_feature/configuration") ?>">Feature Configuration</a></li>
-   <li><a href="<?php print url("admin/tripal/tripal_feature/fasta_loader") ?>">Import a multi-FASTA file</a></li>
-   <li><a href="<?php print url("admin/tripal/tripal_feature/gff3_load") ?>">Import a GFF3 file</a></li>
-   <li><a href="<?php print url("admin/tripal/tripal_feature/sync") ?>">Sync Features</a></li>
-   <li><a href="<?php print url("admin/tripal/tripal_feature/delete") ?>">Delete Features</a></li>
- </ul>
-
   <h3>Module Description:</h3>
   <p>The Tripal Feature module provides a new feature content type and interface for genomic features. </p>
 

+ 1 - 1
tripal_feature/theme/tripal_organism/tripal_organism_feature_browser.tpl.php

@@ -99,7 +99,7 @@ if ($enabled) {
         'header' => $headers,
         'rows' => $rows,
         'attributes' => array(
-          'id' => 'tripal_feature-table-analyses',
+          'id' => 'tripal_organism-table-features',
         ),
         'sticky' => FALSE,
         'caption' => '',

+ 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.

+ 4 - 4
tripal_organism/includes/organism_sync.inc

@@ -175,6 +175,7 @@ function tripal_organism_sync_organisms($organism_id = NULL, $job_id = NULL) {
       $new_node->genus = $organism->genus;
       $new_node->species = $organism->species;
       $new_node->description = '';
+      
       $form = array(); // dummy variable
       $form_state = array(); // dummy variable
       node_validate($new_node, $form, $form_state);
@@ -186,12 +187,11 @@ function tripal_organism_sync_organisms($organism_id = NULL, $job_id = NULL) {
         }
       }
       else {
-        print "Failed to insert organism $organism->common_name\n";
+        watchdog('torg_sync', "Unable to create organism node. ID: %org_id, Name: %name.",
+          array('%org_id' => $organism->organism_id, '%name' => $organism->genus . ' ' . $organism->species), 
+          WATCHDOG_WARNING);
       }
     }
-    else {
-      print "Skipped $organism->common_name\n";
-    }
   }
   return $page_content;
 }

+ 5 - 2
tripal_organism/includes/tripal_organism.admin.inc

@@ -42,8 +42,11 @@ function tripal_organism_admin() {
 
   $form = array();
 
-  get_tripal_organism_admin_form_reindex_set($form);
-  get_tripal_organism_admin_form_taxonomy_set($form);
+  $form['nothing'] = array(
+    '#markup' => t('There are currently no settings to configure.')
+  );
+  //get_tripal_organism_admin_form_reindex_set($form);
+  //get_tripal_organism_admin_form_taxonomy_set($form);
 
   return system_settings_form($form);
 }

+ 38 - 23
tripal_organism/tripal_organism.module

@@ -99,31 +99,33 @@ function tripal_organism_menu() {
 
   // the administative settings menu
   $items['admin/tripal/chado/tripal_organism'] = array(
-   'title' => 'Organisms',
-   'description' => 'Any living biological entity, such as an animal, plant, fungus, or bacterium.',
-   'page callback' => 'tripal_organism_admin_organism_view',
-   'access arguments' => array('adminster tripal organism'),
-   'type' => MENU_NORMAL_ITEM,
+    'title' => 'Organisms',
+    'description' => 'Any living biological entity, such as an animal, plant, fungus, or bacterium.',
+    'page callback' => 'tripal_organism_admin_organism_view',
+    'access arguments' => array('adminster tripal organism'),
+    'type' => MENU_NORMAL_ITEM,
   );
-
+  
   $items['admin/tripal/chado/tripal_organism/help'] = array(
-   'title' => 'Help',
-   'description' => "A description of the Tripal Organism module including a short description of it's usage.",
-   'page callback' => 'theme',
-   'page arguments' => array('tripal_organism_help'),
-   'access arguments' => array('adminster tripal organism'),
-   'type' => MENU_LOCAL_TASK,
+    'title' => 'Help',
+    'description' => "A description of the Tripal Organism module including a short description of it's usage.",
+    'page callback' => 'theme',
+    'page arguments' => array('tripal_organism_help'),
+    'access arguments' => array('adminster tripal organism'),
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 10
   );
-
+  
   $items['admin/tripal/chado/tripal_organism/configuration'] = array(
-   'title' => 'Settings',
-   'description' => 'Manage integration of Chado organisms including associated features',
-   'page callback' => 'drupal_get_form',
-   'page arguments' => array('tripal_organism_admin'),
-   'access arguments' => array('adminster tripal organism'),
-   'type' => MENU_LOCAL_TASK,
+    'title' => 'Settings',
+    'description' => 'Manage integration of Chado organisms including associated features',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('tripal_organism_admin'),
+    'access arguments' => array('adminster tripal organism'),
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 5
   );
-
+  
   $items['admin/tripal/chado/tripal_organism/sync'] = array(
     'title' => 'Sync',
     'description' => 'Sync Chado organisms with Drupal',
@@ -131,6 +133,7 @@ function tripal_organism_menu() {
     'page arguments' => array('tripal_organism_sync'),
     'access arguments' => array('adminster tripal organism'),
     'type' => MENU_LOCAL_TASK,
+    'weight' => 2
   );
 
   $items['admin/tripal/chado/tripal_organism/views/organisms/enable'] = array(
@@ -140,6 +143,7 @@ function tripal_organism_menu() {
     'access arguments' => array('administer tripal_bulk_loader'),
     'type' => MENU_CALLBACK,
   );
+  
 
   return $items;
 }
@@ -355,9 +359,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 +393,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.

+ 246 - 684
tripal_pub/includes/pub_form.inc

@@ -6,126 +6,165 @@
  */
 
 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       = '';
+  $pyear       = '';
+  $uniquename  = '';
+  $type_id     = '';
+  $is_obsolete = '';
+  
+  // some of the fields in the pub table should show up in the properties 
+  // form elements to make the form more seemless.  We will add them
+  // to this array.
+  $more_props = array();
+
+  // 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       = $pub->title;
+    $pyear       = $pub->pyear;
+    $uniquename  = $pub->uniquename;
+    $type_id     = $pub->type_id->cvterm_id;
+    $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
+    $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,
+    );
+    
+    // get fields from the pub table and convert them to properties. We will add these to the $more_props
+    // array which gets passed in to the tripal_core_properties_form() API call further down
+    if ($pub->volumetitle) {
+      $cvterm = tripal_cv_get_cvterm_by_name('Volume Title', NULL, 'tripal_pub');
+      $more_props[] = array('cvterm' => $cvterm, 'value' => $pub->volumetitle);
+    }
+    if ($pub->volume) {
+      $cvterm = tripal_cv_get_cvterm_by_name('Volume', NULL, 'tripal_pub');
+      $more_props[] = array('cvterm' => $cvterm, 'value' => $pub->volume);
+    }
+    if ($pub->series_name) {
+      switch ($pub->type_id->name) {
+        case 'Journal Article':
+          $cvterm = tripal_cv_get_cvterm_by_name('Journal Name', NULL, 'tripal_pub');
+          $more_props[] = array('cvterm' => $cvterm, 'value' => $pub->series_name);
+          break;
+        case 'Conference Proceedings':
+          $cvterm = tripal_cv_get_cvterm_by_name('Conference Name', NULL, 'tripal_pub');
+          $more_props[] = array('cvterm' => $cvterm, 'value' => $pub->series_name);
+          break;
+        default:
+          $cvterm = tripal_cv_get_cvterm_by_name('Series Name', NULL, 'tripal_pub');
+          $more_props[] = array('cvterm' => $cvterm, 'value' => $pub->series_name);
+      }
+    }
+    if ($pub->issue) {
+      $cvterm = tripal_cv_get_cvterm_by_name('Issue', NULL, 'tripal_pub');
+      $more_props[] = array('cvterm' => $cvterm, 'value' => $pub->issue);
+    }
+    if ($pub->pages) {
+      $cvterm = tripal_cv_get_cvterm_by_name('Pages', NULL, 'tripal_pub');
+      $more_props[] = array('cvterm' => $cvterm, 'value' => $pub->pages);
+    }
+    if ($pub->miniref) {
+      // not sure what to do with this one
+    }
+    if ($pub->publisher) {
+      $cvterm = tripal_cv_get_cvterm_by_name('Publisher', NULL, 'tripal_pub');
+      $more_props[] = array('cvterm' => $cvterm, 'value' => $pub->publisher);
+    }
+    if ($pub->pubplace) {
+      $cvterm = tripal_cv_get_cvterm_by_name('Published Location', NULL, 'tripal_pub');
+      $more_props[] = array('cvterm' => $cvterm, 'value' => $pub->pages);
+    }
+  }
+  // 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'];
+    $pyear        = $form_state['values']['pyear'];
+    $uniquename   = $form_state['values']['uniquename'];
+    $type_id      = $form_state['values']['type_id'];
+    $is_obsolete  = $form_state['values']['is_obsolete'];
+  }
+  // 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'];
+    $uniquename   = $form_state['input']['uniquename'];
+    $type_id      = $form_state['input']['type_id'];
+    $is_obsolete  = $form_state['input']['is_obsolete'];
+  }
+ 
+  // 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 +172,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 +181,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, $more_props, $instructions, 'Properties');
+
   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 +262,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 +279,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 +309,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);
 
@@ -288,564 +325,89 @@ function chado_pub_validate($node, &$form) {
     if((strcmp(strtolower($pub[0]->title), strtolower($title)) == 0) and
        (strcmp(strtolower($pub[0]->series_name), strtolower($series_name)) == 0) and
        ($pub[0]->type_id == $type_id) and
-       ($pub[0]->year == $pyear)) {
+       ($pub[0]->pyear == $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>',
-  )
-  );
-}

+ 291 - 246
tripal_pub/includes/pub_importers.inc

@@ -1,6 +1,6 @@
 <?php
 /**
- * A function to render a listing of all publication importers
+ * A function to generate a table containing the list of publication importers
  *
  * @ingroup tripal_pub
  */
@@ -42,8 +42,8 @@ function tripal_pub_importers_list() {
      )
   );
 
-  $page = "<ul class='action-links'>";
-  $page .= '<li>' . l('New Importer', 'admin/tripal/chado/tripal_pub/import/new') . '</li>';
+  $page  = "<ul class='action-links'>";
+  $page .= '  <li>' . l('New Importer', 'admin/tripal/chado/tripal_pub/import/new') . '</li>';
   $page .= '</ul>';
 
   $page .= theme('table', array('header' => $header, 'rows' => $rows));
@@ -53,7 +53,7 @@ function tripal_pub_importers_list() {
 /*
  *
  */
-function tripal_pub_importer_setup($action = 'new', $pub_import_id = NULL) {
+function tripal_pub_importer_setup_page($action = 'new', $pub_import_id = NULL) {
   global $pager_total, $pager_total_items;
 
   $pager_id = 0;
@@ -63,7 +63,7 @@ function tripal_pub_importer_setup($action = 'new', $pub_import_id = NULL) {
   $values = array('name' => 'tripal_pub');
   $tpub_cv = tripal_core_chado_select('cv', array('cv_id'), $values);
   if (count($tpub_cv) == 0) {
-  	drupal_set_message(t('Before importing publications you must first ') . l(t('load the Tripal Pub Ontology'), 'admin/tripal/tripal_cv/obo_loader'), 'error');
+    drupal_set_message(t('Before importing publications you must first ') . l(t('load the Tripal Pub Ontology'), 'admin/tripal/tripal_cv/obo_loader'), 'error');
   }
   $values = array('name' => 'tripal_contact');
   $tpub_cv = tripal_core_chado_select('cv', array('cv_id'), $values);
@@ -75,8 +75,9 @@ function tripal_pub_importer_setup($action = 'new', $pub_import_id = NULL) {
   $form = drupal_get_form('tripal_pub_importer_setup_form',  $pub_import_id, $action);
 
   $output = l("Return to publication importers list", "admin/tripal/chado/tripal_pub/import_list");
-  $output .= $form;
+  $output .= drupal_render($form);
 
+  /*
   // retrieve any results
   $remote_db = $_SESSION['tripal_pub_import']['remote_db'];
   $num_criteria = $_SESSION['tripal_pub_import']['num_criteria'];
@@ -131,55 +132,39 @@ function tripal_pub_importer_setup($action = 'new', $pub_import_id = NULL) {
       ". Page " . ($page + 1) . " of $total_pages. " .
       " Results</b></br>" . $table . '</p>' . $pager;
   }
+  */
   return $output;
 }
-/*
- *
- */
-function theme_tripal_pub_importer_setup_form($form) {
-  $rows = array();
-  foreach ($form['criteria'] as $i => $element) {
-    if(is_numeric($i)) {
-      $rows[] = array(
-      drupal_render($element["operation-$i"]),
-      drupal_render($element["scope-$i"]),
-      drupal_render($element["search_terms-$i"]),
-      drupal_render($element["is_phrase-$i"]),
-      drupal_render($element["add-$i"]) . drupal_render($element["remove-$i"]),
-      );
-    }
-  }
-  $headers = array('Operation','Scope', 'Search Terms', '','');
-
-  $markup  = '';
-  $markup .= '<div>' . drupal_render($form['remote_db']) . '</div>';
-  $markup .= '<div id="pub-search-form-row1">';
-  $markup .= '  <div id="pub-search-form-col1">' . drupal_render($form['loader_name']) . '</div>';
-  $markup .= '  <div id="pub-search-form-col3">' . drupal_render($form['days']) . '</div>';
-  $markup .= '</div>';
-  $markup .= '<div id="pub-search-form-row2">' . drupal_render($form['disabled']) . '</div>';
-  $markup .= '<div id="pub-search-form-row3">' . drupal_render($form['do_contact']) . '</div>';
-  $markup .= theme('table', array('header' => $headers, 'rows' => $rows, 'attributes' => array('id' => 'tripal-pub-importer-table')));
 
-  $form['criteria'] = array(
-    '#type' => 'markup',
-    '#value' =>  $markup,
-    '#weight' => -10,
-  );
-  return drupal_render($form);
-}
 /**
  * Purpose: Provides the form to search pubmed
  *
  * @ingroup tripal_pub
  */
-function tripal_pub_importer_setup_form(&$form_state = NULL, $pub_import_id = NULL, $action = 'new') {
-  tripal_core_ahah_init_form();
-
+function tripal_pub_importer_setup_form($form, &$form_state = NULL, $pub_import_id = NULL, $action = 'new') {
+  // Default values can come in the following ways:
+  //
+  // 1) as elements of the $pub_importer object.  This occurs when editing an existing importer 
+  // 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
+  
+  
   // Set the default values. If the pub_import_id isn't already defined by the form values
   // and one is provided then look it up in the database
   $criteria = NULL;
-  if ($action == "edit" and !$form_state['values']) {
+  $remote_db = '';
+  $days = '';
+  $disabled = '';
+  $do_contact = '';
+  $num_criteria = '';
+  $loader_name = '';
+  
+  // if this is an edit the we are pulling an import object from the database
+  if ($action == "edit") {
     $sql = "SELECT * FROM {tripal_pub_import} WHERE pub_import_id = :pub_import_id";
     $importer = db_query($sql, array(':pub_import_id' => $pub_import_id))->fetchObject();
 
@@ -191,45 +176,47 @@ function tripal_pub_importer_setup_form(&$form_state = NULL, $pub_import_id = NU
     $num_criteria   = $criteria['num_criteria'];
     $loader_name    = $criteria['loader_name'];
   }
-
-  // if we're here because the form was posted then load from the session variable (we lost the form state)
-  $num_criteria = isset($_SESSION['tripal_pub_import']['num_criteria']) ? $_SESSION['tripal_pub_import']['num_criteria'] : $num_criteria;
-  $loader_name  = isset($_SESSION['tripal_pub_import']['loader_name'])  ? $_SESSION['tripal_pub_import']['loader_name']  : $loader_name;
-  $remote_db    = isset($_SESSION['tripal_pub_import']['remote_db'])    ? $_SESSION['tripal_pub_import']['remote_db']    : $remote_db;
-  $disabled     = isset($_SESSION['tripal_pub_import']['disabled'])     ? $_SESSION['tripal_pub_import']['disabled']     : $disabled;
-  $do_contact   = isset($_SESSION['tripal_pub_import']['do_contact'])   ? $_SESSION['tripal_pub_import']['do_contact']   : $do_contact;
-  $days         = isset($_SESSION['tripal_pub_import']['days'])         ? $_SESSION['tripal_pub_import']['days']         : $days;
-
-
-  // If the form_state has variables then use those.  This happens when an error occurs on the form or the
-  // form is resbumitted using AJAX
-  if ($form_state['values']) {
-    $num_criteria = $form_state['values']['num_criteria'] ? $form_state['values']['num_criteria'] : $num_criteria;
-    $loader_name  = $form_state['values']['loader_name']  ? $form_state['values']['loader_name']  : $loader_name;
-    $remote_db    = $form_state['values']['remote_db']    ? $form_state['values']['remote_db']    : $remote_db;
-    $disabled     = $form_state['values']['disabled']     ? $form_state['values']['disabled']     : $disabled;
-    $do_contact   = $form_state['values']['do_contact']   ? $form_state['values']['do_contact']   : $do_contact;
-    $days         = $form_state['values']['days']         ? $form_state['values']['days']         : $days;
+  // 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)) {
+    $remote_db    = $form_state['values']['remote_db'];
+    $days         = $form_state['values']['days'];
+    $disabled     = $form_state['values']['disabled'];
+    $do_contact   = $form_state['values']['do_contact'];
+    $num_criteria = $form_state['values']['num_criteria'];
+    $loader_name  = $form_state['values']['loader_name'];
+  }
+  // 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'])) {
+    $remote_db    = $form_state['input']['remote_db'];
+    $days         = $form_state['input']['days'];
+    $disabled     = $form_state['input']['disabled'];
+    $do_contact   = $form_state['input']['do_contact'];
+    $num_criteria = $form_state['input']['num_criteria'];
+    $loader_name  = $form_state['input']['loader_name'];
   }
 
   // check if the pub_import_id in the session variable is not the same as the one we've been provided
   // if so, then clear the session variable
-  if ($pub_import_id and $pub_import_id != $_SESSION['tripal_pub_import']['pub_import_id']) {
-    unset($_SESSION['tripal_pub_import']);
-  }
+//  if ($pub_import_id and $pub_import_id != $_SESSION['tripal_pub_import']['pub_import_id']) {
+//    unset($_SESSION['tripal_pub_import']);
+//  }
 
 
   // change the number of criteria based on form_state post data.
   if (!$num_criteria) {
     $num_criteria = 1;
   }
+/*  
   if($form_state['post']["add-$num_criteria"]) {
     $num_criteria++;
   }
   if($form_state['post']["remove-$num_criteria"]) {
     $num_criteria--;
   }
-
+*/
+  
   $form['pub_import_id'] = array(
     '#type'          => 'hidden',
     '#value'         => $pub_import_id,
@@ -241,7 +228,7 @@ function tripal_pub_importer_setup_form(&$form_state = NULL, $pub_import_id = NU
     '#required'      => TRUE,
   );
 
-  $form['loader_name'] = array(
+  $form['themed_element']['loader_name'] = array(
     '#type'          => 'textfield',
     '#title'         => t('Loader Name'),
     '#description'   => t('Please provide a name for this loader setup..'),
@@ -262,17 +249,17 @@ function tripal_pub_importer_setup_form(&$form_state = NULL, $pub_import_id = NU
   if (!$remote_db) {
     $remote_db = 'PMID';
   }
-  $form['remote_db'] = array(
+  $form['themed_element']['remote_db'] = array(
     '#title' => t('Remote Database'),
     '#type' => 'select',
     '#options' => $remote_dbs,
     '#default_value' => $remote_db,
-    '#ahah' => array(
-      'path'    => "admin/tripal/chado/tripal_pub/import/changedb",
-      'wrapper' => 'tripal-pub-importer-setup-form',
-      'event'   => 'click',
-      'method'  => 'replace',
-  ),
+    '#ajax' => array(
+      'callback' => "tripal_pubs_setup_form_ajax_update",
+      'wrapper'  => 'tripal-pubs-importer-setup',
+      'effect'   => 'fade',
+      'method'   => 'replace',
+    ),
   );
 
   $form['num_criteria']= array(
@@ -284,27 +271,67 @@ function tripal_pub_importer_setup_form(&$form_state = NULL, $pub_import_id = NU
     '#default_value' => $pub_import_id,
   );
 
-  $form['days'] = array(
+  $form['themed_element']['days'] = array(
     '#type'          => 'textfield',
     '#title'         => t('Days since record modified'),
     '#description'   => t('Limit the search to include pubs that have been added no more than this many days before today.'),
     '#default_value' => $days,
     '#size'          => 5,
   );
-  $form['disabled'] = array(
+  $form['themed_element']['disabled'] = array(
     '#type'          => 'checkbox',
     '#title'         => t('Disabled'),
     '#description'   => t('Check to disable this importer.'),
     '#default_value' => $disabled,
   );
-  $form['do_contact'] = array(
+  $form['themed_element']['do_contact'] = array(
     '#type'          => 'checkbox',
     '#title'         => t('Create Contact'),
     '#description'   => t('Check to create an entry in the contact table for each author of a matching publication during import. This allows storage of
        additional information such as affilation, etc. Otherwise, only authors names are retrieved.'),
     '#default_value' => $do_contact,
   );
+  
+  // add in the form for the criteria
+  tripal_pub_importer_setup_add_criteria_fields($form, $form_state, $num_criteria, $criteria);
 
+  $form['test'] = array(
+    '#type'         => 'submit',
+    '#value'        => t('Test Importer'),
+  );
+  $form['save'] = array(
+    '#type'         => 'submit',
+    '#value'        => t('Save Importer'),
+  );
+  /*
+  $form['import'] = array(
+    '#type'         => 'submit',
+    '#value'        => t('Save & Import Now'),
+  );
+  */
+  $form['delete'] = array(
+    '#type'         => 'submit',
+    '#value'        => t('Delete Importer'),
+  );
+  
+  // allow the selected remote database to make changes to the form if needed
+  $callback = "tripal_pub_remote_alter_form_$remote_db";
+  $form = call_user_func($callback, $form, $form_state);
+ 
+  $form['themed_element']['#theme'] = 'tripal_pub_importer_setup_form_elements';
+  
+  return $form;
+}
+
+/**
+ * 
+ * @param $form
+ * @param $form_state
+ * @param $num_criteria
+ * @param $criteria
+ */
+function tripal_pub_importer_setup_add_criteria_fields(&$form, &$form_state, $num_criteria, $criteria){
+  
   // choices array
   $scope_choices = array(
     'any'      => 'Any Field',
@@ -313,133 +340,151 @@ function tripal_pub_importer_setup_form(&$form_state = NULL, $pub_import_id = NU
     'id'       => 'Accession',
     'title'    => 'Title',
     'journal'   => 'Journal Name'
-    );
-
-    $first_op_choices = array(
+  );
+  
+  $first_op_choices = array(
     ''    => '',
     'NOT' => 'NOT'
-    );
-    $op_choices = array(
+  );
+  $op_choices = array(
     'AND' => 'AND',
     'OR'  => 'OR',
     'NOT' => 'NOT'
+  );
+  
+  for($i = 1; $i <= $num_criteria; $i++) {
+    $is_phrase = 1;
+    
+    $search_terms = '';
+    $scope = '';
+    $is_phrase = '';
+    $operation = '';
+  
+    // if we have criteria supplied from the database then use that as the initial defaults
+    if ($criteria) {
+      $search_terms = $criteria['criteria'][$i]['search_terms'];
+      $scope        = $criteria['criteria'][$i]['scope'];
+      $is_phrase    = $criteria['criteria'][$i]['is_phrase'];
+      $operation    = $criteria['criteria'][$i]['operation'];
+    }
+    
+/*    
+    // if we're here because the form was posted then load from the session variable (we lost the form state)
+    $search_terms = isset($_SESSION['tripal_pub_import']['criteria'][$i]['search_terms']) ? $_SESSION['tripal_pub_import']['criteria'][$i]['search_terms'] : $search_terms;
+    $scope        = isset($_SESSION['tripal_pub_import']['criteria'][$i]['scope'])        ? $_SESSION['tripal_pub_import']['criteria'][$i]['scope']        : $scope;
+    $is_phrase    = isset($_SESSION['tripal_pub_import']['criteria'][$i]['is_phrase'])    ? $_SESSION['tripal_pub_import']['criteria'][$i]['is_phrase']    : $is_phrase;
+    $operation    = isset($_SESSION['tripal_pub_import']['criteria'][$i]['operation'])    ? $_SESSION['tripal_pub_import']['criteria'][$i]['operation']    : $operation;
+*/
+      
+    // If the form_state has variables then use those.  This happens when an error occurs on the form or the
+    // form is resbumitted using AJAX
+    if (array_key_exists('values', $form_state)) {
+      $search_terms = $form_state['values']["search_terms-$i"];
+      $scope        = $form_state['values']["scope-$i"];
+      $is_phrase    = $form_state['values']["is_phrase-$i"];
+      $operation    = $form_state['values']["operation-$i"];
+    }
+    $form['themed_element']['criteria'][$i]["scope-$i"] = array(
+      '#type'          => 'select',
+      '#description'   => t('Please select the fields to search for this term.'),
+      '#options'       => $scope_choices,
+      '#default_value' => $scope,
     );
-    for($i = 1; $i <= $num_criteria; $i++) {
-    	$is_phrase = 1;
-
-      // if we have criteria supplied from the database then use that as the initial defaults
-      if ($criteria) {
-        $search_terms = $criteria['criteria'][$i]['search_terms'];
-        $scope = $criteria['criteria'][$i]['scope'];
-        $is_phrase = $criteria['criteria'][$i]['is_phrase'];
-        $operation = $criteria['criteria'][$i]['operation'];
-      }
-      // if we're here because the form was posted then load from the session variable (we lost the form state)
-      $search_terms = isset($_SESSION['tripal_pub_import']['criteria'][$i]['search_terms']) ? $_SESSION['tripal_pub_import']['criteria'][$i]['search_terms'] : $search_terms;
-      $scope        = isset($_SESSION['tripal_pub_import']['criteria'][$i]['scope'])        ? $_SESSION['tripal_pub_import']['criteria'][$i]['scope']        : $scope;
-      $is_phrase    = isset($_SESSION['tripal_pub_import']['criteria'][$i]['is_phrase'])    ? $_SESSION['tripal_pub_import']['criteria'][$i]['is_phrase']    : $is_phrase;
-      $operation    = isset($_SESSION['tripal_pub_import']['criteria'][$i]['operation'])    ? $_SESSION['tripal_pub_import']['criteria'][$i]['operation']    : $operation;
-
-      // If the form_state has variables then use those.  This happens when an error occurs on the form or the
-      // form is resbumitted using AJAX
-      if ($form_state['values']) {
-        $search_terms = $form_state['values']["search_terms-$i"];
-        $scope        = $form_state['values']["scope-$i"];
-        $is_phrase    = $form_state['values']["is_phrase-$i"];
-        $operation    = $form_state['values']["operation-$i"];
-      }
-
-      $form['criteria'][$i]["search_terms-$i"] = array(
-        '#type'          => 'textfield',
-        '#description'   => t('Please provide a list of words for searching. You may use
-          conjunctions such as "AND" or "OR" to separate words if they are expected in
-          the same scope, but do not mix ANDs and ORs.  Uncheck the "Is Phrase" checkbox to use conjunctions'),
-        '#default_value' => $search_terms,
-        '#required'      => TRUE,
-        '#maxlength' => 2048,
-      );
-      $form['criteria'][$i]["scope-$i"] = array(
-        '#type'          => 'select',
-        '#description'   => t('Please select the fields to search for this term.'),
-        '#options'       => $scope_choices,
-        '#default_value' => $scope,
-      );
-      $form['criteria'][$i]["is_phrase-$i"] = array(
-        '#type'    => 'checkbox',
-        '#title'   => t('Is Phrase?'),
-        '#default_value' => $is_phrase,
-      );
-
-      if ($i == 1) {
-        /*
-         $form['criteria'][$i]["operation-$i"] = array(
+    $form['themed_element']['criteria'][$i]["search_terms-$i"] = array(
+      '#type'          => 'textfield',
+      '#description'   => t('<span style="white-space: normal">Please provide a list of words for searching. You may use
+        conjunctions such as "AND" or "OR" to separate words if they are expected in
+        the same scope, but do not mix ANDs and ORs.  Uncheck the "Is Phrase" checkbox to use conjunctions</span>'),
+      '#default_value' => $search_terms,
+      '#required'      => TRUE,
+      '#maxlength' => 2048,
+    );
+    $form['themed_element']['criteria'][$i]["is_phrase-$i"] = array(
+      '#type'    => 'checkbox',
+      '#title'   => t('Is Phrase?'),
+      '#default_value' => $is_phrase,
+    );
+  
+    if ($i == 1) {
+      /*
+       $form['criteria'][$i]["operation-$i"] = array(
          '#type'          => 'select',
          '#options'       => $first_op_choices,
          '#default_value' => $operation,
-         );*/
-      }
-      if ($i > 1) {
-        $form['criteria'][$i]["operation-$i"] = array(
+       );*/
+    }
+    if ($i > 1) {
+      $form['themed_element']['criteria'][$i]["operation-$i"] = array(
         '#type'          => 'select',
         '#options'       => $op_choices,
         '#default_value' => $operation,
-        );
-      }
-      if ($i == $num_criteria) {
-        if($i > 1) {
-          $form['criteria'][$i]["remove-$i"] = array(
-          '#type'         => 'image_button',
+      );
+    }
+    if ($i == $num_criteria) {
+      if($i > 1) {
+        $form['themed_element']['criteria'][$i]["remove-$i"] = array(
+          '#type'         => 'button',
+          '#name'         => 'remove',
           '#value'        => t('Remove'),
-          '#src'          => drupal_get_path('theme', 'tripal') . '/images/minus.png',
-          '#ahah' => array(
-            'path'    => "admin/tripal/chado/tripal_pub/import/criteria/minus/$i",
-            'wrapper' => 'tripal-pub-importer-setup-form',
-            'event'   => 'click',
-            'method'  => 'replace',
+          '#ajax' => array(
+            'callback' => "tripal_pubs_setup_form_ajax_update",
+            'wrapper'  => 'tripal-pubs-importer-setup',
+            'effect'   => 'fade',
+            'method'   => 'replace',
+            'prevent'  => 'click'
           ),
-          '#attributes' => array('onClick' => 'return false;'),
-          );
-        }
-        $form['criteria'][$i]["add-$i"] = array(
-        '#type'         => 'image_button',
-        '#value'        => t('Add'),
-        '#src'          => drupal_get_path('theme', 'tripal') . '/images/add.png',
-        '#ahah' => array(
-          'path'    => "admin/tripal/chado/tripal_pub/import/criteria/add/$i",
-          'wrapper' => 'tripal-pub-importer-setup-form',
-          'event'   => 'click',
-          'method'  => 'replace',
-        ),
-        '#attributes' => array('onClick' => 'return false;'),
+          // When this button is clicked, the form will be validated and submitted.
+          // Therefore, we set custom submit and validate functions to override the
+          // default form submit.  In the validate function we set the form_state
+          // to rebuild the form so the submit function never actually gets called,
+          // but we need it or Drupal will run the default validate anyway.
+          // we also set #limit_validation_errors to empty so fields that
+          // are required that don't have values won't generate warnings.
+          '#submit'   => array('tripal_pub_setup_form_criteria_button_submit'),
+          '#validate' => array('tripal_pub_setup_form_criteria_button_validate'),
+          '#limit_validation_errors' => array(),
         );
       }
+      $form['themed_element']['criteria'][$i]["add-$i"] = array(
+        '#type'  => 'button',
+        '#name'  => 'add',
+        '#value' => t('Add'),
+        '#ajax'  => array(
+          'callback' => "tripal_pubs_setup_form_ajax_update",
+          'wrapper'  => 'tripal-pubs-importer-setup',
+          'effect'   => 'fade',
+          'method'   => 'replace',
+          'prevent'  => 'click'
+        ),
+        // When this button is clicked, the form will be validated and submitted.
+        // Therefore, we set custom submit and validate functions to override the
+        // default form submit.  In the validate function we set the form_state
+        // to rebuild the form so the submit function never actually gets called,
+        // but we need it or Drupal will run the default validate anyway.
+        // we also set #limit_validation_errors to empty so fields that
+        // are required that don't have values won't generate warnings.
+        '#submit'   => array('tripal_pub_setup_form_criteria_button_submit'),
+        '#validate' => array('tripal_pub_setup_form_criteria_button_validate'),
+        '#limit_validation_errors' => array(),
+      );
     }
-
-    $form['test'] = array(
-    '#type'         => 'submit',
-    '#value'        => t('Test Importer'),
-    );
-    $form['save'] = array(
-    '#type'         => 'submit',
-    '#value'        => t('Save Importer'),
-    );
-    /*
-     $form['import'] = array(
-     '#type'         => 'submit',
-     '#value'        => t('Save & Import Now'),
-     );*/
-    $form['delete'] = array(
-    '#type'         => 'submit',
-    '#value'        => t('Delete Importer'),
-    );
-
-    // allow the selected remote database to make changes to the form if needed
-    $callback = "tripal_pub_remote_alter_form_$remote_db";
-    $form = call_user_func($callback, $form, $form_state);
-
-    return $form;
+  }
+}
+/**
+ * This function is used to rebuild the form if an ajax call is made vai a button.
+ * The button causes the form to be submitted. We don't want this so we override
+ * the validate and submit routines on the form button. Therefore, this function
+ * only needs to tell Drupal to rebuild the form
+ */
+function  tripal_pub_setup_form_criteria_button_validate($form, &$form_state){
+  $form_state['rebuild'] = TRUE;
+}
+/**
+ * This function is just a dummy to override the default form submit on ajax calls for buttons
+ */
+function tripal_pub_setup_form_criteria_button_submit($form, &$form_state){
+  // do nothing
 }
-
 /**
  *
  */
@@ -458,10 +503,10 @@ function tripal_pub_importer_setup_form_validate($form, &$form_state) {
     $operation =  $form_state['values']["operation-$i"];
 
     if (!$is_phrase) {
-    	if (preg_match('/and/i', $search_terms) and preg_match('/or/i', $search_terms)) {
-    	  form_set_error("search_terms-$i", "You may use 'AND' or 'OR' but cannot use both. Add a new entry below with the same scope for the other conunction.");
-    	  $_SESSION['tripal_pub_import']['perform_search'] = 0;
-    	}
+      if (preg_match('/and/i', $search_terms) and preg_match('/or/i', $search_terms)) {
+        form_set_error("search_terms-$i", "You may use 'AND' or 'OR' but cannot use both. Add a new entry below with the same scope for the other conunction.");
+        $_SESSION['tripal_pub_import']['perform_search'] = 0;
+      }
     }
   }
 
@@ -567,64 +612,64 @@ function tripal_pub_importer_setup_form_submit($form, &$form_state) {
     }
   }
 }
-
-/*
- *
+/**
+ * AJAX callback for updating the form.  
  */
-function tripal_pub_importer_delete($pub_import_id) {
-  $sql = "DELETE FROM {tripal_pub_import} WHERE pub_import_id = :pub_import_id";
-  $success = db_query($sql, array(':pub_import_id' => $pub_import_id));
-  if ($success) {
-    drupal_set_message('Publication importer deleted.');
-    drupal_goto('admin/tripal/chado/tripal_pub/import_list');
-  }
-  else {
-    drupal_set_message('Could not delete publication importer.', 'error');
-  }
+function tripal_pubs_setup_form_ajax_update($form, $form_state) {
+  return $form['themed_element'];
 }
-/*
- * AHAH callback
+
+/**
+ * 
+ * @param $form
  */
-function tripal_pub_importer_setup_page_update_remotedb() {
-  $status = TRUE;
-
-  // prepare and render the form
-  $form = tripal_core_ahah_prepare_form();
-  $data = theme('tripal_pub_importer_setup_form', $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 theme_tripal_pub_importer_setup_form_elements($variables) {
+  $form = $variables['form'];
+
+  // first render the fields at the top of the form
+  $markup  = '';
+  $markup .= '<div>' . drupal_render($form['remote_db']) . '</div>';
+  $markup .= '<div id="pub-search-form-row1">';
+  $markup .= '  <div id="pub-search-form-col1">' . drupal_render($form['loader_name']) . '</div>';
+  $markup .= '  <div id="pub-search-form-col3">' . drupal_render($form['days']) . '</div>';
+  $markup .= '</div>';
+  $markup .= '<div id="pub-search-form-row2">' . drupal_render($form['disabled']) . '</div>';
+  $markup .= '<div id="pub-search-form-row3">' . drupal_render($form['do_contact']) . '</div>';
+
+  // next render the criteria fields into a table format
+  $rows = array();
+  foreach ($form['criteria'] as $i => $element) {
+    if(is_numeric($i)) {
+      $rows[] = array(
+        drupal_render($element["operation-$i"]),
+        drupal_render($element["scope-$i"]),
+        drupal_render($element["search_terms-$i"]),
+        drupal_render($element["is_phrase-$i"]),
+        drupal_render($element["add-$i"]) . drupal_render($element["remove-$i"]),
+      );
+    }
+  }
+  
+  $headers = array('Operation','Scope', 'Search Terms', '','');
+  $table = array(
+    'header' => $headers,
+    'rows' => $rows,
+    'attributes' => array(),
+    'sticky' => TRUE,
+    'caption' => '',
+    'colgroups' => array(),
+    'empty' => '',
   );
-}
-/*
- * AHAH callback
- */
-function tripal_pub_importer_setup_page_update_criteria($action, $i) {
-  $status = TRUE;
-
-  // prepare and render the form
-  $form = tripal_core_ahah_prepare_form();
-  $data = theme('tripal_pub_importer_setup_form', $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,
-  )
+  $criteria_table = theme_table($table);
+  $markup .= $criteria_table;
+  
+  // add the rendered form
+  $form = array(
+    '#markup' => $markup,
+    '#prefix' => '<div id="tripal-pubs-importer-setup">',
+    '#suffix' => '</div>',
   );
+  
+  return drupal_render($form);
 }

+ 89 - 59
tripal_pub/includes/pub_sync.inc

@@ -3,32 +3,58 @@
  *
  */
 function tripal_pub_sync_form() {
-
-  $form['sync_all'] = array(
-    '#type' => 'item',
-    '#value' => t('Syncing a publication will create a Drupal page for every publicatoin record in the Chado database. Click the button below to sync all publications in Chado that currently are not already synced with Drupal.'),
+  $form['sync'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Sync')
+  );
+  $form['sync']['sync_all'] = array(
+    '#markup' => t('<p>Syncing a publication will create a Drupal page for every publicatoin record in the Chado database. Click the button below to sync all publications in Chado that currently are not already synced with Drupal.</p>'),
   );
 
-
-
-  $form['submit'] = array(
+  $form['sync']['submit'] = array(
     '#type' => 'submit',
     '#weight' => 10,
     '#value' => t('Sync Publications')
   );
 
+  $form['cleanup'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Clean Up')
+  );
+  $form['cleanup']['description'] = array(
+    '#markup' => t("<p>With Drupal and chado residing in different databases ".
+        "it is possible that nodes in Drupal and publications in Chado become ".
+        "\"orphaned\".  This can occur if an pub node in Drupal is ".
+        "deleted but the corresponding chado pub is not and/or vice ".
+        "versa. Click the button below to resolve these discrepancies.</p>"),
+    '#weight' => 1,
+  );
+  $form['cleanup']['button'] = array(
+    '#type' => 'submit',
+    '#value' => t('Clean up orphaned publications'),
+    '#weight' => 2,
+  );
+  
   return $form;
 }
 
-
 /*
  *
  */
 function tripal_pub_sync_form_submit($form, $form_state) {
   global $user;    //needed to make the current users details available so access of user id is available
-  $job_args = array();
-  $job_id = tripal_add_job('Sync Publications', 'tripal_pub', 'tripal_pub_sync_pubs', $job_args, $user->uid);
-
+  if ($form_state['values']['op'] == t('Sync Publications')) {
+    $job_args = array();
+    $job_id = tripal_add_job('Sync Publications', 'tripal_pub', 'tripal_pub_sync_pubs', $job_args, $user->uid);
+    
+  }
+  // -------------------------------------
+  // Submit the Cleanup Job if selected
+  if ($form_state['values']['op'] == t('Clean up orphaned publications')) {
+    $job_args = array();
+    tripal_add_job('Cleanup orphaned publications', 'tripal_pub',
+    'tripal_pub_cleanup', $job_args, $user->uid);
+  }
 }
 /**
  *
@@ -36,7 +62,8 @@ function tripal_pub_sync_form_submit($form, $form_state) {
  * @ingroup tripal_pub
  */
 function tripal_pub_sync_pubs($job_id = NULL) {
-
+  global $user;
+  
   // get the list of pubs that have not yet been synced
   // and ignore the default 'NULL' pub. we don't want
   // to sync that one.
@@ -48,60 +75,63 @@ function tripal_pub_sync_pubs($job_id = NULL) {
   ";
   $results = chado_query($sql);
 
-
+  // We'll use the following SQL statement for checking if the pub
+  // already exists as a drupal node.
+  $sql = "SELECT * FROM {chado_pub} WHERE pub_id = :pub_id";
+  
   while ($pub = $results->fetchObject()) {
-    $node = tripal_pub_sync_pub($pub);
+
+    // check if this pub already exists in the drupal database. if it
+    // does then skip this pub and go to the next one.
+    if (!db_query($sql, array(':pub_id' => $pub->pub_id))->fetchObject()) {
+      
+      if(!$pub->pyear) {
+        watchdog('tpub_sync', "Skipping pub without published year: %title.", 
+          array('%title' => $pub->title), WATCHDOG_WARNING);
+        return FALSE;
+      }
+    
+      $new_node = new stdClass();
+      $new_node->pub_id      = $pub->pub_id;
+      $new_node->type        = 'chado_pub';
+      $new_node->uid         = $user->uid;
+      $new_node->title       = substr($pub->title, 0 ,255); // node titles can't be longer than 255 characters
+      $new_node->pubtitle    = $pub->title;
+      $new_node->pyear       = $pub->pyear;
+      $new_node->uniquename  = $pub->uniquename;
+      $new_node->type_id     = $pub->type_id;
+      $new_node->series_name = $pub->series_name;
+    
+      $form = array(); // dummy variable
+      $form_state = array(); // dummy variable
+      node_validate($new_node, $form, $form_state);
+      if (!form_get_errors()) {
+        $node = node_submit($new_node);
+        node_save($node);
+        if ($node->nid) {
+          print "Added $new_node->title\n";
+        }
+      }
+      else {
+        watchdog('tpub_sync', "Unable to create publication node. ID: %pub_id, Title: %title",
+          array('%pub_id' => $pub->pub_id, '%title' => $pub->title), WATCHDOG_WARNING);
+      }
+    }
   }
 }
+
 /**
- * @param $pub
- *   A publication object
+ * Remove orphaned drupal nodes
  *
- * @return
- *   A new Drupal node object on success. FALSE on failure
+ * @param $dummy
+ *   Not Used -kept for backwards compatibility
+ * @param $job_id
+ *   The id of the tripal job executing this function
  *
  * @ingroup tripal_pub
  */
-function tripal_pub_sync_pub($pub) {
-  global $user;
+function tripal_pub_cleanup($dummy = NULL, $job_id = NULL) {
 
-  if(!$pub->pyear) {
-    watchdog('tpub_sync', "Skipping pub without published year: %title.", 
-      array('%title' => $pub->title), WATCHDOG_WARNING);
-    return FALSE;
-  }
+  return tripal_core_clean_orphaned_nodes('pub', $job_id);
 
-  $new_node = new stdClass();
-  $new_node->pub_id      = $pub->pub_id;
-  $new_node->type        = 'chado_pub';
-  $new_node->uid         = $user->uid;
-  $new_node->title       = substr($pub->title, 0 ,255); // node titles can't be longer than 255 characters
-  $new_node->pubtitle    = $pub->title;
-  $new_node->pyear       = $pub->pyear;
-  $new_node->uniquename  = $pub->uniquename;
-  $new_node->type_id     = $pub->type_id;
-  $new_node->series_name = $pub->series_name;
-
-  node_validate($new_node);
-  $errors = form_get_errors();
-  if (!$errors) {
-    $node = node_submit($new_node);
-    node_save($node);
-    if ($node->nid) {
-      print "Added " . $pub->pub_id . "\n";
-    }
-    else {
-      watchdog('tpub_sync', "Unable to create publication node: %title.", 
-        array('%title' => $pub->title), WATCHDOG_ERROR);
-      return FALSE;
-    }
-  }
-  // if there are form errors then we need to reset the form errors cache, print a message and return
-  else {
-    form_set_error(NULL,'',TRUE);
-    watchdog('tpub_sync', "Unable to create publication node: %title\n%errs",
-      array('%title' => $pub->title, '%errs' => print_r($errors, TRUE)), WATCHDOG_ERROR);
-    return FALSE;
-  }
-  return $node;
-}
+}

+ 63 - 142
tripal_pub/includes/tripal_pub.admin.inc

@@ -41,41 +41,67 @@ function tripal_pub_admin_pub_view() {
  */
 function tripal_pub_admin() {
   $form = array();
-
-  // before proceeding check to see if we have any
-  // currently processing jobs. If so, we don't want
-  // to give the opportunity to sync publications
-  $active_jobs = FALSE;
-  if (tripal_get_module_active_jobs('tripal_pub')) {
-    $active_jobs = TRUE;
-  }
-
-  // add the field set for syncing publications
-  if (!$active_jobs) {
-    get_tripal_pub_admin_form_select_search_list($form);
-    get_tripal_pub_admin_form_importing_set($form);
-    get_tripal_pub_admin_form_default_type($form);
-    get_tripal_pub_admin_form_cleanup_set($form);
-  }
-  else {
-    $form['notice'] = array(
-     '#type' => 'fieldset',
-     '#title' => t('Publication Management Temporarily Unavailable')
-    );
-    $form['notice']['message'] = array(
-        '#value' => t('Currently, publication management jobs are waiting or are running. . Managemment features have been hidden until these jobs complete.  Please check back later once these jobs have finished.  You can view the status of pending jobs in the Tripal jobs page.'),
-    );
+  
+  // -----------------------------------------
+  // add in the fields for selecting which fields are used when search for pubs
+  $form['searching'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Searching Options'),
+    '#description' => t("The list of checkboxes below indicate which fields a user 
+      can search with when using the publication search tool.  Check the fields that you want 
+      to allow users to search with.  Click the 'Save configuration' button below to save changes."),
+  );
+  
+  // get publication properties list
+  $properties = array();
+  $properties[] = 'Any Field';
+  $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()) {
+    $properties[$prop->cvterm_id] = $prop->name;
   }
+  $form['searching']['allowed_search_fields'] = array(
+    '#type'    => 'checkboxes',
+    '#options' => $properties,
+    '#prefix'  => '<div style="scroll: auto; border:1px solid #CCCCCC;">',
+    '#suffix'  => '</div>',
+    '#default_value' => variable_get('tripal_pub_allowed_search_fields', array()),
+  );
 
-  return system_settings_form($form);
-}
-
-/**
- *
- * @param $form
- */
-function get_tripal_pub_admin_form_default_type(&$form) {
+  // -----------------------------------------
+  // add the field set for syncing publications 
+  $form['import'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Import Settings'),
+    '#description' => t('During import, Tripal will attempt to find duplicate publications,
+       and will not try to insert a publication that already exists in the database.  It can
+       find duplicates using the title, year, series name (e.g. Journal Name) and media type
+       (e.g. Journal Article etc.).
+       There are several options for how to find a duplicate publication.  Choose the
+       option that best suits your needs.'),
+  );
+  $form['import']['import_duplicate_check'] = array(
+    '#type' => 'radios',
+    '#title' => t('Unique Constraint'),
+    '#options' => array(
+      'title_year' => t('Title and Year'),
+      'title_year_media' => t('Title, Year, Media name (e.g. Journal Name, etc.)'),
+      'title_year_type' => t('Title, Year, Media type (e.g. Journal, Conference Proceedings, etc.'),
+    ),
+    '#default_value' => variable_get('tripal_pub_import_duplicate_check', 'title_year_media'),
+  );
 
+  // -----------------------------------------
   // 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'
@@ -110,99 +136,15 @@ function get_tripal_pub_admin_form_default_type(&$form) {
     '#type' => 'select',
     '#title' => t('Publication Type'),
     '#options' => $pub_types,
-    '#description' => t('Please set a default publiation type used for manual entry of a new publication.  This is useful in the event that someone is manually adding the same
-      publication repetitively'),
+    '#description' => t('Please set a default publiation type used for manual entry of a new 
+      publication.  This is useful in the event that someone is manually adding the same
+      publication type repetitively'),
     '#default_value' => $d_type_id
   );
-}
-/**
- *
- *
- * @ingroup tripal_pub
- */
-function get_tripal_pub_admin_form_importing_set(&$form) {
-  $form['import'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Import Settings')
-  );
-  $form['import']['import_duplicate_check'] = array(
-    '#type' => 'radios',
-    '#title' => t('Unique Constraint'),
-    '#options' => array(
-      'title_year' => t('Title and Year'),
-      'title_year_media' => t('Title, Year, Media name (e.g. Journal Name, etc.)'),
-      'title_year_type' => t('Title, Year, Media type (e.g. Journal, Conference Proceedings, etc.'),
-    ),
-    '#description' => t('During import, Tripal will attempt to find duplicate publications.
-       There are several options for how to find a duplicate publication.  Choose the
-       option that best suits your needs.'),
-    '#default_value' => variable_get('tripal_pub_import_duplicate_check', 'title_year_media'),
-  );
-}
 
-/**
- *
- *
- * @ingroup tripal_pub
- */
-function get_tripal_pub_admin_form_cleanup_set(&$form) {
-  $form['cleanup'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Clean Up')
-  );
-  $form['cleanup']['description'] = array(
-     '#type' => 'item',
-     '#value' => t("With Drupal and chado residing in different databases ".
-        "it is possible that nodes in Drupal and publications in Chado become ".
-        "\"orphaned\".  This can occur if an pub node in Drupal is ".
-        "deleted but the corresponding chado pub is not and/or vice ".
-        "versa. Click the button below to resolve these discrepancies."),
-     '#weight' => 1,
-  );
-  $form['cleanup']['button'] = array(
-    '#type' => 'submit',
-    '#value' => t('Clean up orphaned publications'),
-    '#weight' => 2,
-  );
+  return system_settings_form($form);
 }
 
-/**
- *
- *
- * @ingroup tripal_pub
- */
-function get_tripal_pub_admin_form_select_search_list(&$form) {
-  $form['searching'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Searching Options')
-  );
-  // get publication properties list
-  $properties = array();
-  $properties[] = 'Any Field';
-  $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()) {
-    $properties[$prop->cvterm_id] = $prop->name;
-  }
-  $form['searching']['allowed_search_fields'] = array(
-     '#type'    => 'checkboxes',
-     '#options' => $properties,
-     '#description'   => t("Please select the publication details that users can search by in the publication search form.  If none are selected then all fields will be available to the user."),
-     '#prefix'  => '<div style="scroll: auto; border:1px solid #CCCCCC;">',
-     '#suffix'  => '</div>',
-     '#default_value' => variable_get('tripal_pub_allowed_search_fields', array()),
-  );
-}
 
 /**
  *
@@ -227,29 +169,8 @@ function tripal_pub_admin_validate($form, &$form_state) {
   $default_type = $form_state['values']['type_id'];
   variable_set('tripal_pub_default_type', $default_type);
 
-  // -------------------------------------
-  // Submit the Cleanup Job if selected
-  if ($form_state['values']['op'] == t('Clean up orphaned publications')) {
-    tripal_add_job('Cleanup orphaned publications', 'tripal_pub',
-       'tripal_pub_cleanup', $job_args, $user->uid);
-  }
 }
 
-/**
- * Remove orphaned drupal nodes
- *
- * @param $dummy
- *   Not Used -kept for backwards compatibility
- * @param $job_id
- *   The id of the tripal job executing this function
- *
- * @ingroup tripal_pub
- */
-function tripal_pub_cleanup($dummy = NULL, $job_id = NULL) {
-
-  return tripal_core_clean_orphaned_nodes('pub', $job_id);
-
-}
 
 /**
  *
@@ -260,7 +181,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 } ?>

+ 140 - 52
tripal_pub/theme/tripal_pub/pub_types/conference_proceedings.inc

@@ -1,52 +1,140 @@
-<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>Conference Name</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 
+// 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' => 'Conference Name',
+    'header' => TRUE,
+    'nowrap' => 'nowrap'
+  ),
+  $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)
+);
+// allow site admins to see the pub ID
+if (user_access('access administration pages')) {
+  // Pub ID
+  $rows[] = array(
+    array(
+      'data' => 'Pub ID',
+      'header' => TRUE
+    ),
+    $pub->pub_id
+  );
+}
+// Is Obsolete Row
+if($pub->is_obsolete == TRUE){
+  $rows[] = array(
+    array(
+      'data' => '<div class="tripal_pub-obsolete">This publication is obsolete</div>',
+      'colspan' => 2
+    ),
+  );
+}
+// 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);
+if ($abstract_text) { ?>
+  <p><b>Abstract</b></p>
+  <div style="text-align: justify"><?php print $abstract_text; ?></div> <?php 
+} 

+ 140 - 52
tripal_pub/theme/tripal_pub/pub_types/journal_article.inc

@@ -1,52 +1,140 @@
-<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>Journal Name</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 
+// 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' => 'Journal Name',
+    'header' => TRUE,
+    'nowrap' => 'nowrap'
+  ),
+  $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)
+);
+// allow site admins to see the pub ID
+if (user_access('access administration pages')) {
+  // Pub ID
+  $rows[] = array(
+    array(
+      'data' => 'Pub ID',
+      'header' => TRUE
+    ),
+    $pub->pub_id
+  );
+}
+// Is Obsolete Row
+if($pub->is_obsolete == TRUE){
+  $rows[] = array(
+    array(
+      'data' => '<div class="tripal_pub-obsolete">This publication is obsolete</div>',
+      'colspan' => 2
+    ),
+  );
+}
+// 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);
+if ($abstract_text) { ?>
+  <p><b>Abstract</b></p>
+  <div style="text-align: justify"><?php print $abstract_text; ?></div> <?php 
+} 

+ 116 - 36
tripal_pub/theme/tripal_pub/pub_types/patent.inc

@@ -1,36 +1,116 @@
-<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>Year</th>
-    <td><?php print $pub->pyear; ?></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 
+// 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' => 'Patent',
+    'header' => TRUE,
+    'nowrap' => 'nowrap'
+  ),
+  $pub->series_name,
+);
+// Year
+$rows[] = array(
+  array(
+    'data' => 'Year',
+    'header' => TRUE
+  ),
+  $pub->pyear
+);
+// Citation row
+$rows[] = array(
+  array(
+    'data' => 'Citation',
+    'header' => TRUE
+  ),
+  htmlspecialchars($citation->value)
+);
+// allow site admins to see the pub ID
+if (user_access('access administration pages')) {
+  // Pub ID
+  $rows[] = array(
+    array(
+      'data' => 'Pub ID',
+      'header' => TRUE
+    ),
+    $pub->pub_id
+  );
+}
+// Is Obsolete Row
+if($pub->is_obsolete == TRUE){
+  $rows[] = array(
+    array(
+      'data' => '<div class="tripal_pub-obsolete">This publication is obsolete</div>',
+      'colspan' => 2
+    ),
+  );
+}
+// 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);
+if ($abstract_text) { ?>
+  <p><b>Abstract</b></p>
+  <div style="text-align: justify"><?php print $abstract_text; ?></div> <?php 
+} 

+ 76 - 58
tripal_pub/theme/tripal_pub/tripal_pub_authors.tpl.php

@@ -31,64 +31,82 @@ if (count($authors) > 0) {
 
 if ($has_contacts) { ?>
   <div id="tripal_pub-pubauthors-box" class="tripal_pub-info-box tripal-info-box">
-    <div class="tripal_pub-info-box-title tripal-info-box-title">Authors</div>
-    <div class="tripal_pub-info-box-desc tripal-info-box-desc">Additional information about authors:</div>
-    <table id="tripal_pubauthor_<?php print $rank?>-table" class="tripal_pub-table tripal-table tripal-table-horz"><?php 
-      $rank = 1;
-      foreach ($authors as $author) {
-         
-        // expand the author to include the contact information linked via the pubauthor_contact table
-        $contact = $author->pubauthor_contact[0]->contact_id;
-        $options = array(
-          'return_array' => 1,
-          'include_fk' => array(
-            'type_id' => 1,       
-          ),      
-        );
-        $contact = tripal_core_expand_chado_vars($contact, 'table', 'contactprop', $options);
-        $properties = $contact->contactprop;
-        $options = array('order_by' => array('rank' => 'ASC'));
-        $properties = tripal_core_expand_chado_vars($properties, 'field', 'contactprop.value', $options); 
-        
-        $class = 'tripal_pub-table-odd-row tripal-table-odd-row';
-        if($rank % 2 == 0 ){
-           $class = 'tripal_pub-table-even-row tripal-table-even-row';
-        } ?>            
-        <tr class="<?php print $class?>">
-          <td><?php print $rank?></td>
-          <?php
-          // now build the table for display the authors and their information 
-          if ($contact->nid) {?>
-            <td><?php print l($author->givennames . " " . $author->surname, 'node/' . $contact->nid) ?></td><?php
+    <div class="tripal_pub-info-box-title tripal-info-box-title">Author Details</div>
+    <div class="tripal_pub-info-box-desc tripal-info-box-desc">Additional information about authors:</div> <?php
+    // the $headers array is an array of fields to use as the colum headers.
+    // additional documentation can be found here
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $headers = array('', 'Details');
+    
+    // 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();
+    
+    $rank = 1;
+    foreach ($authors as $author) {
+       
+      // expand the author to include the contact information linked via the pubauthor_contact table
+      $contact = $author->pubauthor_contact[0]->contact_id;
+      $options = array(
+        'return_array' => 1,
+        'include_fk' => array(
+          'type_id' => 1,       
+        ),      
+      );
+      $contact = tripal_core_expand_chado_vars($contact, 'table', 'contactprop', $options);
+      $properties = $contact->contactprop;
+      $options = array('order_by' => array('rank' => 'ASC'));
+      $properties = tripal_core_expand_chado_vars($properties, 'field', 'contactprop.value', $options); 
+      
+      // link the contact to it's node if one exists
+      $contact_name = $author->givennames . " " . $author->surname;
+      if (property_exists($contact, 'nid')) {
+        $contact_name = l($contact_name, 'node/' . $contact->nid);
+      }
+      
+      // Get some additional details about this contact if they exists.
+      $details = '';
+      if (is_array($properties)) {
+        foreach ($properties as $property) {
+          // skip the description and name properties
+          if ($property->type_id->name == "contact_description" or
+              $property->type_id->name == "Surname" or
+              $property->type_id->name == "Given Name" or
+              $property->type_id->name == "First Initials" or
+              $property->type_id->name == "Suffix") {
+            continue;
           }
-          else {?>
-            <td><?php print $author->givennames . " " . $author->surname ?></td><?php
-          } ?>
-          <td> 
-            <table class="tripal-subtable"><?php 
-              if (is_array($properties)) {          
-                foreach ($properties as $property) {
-                  // skip the description and name properties
-                  if ($property->type_id->name == "contact_description" or
-                      $property->type_id->name == "Surname" or
-                      $property->type_id->name == "Given Name" or
-                      $property->type_id->name == "First Initials" or
-                      $property->type_id->name == "Suffix") {
-                    continue;
-                  }?>
-                  <tr>
-                    <td><?php print $property->type_id->name ?></td>
-                    <td>:</td>
-                    <td><?php print $property->value ?></td>
-                  </tr><?php
-                  $i++; 
-                } 
-              }?> 
-            </table>
-          </td>
-        </tr><?php 
-        $rank++;
-      }?>
-    </table>
+          $details .= "<br>" . $property->type_id->name . " : " .  $property->value;
+        }
+      }
+      
+      $rows[] = array(
+        $rank,
+        $contact_name . $details,
+      );
+      $rank++;
+    }
+    
+    // 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-contacts',
+      ),
+      'sticky' => FALSE,
+      'caption' => '',
+      'colgroups' => array(),
+      'empty' => '',
+    );
+    
+    // once we have our table array structure defined, we call Drupal's theme_table()
+    // function to generate the table.
+    print theme_table($table); ?>
   </div><?php      
 }

+ 178 - 62
tripal_pub/theme/tripal_pub/tripal_pub_base.tpl.php

@@ -1,5 +1,17 @@
 <?php
-$node = $variables['node'];
+/*
+ * Note, the table generated by this template that lists the publication
+ * details is generic. It can be customized to look different for different
+ * publication types.  To create a custom template for a given type, create a 
+ * new file in the pub_types directory.  Name the file using the name of the
+ * type. The name must be all lower-case and spaces should be replaced with
+ * and underscore symbol.  For example, to create a custom table for the
+ * "Conference Proceedings", create the file conference_proceedings.inc inside
+ * of the pub_types folder.  Cut and paste the code below that generates the table
+ * structure into the new file.  Then edit to your liking.
+ * 
+ */
+
 $pub = $variables['node']->pub;
 
 // expand the title
@@ -25,6 +37,10 @@ $values = array(
 );
 $abstract = tripal_core_generate_chado_var('pubprop', $values); 
 $abstract = tripal_core_expand_chado_vars($abstract, 'field', 'pubprop.value');
+$abstract_text = '';
+if ($abstract) {
+  $abstract_text = htmlspecialchars($abstract->value);
+}
 
 // get the author list
 $values = array(
@@ -35,10 +51,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,78 +79,173 @@ $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> -->
-  <?php 
-  if ($pub->is_obsolete == 't') { ?>
-    <div class="tripal_pub-obsolete">This publication is obsolete</div> <?php 
-  }  
+  <!-- <div class="tripal_pub-info-box-desc tripal-info-box-desc"></div> --> <?php
 
   // to simplify the template, we have a subdirectory named 'pub_types'.  This directory
   // should have include files each specific to a publication type. If the type is 
   // not present then the base template will be used, otherwise the template in the
   // include file is used.
   $inc_name = strtolower(preg_replace('/ /', '_', $pub->type_id->name)) . '.inc';
-  $inc_path = realpath('./') . '/' . drupal_get_path('theme', 'tripal') . "/tripal_pub/pub_types/$inc_name";
+  $inc_path = drupal_realpath(drupal_get_path('module', 'tripal_pub') . "/theme/tripal_pub/pub_types/$inc_name");
   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 { 
+    // ========================================================================
+    // TO CUSTOMIZE A SPECIFIC PUBLICATION TYPE, CUT-AND-PASTE THE CODE
+    // BELOW INTO A NEW FILE WITH THE SAME NAME AS THE TYPE (SEE INSTRUCTIONS
+    // ABOVE), AND EDIT.
+    // ========================================================================
+    
+    // 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' => 'Media Title',
+        'header' => TRUE,
+        'nowrap' => 'nowrap'
+      ),
+      $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)
+    );
+    // allow site admins to see the pub ID
+    if (user_access('access administration pages')) {
+      // Pub ID
+      $rows[] = array(
+        array(
+          'data' => 'Pub ID',
+          'header' => TRUE
+        ),
+        $pub->pub_id
+      );
+    }
+    // Is Obsolete Row
+    if($pub->is_obsolete == TRUE){
+      $rows[] = array(
+        array(
+          'data' => '<div class="tripal_pub-obsolete">This publication is obsolete</div>',
+          'colspan' => 2
+        ),
+      );
+    }
+    // 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);
+    if ($abstract_text) { ?>
+      <p><b>Abstract</b></p>
+      <div style="text-align: justify"><?php print $abstract_text; ?></div> <?php 
+    } 
+    
+    // ========================================================================
+    // END OF CUT-AND-PASTE REGION
+    // ========================================================================
   } ?>
 </div>

+ 72 - 36
tripal_pub/theme/tripal_pub/tripal_pub_featuremaps.tpl.php

@@ -2,15 +2,22 @@
 $pub = $variables['node']->pub;
 $featuremaps = array();
 
-// expand the pub object to include the records from the pub_dbxref table
-// specify the number of genotypes to show by default and the unique pager ID
-$num_results_per_page = 25; 
-$featuremap_pager_id = 5;
+// get the featuremaps that are associated with this publication.  But we only
+// want 25 and we want a pager to let the user cycle between pages of featuremaps.
+// so we, use the tripal_core_chado_select API function to get the results and
+// generate the pager.  The function is smart enough to know which page the user is
+// on and retrieves the proper set of featuremaps
 
-// get the genotypes from the featuremap_genotype table
+$element = 1;        // an index to specify the pager this must be unique amongst all pub templates
+$num_per_page = 25;  // the number of featuremaps to show per page$num_results_per_page = 25; 
+
+// get the featuremaps from the featuremap_pub table
 $options = array(  
   'return_array' => 1,
-  'pager' => array('limit' => $num_results_per_page, 'element' => $featuremap_pager_id),
+  'pager' => array(
+    'limit'   => $num_per_page, 
+    'element' => $element
+  ),
 );
 
 $pub = tripal_core_expand_chado_vars($pub, 'table', 'featuremap_pub', $options);
@@ -21,40 +28,69 @@ if (count($featuremap_pubs) > 0 ) {
   }
 }
 
-// create the pager.  
-global $pager_total_items;
-$featuremap_pager = theme('pager', array(), $num_results_per_page, $featuremap_pager_id, array('block' => 'featuremaps'));
-$total_featuremaps = $pager_total_items[$featuremap_pager_id];
-
+// the total number of records for the paged query is stored in a session variable
+$total_records = $_SESSION['chado_pager'][$element]['total_records'];
 
 if(count($featuremaps) > 0){ ?>
   <div id="tripal_pub-featuremaps-box" class="tripal_pub-info-box tripal-info-box">
     <div class="tripal_pub-info-box-title tripal-info-box-title">Maps</div>
-    <div class="tripal_pub-info-box-desc tripal-info-box-desc">This publication contains information about <?php print number_format($total_featuremaps) ?> map(s):</div>
-    <table id="tripal_pub-featuremap-table" class="tripal_pub-table tripal-table tripal-table-horz">
-      <tr>
-        <th>Map Name</th>
-      </tr> <?php
-      $i = 0; 
-      foreach ($featuremaps as $featuremap){         
-        $class = 'tripal_pub-table-odd-row tripal-table-odd-row';
-        if($i % 2 == 0 ){
-           $class = 'tripal_pub-table-even-row tripal-table-even-row';
-        } ?>
-        <tr class="<?php print $class ?>">
-          <td> <?php 
-            if ($featuremap->nid) { 
-              print l($featuremap->name, 'node/' . $featuremap->nid, array('attributes' => array('target' => '_blank')));
-            } 
-            else { 
-              print $featuremap->name;
-            } ?>
-          </td>
-        </tr> <?php
-        $i++;  
-      } ?>
-    </table> <?php 
-    print $featuremap_pager ?>
+    <div class="tripal_pub-info-box-desc tripal-info-box-desc">This publication contains information about <?php print number_format($total_records) ?> maps:</div> <?php 
+
+    // the $headers array is an array of fields to use as the colum headers.
+    // additional documentation can be found here
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $headers = array('Map Name');
+    
+    // the $rows array contains an array of rows where each row is an array
+    // of values for each column of the table in that row.  Additional documentation
+    // can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $rows = array();
+    
+    foreach ($featuremaps as $featuremap){
+       $featuremap_name = $featuremap->name;
+       if (property_exists($featuremap, 'nid')) {
+         $featuremap_name = l($featuremap_name, 'node/' . $featuremap->nid, array('attributes' => array('target' => '_blank')));
+       }
+       
+       $rows[] = array(
+         $featuremap_name,
+       );
+    }
+    // the $table array contains the headers and rows array as well as other
+    // options for controlling the display of the table.  Additional
+    // documentation can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $table = array(
+      'header' => $headers,
+      'rows' => $rows,
+      'attributes' => array(
+        'id' => 'tripal_pub-table-featuremaps',
+      ),
+      '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);
+    
+    // the $pager array values that control the behavior of the pager.  For
+    // documentation on the values allows in this array see:
+    // https://api.drupal.org/api/drupal/includes!pager.inc/function/theme_pager/7
+    // here we add the paramter 'block' => 'featuremaps'. This is because
+    // the pager is not on the default block that appears. When the user clicks a
+    // page number we want the browser to re-appear with the page is loaded.
+    $pager = array(
+      'tags' => array(),
+      'element' => $element,
+      'parameters' => array(
+        'block' => 'featuremaps'
+      ),
+      'quantity' => $num_per_page,
+    );
+    print theme_pager($pager); ?>
   </div><?php 
 }?>
 

+ 74 - 38
tripal_pub/theme/tripal_pub/tripal_pub_features.tpl.php

@@ -2,15 +2,22 @@
 $pub = $variables['node']->pub;
 $features = array();
 
-// expand the pub object to include the records from the pub_dbxref table
-// specify the number of genotypes to show by default and the unique pager ID
-$num_results_per_page = 25; 
-$feature_pager_id = 5;
+// get the features that are associated with this publication.  But we only
+// want 25 and we want a pager to let the user cycle between pages of features.
+// so we, use the tripal_core_chado_select API function to get the results and
+// generate the pager.  The function is smart enough to know which page the user is
+// on and retrieves the proper set of features
 
-// get the genotypes from the feature_genotype table
+$element = 2;        // an index to specify the pager this must be unique amongst all pub templates
+$num_per_page = 25;  // the number of features to show per page$num_results_per_page = 25; 
+
+// get the features from the feature_pub table
 $options = array(  
   'return_array' => 1,
-  'pager' => array('limit' => $num_results_per_page, 'element' => $feature_pager_id),
+  'pager' => array(
+    'limit'   => $num_per_page, 
+    'element' => $element
+  ),
 );
 
 $pub = tripal_core_expand_chado_vars($pub, 'table', 'feature_pub', $options);
@@ -21,42 +28,71 @@ if (count($feature_pubs) > 0 ) {
   }
 }
 
-// create the pager.  
-global $pager_total_items;
-$feature_pager = theme('pager', array(), $num_results_per_page, $feature_pager_id, array('block' => 'features'));
-$total_features = $pager_total_items[$feature_pager_id];
-
+// the total number of records for the paged query is stored in a session variable
+$total_records = $_SESSION['chado_pager'][$element]['total_records'];
 
 if(count($features) > 0){ ?>
   <div id="tripal_pub-features-box" class="tripal_pub-info-box tripal-info-box">
     <div class="tripal_pub-info-box-title tripal-info-box-title">Features</div>
-    <div class="tripal_pub-info-box-desc tripal-info-box-desc">This publication contains information about <?php print number_format($total_features) ?> features:</div>
-    <table id="tripal_pub-feature-table" class="tripal_pub-table tripal-table tripal-table-horz">
-      <tr>
-        <th>Feature Name</th>
-        <th>Type</th>
-      </tr> <?php
-      $i = 0; 
-      foreach ($features as $feature){         
-        $class = 'tripal_pub-table-odd-row tripal-table-odd-row';
-        if($i % 2 == 0 ){
-           $class = 'tripal_pub-table-even-row tripal-table-even-row';
-        } ?>
-        <tr class="<?php print $class ?>">
-          <td> <?php 
-            if ($feature->nid) { 
-              print l($feature->name, 'node/' . $feature->nid, array('attributes' => array('target' => '_blank')));
-            } 
-            else { 
-              print $feature->name;
-            } ?>
-          </td>
-          <td><?php print $feature->type_id->name ?></td>
-        </tr> <?php
-        $i++;  
-      } ?>
-    </table> <?php 
-    print $feature_pager ?>
+    <div class="tripal_pub-info-box-desc tripal-info-box-desc">This publication contains information about <?php print number_format($total_records) ?> features:</div> <?php 
+
+    // the $headers array is an array of fields to use as the colum headers.
+    // additional documentation can be found here
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $headers = array('Feature Name', 'Uniquenaem', 'Type');
+    
+    // the $rows array contains an array of rows where each row is an array
+    // of values for each column of the table in that row.  Additional documentation
+    // can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $rows = array();
+    
+    foreach ($features as $feature){
+       $feature_name = $feature->name;
+       if (property_exists($feature, 'nid')) {
+         $feature_name = l($feature_name, 'node/' . $feature->nid, array('attributes' => array('target' => '_blank')));
+       }
+       
+       $rows[] = array(
+         $feature_name,
+         $feature->uniquename,
+         $feature->type_id->name,
+       );
+    }
+    // the $table array contains the headers and rows array as well as other
+    // options for controlling the display of the table.  Additional
+    // documentation can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $table = array(
+      'header' => $headers,
+      'rows' => $rows,
+      'attributes' => array(
+        'id' => 'tripal_pub-table-features',
+      ),
+      '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);
+    
+    // the $pager array values that control the behavior of the pager.  For
+    // documentation on the values allows in this array see:
+    // https://api.drupal.org/api/drupal/includes!pager.inc/function/theme_pager/7
+    // here we add the paramter 'block' => 'features'. This is because
+    // the pager is not on the default block that appears. When the user clicks a
+    // page number we want the browser to re-appear with the page is loaded.
+    $pager = array(
+      'tags' => array(),
+      'element' => $element,
+      'parameters' => array(
+        'block' => 'features'
+      ),
+      'quantity' => $num_per_page,
+    );
+    print theme_pager($pager); ?>
   </div><?php 
 }?>
 

+ 77 - 40
tripal_pub/theme/tripal_pub/tripal_pub_libraries.tpl.php

@@ -2,15 +2,22 @@
 $pub = $variables['node']->pub;
 $libraries = array();
 
-// expand the pub object to include the records from the pub_dbxref table
-// specify the number of genotypes to show by default and the unique pager ID
-$num_results_per_page = 25; 
-$library_pager_id = 5;
+// get the libraries that are associated with this publication.  But we only
+// want 25 and we want a pager to let the user cycle between pages of libraries.
+// so we, use the tripal_core_chado_select API function to get the results and
+// generate the pager.  The function is smart enough to know which page the user is
+// on and retrieves the proper set of libraries
 
-// get the genotypes from the library_genotype table
+$element = 3;        // an index to specify the pager this must be unique amongst all pub templates
+$num_per_page = 25;  // the number of libraries to show per page$num_results_per_page = 25; 
+
+// get the libraries from the library_pub table
 $options = array(  
   'return_array' => 1,
-  'pager' => array('limit' => $num_results_per_page, 'element' => $library_pager_id),
+  'pager' => array(
+    'limit'   => $num_per_page, 
+    'element' => $element
+  ),
 );
 
 $pub = tripal_core_expand_chado_vars($pub, 'table', 'library_pub', $options);
@@ -21,44 +28,74 @@ if (count($library_pubs) > 0 ) {
   }
 }
 
-// create the pager.  
-global $pager_total_items;
-$library_pager = theme('pager', array(), $num_results_per_page, $library_pager_id, array('block' => 'libraries'));
-$total_libraries = $pager_total_items[$library_pager_id];
-
+// the total number of records for the paged query is stored in a session variable
+$total_records = $_SESSION['chado_pager'][$element]['total_records'];
 
 if(count($libraries) > 0){ ?>
   <div id="tripal_pub-libraries-box" class="tripal_pub-info-box tripal-info-box">
     <div class="tripal_pub-info-box-title tripal-info-box-title">Libraries</div>
-    <div class="tripal_pub-info-box-desc tripal-info-box-desc">This publication contains information about <?php print number_format($total_libraries) ?> libraries:</div>
-    <table id="tripal_pub-library-table" class="tripal_pub-table tripal-table tripal-table-horz">
-      <tr>
-        <th>Library Name</th>
-        <th>Species</th>
-        <th>Type</th>
-      </tr> <?php
-      $i = 0; 
-      foreach ($libraries as $library){         
-        $class = 'tripal_pub-table-odd-row tripal-table-odd-row';
-        if($i % 2 == 0 ){
-           $class = 'tripal_pub-table-even-row tripal-table-even-row';
-        } ?>
-        <tr class="<?php print $class ?>">
-          <td> <?php 
-            if ($library->nid) { 
-              print l($library->name, 'node/' . $library->nid, array('attributes' => array('target' => '_blank')));
-            } 
-            else { 
-              print $library->name;
-            } ?>
-          </td>
-          <td><?php print $library->type_id->name ?></td>
-          <td><?php print $library->organism_id->genus ?> <?php print $library->organism_id->species ?></td>
-        </tr> <?php
-        $i++;  
-      } ?>
-    </table> <?php 
-    print $library_pager ?>
+    <div class="tripal_pub-info-box-desc tripal-info-box-desc">This publication contains information about <?php print number_format($total_records) ?> libraries:</div> <?php 
+
+    // the $headers array is an array of fields to use as the colum headers.
+    // additional documentation can be found here
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $headers = array('Library Name', 'Unique Name', 'Organism');
+    
+    // the $rows array contains an array of rows where each row is an array
+    // of values for each column of the table in that row.  Additional documentation
+    // can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $rows = array();
+    
+    foreach ($libraries as $library){
+       $library_name = $library->name;
+       if (property_exists($library, 'nid')) {
+         $library_name = l($library_name, 'node/' . $library->nid, array('attributes' => array('target' => '_blank')));
+       }
+       $organism = '<i>' . $library->organism_id->genus . ' ' . $library->organism_id->species . '</i>';
+       if (property_exists($library->organism_id, 'nid')) {
+         $organism = l($organism, 'node/' . $library->organism_id->nid, array('attributes' => array('target' => '_blank')));
+       }
+       $rows[] = array(
+         $library_name,
+         $library->uniquename,
+         $organism,
+       );
+    }
+    // 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-libraries',
+      ),
+      'sticky' => FALSE,
+      'caption' => '',
+      'colgroups' => array(),
+      'empty' => '',
+    );
+    // once we have our table array structure defined, we call Drupal's theme_table()
+    // function to generate the table.
+    print theme_table($table);
+    
+    // the $pager array values that control the behavior of the pager.  For
+    // documentation on the values allows in this array see:
+    // https://api.drupal.org/api/drupal/includes!pager.inc/function/theme_pager/7
+    // here we add the paramter 'block' => 'libraries'. This is because
+    // the pager is not on the default block that appears. When the user clicks a
+    // page number we want the browser to re-appear with the page is loaded.
+    $pager = array(
+      'tags' => array(),
+      'element' => $element,
+      'parameters' => array(
+        'block' => 'libraries'
+      ),
+      'quantity' => $num_per_page,
+    );
+    print theme_pager($pager); ?>
   </div><?php 
 }?>
 

+ 76 - 36
tripal_pub/theme/tripal_pub/tripal_pub_projects.tpl.php

@@ -2,15 +2,22 @@
 $pub = $variables['node']->pub;
 $projects = array();
 
-// expand the pub object to include the records from the pub_dbxref table
-// specify the number of genotypes to show by default and the unique pager ID
-$num_results_per_page = 25; 
-$project_pager_id = 5;
+// get the features that are associated with this publication.  But we only
+// want 25 and we want a pager to let the user cycle between pages of features.
+// so we, use the tripal_core_chado_select API function to get the results and
+// generate the pager.  The function is smart enough to know which page the user is
+// on and retrieves the proper set of features
 
-// get the genotypes from the project_genotype table
+$element = 4;        // an index to specify the pager this must be unique amongst all pub templates
+$num_per_page = 25;  // the number of projects to show per page$num_results_per_page = 25; 
+
+// get the projects from the project_pub table
 $options = array(  
   'return_array' => 1,
-  'pager' => array('limit' => $num_results_per_page, 'element' => $project_pager_id),
+  'pager' => array(
+    'limit'   => $num_per_page, 
+    'element' => $element
+  ),
 );
 
 $pub = tripal_core_expand_chado_vars($pub, 'table', 'project_pub', $options);
@@ -21,40 +28,73 @@ if (count($project_pubs) > 0 ) {
   }
 }
 
-// create the pager.  
-global $pager_total_items;
-$project_pager = theme('pager', array(), $num_results_per_page, $project_pager_id, array('block' => 'projects'));
-$total_projects = $pager_total_items[$project_pager_id];
-
+// the total number of records for the paged query is stored in a session variable
+$total_records = $_SESSION['chado_pager'][$element]['total_records'];
 
 if(count($projects) > 0){ ?>
   <div id="tripal_pub-projects-box" class="tripal_pub-info-box tripal-info-box">
     <div class="tripal_pub-info-box-title tripal-info-box-title">Projects</div>
-    <div class="tripal_pub-info-box-desc tripal-info-box-desc">This publication contains information about <?php print number_format($total_projects) ?> projects:</div>
-    <table id="tripal_pub-project-table" class="tripal_pub-table tripal-table tripal-table-horz">
-      <tr>
-        <th>Project Name</th>
-      </tr> <?php
-      $i = 0; 
-      foreach ($projects as $project){         
-        $class = 'tripal_pub-table-odd-row tripal-table-odd-row';
-        if($i % 2 == 0 ){
-           $class = 'tripal_pub-table-even-row tripal-table-even-row';
-        } ?>
-        <tr class="<?php print $class ?>">
-          <td> <?php 
-            if ($project->nid) { 
-              print l($project->name, 'node/' . $project->nid, array('attributes' => array('target' => '_blank')));
-            } 
-            else { 
-              print $project->name;
-            } ?>
-          </td>
-        </tr> <?php
-        $i++;  
-      } ?>
-    </table> <?php 
-    print $project_pager ?>
+    <div class="tripal_pub-info-box-desc tripal-info-box-desc">This publication contains information about <?php print number_format($total_records) ?> projects:</div> <?php 
+
+    // the $headers array is an array of fields to use as the colum headers.
+    // additional documentation can be found here
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $headers = array('Project Name', 'Description');
+    
+    // the $rows array contains an array of rows where each row is an array
+    // of values for each column of the table in that row.  Additional documentation
+    // can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $rows = array();
+    
+    foreach ($projects as $project){
+       $project_name = $project->name;
+       if (property_exists($project, 'nid')) {
+         $project_name = l($project_name, 'node/' . $project->nid, array('attributes' => array('target' => '_blank')));
+       }
+       $description =  substr($project->description, 0, 200);
+       if (strlen($project->description) > 200) {
+         $description .= "... " . l("[more]", 'node/' . $project->nid, array('attributes' => array('target' => '_blank')));
+       } 
+       $rows[] = array(
+         $project_name,
+         $description
+       );
+    }
+    // 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-projects',
+      ),
+      '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);
+    
+    // the $pager array values that control the behavior of the pager.  For
+    // documentation on the values allows in this array see:
+    // https://api.drupal.org/api/drupal/includes!pager.inc/function/theme_pager/7
+    // here we add the paramter 'block' => 'projects'. This is because
+    // the pager is not on the default block that appears. When the user clicks a
+    // page number we want the browser to re-appear with the page is loaded.
+    $pager = array(
+      'tags' => array(),
+      'element' => $element,
+      'parameters' => array(
+        'block' => 'projects'
+      ),
+      'quantity' => $num_per_page,
+    );
+    print theme_pager($pager); ?>
   </div><?php 
 }?>
 

+ 59 - 49
tripal_pub/theme/tripal_pub/tripal_pub_properties.tpl.php

@@ -24,54 +24,64 @@ if (is_array($pubprops)) {
   }
 }
 // we'll keep track of the keywords so we can lump them into a single row
-$keywords = array(); ?>
+$keywords = array(); 
+
+if (count($properties)) { ?>
   <div id="tripal_pub-properties-box" class="tripal_pub-info-box tripal-info-box">
-    <div class="tripal_pub-info-box-title tripal-info-box-title">More Details</div>
-    <div class="tripal_pub-info-box-desc tripal-info-box-desc">Additional details for this publication include:</div>
-    <table class="tripal_pub-table tripal-table tripal-table-horz">
-      <tr>
-        <th>Property Name</th>
-        <th>Value</th>
-      </tr> <?php
-      if (count($properties) > 0) {
-        $i = 0;
-        foreach ($properties as $property) {
-          if ($property->type_id->name == 'Keywords') {
-            $keywords[] = $property->value;
-            continue;
-          }
-          $class = 'tripal_pub-table-odd-row tripal-table-odd-row';
-          if ($i % 2 == 0 ) {
-             $class = 'tripal_pub-table-odd-row tripal-table-even-row';
-          }
-          $i++; 
-          ?>
-          <tr class="<?php print $class ?>">
-            <td nowrap><?php print $property->type_id->name ?></td>
-            <td><?php print $property->value ?></td>
-          </tr><?php 
-        } 
-        if (count($keywords) > 0) {
-          $class = 'tripal_pub-table-odd-row tripal-table-odd-row';
-          if ($i % 2 == 0 ) {
-             $class = 'tripal_pub-table-odd-row tripal-table-even-row';
-          }
-          $i++; 
-          ?>
-          <tr class="<?php print $class ?>">
-            <td nowrap>Keywords</td>
-            <td><?php print implode(', ', $keywords) ?></td>
-          </tr><?php   
-        }
-        $class = 'tripal_pub-table-odd-row tripal-table-odd-row';
-        if ($i % 2 == 0 ) {
-           $class = 'tripal_pub-table-odd-row tripal-table-even-row';
-        }
-      } ?>
-    <tr class="<?php print $class ?>">
-      <td>Internal ID</td>
-      <td style="text-align:justify;"><?php print $pub->pub_id; ?></td>
-    </tr>
-  </table> 
-</div> <?php
+    <div class="tripal_pub-info-box-title tripal-info-box-title">Additional Properties</div>
+    <div class="tripal_pub-info-box-desc tripal-info-box-desc">Additional details for this publication include:</div> <?php 
+  
+    // the $headers array is an array of fields to use as the colum headers.
+    // additional documentation can be found here
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $headers = array('Property Name', 'Value');
+    
+    // the $rows array contains an array of rows where each row is an array
+    // of values for each column of the table in that row.  Additional documentation
+    // can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $rows = array();
+    
+    $keywords = array();
+    foreach ($properties as $property) {
+      // each keyword is stored as a seperate properties. We want to show them
+      // only in a single field not as a bunc of individual properties, so when we see one, 
+      // save it in an array for later and down't add it yet to the table yet.
+      if ($property->type_id->name == 'Keywords') {
+        $keywords[] = $property->value;
+        continue;
+      }
+      $rows[] = array(
+        $property->type_id->name,
+        $property->value
+      );
+    }
+    // now add in a single row for all keywords
+    if (count($keywords) > 0) {
+      $rows[] = array(
+        'Keywords',
+        implode(', ', $keywords),
+      );
+    } 
 
+    // 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-properties',
+      ),
+      'sticky' => FALSE,
+      'caption' => '',
+      'colgroups' => array(),
+      'empty' => '',
+    );
+    
+    // once we have our table array structure defined, we call Drupal's theme_table()
+    // function to generate the table.
+    print theme_table($table);?> 
+  </div> <?php
+}

+ 54 - 38
tripal_pub/theme/tripal_pub/tripal_pub_references.tpl.php

@@ -1,11 +1,13 @@
 <?php
 $pub = $variables['node']->pub;
-$references = array();
+
 
 // expand the pub object to include the records from the pub_dbxref table
 $options = array('return_array' => 1);
 $pub = tripal_core_expand_chado_vars($pub, 'table', 'pub_dbxref', $options);
 $pub_dbxrefs = $pub->pub_dbxref;
+
+$references = array();
 if (count($pub_dbxrefs) > 0 ) {
   foreach ($pub_dbxrefs as $pub_dbxref) {    
     $references[] = $pub_dbxref->dbxref_id;
@@ -15,42 +17,56 @@ if (count($pub_dbxrefs) > 0 ) {
 if(count($references) > 0){ ?>
   <div id="tripal_pub-references-box" class="tripal_pub-info-box tripal-info-box">
     <div class="tripal_pub-info-box-title tripal-info-box-title">Cross References</div>
-    <div class="tripal_pub-info-box-desc tripal-info-box-desc">This publication is also available in the following databases:</div>
-    <table id="tripal_pub-references-table" class="tripal_pub-table tripal-table tripal-table-horz">
-      <tr>
-        <th>Dababase</th>
-        <th>Accession</th>
-      </tr> <?php
-      $i = 0; 
-      foreach ($references as $dbxref){         
-        $class = 'tripal_pub-table-odd-row tripal-table-odd-row';
-        if($i % 2 == 0 ){
-           $class = 'tripal_pub-table-even-row tripal-table-even-row';
-        } ?>
-        <tr class="<?php print $class ?>">
-          <td> <?php 
-            if ($dbxref->db_id->url) { 
-              print l($dbxref->db_id->name, $dbxref->db_id->url, array('attributes' => array('target' => '_blank'))) . '<br>' . $dbxref->db_id->description;             
-            } 
-            else { 
-              print $dbxref->db_id->name . '<br>' . $dbxref->db_id->description;
-            } ?>
-          </td>
-          <td> <?php 
-            if ($dbxref->db_id->urlprefix) { 
-              print l($dbxref->db_id->name . ':' . $dbxref->accession, $dbxref->db_id->urlprefix . $dbxref->accession, array('attributes' => array('target' => '_blank')));
-            } 
-            else { 
-              print $dbxref->db_id->name . ':' . $dbxref->accession; 
-            }
-            if ($dbxref->is_primary) {
-              print " <i>(primary cross-reference)</i>";
-            } ?>
-          </td>
-        </tr> <?php
-        $i++;  
-      } ?>
-    </table>
+    <div class="tripal_pub-info-box-desc tripal-info-box-desc">This publication is also available in the following databases:</div><?php 
+    
+    // the $headers array is an array of fields to use as the colum headers.
+    // additional documentation can be found here
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $headers = array('Database', 'Accession');
+    
+    // the $rows array contains an array of rows where each row is an array
+    // of values for each column of the table in that row.  Additional documentation
+    // can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $rows = array();
+    
+    foreach ($references as $dbxref){
+      $database = $dbxref->db_id->name . ': ' . $dbxref->db_id->description;
+      if ($dbxref->db_id->url) {
+        $database = l($dbxref->db_id->name, $dbxref->db_id->url, array('attributes' => array('target' => '_blank'))) . ': ' . $dbxref->db_id->description; 
+      }
+      $accession = $dbxref->db_id->name . ':' . $dbxref->accession;
+      if ($dbxref->db_id->urlprefix) {
+        $accession = l($accession, $dbxref->db_id->urlprefix . $dbxref->accession, array('attributes' => array('target' => '_blank')));
+      }
+      if (property_exists($dbxref, 'is_primary')) {
+        $accession .= " <i>(primary cross-reference)</i>";
+      }
+      
+      $rows[] = array(
+        $database,
+        $accession
+      );
+    }
+    // the $table array contains the headers and rows array as well as other
+    // options for controlling the display of the table.  Additional
+    // documentation can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $table = array(
+      'header' => $headers,
+      'rows' => $rows,
+      'attributes' => array(
+        'id' => 'tripal_pub-table-references',
+      ),
+      'sticky' => FALSE,
+      'caption' => '',
+      'colgroups' => array(),
+      'empty' => '',
+    );
+    
+    // once we have our table array structure defined, we call Drupal's theme_table()
+    // function to generate the table.
+    print theme_table($table);?>
   </div><?php 
-}?>
+}
 

+ 138 - 69
tripal_pub/theme/tripal_pub/tripal_pub_relationships.tpl.php

@@ -1,81 +1,150 @@
 <?php
-// this template does not follow the typical Tripal API. Normally
-// variables are expanded using the tripal_core_expand_chado_vars API
-// function call, but expanding the relationships table does not yeild
-// a meaningful order to the data.  Therefore, relationships are preprocessed
-// into an array named 'all_relationships', which is used in the template below.
-
+/* Typically in a Tripal template, the data needed is retrieved using a call to
+ * tripal_core_expand_chado_vars function.  For example, to retrieve all 
+ * of the pub relationships for this node, the following function call would be made:
+ * 
+ *   $pub = tripal_core_expand_chado_vars($pub,'table','pub_relationship');
+ * 
+ * However, this function call can be extremely slow when there are numerous relationships.
+ * This is because the tripal_core_expand_chado_vars function is recursive and expands 
+ * all data following the foreign key relationships tree.  Therefore, to speed retrieval
+ * of data, a special variable is provided to this template:
+ * 
+ *   $pub->all_relationships;
+ *   
+ * This variable is an array with two sub arrays with the keys 'object' and 'subject'.  The array with
+ * key 'object' contains relationships where the pub is the object, and the array with
+ * the key 'subject' contains relationships where the pub is the subject
+ */
 $pub = $variables['node']->pub;
 
 $all_relationships = $pub->all_relationships;
 $object_rels = $all_relationships['object'];
 $subject_rels = $all_relationships['subject'];
 
-// make the pub type a bit more human readable
-$pub_type =  preg_replace("/_/", ' ', $pub->type_id->name);
-
-if (count($object_rels) > 0 or count($subject_rels) > 0) {
-?>
+if (count($object_rels) > 0 or count($subject_rels) > 0) { ?>
   <div id="tripal_pub-relationships-box" class="tripal_pub-info-box tripal-info-box">
     <div class="tripal_pub-info-box-title tripal-info-box-title">Relationships</div>
-    <!--  <div class="tripal_pub-info-box-desc tripal-info-box-desc"></div> --><?php
+    <div class="tripal_pub-info-box-desc tripal-info-box-desc"></div> <?php
+    // first add in the subject relationships.  
+    foreach ($subject_rels as $rel_type => $rels){
+      foreach ($rels as $obj_type => $objects){ ?>
+        <p>This <?php print $pub->type_id->name;?> is <?php print $rel_type ?> the following <b><?php print $obj_type ?></b> pub(s): <?php
+         
+        // the $headers array is an array of fields to use as the colum headers.
+        // additional documentation can be found here
+        // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+        $headers = array('Publication');
+        
+        // the $rows array contains an array of rows where each row is an array
+        // of values for each column of the table in that row.  Additional documentation
+        // can be found here:
+        // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+        $rows = array();
+        
+        foreach ($objects as $object){
+          // link the pub to it's node
+          $title = $object->record->object_id->title;
+          if (property_exists($object->record, 'nid')) {
+            $title = l($title, "node/" . $object->record->nid, array('attributes' => array('target' => "_blank")));
+          }
+          
+          // get the citation
+          $values = array(
+            'pub_id' => $object->record->object_id->pub_id,
+            'type_id' => array(
+              'name' => 'Citation',
+            ),
+          );
+          $citation = tripal_core_generate_chado_var('pubprop', $values);
+          $citation = tripal_core_expand_chado_vars($citation, 'field', 'pubprop.value');
+          
+          $rows[] = array(
+            $title . '<br>' . htmlspecialchars($citation->value),
+          ); 
+         } 
+         // the $table array contains the headers and rows array as well as other
+         // options for controlling the display of the table.  Additional
+         // documentation can be found here:
+         // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+         $table = array(
+           'header' => $headers,
+           'rows' => $rows,
+           'attributes' => array(
+             'id' => 'tripal_pub-table-relationship-object',
+           ),
+           '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); ?>
+         </p>
+         <br><?php
+       }
+    }
     
-      // first add in the subject relationships.  
-      foreach ($subject_rels as $rel_type => $rels){
-         // make the type a bit more human readable
-         $rel_type = preg_replace("/_/", ' ', $rel_type);
-         $rel_type = preg_replace("/^is/", '', $rel_type);
-         // iterate through each parent   
-         foreach ($rels as $obj_type => $objects){?>
-           <p>This pub is a <b><?php print $rel_type ?></b> of the following pub(s):
-           <table id="tripal_pub-relationships_as_object-table" class="tripal_pub-table tripal-table tripal-table-horz">
-             <tr>
-               <th>pub Name</th>
-             </tr> <?php
-             foreach ($objects as $object){ ?>
-               <tr>
-                 <td><?php 
-                    if ($object->nid) {
-                      print "<a href=\"" . url("node/" . $object->nid) . "\" target=\"_blank\">" . $object->title . "</a>";
-                    }
-                    else {
-                      print $object->name;
-                    } ?>
-                 </td>
-               </tr> <?php
-             } ?>
-             </table>
-             </p><br><?php
-         }
-      }
-      
-      // second add in the object relationships.  
-      foreach ($object_rels as $rel_type => $rels){
-         // make the type more human readable
-         $rel_type = preg_replace('/_/', ' ', $rel_type);
-         $rel_type = preg_replace("/^is/", '', $rel_type);
-         // iterate through the children         
-         foreach ($rels as $subject_type => $subjects){?>
-           <p>The following pubs are a <b><?php print $rel_type ?></b> of this pub:
-           <table id="tripal_pub-relationships_as_object-table" class="tripal_pub-table tripal-table tripal-table-horz">
-             <tr>
-               <th>Title</th>
-             </tr> <?php
-             foreach ($subjects as $subject){ ?>
-               <tr>
-                 <td><?php 
-                    if ($subject->nid) {
-                      print "<a href=\"" . url("node/" . $subject->nid) . "\" target=\"_blank\">" . $subject->title . "</a>";
-                    }
-                    else {
-                      print $subject->name;
-                    } ?>
-                 </td>
-               </tr> <?php
-             } ?>
-             </table>
-             </p><br><?php
-         }
-      } ?>
+    // second add in the object relationships.  
+    foreach ($object_rels as $rel_type => $rels){
+      foreach ($rels as $subject_type => $subjects){?>
+        <p>The following <b><?php print $subjects[0]->record->subject_id->type_id->name ?></b> pub(s) are <?php print $rel_type ?> this <?php print $pub->type_id->name;?>: <?php 
+        // the $headers array is an array of fields to use as the colum headers.
+        // additional documentation can be found here
+        // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+        $headers = array('Publication');
+        
+        // the $rows array contains an array of rows where each row is an array
+        // of values for each column of the table in that row.  Additional documentation
+        // can be found here:
+        // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+        $rows = array();
+        
+        foreach ($subjects as $subject){
+          // link the pub to it's node
+          $title = $subject->record->subject_id->title;
+          if (property_exists($subject->record, 'nid')) {
+            $title = l($title, "node/" . $subject->record->nid, array('attributes' => array('target' => "_blank")));
+          }
+          
+          // get the citation
+          $values = array(
+            'pub_id' => $subject->record->subject_id->pub_id,
+            'type_id' => array(
+              'name' => 'Citation',
+            ),
+          );
+          $citation = tripal_core_generate_chado_var('pubprop', $values);
+          $citation = tripal_core_expand_chado_vars($citation, 'field', 'pubprop.value');
+          
+          $rows[] = array(
+            $title . '<br>' . htmlspecialchars($citation->value),
+          );
+         } 
+         // the $table array contains the headers and rows array as well as other
+         // options for controlling the display of the table.  Additional
+         // documentation can be found here:
+         // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+         $table = array(
+           'header' => $headers,
+           'rows' => $rows,
+           'attributes' => array(
+             'id' => 'tripal_pub-table-relationship-subject',
+           ),
+           '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); ?>
+         </p>
+         <br><?php
+       }
+    }?>
   </div> <?php
 }

+ 74 - 38
tripal_pub/theme/tripal_pub/tripal_pub_stocks.tpl.php

@@ -2,15 +2,22 @@
 $pub = $variables['node']->pub;
 $stocks = array();
 
-// expand the pub object to include the records from the pub_dbxref table
-// specify the number of genotypes to show by default and the unique pager ID
-$num_results_per_page = 25; 
-$stock_pager_id = 5;
+// get the stocks that are associated with this publication.  But we only
+// want 25 and we want a pager to let the user cycle between pages of stocks.
+// so we, use the tripal_core_chado_select API function to get the results and
+// generate the pager.  The function is smart enough to know which page the user is
+// on and retrieves the proper set of stocks
 
-// get the genotypes from the stock_genotype table
+$element = 5;        // an index to specify the pager this must be unique amongst all pub templates
+$num_per_page = 25;  // the number of stocks to show per page$num_results_per_page = 25; 
+
+// get the stocks from the stock_pub table
 $options = array(  
   'return_array' => 1,
-  'pager' => array('limit' => $num_results_per_page, 'element' => $stock_pager_id),
+  'pager' => array(
+    'limit'   => $num_per_page, 
+    'element' => $element
+  ),
 );
 
 $pub = tripal_core_expand_chado_vars($pub, 'table', 'stock_pub', $options);
@@ -21,42 +28,71 @@ if (count($stock_pubs) > 0 ) {
   }
 }
 
-// create the pager.  
-global $pager_total_items;
-$stock_pager = theme('pager', array(), $num_results_per_page, $stock_pager_id, array('block' => 'stocks'));
-$total_stocks = $pager_total_items[$stock_pager_id];
-
+// the total number of records for the paged query is stored in a session variable
+$total_records = $_SESSION['chado_pager'][$element]['total_records'];
 
 if(count($stocks) > 0){ ?>
   <div id="tripal_pub-stocks-box" class="tripal_pub-info-box tripal-info-box">
     <div class="tripal_pub-info-box-title tripal-info-box-title">Stocks</div>
-    <div class="tripal_pub-info-box-desc tripal-info-box-desc">This publication contains information about <?php print number_format($total_stocks) ?> stocks:</div>
-    <table id="tripal_pub-stock-table" class="tripal_pub-table tripal-table tripal-table-horz">
-      <tr>
-        <th>Stock Name</th>
-        <th>Type</th>
-      </tr> <?php
-      $i = 0; 
-      foreach ($stocks as $stock){         
-        $class = 'tripal_pub-table-odd-row tripal-table-odd-row';
-        if($i % 2 == 0 ){
-           $class = 'tripal_pub-table-even-row tripal-table-even-row';
-        } ?>
-        <tr class="<?php print $class ?>">
-          <td> <?php 
-            if ($stock->nid) { 
-              print l($stock->name, 'node/' . $stock->nid, array('attributes' => array('target' => '_blank')));
-            } 
-            else { 
-              print $stock->name;
-            } ?>
-          </td>
-          <td><?php print $stock->type_id->name ?></td>
-        </tr> <?php
-        $i++;  
-      } ?>
-    </table> <?php 
-    print $stock_pager ?>
+    <div class="tripal_pub-info-box-desc tripal-info-box-desc">This publication contains information about <?php print number_format($total_records) ?> stocks:</div> <?php 
+
+    // the $headers array is an array of fields to use as the colum headers.
+    // additional documentation can be found here
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $headers = array('Stock Name', 'Uniquenaem', 'Type');
+    
+    // the $rows array contains an array of rows where each row is an array
+    // of values for each column of the table in that row.  Additional documentation
+    // can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $rows = array();
+    
+    foreach ($stocks as $stock){
+       $stock_name = $stock->name;
+       if (property_exists($stock, 'nid')) {
+         $stock_name = l($stock_name, 'node/' . $stock->nid, array('attributes' => array('target' => '_blank')));
+       }
+       
+       $rows[] = array(
+         $stock_name,
+         $stock->uniquename,
+         $stock->type_id->name,
+       );
+    }
+    // the $table array contains the headers and rows array as well as other
+    // options for controlling the display of the table.  Additional
+    // documentation can be found here:
+    // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+    $table = array(
+      'header' => $headers,
+      'rows' => $rows,
+      'attributes' => array(
+        'id' => 'tripal_pub-table-stocks',
+      ),
+      '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);
+    
+    // the $pager array values that control the behavior of the pager.  For
+    // documentation on the values allows in this array see:
+    // https://api.drupal.org/api/drupal/includes!pager.inc/function/theme_pager/7
+    // here we add the paramter 'block' => 'stocks'. This is because
+    // the pager is not on the default block that appears. When the user clicks a
+    // page number we want the browser to re-appear with the page is loaded.
+    $pager = array(
+      'tags' => array(),
+      'element' => $element,
+      'parameters' => array(
+        'block' => 'stocks'
+      ),
+      'quantity' => $num_per_page,
+    );
+    print theme_pager($pager); ?>
   </div><?php 
 }?>
 

+ 41 - 0
tripal_pub/theme/tripal_pub/tripal_pub_teaser.tpl.php

@@ -0,0 +1,41 @@
+<?php
+$node = $variables['node'];
+$pub = $variables['node']->pub;
+
+// get the citation
+$values = array(
+  'pub_id' => $pub->pub_id, 
+  'type_id' => array(
+    'name' => 'Citation',
+  ),
+);
+$citation = tripal_core_generate_chado_var('pubprop', $values); 
+$citation = tripal_core_expand_chado_vars($citation, 'field', 'pubprop.value'); 
+
+// get the abstract
+$values = array(
+  'pub_id' => $pub->pub_id, 
+  'type_id' => array(
+    'name' => 'Abstract',
+  ),
+);
+$abstract = tripal_core_generate_chado_var('pubprop', $values); 
+$abstract = tripal_core_expand_chado_vars($abstract, 'field', 'pubprop.value');
+$abstract_text = '';
+if ($abstract) {
+  $abstract_text = htmlspecialchars($abstract->value);
+  $abstract_text = substr($abstract_text, 0, 450);
+  $abstract_text .= "... " . l("[more]", "node/$node->nid");
+} 
+
+$teaser_text = "<ul id=\"tripal-pub-teaser-citation\"><li>" . $citation->value . "</li></ul>" . $abstract_text; 
+?>
+
+<div class="tripal_pub-teaser tripal-teaser"> 
+  <div class="tripal-pub-teaser-title tripal-teaser-title"><?php 
+    print l($pub->title, "node/$node->nid", array('html' => TRUE));?>
+  </div>
+  <div class="tripal-pub-teaser-text tripal-teaser-text"><?php 
+    print $teaser_text; ?>
+  </div>
+</div>

+ 0 - 9
tripal_pub/theme/tripal_pub_help.tpl.php

@@ -1,13 +1,4 @@
 <br />
-<h3>Tripal Publication Quick Links</h3>
-<ul>
-	<li><?php print l('Search for Publications', 'find/publications') ?></li>
-	<li><?php print l('Configuration', 'admin/tripal/tripal_pub/configuration') ?></li>
-	<li><?php print l('Sync Publications', 'admin/tripal/tripal_pub/sync') ?></li>
-	<li><?php print l('List of Importers', 'admin/tripal/tripal_pub/import_list') ?></li>
-	<li><?php print l('Add a New Importer', 'admin/tripal/tripal_pub/import/new') ?></li>
-</ul>
-
 <h3>Module Description:</h3>
 <p>The Tripal Publication Module provides the functionality for adding,
 editing, deleting viewing and bulk importing of publications. This

+ 195 - 149
tripal_pub/tripal_pub.module

@@ -129,21 +129,21 @@ function tripal_pub_menu() {
   $items['admin/tripal/chado/tripal_pub/import/new'] = array(
     'title' => t('Add an Importer'),
     'description' => t('Add a new publication importer.'),
-    'page callback' => 'tripal_pub_importer_setup',
-    'page arguments' => array(5, NULL),
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('tripal_pub_importer_setup_form'),
     'access arguments' => array('administer tripal pubs'),
     'type ' => MENU_CALLBACK,
   );
 
   $items['admin/tripal/chado/tripal_pub/import/raw/%'] = array(
     'page callback' => 'tripal_pub_get_raw_data',
-    'page arguments' => array(5),
+    'page arguments' => array(6),
     'access arguments' => array('administer tripal pubs'),
     'type ' => MENU_CALLBACK,
   );
 
   $items['admin/tripal/chado/tripal_pub/import/edit/%'] = array(
-    'page callback' => 'tripal_pub_importer_setup',
+    'page callback' => 'tripal_pub_importer_setup_page',
     'page arguments' => array(4, 5),
     'access arguments' => array('administer tripal pubs'),
     'type ' => MENU_CALLBACK,
@@ -207,77 +207,88 @@ 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(
+    '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_properties' => array(
+    '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_authors' => array(
+    '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_references' => array(
+    '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_relationships' => array(
+    '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_featuremaps' => array(
+    '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_features' => array(
+    '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_libraries' => array(
+    '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_projects' => array(
+    '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_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/theme",
     ),
 
     // themed forms
-    'tripal_pub_importer_setup_form' => array(
-      'arguments' => array('form'),
+    'tripal_pub_importer_setup_form_elements' => array(
+      'render element' => 'form',
     ),
     'tripal_pub_search_form' => array(
-      'arguments' => array('form'),
+      'render element' => 'form',
     ),
-    'chado_pub_node_form' => array(
-      'arguments' => array('form'),
+    
+    // teaser
+    'tripal_pub_teaser' => array(
+      'variables' => array('node' => NULL),
+      'template' => 'tripal_pub_teaser',
+      'path' => "$path/theme/tripal_pub",
     ),
   );
 
@@ -402,20 +413,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 +457,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") {
@@ -487,13 +495,14 @@ function chado_pub_insert($node) {
         $publisher = $value;
         unset($properties[$name]);
       }
-      elseif ($name == "Journal Name" or $name == "Conference Name") {
-        $node->series_name = $value;
+      elseif ($name == "Series Name" or $name == "Journal Name" or $name == "Conference Name") {
+        $series_name = $value;
         unset($properties[$name]);
       }
       elseif ($name == "Journal Country" or $name == "Published Location") {
         $pubplace = $value;
-        unset($properties[$name]);
+        // allow this property to go into the pubprop table so we don't loose info
+        // so don't unset it. But it will also go into the pub.pubplace field
       }
       elseif ($name == "Publication Dbxref") {
         // we will add the cross-references to the pub_dbxref table
@@ -503,8 +512,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 +522,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 +542,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 +566,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 +598,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 +614,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 +641,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,12 +679,13 @@ 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") {
         $pubplace = $value;
-        unset($properties[$name]);
+        // allow this property to go into the pubprop table so we don't loose info
+        // so don't unset it. But it will also go into the pub.pubplace field
       }
       elseif ($name == "Publication Dbxref") {
         // we will add the cross-references to the pub_dbxref table
@@ -713,19 +709,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 +786,7 @@ function chado_pub_load($nodes) {
     
     // set the URL path
     $nodes[$nid]->path = "pub/$pub_id";
-    $nodes[$nid]->pub = $pug;
+    $nodes[$nid]->pub = $pub;
   }
 }
 
@@ -844,7 +840,7 @@ function tripal_pub_preprocess_tripal_pub_relationships(&$variables) {
   // query, therefore we will manually perform the query
   $sql = "
     SELECT P.title, P.pub_id, CP.nid, CVT.name as rel_type
-    FROM pub_relationship PR
+    FROM {pub_relationship} PR
       INNER JOIN {pub} P            ON PR.object_id = P.pub_id
       INNER JOIN {cvterm} CVT       ON PR.type_id   = CVT.cvterm_id
       LEFT JOIN public.chado_pub CP ON P.pub_id     = CP.pub_id
@@ -853,7 +849,7 @@ function tripal_pub_preprocess_tripal_pub_relationships(&$variables) {
   $as_subject = chado_query($sql, array(':subject_id' => $pub->pub_id));
   $sql = "
     SELECT P.title, P.pub_id, CP.nid, CVT.name as rel_type
-    FROM pub_relationship PR
+    FROM {pub_relationship} PR
       INNER JOIN {pub} P            ON PR.subject_id = P.pub_id
       INNER JOIN {cvterm} CVT       ON PR.type_id    = CVT.cvterm_id
       LEFT JOIN public.chado_pub CP ON P.pub_id      = CP.pub_id
@@ -922,7 +918,54 @@ 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
@@ -953,9 +996,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);
+      }
     }
   }
 }
@@ -989,15 +1034,16 @@ function tripal_pub_form_alter(&$form, &$form_state, $form_id) {
     $form['actions']['preview']['#access'] = FALSE;
   }
   if ($form_id == "tripal_pub_importer_setup_form") {
-    // updating the form through the ahah callback sets the action of
+/*    // updating the form through the ahah callback sets the action of
     // the form to the ahah callback URL. We need to set it back
     // to the normal form URL
-    if ($form_state['values']['action'] == 'edit') {
+    if (array_key_exists('values', $form_state) and $form_state['values']['action'] == 'edit') {
       $form['#action'] = url("admin/tripal/chado/tripal_pub/import/edit/" . $form_state['values']['pub_import_id']);
     }
-    if ($form_state['values']['action'] == 'new') {
+    if (array_key_exists('values', $form_state) and $form_state['values']['action'] == 'new') {
       $form['#action'] = url("admin/tripal/chado/tripal_pub/import/new");
     }
+    */
   }
   if ($form_id == "tripal_pub_search_form") {
     $form['#action'] = url("find/publications");

+ 1 - 1
tripal_stock/tripal_stock.module

@@ -641,7 +641,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";