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
ab6f24fc0d

+ 3 - 3
tripal_analysis/theme/tripal_analysis/tripal_analysis_teaser.tpl.php

@@ -3,11 +3,11 @@ $node = $variables['node'];
 $analysis = $variables['node']->analysis;
 $analysis = tripal_core_expand_chado_vars($analysis,'field','analysis.description'); ?>
 
-<div class="tripal_analysis-teaser tripal-teaser"> 
-  <div class="tripal-analysis-teaser-title tripal-teaser-title"><?php 
+<div class="tripal_analysis_blast-teaser tripal-teaser"> 
+  <div class="tripal-analysis-blast-teaser-title tripal-teaser-title"><?php 
     print l($node->title, "node/$node->nid", array('html' => TRUE));?>
   </div>
-  <div class="tripal-analysis-teaser-text tripal-teaser-text"><?php 
+  <div class="tripal-analysis-blast-teaser-text tripal-teaser-text"><?php 
     print substr($analysis->description, 0, 650);
     if (strlen($analysis->description) > 650) {
       print "... " . l("[more]", "node/$node->nid");

+ 4 - 11
tripal_core/api/tripal_core.chado_general.api.inc

@@ -431,15 +431,11 @@ function chado_get_record_with_property($basetable, $property, $record = array()
 
   // Check parameters
   if (!isset($property->type_name) AND !isset($property->type_id)) {
-    tripal_report_error(
-      'chado_api',
-      TRIPAL_ERROR,
+    tripal_report_error('chado_api', TRIPAL_ERROR,
       "chado_get_record_with_property: You must identify the type of property you want to
        select records for by supplying either a type_name or type_id. You identified the
        property as %prop.",
-      array(
-        '%prop'=> print_r($property, TRUE)
-      )
+      array('%prop'=> print_r($property, TRUE))
     );
   }
 
@@ -482,11 +478,8 @@ function chado_get_record_with_property($basetable, $property, $record = array()
   $records = array();
   foreach ($select as $s) {
     $id = $s->{$foreignkey_name};
-    $records[$id] = chado_generate_var(
-      $basetable,
-      array($foreignkey_name => $id),
-      $options
-    );
+    $values = array($foreignkey_name => $id);
+    $records[$id] = chado_generate_var($basetable, $values, $options);
   }
 
   return $records;

+ 21 - 13
tripal_core/api/tripal_core.chado_nodes.dbxrefs.api.inc

@@ -124,17 +124,20 @@
  */
 function chado_add_node_form_dbxrefs(&$form, &$form_state, $details) {
 
-  // Set Defaults for optional fields
+  // Set defaults for optional fields
   $details['fieldset_title'] = 'Additional Database References';
   $details['additional_instructions'] = '';
 
-  // Get Property Types for the Select List
+  // Get the list of databases to display in the dropdown. 
   if (isset($details['select_options'])) {
+    // the callee has provided a list
     $db_options = $details['select_options'];
   }
   else {
+    // get the list of databases from the db table
     $db_options = array(0 => 'Select a Database');
-    $select = chado_select_record('db', array('db_id','name'), array(), array('order_by' => array('name' => 'ASC')));
+    $options = array('order_by' => array('name' => 'ASC'));
+    $select = chado_select_record('db', array('db_id','name'), array(), $options);
     foreach($select as $db) {
       $db_options[$db->db_id] = $db->name;
     }
@@ -196,16 +199,18 @@ function chado_add_node_form_dbxrefs(&$form, &$form_state, $details) {
   }
   else {
     $existing_dbxrefs = chado_query(
-      "SELECT dbxref.dbxref_id, db.name as db_name, db.db_id as db_id, dbxref.accession as accession, dbxref.description as description, dbxref.version
-        FROM {dbxref} dbxref
-        LEFT JOIN {db} db ON db.db_id = dbxref.db_id
-        LEFT JOIN {".$details['linking_table']."} linking_table ON linking_table.dbxref_id = dbxref.dbxref_id
+      "SELECT 
+         db.name as db_name, db.db_id as db_id,
+         dbxref.dbxref_id, dbxref.accession as accession, 
+         dbxref.description as description, dbxref.version
+       FROM {dbxref} dbxref
+         LEFT JOIN {db} db ON db.db_id = dbxref.db_id
+         LEFT JOIN {".$details['linking_table']."} linking_table ON linking_table.dbxref_id = dbxref.dbxref_id
        WHERE linking_table.".$details['base_foreign_key']."= :base_key_value
        ORDER BY db.name ASC, dbxref.version ASC",
        array(':base_key_value' => $details['base_key_value'])
     );
   }
-
   /* The format of the $existing_dbxref's array is either:
    *
    * From the chado_additional_dbxrefs array:
@@ -238,13 +243,16 @@ function chado_add_node_form_dbxrefs(&$form, &$form_state, $details) {
    * an element to the form for each one.
    */
   foreach ($existing_dbxrefs as $dbxref) {
+    
     if (array_key_exists($dbxref->db_id, $db_options)) {
 
-      // Since the version is part of the key, when it is '' we need to use something
-      // in the key to indicate this case. Otherwise, you wouldn't be able to select
-      // those elements from the array (ie: $form['addtl_dbxrefs']['dbxref_table'][9999]['']
-      // doesn't work as expected whereas $form['addtl_dbxrefs']['dbxref_table'][9999][NONE]
-      // is much better)
+      /* Since the dbxref version is part of the unique constraint, when it is 
+       * empty we need to use something in the key to indicate this case. Otherwise, 
+       * you wouldn't be able to select those elements from the array 
+       * (ie: $form['addtl_dbxrefs']['dbxref_table'][9999][''] doesn't work as 
+       * expected whereas $form['addtl_dbxrefs']['dbxref_table'][9999][NONE] 
+       * is much better)
+       */
       $version = (!empty($dbxref->version)) ? $dbxref->version : 'NONE';
 
       $form['addtl_dbxrefs']['dbxref_table'][$dbxref->db_id] = array(

+ 7 - 6
tripal_core/api/tripal_core.chado_variables.api.inc

@@ -63,12 +63,13 @@ function tripal_core_exclude_field_from_feature_by_default() {
 }
 
 /**
- * Generates an object containing the full details of a record(s) in chado.
- *
- * This differs from the objects returned by chado_select_record in so far as all foreign key
- * relationships have been followed meaning you have more complete details. Thus this function
- * should be used whenever you need a full variable and chado_select_record should be used if
- * you only case about a few columns.
+ * Generates an array containing the full details of a record(s) in chado. The 
+ * returned array differs from the array returned by chado_select_record as all foreign key
+ * relationships have been followed and those data are also included. The array
+ * returned by this function can be used with chado_expand_var function to add
+ * additional FK relationships that were not included because they were not
+ * a one-to-one mapping or for fields that were excluded such as large text fields.
+ *  
  *
  * @param $table
  *   The name of the base table to generate a variable for

+ 17 - 2
tripal_core/api/tripal_core.tripal.api.inc

@@ -37,7 +37,10 @@ define('TRIPAL_INFO',6);
 define('TRIPAL_DEBUG',7);
 
 /**
- * Provide better error notice for Tripal
+ * Provide better error notice for Tripal. If the environment variable 
+ * 'TRIPAL_DEBUG' is set to 1 then this function will add backtrace
+ * information to the message.
+ * 
  * @param $type
  *   The catagory to which this message belongs. Can be any string, but the general
  *   practice is to use the name of the module.
@@ -87,6 +90,18 @@ function tripal_report_error($type, $severity, $message, $variables = array(), $
       $severity_string = 'DEBUG';
       break;
   }
+  
+  // get the backtrace and include in the error message, but only if the
+  // TRIPAL_DEBUG environment variable is set.
+  if (getenv('TRIPAL_DEBUG') == 1) {
+    $backtrace = debug_backtrace();
+    $message .= "\nBacktrace:\n";
+    $i = 1;
+    for ($i = 1; $i < count($backtrace); $i++) {
+      $function = $backtrace[$i];
+      $message .= "  $i) " . $function['function'] . "\n";
+    }
+  }
 
   // Send to watchdog
   try {
@@ -102,7 +117,7 @@ function tripal_report_error($type, $severity, $message, $variables = array(), $
     if (sizeof($variables) > 0) {
       $message = str_replace(array_keys($variables), $variables, $message);
     }
-    print $severity_string . ' (' . strtoupper($type) . '):' . $message . "\n";
+    print $severity_string . ' (' . strtoupper($type) . '): ' . $message . "\n";
   }
 }
 

+ 9 - 23
tripal_cv/api/tripal_cv.api.inc

@@ -202,25 +202,17 @@ function cvterm_retrieve($identifiers, $options = array()) {
   }
 
   // If synonym was passed in, then process this first before calling chado_generate_var()
-  if (isset($identifier['synonym'])) {
-    $synonym = $identifier['synonym']['name'];
+  if (array_key_exists('synonym', $identifiers)) {
+    $sname = $identifiers['synonym']['name'];
 
-    $values = array(
-       'synonym' => $synonym,
-    );
-    $statement = "sel_cvtermsynonym_sy";
-    if (isset($identifier['synonym']['cv_id'])) {
-      $values['cvterm_id'] = array('cv_id' => $identifier['synonym']['cv_id']);
-      $statement = "sel_cvtermsynonym_sycv";
+    $values = array('synonym' => $sname);
+    if (array_key_exists('cv_id', $identifiers['synonym'])) {
+      $values['cvterm_id'] = array('cv_id' => $identifiers['synonym']['cv_id']);
     }
-    if (isset($identifier['synonym']['cv_name'])) {
-      $values['cvterm_id'] = array('cv_id' => array('name' => $identifier['synonym']['cv_name']));
-      $statement = "sel_cvtermsynonym_sycv";
+    if (array_key_exists('cv_name', $identifiers['synonym'])) {
+      $values['cvterm_id'] = array('cv_id' => array('name' => $identifiers['synonym']['cv_name']));
     }
-    $options = array(
-      'statement_name' => $statement,
-      'case_insensitive_columns' => array('name')
-    );
+    $options = array('case_insensitive_columns' => array('name'));
     $synonym = chado_select_record('cvtermsynonym', array('cvterm_id'), $values, $options);
 
     // if the synonym doens't exist or more than one record is returned then return false
@@ -240,16 +232,10 @@ function cvterm_retrieve($identifiers, $options = array()) {
     unset($identifiers['property']);
     $cvterm = chado_get_record_with_property('cvterm', $property, $identifiers, $options);
   }
-
   // Else we have a simple case and we can just use chado_generate_var to get the cvterm
   else {
-
     // Try to get the cvterm
-    $cvterm = chado_generate_var(
-      'cvterm',
-      $identifiers,
-      $options
-    );
+    $cvterm = chado_generate_var('cvterm', $identifiers, $options);
   }
 
   // Ensure the cvterm is singular. If it's an array then it is not singular

+ 7 - 4
tripal_db/api/tripal_db.api.inc

@@ -413,9 +413,11 @@ function chado_dbxref_insert_record($values) {
  * @param $record_id
  *   The primary key of the basetable to associate the dbxref with. This should be in integer.
  * @param $dbxref
- *   An associative array describing the dbxref. Valid keys include: 'accession' => the
- *   accession for the dbxref, 'db_name' => the name of the database the dbxref belongs to;
- *   'db_id' => the primary key of the database the dbxref belongs to.
+ *   An associative array describing the dbxref. Valid keys include: 
+ *     'accession' => the accession for the dbxref, 
+ *     'db_name' => the name of the database the dbxref belongs to;
+ *     'db_id' => the db_id from the databaes table of Chado. Substitutes for 'db_name'
+ *     'dbxref_id' => the dbxref_id of the dbxref to assocaite.  Substitutes for all other keys.
  * @param $options
  *   An associative array of options. Valid keys include:
  *    - insert_dbxref: Insert the dbxref if it doesn't already exist. TRUE is the default
@@ -437,7 +439,8 @@ function chado_associate_dbxref($basetable, $record_id, $dbxref, $options = arra
     );
     if (isset($dbxref['db_id'])) {
       $values['db_id'] = $dbxref['db_id'];
-    } elseif (isset($dbxref['db_name'])) {
+    } 
+    elseif (isset($dbxref['db_name'])) {
       $values['db_id'] = array(
         'name' => $dbxref['db_name']
       );

+ 1 - 1
tripal_feature/tripal_feature.module

@@ -184,7 +184,7 @@ function tripal_feature_menu() {
 
   /** Loaders */
   $items['admin/tripal/loaders/fasta_loader'] = array(
-    'title' => 'Multi-FASTA file Loader',
+    'title' => 'FASTA file Loader',
     'description' => 'Load sequences from a multi-FASTA file into Chado',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('tripal_feature_fasta_load_form'),

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

@@ -263,7 +263,7 @@ function chado_featuremap_node_access($node, $op, $account) {
  */
 function chado_featuremap_insert($node) {
 
-  $node->fmapname          = trim($node->fmapname);
+  $node->fmapname       = trim($node->fmapname);
   $node->description    = trim($node->description);
 
   // if there is an featuremap_id in the $node object then this must be a sync so

+ 45 - 130
tripal_pub/api/tripal_pub.DEPRECATED.inc

@@ -7,9 +7,9 @@
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by pub_search_remote().
+ * This function has been replaced by tripal_get_remote_pubs().
  *
- * @see pub_search_remote().
+ * @see tripal_get_remote_pubs().
  */
 function tripal_pub_get_remote_search_results($remote_db, $search_array, $num_to_retrieve, $page = 0) {
 
@@ -19,11 +19,11 @@ function tripal_pub_get_remote_search_results($remote_db, $search_array, $num_to
     "DEPRECATED: %old_function has been replaced with %new_function. Please update your code.",
     array(
       '%old_function'=>'tripal_pub_get_remote_search_results',
-      '%new_function' => 'pub_search_remote'
+      '%new_function' => 'tripal_get_remote_pubs'
     )
   );
-
-  return FALSE;
+  
+  return tripal_get_remote_pubs($remote_db, $search_array, $num_to_retrieve, $page);;
 }
 
 /**
@@ -44,8 +44,8 @@ function tripal_pub_get_raw_data($dbxref) {
       '%new_function' => 'chado_get_remote_pub_record'
     )
   );
-
-  return FALSE;
+  
+  return tripal_get_remote_pub($dbxref);
 }
 
 /**
@@ -63,11 +63,11 @@ function tripal_pub_update_publications($do_contact = FALSE, $dbxref = NULL, $db
     "DEPRECATED: %old_function has been replaced with %new_function. Please update your code.",
     array(
       '%old_function'=>'tripal_pub_update_publications',
-      '%new_function' => 'chado_update_multiple_publications'
+      '%new_function' => 'chado_reimport_publications'
     )
   );
-
-  return FALSE;
+  
+  return chado_reimport_publications($do_contact, $dbxref, $db);
 }
 
 /**
@@ -85,11 +85,11 @@ function tripal_pub_import_publications_by_import_id($import_id, $job_id = NULL)
     "DEPRECATED: %old_function has been replaced with %new_function. Please update your code.",
     array(
       '%old_function'=>'tripal_pub_import_publications_by_import_id',
-      '%new_function' => 'chado_import_multiple_publications'
+      '%new_function' => 'tripal_execute_pub_importer'
     )
   );
 
-  return FALSE;
+  return tripal_execute_pub_importer($import_id, $job_id);
 }
 
 /**
@@ -107,11 +107,11 @@ function tripal_pub_import_publications($report_email = FALSE, $do_update = FALS
     "DEPRECATED: %old_function has been replaced with %new_function. Please update your code.",
     array(
       '%old_function'=>'tripal_pub_import_publications',
-      '%new_function' => 'chado_import_multiple_publications'
+      '%new_function' => 'tripal_execute_active_pub_importers'
     )
   );
 
-  return FALSE;
+  return tripal_execute_active_pub_importers($report_email, $do_update);
 }
 
 /**
@@ -133,29 +133,7 @@ function tripal_pub_import_by_dbxref($pub_dbxref, $do_contact = FALSE, $do_updat
     )
   );
 
-  return FALSE;
-}
-
-/**
- * @deprecated Restructured API to make naming more readable and consistent.
- * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by chado_insert_multiple_publications().
- *
- * @see chado_insert_multiple_publications().
- */
-function tripal_pub_add_publications($pubs, $do_contact, $update = FALSE) {
-
-  tripal_report_error(
-    'tripal_api',
-    TRIPAL_NOTICE,
-    "DEPRECATED: %old_function has been replaced with %new_function. Please update your code.",
-    array(
-      '%old_function'=>'tripal_pub_add_publications',
-      '%new_function' => 'chado_insert_multiple_publications'
-    )
-  );
-
-  return FALSE;
+  return tripal_import_pub_by_dbxref($pub_dbxref, $do_contact, $do_udpate);
 }
 
 /**
@@ -176,8 +154,13 @@ function tripal_pub_add_pub_dbxref($pub_id, $pub_dbxref) {
       '%new_function' => 'chado_associate_dbxref'
     )
   );
-
-  return FALSE;
+ 
+  $dbxref = array();
+  if(preg_match('/^(.*?):(.*?)$/', trim($pub_dbxref), $matches)) {
+    $dbxref['db_name']   = $matches[1];
+    $dbxref['accession'] = $matches[2];
+  }
+  return chado_associate_dbxref('pub', $pub_id, $dbxref);
 }
 
 /**
@@ -198,8 +181,16 @@ function tripal_pub_get_pubs_by_dbxref($pub_dbxref) {
       '%new_function' => 'chado_get_publication'
     )
   );
+  
+  $pub = chado_get_publication(array('dbxref' => $pub_dbxref));
+  if ($pub) {
+    // the original function returned an array of pub_ids
+    return array($pub->pub_id);
+  }
+  else {
+    return array();
+  }
 
-  return FALSE;
 }
 
 /**
@@ -221,7 +212,13 @@ function tripal_pub_get_pubs_by_title_type_pyear_series($title, $type = NULL, $p
     )
   );
 
-  return FALSE;
+  $pub_details = array(
+    'Title' => $title,
+    'Year' => $pyear,
+    'Series Name' => $series_name,
+    'Publication Type' => $type,
+  );
+  return chado_does_pub_exist($pub_details);
 }
 
 /**
@@ -231,7 +228,7 @@ function tripal_pub_get_pubs_by_title_type_pyear_series($title, $type = NULL, $p
  *
  * @see chado_get_publication().
  */
-function tripal_pub_get_pub_by_uniquename($name) {
+function tripal_pub_get_pub_by_uniquename($uniquenname) {
 
   tripal_report_error(
     'tripal_api',
@@ -243,52 +240,14 @@ function tripal_pub_get_pub_by_uniquename($name) {
     )
   );
 
-  return FALSE;
-}
-
-/**
- * @deprecated Restructured API to make naming more readable and consistent.
- * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by chado_insert_publication().
- *
- * @see chado_insert_publication().
- */
-function tripal_pub_add_publication($pub_details, &$action, $do_contact = FALSE, $update_if_exists = FALSE) {
-
-  tripal_report_error(
-    'tripal_api',
-    TRIPAL_NOTICE,
-    "DEPRECATED: %old_function has been replaced with %new_function. Please update your code.",
-    array(
-      '%old_function'=>'tripal_pub_add_publication',
-      '%new_function' => 'chado_insert_publication'
-    )
-  );
-
-  return FALSE;
+  $pub = chado_get_publication(array('uniquename' => $uniquenname));
+  if ($pub) {
+    // the original version of this function returned an array of matching pub_ids
+    return array($pub->pub_id);
+  }
+  return array();
 }
 
-/**
- * @deprecated Restructured API to make naming more readable and consistent.
- * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by chado_insert_multiple_pubauthors().
- *
- * @see chado_insert_multiple_pubauthors().
- */
-function tripal_pub_add_authors($pub_id, $authors, $do_contact) {
-
-  tripal_report_error(
-    'tripal_api',
-    TRIPAL_NOTICE,
-    "DEPRECATED: %old_function has been replaced with %new_function. Please update your code.",
-    array(
-      '%old_function'=>'tripal_pub_add_authors',
-      '%new_function' => 'chado_insert_multiple_pubauthors'
-    )
-  );
-
-  return FALSE;
-}
 
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
@@ -377,47 +336,3 @@ function tripal_pub_delete_property($pub_id, $property) {
 
   return chado_delete_property('pub', $pub_id, $property, 'tripal_pub');
 }
-
-/**
- * @deprecated Restructured API to make naming more readable and consistent.
- * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by chado_get_publication().
- *
- * @see chado_get_publication().
- */
-function tripal_pub_get_publication_array($pub_id, $skip_existing = TRUE) {
-
-  tripal_report_error(
-    'tripal_api',
-    TRIPAL_NOTICE,
-    "DEPRECATED: %old_function has been replaced with %new_function. Please update your code.",
-    array(
-      '%old_function'=>'tripal_pub_get_publication_array',
-      '%new_function' => 'chado_get_publication'
-    )
-  );
-
-  return FALSE;
-}
-
-/**
- * @deprecated Restructured API to make naming more readable and consistent.
- * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by pub_generate_citation().
- *
- * @see pub_generate_citation().
- */
-function tripal_pub_create_citation($pub) {
-
-  tripal_report_error(
-    'tripal_api',
-    TRIPAL_NOTICE,
-    "DEPRECATED: %old_function has been replaced with %new_function. Please update your code.",
-    array(
-      '%old_function'=>'tripal_pub_create_citation',
-      '%new_function' => 'pub_generate_citation'
-    )
-  );
-
-  return FALSE;
-}

+ 429 - 1101
tripal_pub/api/tripal_pub.api.inc

@@ -55,7 +55,7 @@
  *
  * @ingroup tripal_pub_api
  */
-function tripal_pub_get_remote_search_results($remote_db, $search_array, $num_to_retrieve, $page = 0) {
+function tripal_get_remote_pubs($remote_db, $search_array, $num_to_retrieve, $page = 0) {
 
   // now call the callback function to get the results
   $callback = "tripal_pub_remote_search_$remote_db";
@@ -72,21 +72,23 @@ function tripal_pub_get_remote_search_results($remote_db, $search_array, $num_to
 
 /**
  * This function is used to perfom a query using one of the supported databases
- * and return the raw query results. This may be XML or some other format 
+ * and return the raw query results. This may be XML or some other format
  * as provided by the database.
  *
  * @param $dbxref
  *   The unique database ID for the record to retrieve.  This value must
- *   be of the format DB_NAME:ACCESSION where DB_NAME is the name of the 
+ *   be of the format DB_NAME:ACCESSION where DB_NAME is the name of the
  *   database (e.g. PMID or AGL) and the ACCESSION is the unique identifier
  *   for the record in the database.
- *   
+ *
  * @return
- *   Returns the raw output wrapped in an HTML textarea element
+ *   Returns the raw output wrapped in an HTML textarea element or an
+ *   error message indicating if the database type is unsupported or the
+ *   dbxref is invalid
  *
  * @ingroup tripal_pub_api
  */
-function tripal_pub_get_raw_data($dbxref) {
+function tripal_get_remote_pub($dbxref) {
 
   if(preg_match('/^(.*?):(.*?)$/', $dbxref, $matches)) {
     $remote_db = $matches[1];
@@ -107,19 +109,416 @@ function tripal_pub_get_raw_data($dbxref) {
           'scope' => 'id',
           'operation' => '',
           'is_phrase' => 0,
-       ),
+        ),
       ),
     );
-    $pubs = tripal_pub_get_remote_search_results($remote_db, $search, 1, 0);
+    $pubs = tripal_get_remote_pubs($remote_db, $search, 1, 0);
 
-    return '<textarea cols=80 rows=20>' . $pubs[0]['raw'] . '</textarea>';
+    return $pubs[0]['raw'];
   }
   return 'Invalid DB xref';
 }
 
 /**
- * Updates publication records with the most recent data in the remote
- * database.
+ * Builds the SQL statement need to search Chado for the publications
+ * that match the user supplied criteria.  Tpyically, this function is
+ * called by the search form generated by the tripal_pub_search_form() function
+ * but this function is included in the API for calling by anyone. 
+ * 
+ * @param $search_array
+ *   An array of search criteria provided by the user. The search array is
+ *   an associative array with the following keys:
+ *     'num_criteria': an integer indicating the number of search criteria supplied
+ *     'from_year':    filters records by a start year
+ *     'to_year':      filters records by an end year
+ *     'criteria':     an array of criteria. Each criteria is an associative
+ *                     array with the following keys:
+ *                     'search_terms':   The text used for searching
+ *                     'scope':          The cvterm_id of the property used for filtering
+ *                     'mode':           The operation (e.g. AND, OR or NOT)
+ * @param $offset
+ *   The offset for paging records.  The first record returned will be 
+ *   at the offset indicated here, and the next $limit number of records
+ *   will be returned.
+ *   
+ * @param $limit
+ *   The number of records to retrieve
+ *   
+ * @param total_records
+ *   A value passed by reference. This value will get set to the total
+ *   number of matching records
+ *   
+ * @return 
+ *   a PDO database object of the query results.
+ *
+ * @ingroup tripal_pub
+ */
+function pub_search($search_array, $offset, $limit, &$total_records) {
+
+  // build the SQL based on the criteria provided by the user
+  $select = "SELECT DISTINCT P.*, CP.nid ";
+  $from   = "FROM {pub} P
+               LEFT JOIN public.chado_pub CP on P.pub_id = CP.pub_id
+               INNER JOIN {cvterm} CVT on CVT.cvterm_id = P.type_id
+            ";
+  $where  = "WHERE (NOT P.title = 'null') "; // always exclude the dummy pub
+  $order  = "ORDER BY P.pyear DESC, P.title ASC";
+  $args = array();  // arguments for where clause
+  $join = 0;
+
+  $num_criteria = $search_array['num_criteria'];
+  $from_year    = $search_array['from_year'];
+  $to_year      = $search_array['to_year'];
+
+  for ($i = 1; $i <= $num_criteria; $i++) {
+    $value = $search_array['criteria'][$i]['search_terms'];
+    $type_id = $search_array['criteria'][$i]['scope'];
+    $mode = $search_array['criteria'][$i]['mode'];
+    $op = $search_array['criteria'][$i]['operation'];
+
+    // skip criteria with no values
+    if(!$value) {
+      continue;
+    }
+
+    // to prevent SQL injection make sure our operator is
+    // what we expect
+    if ($op and $op != "AND" and $op != "OR" and $op != 'NOT') {
+      $op = 'AND';
+    }
+    if ($op == 'NOT') {
+      $op = 'AND NOT';
+    }
+    if (!$op) {
+      $op = 'AND';
+    }
+
+    // get the scope type
+    $values = array('cvterm_id' => $type_id);
+    $cvterm = chado_select_record('cvterm', array('name'), $values);
+    $type_name = '';
+    if (count($cvterm) > 0) {
+      $type_name = $cvterm[0]->name;
+    }
+    if ($type_name == 'Title') {
+      $where .= " $op (lower(P.title) LIKE lower(:crit$i)) ";
+      $args[":crit$i"] = '%' . $value . '%';
+    }
+    elseif ($type_name == 'Year') {
+      $where .= " $op (lower(P.pyear) = lower(:crit$i)) ";
+      $args[":crit$i"] = '%' . $value . '%';
+    }
+    elseif ($type_name == 'Volume') {
+      $where .= " $op (lower(P.volume) = lower(:crit$i)) ";
+      $args[":crit$i"] = '%' . $value . '%';
+    }
+    elseif ($type_name == 'Issue') {
+      $where .= " $op (lower(P.issue) = lower(:crit$i)) ";
+      $args[":crit$i"] = '%' . $value . '%';
+    }
+    elseif ($type_name == 'Journal Name') {
+      $from .= " LEFT JOIN {pubprop} PP$i ON PP$i.pub_id = P.pub_id AND PP$i.type_id = :crit$i ";
+      $where .= " $op ((lower(P.series_name) = lower(:crit$i) and CVT.name = 'Journal Article') OR
+      (lower(PP$i.value) = lower(:crit$i))) ";
+      $args[":crit$i"] = $type_id;
+    }
+    elseif ($type_name == 'Conference Name') {
+      $from .= " LEFT JOIN {pubprop} PP$i ON PP$i.pub_id = P.pub_id AND PP$i.type_id = :crit$i ";
+      $where .= " $op ((lower(P.series_name) = lower(:crit$i) and CVT.name = 'Conference Proceedings') OR
+      (lower(PP$i.value) = lower(:crit$i))) ";
+      $args[":crit$i"] = $type_id;
+    }
+    elseif ($type_name == 'Publication Type') {
+      $where .= " $op (lower(CVT.name) = lower(:crit$i))";
+      $args[":crit$i"] = $value;
+    }
+    elseif ($type_id == 0) { //'Any Field'
+      $from .= " LEFT JOIN {pubprop} PP$i ON PP$i.pub_id = P.pub_id ";
+      $where .= " $op (lower(PP$i.value)  LIKE lower(:crit$i) OR
+      lower(P.title) LIKE lower(:crit$i) OR
+      lower(P.volumetitle) LIKE lower(:crit$i) OR
+      lower(P.publisher) LIKE lower(:crit$i) OR
+      lower(P.uniquename) LIKE lower(:crit$i) OR
+      lower(P.pubplace) LIKE lower(:crit$i) OR
+      lower(P.miniref) LIKE lower(:crit$i) OR
+      lower(P.series_name) LIKE lower(:crit$i)) ";
+      $args[":crit$i"] = '%' . $value . '%';
+    }
+    // for all other properties
+    else {
+      $from .= " LEFT JOIN {pubprop} PP$i ON PP$i.pub_id = P.pub_id AND PP$i.type_id = :type_id$i ";
+      $where .= " $op (lower(PP$i.value) LIKE lower(:crit$i)) ";
+      $args[":crit$i"] = '%' . $value . '%';
+      $args[":type_id$i"] = $type_id;
+    }
+  }
+  if($from_year and $to_year) {
+    $where .= " AND (P.pyear ~ '....' AND to_number(P.pyear,'9999') >= :from$i AND to_number(P.pyear,'9999') <= :to$i) ";
+    $args[":from$i"] = $from_year;
+    $args[":to$i"] = $to_year;
+  }
+  $sql = "$select $from $where $order  LIMIT " . (int) $limit . ' OFFSET ' . (int) $offset;
+  $count = "SELECT count(*) FROM ($select $from $where $order) as t1";
+  
+  // first get the total number of matches
+  $total_records = chado_query($count, $args)->fetchField();
+  $results = chado_query($sql, $args);
+  
+  return $results;
+}
+
+/**
+ * Retrieves a chado publication array
+ *
+ * @param $identifier
+ *   An array used to uniquely identify a publication. This array has the same
+ *   format as that used by the chado_generate_var(). The following keys can be 
+ *   useful for uniquely identifying a publication as they should be unique:
+ *    - pub_id: the chado pub.pub_id primary key
+ *    - nid: the drupal nid of the publication
+ *    - uniquename: A value to matach with the pub.uniquename field
+ *   There are also some specially handled keys. They are:
+ *    - property: An array describing the property to select records for. It
+ *      should at least have either a 'type_name' key (if unique across cvs) or 
+ *      'type_id' key. Other supported keys include: 'cv_id', 'cv_name' (of the type), 
+ *      'value' and 'rank'
+ *    - dbxref: The database cross reference accession.  It should be in the form
+ *        DB:ACCESSION, where DB is the database name and ACCESSION is the
+ *        unique publication identifier (e.g. PMID:4382934)
+ *    - dbxref_id:  The dbxref.dbxref_id of the publication.
+ * @param $options
+ *   An array of options. Supported keys include:
+ *     - Any keys supported by chado_generate_var(). See that function definition for
+ *       additional details.
+ *
+ * NOTE: the $identifier parameter can really be any array similar to $values passed into
+ *   chado_select_record(). It should fully specify the pub record to be returned.
+ *
+ * @return
+ *   If a singe publication is retreived using the identifiers, then a publication
+ *   array will be returned.  The array is of the same format returned by the 
+ *   chado_generate_var() function. Otherwise, FALSE will be returned.
+ *
+ * @ingroup tripal_pub_api
+ */
+function chado_get_publication($identifiers, $options = array()) {
+
+  // Error Checking of parameters
+  if (!is_array($identifiers)) {
+    tripal_report_error('tripal_pub_api', TRIPAL_ERROR,
+      "chado_get_publication: The identifier passed in is expected to be an array with the key
+       matching a column name in the pub table (ie: pub_id or name). You passed in %identifier.",
+      array('%identifier'=> print_r($identifiers, TRUE))
+    );
+  }
+  elseif (empty($identifiers)) {
+    tripal_report_error('tripal_pub_api', TRIPAL_ERROR,
+      "chado_get_publication: You did not pass in anything to identify the publication you want. The identifier
+       is expected to be an array with the key matching a column name in the pub table
+       (ie: pub_id or name). You passed in %identifier.",
+      array('%identifier'=> print_r($identifiers, TRUE))
+    );
+  }
+  
+  // If one of the identifiers is property then use chado_get_record_with_property()
+  if (array_key_exists('property', $identifiers)) {
+    $property = $identifiers['property'];
+    unset($identifiers['property']);
+    $pub = chado_get_record_with_property('pub', $property, $identifiers, $options);
+  }
+  elseif (array_key_exists('dbxref', $identifiers)) {
+    if(preg_match('/^(.*?):(.*?)$/', $identifiers['dbxref'], $matches)) {
+      $dbname = $matches[1];
+      $accession = $matches[2];
+    
+      $values = array(
+        'dbxref_id' => array (
+          'accession' => $accession,
+          'db_id' => array(
+            'name' => $dbname
+          ),
+        ),
+      );
+      $pub_dbxref = chado_select_record('pub_dbxref', array('pub_id'), $values);
+      if (count($pub_dbxref) > 0) {
+        $pub = chado_generate_var('pub', array('pub_id' => $pub_dbxref[0]->pub_id), $options);
+      }
+      else {
+        return FALSE;
+      }
+    }
+    else {
+      tripal_report_error('tripal_pub_api', TRIPAL_ERROR,
+        "chado_get_publication: The dbxref identifier is not correctly formatted.",
+        array('%identifier'=> print_r($identifiers, TRUE))
+      );
+    }
+  }
+  elseif (array_key_exists('dbxref_id', $identifiers)) {
+    // first get the pub_dbxref record
+    $values = array('dbxref_id' => $identifiers['dbxref_id']);
+    $pub_dbxref = chado_select_record('pub_dbxref', array('pub_id'), $values);
+    
+    // now get the pub 
+    if (count($pub_dbxref) > 0) {
+      $pub = chado_generate_var('pub', array('pub_id' => $pub_dbxref[0]->pub_id), $options);
+    }
+    else {
+      return FALSE;
+    }
+    
+  }
+  // Else we have a simple case and we can just use chado_generate_var to get the pub
+  else {
+    // Try to get the pub
+    $pub = chado_generate_var('pub', $identifiers, $options);
+  }
+  
+  // Ensure the pub is singular. If it's an array then it is not singular
+  if (is_array($pub)) {
+    tripal_report_error('tripal_pub_api', TRIPAL_ERROR,
+      "chado_get_publication: The identifiers did not find a single unique record. Identifiers passed: %identifier.",
+      array('%identifier'=> print_r($identifiers, TRUE))
+    );
+  }
+  
+  // Report an error if $pub is FALSE since then chado_generate_var has failed
+  elseif ($pub === FALSE) {
+    tripal_report_error('tripal_pub_api', TRIPAL_ERROR,
+      "chado_get_publication: Could not find a publication using the identifiers
+       provided. Check that the identifiers are correct. Identifiers passed: %identifier.",
+      array('%identifier'=> print_r($identifiers, TRUE))
+    );
+  }
+  
+  // Else, as far we know, everything is fine so give them their pub :)
+  else {
+    return $pub;
+  }
+}
+/**
+ * The publication table of Chado only has a unique constraint for the
+ * uniquename of the publiation, but in reality a publication can be considered
+ * unique by a combination of the title, publication type, published year and
+ * series name (e.g. journal name or conference name). The site administrator
+ * can configure how publications are determined to be unique.  This function
+ * uses the configuration specified by the administrator to look for publications
+ * that match the details specified by the $pub_details argument
+ * and indicates if one ore more publications match the criteria.
+ *
+ * @param $pub_details
+ *   An associative array with details about the publications. The expected keys
+ *   are:
+ *     'Title':              The title of the publication
+ *     'Year':               The published year of the publication
+ *     'Publication Type':   An array of publication types. A publication can have more than one type.
+ *     'Series Name':        The series name of the publication
+ *     'Journal Name':       An alternative to 'Series Name' is 'Journal Name'
+ *     'Citation':           The publication citation (this is the value saved in the pub.uniquename field and must be unique)
+ *   If this key is present it will also be checked
+ *     'Publication Dbxref': A database cross reference of the form DB:ACCESSION where DB is the name
+ *                           of the database and ACCESSION is the unique identifier (e.g PMID:3483139)
+ *
+ * @return
+ *   An array containing the pub_id's of matching publications.
+ */
+function chado_does_pub_exist($pub_details) {
+  
+
+  // first try to find the publication using the accession number if that key exists in the details array
+  if (array_key_exists('Publication Dbxref', $pub_details)) {
+    $pub = chado_get_publication(array('dbxref' => $pub_details['Publication Dbxref']));
+    if($pub) {
+      return array($pub->pub_id);
+    }
+  }
+  
+  // make sure the citation is unique
+  if (array_key_exists('Citation', $pub_details)) {
+    $pub = chado_get_publication(array('uniquename' => $pub_details['Citation']));
+    if($pub) {
+      return array($pub->pub_id);
+    }
+  }
+
+  // get the publication type (use the first publication type)
+  if (array_key_exists('Publication Type', $pub_details)) {
+    $type_name = '';
+    if(is_array($pub_details['Publication Type'])) {
+      $type_name = $pub_details['Publication Type'][0];
+    }
+    else {
+      $type_name = $pub_details['Publication Type'];
+    }
+    $identifiers = array(
+      'name' => $type_name,
+      'cv_id' => array(
+        'name' => 'tripal_pub',
+      ),
+    );
+    $pub_type = cvterm_retrieve($identifiers);
+  }
+  else {
+    tripal_report_error('tripal_pub', TRIPAL_ERROR, "chado_does_pub_exist(): The Publication Type is a " .
+        "required property but is missing", array());
+    return FALSE;
+  }
+  if (!$pub_type) {
+    tripal_report_error('tripal_pub', TRIPAL_ERROR, "chado_does_pub_exist(): Cannot find publication type: '%type'",
+    array('%type' => $pub_details['Publication Type'][0]));
+    return FALSE;
+  }
+
+  // get the series name.  The pub.series_name field is only 255 chars so we must truncate to be safe
+  $series_name = '';
+  if (array_key_exists('Series_Name', $pub_details)) {
+    $series_name = substr($pub_details['Series Name'], 0, 255);
+  }
+  if (array_key_exists('Journal Name', $pub_details)) {
+    $series_name = substr($pub_details['Journal Name'], 0, 255);
+  }
+
+
+  // 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');
+  $pubs = array();
+  switch ($import_dups_check) {
+    case 'title_year':
+      $identifiers = array(
+        'title' => $pub_details['Title'],
+        'pyear' => $pub_details['Year']
+      );
+      $pubs = chado_select_record('pub', array('pub_id'), $identifiers);
+      break;
+    case 'title_year_type':
+      $identifiers = array(
+        'title'   => $pub_details['Title'],
+        'pyear'   => $pub_details['Year'],
+        'type_id' => $pub_type->cvterm_id,
+      );
+      $pubs = chado_select_record('pub', array('pub_id'), $identifiers);
+      break;
+    case 'title_year_media':
+      $identifiers = array(
+        'title'       => $pub_details['Title'],
+        'pyear'       => $pub_details['Year'],
+        'series_name' => $series_name,
+      );
+      $pubs = chado_select_record('pub', array('pub_id'), $identifiers);
+      break;
+  }
+
+  $return = array();
+  foreach ($pubs as $pub) {
+    $return[] = $pub->pub_id;
+  }
+
+  return $return;
+}
+
+/**
+ * Updates publication records that currently exist in the Chado pub table
+ * with the most recent data in the remote database. 
  *
  * @param $do_contact
  *   Set to TRUE if authors should automatically have a contact record added
@@ -137,7 +536,7 @@ function tripal_pub_get_raw_data($dbxref) {
  *   
  * @ingroup tripal_pub_api
  */
-function tripal_pub_update_publications($do_contact = FALSE, $dbxref = NULL, $db = NULL) {
+function chado_reimport_publications($do_contact = FALSE, $dbxref = NULL, $db = NULL) {
 
   print "\nNOTE: Loading of publications is performed using a database transaction. \n" .
       "If the load fails or is terminated prematurely then the entire set of \n" .
@@ -196,7 +595,7 @@ function tripal_pub_update_publications($do_contact = FALSE, $dbxref = NULL, $db
           ),
         ),
       );
-      $pubs = tripal_pub_get_remote_search_results($remote_db, $search, 1, 0);
+      $pubs = tripal_get_remote_pubs($remote_db, $search, 1, 0);
       tripal_pub_add_publications($pubs, $do_contact, TRUE);
 
       $i++;
@@ -204,12 +603,12 @@ function tripal_pub_update_publications($do_contact = FALSE, $dbxref = NULL, $db
 
     // sync the newly added publications with Drupal
     print "Syncing publications with Drupal...\n";
-    tripal_pub_sync_pubs();
+    chado_node_sync_records('pub');
 
     // if the caller wants to create contacts then we should sync them
     if ($do_contact) {
       print "Syncing contacts with Drupal...\n";
-      tripal_contact_sync_contacts();
+      chado_node_sync_records('contact');
     }
   }
   catch (Exception $e) {
@@ -232,7 +631,7 @@ function tripal_pub_update_publications($do_contact = FALSE, $dbxref = NULL, $db
  *
  * @ingroup tripal_pub_api
  */
-function tripal_pub_import_publications_by_import_id($import_id, $job_id = NULL) {
+function tripal_execute_pub_importer($import_id, $job_id = NULL) {
   print "\nNOTE: Loading of publications is performed using a database transaction. \n" .
         "If the load fails or is terminated prematurely then the entire set of \n" .
         "insertions/updates is rolled back and will not be found in the database\n\n";
@@ -250,14 +649,14 @@ function tripal_pub_import_publications_by_import_id($import_id, $job_id = NULL)
     $sql = "SELECT * FROM {tripal_pub_import} WHERE pub_import_id = :import_id ";
     $import = db_query($sql, $args)->fetchObject();
 
-    print "Importing: " . $import->name . "\n";
+    print "Executing Importer: '" . $import->name . "'\n";
 
     $criteria = unserialize($import->criteria);
     $remote_db = $criteria['remote_db'];
     $total_pubs = 0;
     do {
       // retrieve the pubs for this page. We'll retreive 100 at a time
-      $results  = tripal_pub_get_remote_search_results($remote_db, $criteria, $num_to_retrieve, $page);
+      $results  = tripal_get_remote_pubs($remote_db, $criteria, $num_to_retrieve, $page);
       $pubs     = $results['pubs'];
       $num_pubs = $rseults['total_records'];
       $total_pubs += $num_pubs;
@@ -272,12 +671,12 @@ function tripal_pub_import_publications_by_import_id($import_id, $job_id = NULL)
     // requested a report then we don't want to print any syncing information
     // so pass 'FALSE' to the sync call
     print "Syncing publications with Drupal...\n";
-    tripal_pub_sync_pubs();
+    chado_node_sync_records('pub');
 
     // if any of the importers wanted to create contacts from the authors then sync them
     if($import->do_contact) {
       print "Syncing contacts with Drupal...\n";
-      tripal_contact_sync_contacts();
+      chado_node_sync_records('contact');
     }
     tripal_set_job_progress($job_id, '100');
   }
@@ -303,7 +702,7 @@ function tripal_pub_import_publications_by_import_id($import_id, $job_id = NULL)
  *   
  * @ingroup tripal_pub_api
  */
-function tripal_pub_import_publications($report_email = FALSE, $do_update = FALSE) {
+function tripal_execute_active_pub_importers($report_email = FALSE, $do_update = FALSE) {
   $num_to_retrieve = 100;
   $page = 0;
 
@@ -323,7 +722,7 @@ function tripal_pub_import_publications($report_email = FALSE, $do_update = FALS
     $reports = array();
     foreach ($results as $import) {
       $page = 0;
-      print "Importing: " . $import->name . "\n";
+      print "Executing importer: '" . $import->name . "'\n";
       // keep track if any of the importers want to create contacts from authors
       if ($import->do_contact == 1) {
         $do_contact = TRUE;
@@ -332,7 +731,7 @@ function tripal_pub_import_publications($report_email = FALSE, $do_update = FALS
       $remote_db = $criteria['remote_db'];
       do {
         // retrieve the pubs for this page. We'll retreive 100 at a time
-        $results = tripal_pub_get_remote_search_results($remote_db, $criteria, $num_to_retrieve, $page);
+        $results = tripal_get_remote_pubs($remote_db, $criteria, $num_to_retrieve, $page);
         $pubs = $results['pubs'];
         $reports[$import->name] = tripal_pub_add_publications($pubs, $import->do_contact, $do_update);
         $page++;
@@ -346,7 +745,7 @@ function tripal_pub_import_publications($report_email = FALSE, $do_update = FALS
     // requested a report then we don't want to print any syncing information
     // so pass 'FALSE' to the sync call
     print "Syncing publications with Drupal...\n";
-    tripal_pub_sync_pubs();
+    chado_node_sync_records('pub');
 
     // iterate through each of the reports and generate a final report with HTML links
     $HTML_report = '';
@@ -376,7 +775,7 @@ function tripal_pub_import_publications($report_email = FALSE, $do_update = FALS
     // if any of the importers wanted to create contacts from the authors then sync them
     if($do_contact) {
       print "Syncing contacts with Drupal...\n";
-      tripal_contact_sync_contacts();
+      chado_node_sync_records('contact');
     }
   }
   catch (Exception $e) {
@@ -406,7 +805,7 @@ function tripal_pub_import_publications($report_email = FALSE, $do_update = FALS
  *   
  * @ingroup tripal_pub_api
  */
-function tripal_pub_import_by_dbxref($pub_dbxref, $do_contact = FALSE, $do_update) {
+function tripal_import_pub_by_dbxref($pub_dbxref, $do_contact = FALSE, $do_update) {
   $num_to_retrieve = 1;
   $pager_id = 0;
   $page = 0;
@@ -435,7 +834,7 @@ function tripal_pub_import_by_dbxref($pub_dbxref, $do_contact = FALSE, $do_updat
         ),
       );
       $remote_db = $criteria['remote_db'];
-      $results = tripal_pub_get_remote_search_results($remote_db, $criteria, $num_to_retrieve, $page);
+      $results = tripal_get_remote_pubs($remote_db, $criteria, $num_to_retrieve, $page);
       $pubs          = $results['pubs'];
       $search_str    = $results['search_str'];
       $total_records = $results['total_records'];
@@ -444,12 +843,12 @@ function tripal_pub_import_by_dbxref($pub_dbxref, $do_contact = FALSE, $do_updat
 
     // sync the newly added publications with Drupal
     print "Syncing publications with Drupal...\n";
-    tripal_pub_sync_pubs();
+    chado_node_sync_records('pub');
 
     // if any of the importers wanted to create contacts from the authors then sync them
     if($do_contact) {
       print "Syncing contacts with Drupal...\n";
-      tripal_contact_sync_contacts();
+      chado_node_sync_records('contact');
     }
   }
   catch (Exception $e) {
@@ -461,1075 +860,4 @@ function tripal_pub_import_by_dbxref($pub_dbxref, $do_contact = FALSE, $do_updat
   }
 
   print "Done.\n";
-}
-
-/**
- * Adds publications that have been retrieved from a remote database and 
- * consolidated into an array of details.
- *
- * @param $pubs
- *   An array containing a list of publications to add to Chado.  The
- *   array contains a set of details for the publication.
- * @param $do_contact
- *   Set to TRUE if authors should automatically have a contact record added
- *   to Chado. 
- * @param $update
- *   If set to TRUE then publications that already exist in the Chado database
- *   will be updated, whereas if FALSE only new publications will be added
- *   
- * @return
- *   Returns an array containing the number of publications that were
- *   inserted, updated, skipped and which had an error during import.
- *
- * @ingroup tripal_pub_api
- */
-function tripal_pub_add_publications($pubs, $do_contact, $update = FALSE) {
-  $report = array();
-  $report['error'] = 0;
-  $report['inserted'] = array();
-  $report['skipped'] = array();
-  $total_pubs = count($pubs);
-
-  // iterate through the publications and add each one
-  $i = 1;
-  foreach ($pubs as $pub) {
-    $memory = number_format(memory_get_usage()) . " bytes";
-    print "Processing $i of $total_pubs. Memory usage: $memory.\r";
-
-    // add the publication to Chado
-    $action = '';
-    $pub_id = tripal_pub_add_publication($pub, $action, $do_contact, $update);
-    if ($pub_id){
-      // add the publication cross reference (e.g. to PubMed)
-      if ($pub_id and $pub['Publication Dbxref']) {
-        $pub_dbxref = tripal_pub_add_pub_dbxref($pub_id, $pub['Publication Dbxref']);
-      }
-      $pub['pub_id'] = $pub_id;
-    }
-
-    switch ($action) {
-      case 'error':
-        $report['error']++;
-        break;
-      case 'inserted':
-        $report['inserted'][] = $pub;
-        break;
-      case 'updated':
-        $report['updated'][] = $pub;
-        break;
-      case 'skipped':
-        $report['skipped'][] = $pub;
-        break;
-    }
-    $i++;
-  }
-  print "\n";
-  return $report;
-}
-
-/**
- * Adds a database cross-reference to a publication
- *
- * @param $pub_id
- *   The ID of the publication   
- * @param $pub_dbxref
- *   The cross reference.  This value must be of the format DB_NAME:ACCESSION 
- *   where DB_NAME is the name of the database and the 
- *   ACCESSION is the unique identifier for the record in the database.
- *
- * @return
- *
- * @ingroup tripal_pub_api
- */
-function tripal_pub_add_pub_dbxref($pub_id, $pub_dbxref) {
-
-  // break apart the dbxref
-  $dbname = '';
-  $accession = '';
-  if(preg_match('/^(.*?):(.*?)$/', $pub_dbxref, $matches)) {
-    $dbname = $matches[1];
-    $accession = $matches[2];
-  }
-  else {
-    return FALSE;
-  }
-
-  // check to see if the pub_dbxref record already exist
-  $values = array(
-    'dbxref_id' => array(
-      'accession' => $accession,
-      'db_id' => array(
-        'name' => $dbname,
-      ),
-    ),
-    'pub_id' => $pub_id,
-  );
-  $options = array('statement_name' => 'sel_pubdbxref_dbpu');
-  $results = chado_select_record('pub_dbxref', array('*'), $values, $options);
-
-  // if the pub_dbxref record  exist then we don't need to re-add it.
-  if(count($results) > 0) {
-    return $results[0];
-  }
-
-  // make sure our database already exists
-  $db = tripal_db_add_db($dbname);
-
-  // get the database cross-reference
-  $dbxvalues = array(
-    'accession' => $accession,
-    'db_id' => $db->db_id,
-  );
-  $dbxoptions = array('statement_name' => 'sel_dbxref_acdb');
-  $results = chado_select_record('dbxref', array('dbxref_id'), $dbxvalues, $dbxoptions);
-  // if the accession doesn't exist then add it
-  if(count($results) == 0){
-    $dbxref = tripal_db_add_dbxref($db->db_id, $accession);
-  }
-  else {
-    $dbxref = $results[0];
-  }
-
-  // now add the record
-  $options = array('statement_name' => 'ins_pubdbxref_dbpu');
-  $results = chado_insert_record('pub_dbxref', $values, $options);
-  if (!$results) {
-    tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot add publication dbxref: %db:%accession.",
-    array('%db' => $dbname, '%accession' => $accession));
-    return FALSE;
-  }
-  return $results;
-}
-
-/**
- * Returns the list of publications that are assigned the database
- * cross-reference provided
- *
- * @param $pub_dbxref
- *   The database cross reference accession.  It should be in the form
- *   DB:ACCESSION, where DB is the database name and ACCESSION is the
- *   unique publication identifier (e.g. PMID:4382934)
- *
- * @return
- *   Returns an array of all the publications that have the provided
- *   cross reference. If no publications match, then an empty array
- *   is returned.
- *
- * @ingroup tripal_pub_api
- */
-function tripal_pub_get_pubs_by_dbxref($pub_dbxref) {
-
-  $return = array();
-
-  if(preg_match('/^(.*?):(.*?)$/', $pub_dbxref, $matches)) {
-    $dbname = $matches[1];
-    $accession = $matches[2];
-
-    $values = array(
-      'dbxref_id' => array (
-        'accession' => $accession,
-        'db_id' => array(
-          'name' => $dbname
-    ),
-    ),
-    );
-    $options = array('statement_name' => 'sel_pubdbxref_db');
-    $results = chado_select_record('pub_dbxref', array('pub_id'), $values, $options);
-    foreach ($results as $index => $pub) {
-      $return[] = $pub->pub_id;
-    }
-  }
-  return $return;
-}
-
-/**
- * Returns the list of publications that match a given title, type and year
- *
- * @param title
- *   The title of the publication to look for
- * @param type
- *   Optional. The publication type. The value of this field should come from
- *   the Tripal Pub vocabulary. This should be the type name (e.g. cvterm.name)
- * @param pyear
- *   Optional. The year the publication was published.
- * @param series_name
- *   Optional.  The name of the series (e.g. Journal name)
- *
- * @return
- *   Returns an array of all the publications that have the provided
- *   cross reference. If no publications match, then an empty array
- *   is returned.
- *
- * @ingroup tripal_pub_api
- */
-function tripal_pub_get_pubs_by_title_type_pyear_series($title, $type = NULL, $pyear = NULL, $series_name = NULL) {
-
-  $return = array();
-
-  // build the values array for the query.
-  $values = array(
-    'title' => $title,
-  );
-  $stmnt_suffix = 'ti';
-  if ($type) {
-    $values['type_id'] = array(
-      'name' => $type,
-      'cv_id' => array(
-        'name' => 'tripal_pub'
-        )
-        );
-        $stmnt_suffix .= 'ty';
-  }
-  if ($pyear) {
-    $values['pyear'] = $pyear;
-    $stmnt_suffix .= 'py';
-  }
-  if ($series_name) {
-    $values['series_name'] = strtolower($series_name);
-    $stmnt_suffix .= 'se';
-  }
-  $options = array(
-    'statement_name' => 'sel_pub_' . $stmnt_suffix,
-    'case_insensitive_columns' => array('title', 'series_name'),
-  );
-  $results = chado_select_record('pub', array('pub_id'), $values, $options);
-
-  // iterate through any matches and pull out the pub_id
-  foreach ($results as $index => $pub) {
-    $return[] = $pub->pub_id;
-  }
-  return $return;
-}
-
-/**
- * Returns the list of publications that match a given title, type and year
- *
- * @param title
- *   The title of the publication to look for
- * @param type
- *   Optional. The publication type. The value of this field should come from
- *   the Tripal Pub vocabulary. This should be the type name (e.g. cvterm.name)
- * @param year
- *   Optional. The year the publication was published.
- * @param series_name
- *   Optional.  The name of the series (e.g. Journal name)
- *
- * @return
- *   Returns an array of all the publications that have the provided
- *   cross reference. If no publications match, then an empty array
- *   is returned.
- *
- * @ingroup tripal_pub_api
- */
-function tripal_pub_get_pub_by_uniquename($name) {
-
-  $return = array();
-
-  // build the values array for the query.
-  $values = array(
-    'uniquename' => $name,
-  );
-  $options = array(
-    'statement_name' => 'sel_pub_un',
-    'case_insensitive_columns' => array('uniquename'),
-  );
-  $results = chado_select_record('pub', array('pub_id'), $values, $options);
-
-  // iterate through any matches and pull out the pub_id
-  foreach ($results as $index => $pub) {
-    $return[] = $pub->pub_id;
-  }
-  return $return;
-}
-
-/**
- * Adds a new publication to the Chado, along with all properties and
- * database cross-references. If the publication does not already exist
- * in Chado then it is added.  If it does exist nothing is done.  If
- * the $update parameter is TRUE then the publication is updated if it exists.
- *
- * @param $pub_details
- *   An associative array containing all of the details about the publication.
- * @param $action
- *   This variable will get set to a text value indicating the action that was
- *   performed. The values include 'skipped', 'inserted', 'updated' or 'error'.
- * @param $do_contact
- *   Optional. Set to TRUE if a contact entry should be added to the Chado contact table
- *   for authors of the publication.
- * @param $update_if_exists
- *   Optional.  If the publication already exists then this function will return
- *   without adding a new publication.  However, set this value to TRUE to force
- *   the function to pudate the publication using the $pub_details that are provided.
- *
- * @return
- *   If the publication already exists, is inserted or updated then the publication
- *   ID is returned, otherwise FALSE is returned. If the publication already exists
- *   and $update_if_exists is not TRUE then the $action variable is set to 'skipped'.
- *   If the publication already exists and $update_if_exists is TRUE and if the update
- *   was successful then $action is set to 'updated'.  Otherwise on successful insert
- *   the $action variable is set to 'inserted'.  If the function failes then the
- *   $action variable is set to 'error'
- *
- * @ingroup tripal_pub_api
- */
-function tripal_pub_add_publication($pub_details, &$action, $do_contact = FALSE, $update_if_exists = FALSE) {
-  $pub_id = 0;
-
-  if (!is_array($pub_details)) {
-    return FALSE;
-  }
-
-  // first try to find the publication using the accession number. It will have
-  // one if the pub has already been loaded for the publication database
-  if (array_key_exists('Publication Dbxref', $pub_details)) {
-    $results = tripal_pub_get_pubs_by_dbxref($pub_details['Publication Dbxref']);
-    if(count($results) == 1) {
-      $pub_id = $results[0];
-      if ($pub_id and !$update_if_exists) {
-        //tripal_core_report_error('tripal_pub', TRIPAL_WARNING, "A publication with this Dbxref already exists... Skipping: %dbxref",
-        //array('%dbxref' => $pub_details['Publication Dbxref']));
-        $action = 'skipped';
-        return $pub_id;
-      }
-    }
-    elseif (count($results) > 1) {
-      tripal_report_error('tripal_pub', TRIPAL_ERROR, "There are two publications with this accession: %db:%accession. Cannot determine which to update.",
-      array('%db' => $dbname, '%accession' => $accession));
-      $action = 'error';
-      return FALSE;
-    }
-  }
-
-  // if we couldn't find a publication by the accession (which means it doesn't
-  // yet exist or it has been added using a different publication database) then
-  // try to find it using the title and publication year.
-  if (!$pub_id and array_key_exists('Title', $pub_details)) {
-
-    $results = tripal_pub_get_pubs_by_title_type_pyear_series($pub_details['Title'], NULL, $pub_details['Year']);
-    if (count($results) == 1) {
-      $pub_id = $results[0];
-      if ($pub_id and !$update_if_exists) {
-        tripal_report_error('tripal_pub', TRIPAL_WARNING, "The publication with the same title, type and year already exists. Skipping. ".
-          " Title: '%title'. Type: '%type'. Year: '%year'",
-          array('%title' => $pub_details['Title'], '%type' => $pub_details['Publication Type'], '%year' => $pub_details['Year']));
-        $action = 'skipped';
-        return $pub_id;
-      }
-    }
-    elseif (count($results) > 1) {
-      tripal_report_error('tripal_pub', TRIPAL_ERROR, "The publication with the same title, type and year is present multiple times. Cannot ".
-        "determine which to use.  Title: '%title'. Type: '%type'. Year: '%year'",
-      array('%title' => $pub_details['Title'], '%type' => $pub_details['Publication Type'], '%year' => $pub_details['Year']));
-      $action = 'error';
-      return FALSE;
-    }
-  }
-  // get the publication type (use the first publication type, any others will get stored as properties)
-  if (array_key_exists('Publication Type', $pub_details)) {
-    if(is_array($pub_details['Publication Type'])) {
-      $pub_type = tripal_cv_get_cvterm_by_name($pub_details['Publication Type'][0], NULL, 'tripal_pub');
-    }
-    else {
-      $pub_type = tripal_cv_get_cvterm_by_name($pub_details['Publication Type'], NULL, 'tripal_pub');
-    }
-  }
-  else {
-    tripal_report_error('tripal_pub', TRIPAL_ERROR, "The Publication Type is a required property but is missing", array());
-    $action = 'error';
-    return FALSE;
-  }
-  if (!$pub_type) {
-    tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot find publication type: '%type'",
-    array('%type' => $pub_details['Publication Type'][0]));
-    $action = 'error';
-    return FALSE;
-  }
-
-  // build the values array for inserting or updating
-  $values = array(
-    'title'       => $pub_details['Title'],
-    'volume'      => $pub_details['Volume'],
-    'series_name' => substr($pub_details['Journal Name'], 0, 255),
-    'issue'       => $pub_details['Issue'],
-    'pyear'       => $pub_details['Year'],
-    'pages'       => $pub_details['Pages'],
-    'uniquename'  => $pub_details['Citation'],
-    'type_id'     => $pub_type->cvterm_id,
-  );
-
-  // if there is no pub_id then we need to do an insert.
-  if (!$pub_id) {
-    $options = array('statement_name' => 'ins_pub_tivoseispypaunty');
-    $pub = chado_insert_record('pub', $values, $options);
-    if (!$pub) {
-      tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot insert the publication with title: %title",
-      array('%title' => $pub_details['Title']));
-      $action = 'error';
-      return FALSE;
-    }
-    $pub_id = $pub['pub_id'];
-    $action = 'inserted';
-  }
-
-  // if there is a pub_id and we've been told to update, then do the update
-  if ($pub_id and $update_if_exists) {
-    $match = array('pub_id' => $pub_id);
-    $options = array('statement_name' => 'up_pub_tivoseispypaunty');
-    $success = chado_update_record('pub', $match, $values, $options);
-    if (!$success) {
-      tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot update the publication with title: %title",
-      array('%title' => $pub_details['Title']));
-      $action = 'error';
-      return FALSE;
-    }
-    $action = 'updated';
-  }
-
-  // before we add any new properties we need to remove those that are there if this
-  // is an update.  The only thing we don't want to remove are the 'Publication Dbxref'
-  if ($update_if_exists) {
-    $sql = "
-      DELETE FROM {pubprop}
-      WHERE
-        pub_id = :pub_id AND
-        NOT type_id in (
-          SELECT cvterm_id
-          FROM {cvterm}
-          WHERE name = 'Publication Dbxref'
-        )
-    ";
-    chado_query($sql, array(':pub_id' => $pub_id));
-  }
-
-  // iterate through the properties and add them
-  foreach ($pub_details as $key => $value) {
-    // the pub_details may have the raw search data (e.g. in XML from PubMed.  We'll irgnore this for now
-    if($key == 'raw') {
-      continue;
-    }
-    // get the cvterm by name or synonym
-    $cvterm = tripal_cv_get_cvterm_by_name($key, NULL, 'tripal_pub');
-    if (!$cvterm) {
-      $cvterm = tripal_cv_get_cvterm_by_synonym($key, NULL, 'tripal_pub');
-    }
-    if (!$cvterm) {
-      tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot find term: '%prop'. Skipping.", array('%prop' => $key));
-      continue;
-    }
-
-    // skip details that won't be stored as properties
-    if ($key == 'Author List') {
-      tripal_pub_add_authors($pub_id, $value, $do_contact);
-      continue;
-    }
-    if ($key == 'Title' or $key == 'Volume' or $key == 'Journal Name' or $key == 'Issue' or
-    $key == 'Year' or $key == 'Pages') {
-      continue;
-    }
-
-    $success = 0;
-    if (is_array($value)) {
-      foreach ($value as $subkey => $subvalue) {
-        // if the key is an integer then this array is a simple list and
-        // we will insert using the primary key. Otheriwse, use the new key
-        if(is_int($subkey)) {
-          $success = chado_insert_property('pub', $pub_id, $key, 'tripal_pub', $subvalue, FALSE);
-        }
-        else {
-          $success = chado_insert_property('pub', $pub_id, $subkey, 'tripal_pub', $subvalue, FALSE);
-        }
-      }
-    }
-    else {
-      $success = chado_insert_property('pub', $pub_id, $key, 'tripal_pub', $value, TRUE);
-    }
-    if (!$success) {
-      tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot add property '%prop' to publication. Skipping.",
-      array('%prop' => $key));
-      continue;
-    }
-  }
-
-  return $pub_id;
-}
-
-/**
- * Add one or more authors to a publication
- *
- * @param $pub_id
- *   The publication ID of the pub in Chado.
- * @param $authors
- *   An array of authors.  Each author should have a set of keys/value pairs
- *   describing the author.
- * @param $do_contact
- *   Optional. Set to TRUE if a contact entry should be added to the Chado contact table
- *   for authors of the publication.
- * @ingroup tripal_pub_api
- */
-function tripal_pub_add_authors($pub_id, $authors, $do_contact) {
-  $rank = 0;
-
-  // first remove any of the existing pubauthor entires
-  $sql = "DELETE FROM {pubauthor} WHERE pub_id = :pub_id";
-  chado_query($sql, array(':pub_id' => $pub_id));
-
-  // iterate through the authors and add them to the pubauthors and contact
-  // tables of chado, then link them through the custom pubauthors_contact table
-  foreach ($authors as $author) {
-    // skip invalid author entires
-    if ($author['valid'] == 'N') {
-      continue;
-    }
-    // remove the 'valid' property as we don't have a CV term for it
-    unset($author['valid']);
-
-    // construct the contact.name field using the author information
-    $name = '';
-    $type = 'Person';
-    if ($author['Given Name']) {
-      $name .= $author['Given Name'];
-    }
-    if ($author['Surname']) {
-      $name .= ' ' . $author['Surname'];
-    }
-    if ($author['Suffix']) {
-      $name .= ' ' . $author['Suffix'];
-    }
-    if ($author['Collective']) {
-      $name = $author['Collective'];
-      $type = 'Collective';
-    }
-    $name = trim($name);
-
-    // add an entry to the pubauthors table
-    $values = array(
-      'pub_id' => $pub_id,
-      'rank' => $rank,
-      'surname' => $author['Surname'] ? substr($author['Surname'], 0, 100) : substr($author['Collective'], 0, 100),
-      'givennames' => $author['Given Name'],
-      'suffix' => $author['Suffix'],
-    );
-    $options = array('statement_name' => 'ins_pubauthor_idrasugisu');
-    $pubauthor = chado_insert_record('pubauthor', $values, $options);
-
-    // if the user wants us to create a contact for each author then do it.
-    if ($do_contact) {
-      // Add the contact
-      $contact = tripal_contact_add_contact($name, '', $type, $author);
-
-      // if we have succesfully added the contact and the pubauthor entries then we want to
-      // link them together
-      if ($contact and $pubauthor) {
-
-        // link the pubauthor entry to the contact
-        $values = array(
-          'pubauthor_id' => $pubauthor['pubauthor_id'],
-          'contact_id' => $contact['contact_id'],
-        );
-        $options = array('statement_name' => 'ins_pubauthorcontact_puco');
-        $pubauthor_contact = chado_insert_record('pubauthor_contact', $values, $options);
-        if (!$pubauthor_contact) {
-          tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot link pub authro and contact.", array());
-        }
-      }
-    }
-    $rank++;
-  }
-}
-
-/**
- * Retrieve properties of a given type for a given pub
- *
- * @param $pub_id
- *    The pub_id of the properties you would like to retrieve
- * @param $property
- *    The cvterm name of the properties to retrieve
- *
- * @return
- *    An pub chado variable with the specified properties expanded
- *
- * @ingroup tripal_pub_api
- */
-function tripal_pub_get_property($pub_id, $property) {
-  return chado_get_property('pub', $pub_id, $property, 'tripal_pub');
-}
-
-/**
- * Insert a given property
- *
- * @param $pub_id
- *   The pub_id of the property to insert
- * @param $property
- *   The cvterm name of the property to insert
- * @param $value
- *   The value of the property to insert
- * @param $update_if_present
- *   A boolean indicated whether to update the record if it's already present
- *
- * @return
- *   True of success, False otherwise
- *
- * @ingroup tripal_pub_api
- */
-function tripal_pub_insert_property($pub_id, $property, $value, $update_if_present = 0) {
-  return chado_insert_property('pub', $pub_id, $property, 'tripal_pub', $value, $update_if_present);
-}
-
-/**
- * Update a given property
- *
- * @param $pub_id
- *   The pub_id of the property to update
- * @param $property
- *   The cvterm name of the property to update
- * @param $value
- *   The value of the property to update
- * @param $insert_if_missing
- *   A boolean indicated whether to insert the record if it's absent
- *
- * Note: The property will be identified using the unique combination of the $pub_id and $property
- * and then it will be updated with the supplied value
- *
- * @return
- *   True of success, False otherwise
- *
- * @ingroup tripal_pub_api
- */
-function tripal_pub_update_property($pub_id, $property, $value, $insert_if_missing = 0) {
-  return chado_update_property('pub', $pub_id, $property, 'tripal_pub', $value, $insert_if_missing);
-}
-
-/**
- * Delete a given property
- *
- * @param $pub_id
- *   The pub_id of the property to delete
- * @param $property
- *   The cvterm name of the property to delete
- *
- * Note: The property will be identified using the unique combination of the $pub_id and $property
- * and then it will be deleted
- *
- * @return
- *   True of success, False otherwise
- *
- * @ingroup tripal_pub_api
- */
-function tripal_pub_delete_property($pub_id, $property) {
-  return chado_delete_property('pub', $pub_id, $property, 'tripal_pub');
-}
-
-/**
- * This function generates an array suitable for use with the
- * tripal_pub_create_citation function for any publication
- * already stored in the Chado tables.
- *
- * @param $pub_id
- *   The publication ID
- * @param $skip_existing
- *   Set to TRUE to skip publications that already have a citation
- *   in the pubprop table.  Set to FALSE to generate a citation
- *   regardless if the citation already exists.
- *
- * @return
- *   An array suitable for the trpial_pub_create_citation function. On
- *   failure returns FALSE.
- *
- * @ingroup tripal_pub_api
- */
-function tripal_pub_get_publication_array($pub_id, $skip_existing = TRUE) {
-
-  $options = array('return_array' => 1);
-
-  // ---------------------------------
-  // get the publication
-  // ---------------------------------
-  $values = array('pub_id' => $pub_id);
-  $pub = chado_generate_var('pub', $values);
-
-  // expand the title
-  $pub = chado_expand_var($pub, 'field', 'pub.title');
-  $pub = chado_expand_var($pub, 'field', 'pub.volumetitle');
-  $pub = chado_expand_var($pub, 'field', 'pub.uniquename');
-  $pub_array = array();
-  if (trim($pub->title)) {
-    $pub_array['Title'] = $pub->title;
-  }
-  if (trim($pub->volumetitle)) {
-    $pub_array['Volume Title'] = $pub->volumetitle;
-  }
-  if (trim($pub->volume)) {
-    $pub_array['Volume'] = $pub->volume;
-  }
-  if (trim($pub->series_name)) {
-    $pub_array['Series Name'] = $pub->series_name;
-  }
-  if (trim($pub->issue)) {
-    $pub_array['Issue'] = $pub->issue;
-  }
-  if (trim($pub->pyear)) {
-    $pub_array['Year'] = $pub->pyear;
-  }
-  if (trim($pub->pages)) {
-    $pub_array['Pages'] = $pub->pages;
-  }
-  if (trim($pub->miniref)) {
-    $pub_array['Mini Ref'] = $pub->miniref;
-  }
-  if (trim($pub->uniquename)) {
-    $pub_array['Uniquename'] = $pub->uniquename;
-  }
-  $pub_array['Publication Type'][] = $pub->type_id->name;
-
-  // ---------------------------------
-  // get the citation
-  // ---------------------------------
-  $values = array(
-    'pub_id' => $pub->pub_id,
-    'type_id' => array(
-      'name' => 'Citation',
-    ),
-  );
-  $citation = chado_generate_var('pubprop', $values);
-  if ($citation) {
-    $citation = chado_expand_var($citation, 'field', 'pubprop.value', $options);
-    if (count($citation) > 1) {
-      tripal_report_error('tripal_pub', TRIPAL_ERROR, "Publication has multiple citations already: %pub_id",
-      array('%pub_id' => $pubid));
-      return FALSE;
-    }
-    elseif (count($citation) == 1 and $skip_existing == TRUE) {
-      // skip this publication, it already has a citation
-      return FALSE;
-    }
-  }
-
-  // ---------------------------------
-  // get the publication types
-  // ---------------------------------
-  $values = array(
-    'pub_id' => $pub->pub_id,
-    'type_id' => array(
-      'name' => 'Publication Type',
-    ),
-  );
-  $ptypes = chado_generate_var('pubprop', $values, $options);
-  if ($ptypes) {
-    $ptypes = chado_expand_var($ptypes, 'field', 'pubprop.value', $options);
-    foreach ($ptypes as $ptype) {
-     $pub_array['Publication Type'][] = $ptype->value;
-    }
-  }
-
-  // ---------------------------------
-  // get the authors list
-  // ---------------------------------
-  $values = array(
-    'pub_id' => $pub->pub_id,
-    'type_id' => array(
-      'name' => 'Authors',
-    ),
-  );
-  $authors = chado_generate_var('pubprop', $values);
-  $authors = chado_expand_var($authors, 'field', 'pubprop.value', $options);
-  if (count($authors) > 1) {
-   tripal_report_error('tripal_pub', TRIPAL_ERROR, "Publication has multiple author lists. It should have only one list: %pub_id",
-   array('%pub_id' => $pubid));
-   return FALSE;
-  }
-  else if (trim($authors->value)) {
-    $pub_array['Authors'] = $authors->value;
-  }
-  // if there is no 'Author's property then try to retreive authors from the pubauthor table
-  else {
-    $sql = "
-      SELECT string_agg(surname || ' ' || givennames, ', ')
-      FROM {pubauthor}
-      WHERE pub_id = :pub_id
-      GROUP BY pub_id
-    ";
-    $au = chado_query($sql, array(':pub_id' => $pub_id))->fetchField();
-    if ($au) {
-      $pub_array['Authors'] = $au;
-    }
-  }
-
-  //Get other props
-  $props = array(
-    'Journal Abbreviation',
-    'Elocation',
-    'Media Code',
-    'Conference Name',
-    'Keywords',
-    'Series Name',
-    'pISSN',
-    'Publication Date',
-    'Journal Code',
-    'Journal Alias',
-    'Journal Country',
-    'Published Location',
-    'Publication Model',
-    'Language Abbr',
-    'Alias',
-    'Publication Dbxref',
-    'Copyright',
-    'Abstract',
-    'Notes',
-    'Citation',
-    'Language',
-    'URL',
-    'eISSN',
-    'DOI',
-    'ISSN',
-    'Publication Code',
-    'Comments',
-    'Publisher',
-    'Media Alias',
-    'Original Title');
-  foreach ($props AS $prop) {
-    $sql =
-      "SELECT value FROM {pubprop}
-       WHERE type_id =
-         (SELECT cvterm_id
-          FROM {cvterm}
-          WHERE name = :cvtname AND cv_id =
-            (SELECT cv_id
-             FROM {cv}
-             WHERE name = 'tripal_pub'
-            )
-         )
-       AND pub_id = :pub_id
-    ";
-    $val = trim(chado_query($sql, array(':cvtname' => $prop, ':pub_id' => $pub->pub_id))->fetchField());
-    if ($val) {
-      $pub_array[$prop] =$val;
-    }
-  }
-  return $pub_array;
-}
-
-/**
- * This function generates citations for publications.  It requires
- * an array structure with keys being the terms in the Tripal
- * publication ontology.  This function is intended to be used
- * for any function that needs to generate a citation.
- *
- * @param $pub
- *   An array structure containing publication details where the keys
- *   are the publication ontology term names and values are the
- *   corresponding details.  The pub array can contain the following
- *   keys with corresponding values:
- *     - Publication Type:  an array of publication types. a publication can have more than one type
- *     - Authors: a  string containing all of the authors of a publication
- *     - Journal Name:  a string containing the journal name
- *     - Journal Abbreviation: a string containing the journal name abbreviation
- *     - Series Name: a string containing the series (e.g. conference proceedings) name
- *     - Series Abbreviation: a string containing the series name abbreviation
- *     - Volume: the serives volume number
- *     - Issue: the series issue number
- *     - Pages: the page numbers for the publication
- *     - Publication Date:  A date in the format "Year Month Day"
- *
- * @return
- *   A text string containing the citation
- *
- * @ingroup tripal_pub_api
- */
-function tripal_pub_create_citation($pub) {
-  $citation = '';
-  $pub_type = '';
-
-  // An article may have more than one publication type. For example,
-  // a publication type can be 'Journal Article' but also a 'Clinical Trial'.
-  // Therefore, we need to select the type that makes most sense for
-  // construction of the citation. Here we'll iterate through them all
-  // and select the one that matches best.
-  if(is_array($pub['Publication Type'])) {
-    foreach ($pub['Publication Type'] as $ptype) {
-      if ($ptype == 'Journal Article' ) {
-        $pub_type = $ptype;
-        break;
-      }
-      else if ($ptype == 'Conference Proceedings'){
-        $pub_type = $ptype;
-        break;
-      }
-      else if ($ptype == 'Book') {
-        $pub_type = $ptype;
-        break;
-      }
-      else if ($ptype == 'Letter') {
-        $pub_type = $ptype;
-        break;
-      }
-      else if ($ptype == 'Book Chapter') {
-        $pub_type = $ptype;
-        break;
-      }
-      else if ($ptype == "Research Support, Non-U.S. Gov't") {
-        $pub_type = $ptype;
-        // we don't break because if the article is also a Journal Article
-        // we prefer that type
-      }
-    }
-    if (!$pub_type) {
-      tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot generate citation for publication type: %types",
-        array('%types' => print_r($pub['Publication Type'], TRUE)));
-      return FALSE;
-    }
-  }
-  else {
-    $pub_type = $pub['Publication Type'];
-  }
-  //----------------------
-  // Journal Article
-  //----------------------
-  if ($pub_type == 'Journal Article') {
-    $citation = $pub['Authors'] . '. ' . $pub['Title'] .  '. ';
-
-    if (array_key_exists('Journal Name', $pub)) {
-      $citation .= $pub['Journal Name'] . '. ';
-    }
-    elseif (array_key_exists('Journal Abbreviation', $pub)) {
-      $citation .= $pub['Journal Abbreviation'] . '. ';
-    }
-    elseif (array_key_exists('Series Name', $pub)) {
-      $citation .= $pub['Series Name'] . '. ';
-    }
-    elseif (array_key_exists('Series Abbreviation', $pub)) {
-      $citation .= $pub['Series Abbreviation'] . '. ';
-    }
-    if (array_key_exists('Publication Date', $pub)) {
-      $citation .= $pub['Publication Date'];
-    }
-    elseif (array_key_exists('Year', $pub)) {
-      $citation .= $pub['Year'];
-    }
-    if (array_key_exists('Volume', $pub) or array_key_exists('Issue', $pub) or array_key_exists('Pages',$pub)) {
-      $citation .= '; ';
-    }
-    if (array_key_exists('Volume', $pub)) {
-      $citation .= $pub['Volume'];
-    }
-    if (array_key_exists('Issue', $pub)) {
-      $citation .= '(' . $pub['Issue'] . ')';
-    }
-    if (array_key_exists('Pages', $pub)) {
-      if (array_key_exists('Volume', $pub)) {
-        $citation .= ':';
-      }
-      $citation .= $pub['Pages'];
-    }
-    $citation .= '.';
-  }
-  //----------------------
-  // Research Support, Non-U.S. Gov't
-  //----------------------
-  elseif ($pub_type == "Research Support, Non-U.S. Gov't") {
-    $citation = $pub['Authors'] . '. ' . $pub['Title'] .  '. ';
-
-    if (array_key_exists('Journal Name', $pub)) {
-      $citation .= $pub['Journal Name'] . '. ';
-    }
-    if (array_key_exists('Publication Date', $pub)) {
-      $citation .= $pub['Publication Date'];
-    }
-    elseif (array_key_exists('Year', $pub)) {
-      $citation .= $pub['Year'];
-    }
-    $citation .= '.';
-  }
-  //----------------------
-  // Letter
-  //----------------------
-  elseif ($pub_type == 'Letter') {
-    $citation = $pub['Authors'] . '. ' . $pub['Title'] .  '. ';
-
-    if (array_key_exists('Journal Name', $pub)) {
-      $citation .= $pub['Journal Name'] . '. ';
-    }
-    elseif (array_key_exists('Journal Abbreviation', $pub)) {
-      $citation .= $pub['Journal Abbreviation'] . '. ';
-    }
-    elseif (array_key_exists('Series Name', $pub)) {
-      $citation .= $pub['Series Name'] . '. ';
-    }
-    elseif (array_key_exists('Series Abbreviation', $pub)) {
-      $citation .= $pub['Series Abbreviation'] . '. ';
-    }
-    if (array_key_exists('Publication Date', $pub)) {
-      $citation .= $pub['Publication Date'];
-    }
-    elseif (array_key_exists('Year', $pub)) {
-      $citation .= $pub['Year'];
-    }
-    if (array_key_exists('Volume', $pub) or array_key_exists('Issue', $pub) or array_key_exists('Pages',$pub)) {
-      $citation .= '; ';
-    }
-    if (array_key_exists('Volume', $pub)) {
-      $citation .= $pub['Volume'];
-    }
-    if (array_key_exists('Issue', $pub)) {
-      $citation .= '(' . $pub['Issue'] . ')';
-    }
-    if (array_key_exists('Pages', $pub)) {
-      if (array_key_exists('Volume', $pub)) {
-        $citation .= ':';
-      }
-      $citation .= $pub['Pages'];
-    }
-    $citation .= '.';
-  }
-  //----------------------
-  // Book
-  //----------------------
-  elseif ($pub_type == 'Book') {
-
-  }
-  //----------------------
-  // Book Chapter
-  //----------------------
-  elseif ($pub_type == 'Book Chapter') {
-
-  }
-  //----------------------
-  // Conference Proceedings
-  //----------------------
-  elseif ($pub_type == 'Conference Proceedings') {
-    $citation = $pub['Authors'] . '. ' . $pub['Title'] .  '. ';
-
-    if (array_key_exists('Conference Name', $pub)) {
-      $citation .= $pub['Conference Name'] . '. ';
-    }
-    elseif (array_key_exists('Series Name', $pub)) {
-      $citation .= $pub['Series Name'] . '. ';
-    }
-    elseif (array_key_exists('Series Abbreviation', $pub)) {
-      $citation .= $pub['Series Abbreviation'] . '. ';
-    }
-    if (array_key_exists('Publication Date', $pub)) {
-      $citation .= $pub['Publication Date'];
-    }
-    elseif (array_key_exists('Year', $pub)) {
-      $citation .= $pub['Year'];
-    }
-    if (array_key_exists('Volume', $pub) or array_key_exists('Issue', $pub) or array_key_exists('Pages',$pub)) {
-      $citation .= '; ';
-    }
-    if (array_key_exists('Volume', $pub)) {
-      $citation .= $pub['Volume'];
-    }
-    if (array_key_exists('Issue', $pub)) {
-      $citation .= '(' . $pub['Issue'] . ')';
-    }
-    if (array_key_exists('Pages', $pub)) {
-      if (array_key_exists('Volume', $pub)) {
-        $citation .= ':';
-      }
-      $citation .= $pub['Pages'];
-    }
-    $citation .= '.';
-  }
-
-  return $citation;
-}
+}

+ 22 - 7
tripal_pub/includes/importers/tripal_pub.PMID.inc

@@ -215,7 +215,7 @@ function tripal_pub_PMID_search_init($search_str, $retmax){
   $rfh = fopen($query_url, "r");
   if (!$rfh) {
     drupal_set_message('Could not perform Pubmed query. Cannot connect to Entrez.', 'error');
-    tripal_report_error('tpub_pubmed', TRIPAL_ERROR, "Could not perform Pubmed query. Cannot connect to Entrez.",
+    tripal_report_error('tripal_pubmed', TRIPAL_ERROR, "Could not perform Pubmed query. Cannot connect to Entrez.",
               array());
     return 0;
   }
@@ -316,7 +316,7 @@ function tripal_pub_PMID_fetch($query_key, $web_env, $rettype = 'null',
   $rfh = fopen($fetch_url, "r");
   if (!$rfh) {
     drupal_set_message('ERROR: Could not perform PubMed query.', 'error');
-    tripal_report_error('tpub_pubmed', TRIPAL_ERROR, "Could not perform PubMed query: %fetch_url.",
+    tripal_report_error('tripal_pubmed', TRIPAL_ERROR, "Could not perform PubMed query: %fetch_url.",
               array('%fetch_url' => $fetch_url));
     return '';
   }
@@ -368,7 +368,7 @@ function tripal_pub_PMID_parse_pubxml($pub_xml) {
       switch ($element) {
         case 'ERROR':
           $xml->read(); // get the value for this element
-          tripal_report_error('tpub_pubmed', TRIPAL_ERROR, "Error: %err", array('%err' => $xml->value));
+          tripal_report_error('tripal_pubmed', TRIPAL_ERROR, "Error: %err", array('%err' => $xml->value));
           break;
         case 'PMID':
           // thre are multiple places where a PMID is present in the XML and
@@ -612,13 +612,28 @@ function tripal_pub_PMID_parse_publication_type($xml, &$pub) {
         case 'PublicationType':
           $xml->read();
           $value = $xml->value;
-          $pub_cvterm = tripal_cv_get_cvterm_by_name($value, NULL, 'tripal_pub');
+          
+          $identifiers = array(
+            'name' => $value,
+            'cv_id' => array(
+              'name' => 'tripal_pub',
+            )
+          );
+          $options = array('case_insensitive_columns' => array('name'));
+          $pub_cvterm = cvterm_retrieve($identifiers, $options);
           if (!$pub_cvterm) {
             // see if this we can find the name using a synonym
-            $pub_cvterm = tripal_cv_get_cvterm_by_synonym($value, NULL, 'tripal_pub');
+            $identifiers = array(
+              'synonym' => array(
+                'name' => $value,
+                'cv_name' => 'tripal_pub'
+              )
+            );
+            $pub_cvterm = cvterm_retrieve($identifiers, $options);
             if (!$pub_cvterm) {
-              tripal_report_error('tpub_pubmed', TRIPAL_ERROR, 'Cannot find a valid vocabulary term for the publication type: "%term".',
-              array('%term' => $value));
+              tripal_report_error('tripal_pubmed', TRIPAL_ERROR, 
+                'Cannot find a valid vocabulary term for the publication type: "%term".',
+                array('%term' => $value));
             }
           }
           else {

+ 60 - 56
tripal_pub/includes/tripal_pub.chado_node.inc

@@ -241,9 +241,14 @@ function chado_pub_form($node, $form_state) {
   $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') {
-      $select_options[$prop->cvterm_id] = $prop->name;
+    if ($prop->name == 'Citation') {
+      continue;
+    }
+    // Publication Dbxref's are handled by the dbxref form addition below
+    if ($prop->name == 'Publication Dbxref') {
+      continue;
     }
+    $select_options[$prop->cvterm_id] = $prop->name;
   }
 
   $details = array(
@@ -279,6 +284,7 @@ function chado_pub_form($node, $form_state) {
   // Adds the form elements to your current form
   chado_add_node_form_relationships($form, $form_state, $details);
 
+  
   // ADDITIONAL DBXREFS FORM
   //---------------------------------------------
   $details = array(
@@ -421,22 +427,25 @@ function chado_pub_validate($node, $form, &$form_state) {
  *
  * @param $uniquename
  *  The uniquename of the publication
+ * @param $pub_id
+ *  If an update, provide the pub_id so we don't check for a matching
+ *  uniquename of the pub we are editing
  *
  * @ingroup tripal_pub
  */
 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]);
+  // check to see if a pub exists with this uniquename
+  $pub = chado_get_publication(array('uniquename' => $uniquename));
+  if ($pub) {
+    // if a $pub_id is provided to the function then this is an update
+    // if the pub_id's don't match then a different pub with the same 
+    // uniquename already exists.
+    if ($pub->pub_id != $pub_id) {
+      $message = t('A publication with this unique citation already exists.');
+      form_set_error('uniquename', $message);
     }
   }
-  if (count($results) > 0) {
-    $message = t('A publication with this unique citation already exists.');
-    form_set_error('uniquename', $message);
-  }
 }
 
 /**
@@ -457,49 +466,34 @@ function chado_pub_validate_check_uniquename($uniquename, $pub_id = NULL) {
  */
 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
+  $pub_details = array(
+    'Title' => $title,
+    'Year' => $pyear,
+    'Series Name' => $series_name,
+    'Publication Type' => $cvterm->name,
+  );
+  $pub_ids = chado_does_pub_exist($pub_details);
+  
+  // if we found only one publication and it is our publication then 
+  // return, we're good.
+  if(count($pub_ids) == 1 and !in_array($pub_id, $pub_ids)) {
+    return;
+  }
+  
+  // return an appropriate message based on the unique constraint settings
   $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);
-      }
+      $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);
-      }
+      $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);
-      }
+      $message = t('A publication with this title, media name (e.g. Journal Name) and publication year already exists.');
+      form_set_error('pyear', $message);
       break;
   }
 }
@@ -719,9 +713,14 @@ function chado_pub_insert($node) {
     chado_update_node_form_relationships($node, $details);
 
     // add in any database cross-references
-    foreach ($cross_refs as $index => $ref) {
-      $pub_dbxref = tripal_pub_add_pub_dbxref($pub['pub_id'], trim($ref));
-      if (!$pub_dbxref) {
+    foreach ($cross_refs as $index => $ref) { 
+      $dbxref = array();
+      if(preg_match('/^(.*?):(.*?)$/', trim($ref), $matches)) {
+        $dbxref['db_name']   = $matches[1];
+        $dbxref['accession'] = $matches[2];
+      }
+      $success = chado_associate_dbxref('pub', $pub['pub_id'], $dbxref);
+      if (!$success) {
         drupal_set_message("Error cannot add publication cross reference: $ref", "error");
         watchdog('tripal_pub', "Error cannot add publication cross reference: %ref",
         array('%ref' => $ref), WATCHDOG_ERROR);
@@ -905,25 +904,30 @@ function chado_pub_update($node) {
   // now add in the properties by first removing any the publication
   // already has and adding the ones we have
   $details = array(
-    'property_table' => 'pubprop',
-    'base_table' => 'pub',
+    'property_table'  => 'pubprop',
+    'base_table'      => 'pub',
     'foreignkey_name' => 'pub_id',
-    'foreignkey_value' => $pub_id
+    'foreignkey_value'=> $pub_id
   );
   chado_update_node_form_properties($node, $details, $properties);
 
   // * Relationships Form *
   $details = array(
     'relationship_table' => 'pub_relationship',  // name of the _relationship table
-    'foreignkey_value' => $pub_id                // value of the pub_id key
+    'foreignkey_value'   => $pub_id                // value of the pub_id key
   );
   chado_update_node_form_relationships($node, $details);
 
   // add in any database cross-references after first removing
   chado_delete_record('pub_dbxref', array('pub_id' => $pub_id));
   foreach ($cross_refs as $index => $ref) {
-    $pub_dbxref = tripal_pub_add_pub_dbxref($pub_id, trim($ref));
-    if (!$pub_dbxref) {
+    $dbxref = array();
+    if(preg_match('/^(.*?):(.*?)$/', trim($ref), $matches)) {
+      $dbxref['db_name']   = $matches[1];
+      $dbxref['accession'] = $matches[2];
+    }
+    $success = chado_associate_dbxref('pub', $pub_id, $dbxref);
+    if (!$success) {
       drupal_set_message("Error cannot add publication cross reference: $ref", "error");
       watchdog('tripal_pub', "Error cannot add publication cross reference: %ref",
       array('%ref' => $ref), WATCHDOG_ERROR);

+ 279 - 1
tripal_pub/includes/tripal_pub.pub_citation.inc

@@ -98,7 +98,7 @@ function tripal_pub_create_citations($options) {
   while ($pub = $result->fetchObject()) {
     $pub_arr = tripal_pub_get_publication_array($pub->pub_id, $skip_existing);
     if ($pub_arr) {
-      $citation = tripal_pub_create_citation ($pub_arr);
+      $citation = tripal_pub_create_citation($pub_arr);
       print $citation . "\n\n";
       // Replace if citation exists. This condition is never TRUE if $skip_existing is TRUE
       if ($pub_arr['Citation']) {
@@ -123,3 +123,281 @@ function tripal_pub_create_citations($options) {
   }
   print "$counter_generated citations generated. $counter_updated citations updated.\n";
 }
+
+
+/**
+ * This function generates citations for publications.  It requires
+ * an array structure with keys being the terms in the Tripal
+ * publication ontology.  This function is intended to be used
+ * for any function that needs to generate a citation.
+ *
+ * @param $pub
+ *   An array structure containing publication details where the keys
+ *   are the publication ontology term names and values are the
+ *   corresponding details.  The pub array can contain the following
+ *   keys with corresponding values:
+ *     - Publication Type:  an array of publication types. a publication can have more than one type
+ *     - Authors: a  string containing all of the authors of a publication
+ *     - Journal Name:  a string containing the journal name
+ *     - Journal Abbreviation: a string containing the journal name abbreviation
+ *     - Series Name: a string containing the series (e.g. conference proceedings) name
+ *     - Series Abbreviation: a string containing the series name abbreviation
+ *     - Volume: the serives volume number
+ *     - Issue: the series issue number
+ *     - Pages: the page numbers for the publication
+ *     - Publication Date:  A date in the format "Year Month Day"
+ *
+ * @return
+ *   A text string containing the citation
+ *
+ * @ingroup tripal_pub_api
+ */
+function tripal_pub_create_citation($pub) {
+  $citation = '';
+  $pub_type = '';
+
+  // An article may have more than one publication type. For example,
+  // a publication type can be 'Journal Article' but also a 'Clinical Trial'.
+  // Therefore, we need to select the type that makes most sense for
+  // construction of the citation. Here we'll iterate through them all
+  // and select the one that matches best.
+  if(is_array($pub['Publication Type'])) {
+    foreach ($pub['Publication Type'] as $ptype) {
+      if ($ptype == 'Journal Article' ) {
+        $pub_type = $ptype;
+        break;
+      }
+      else if ($ptype == 'Conference Proceedings'){
+        $pub_type = $ptype;
+        break;
+      }
+      else if ($ptype == 'Review') {
+        $pub_type = $ptype;
+        break;
+      }
+      else if ($ptype == 'Book') {
+        $pub_type = $ptype;
+        break;
+      }
+      else if ($ptype == 'Letter') {
+        $pub_type = $ptype;
+        break;
+      }
+      else if ($ptype == 'Book Chapter') {
+        $pub_type = $ptype;
+        break;
+      }
+      else if ($ptype == "Research Support, Non-U.S. Gov't") {
+        $pub_type = $ptype;
+        // we don't break because if the article is also a Journal Article
+        // we prefer that type
+      }
+    }
+    if (!$pub_type) {
+      tripal_report_error('tripal_pub', TRIPAL_ERROR, 
+        "Cannot generate citation for publication type: %types.\nTitle: %title.\nDbxref: %dbxref",
+        array(
+          '%types' => print_r($pub['Publication Type'], TRUE),
+          '%title' => $pub['Title'],
+          '%dbxref' => $pub['Publication Dbxref'],
+        )
+      );
+      return FALSE;
+    }
+  }
+  else {
+    $pub_type = $pub['Publication Type'];
+  }
+  //----------------------
+  // Journal Article
+  //----------------------
+  if ($pub_type == 'Journal Article') {
+    $citation = $pub['Authors'] . '. ' . $pub['Title'] .  '. ';
+
+    if (array_key_exists('Journal Name', $pub)) {
+      $citation .= $pub['Journal Name'] . '. ';
+    }
+    elseif (array_key_exists('Journal Abbreviation', $pub)) {
+      $citation .= $pub['Journal Abbreviation'] . '. ';
+    }
+    elseif (array_key_exists('Series Name', $pub)) {
+      $citation .= $pub['Series Name'] . '. ';
+    }
+    elseif (array_key_exists('Series Abbreviation', $pub)) {
+      $citation .= $pub['Series Abbreviation'] . '. ';
+    }
+    if (array_key_exists('Publication Date', $pub)) {
+      $citation .= $pub['Publication Date'];
+    }
+    elseif (array_key_exists('Year', $pub)) {
+      $citation .= $pub['Year'];
+    }
+    if (array_key_exists('Volume', $pub) or array_key_exists('Issue', $pub) or array_key_exists('Pages',$pub)) {
+      $citation .= '; ';
+    }
+    if (array_key_exists('Volume', $pub)) {
+      $citation .= $pub['Volume'];
+    }
+    if (array_key_exists('Issue', $pub)) {
+      $citation .= '(' . $pub['Issue'] . ')';
+    }
+    if (array_key_exists('Pages', $pub)) {
+      if (array_key_exists('Volume', $pub)) {
+        $citation .= ':';
+      }
+      $citation .= $pub['Pages'];
+    }
+    $citation .= '.';
+  }
+  //----------------------
+  // Review
+  //----------------------
+  if ($pub_type == 'Review') {
+    $citation = $pub['Authors'] . '. ' . $pub['Title'] .  '. ';
+  
+    if (array_key_exists('Journal Name', $pub)) {
+      $citation .= $pub['Journal Name'] . '. ';
+    }
+    elseif (array_key_exists('Journal Abbreviation', $pub)) {
+      $citation .= $pub['Journal Abbreviation'] . '. ';
+    }
+    elseif (array_key_exists('Series Name', $pub)) {
+      $citation .= $pub['Series Name'] . '. ';
+    }
+    elseif (array_key_exists('Series Abbreviation', $pub)) {
+      $citation .= $pub['Series Abbreviation'] . '. ';
+    }
+    if (array_key_exists('Publication Date', $pub)) {
+      $citation .= $pub['Publication Date'];
+    }
+    elseif (array_key_exists('Year', $pub)) {
+      $citation .= $pub['Year'];
+    }
+    if (array_key_exists('Volume', $pub) or array_key_exists('Issue', $pub) or array_key_exists('Pages',$pub)) {
+      $citation .= '; ';
+    }
+    if (array_key_exists('Volume', $pub)) {
+      $citation .= $pub['Volume'];
+    }
+    if (array_key_exists('Issue', $pub)) {
+      $citation .= '(' . $pub['Issue'] . ')';
+    }
+    if (array_key_exists('Pages', $pub)) {
+      if (array_key_exists('Volume', $pub)) {
+        $citation .= ':';
+      }
+      $citation .= $pub['Pages'];
+    }
+    $citation .= '.';
+  }
+  //----------------------
+  // Research Support, Non-U.S. Gov't
+  //----------------------
+  elseif ($pub_type == "Research Support, Non-U.S. Gov't") {
+    $citation = $pub['Authors'] . '. ' . $pub['Title'] .  '. ';
+
+    if (array_key_exists('Journal Name', $pub)) {
+      $citation .= $pub['Journal Name'] . '. ';
+    }
+    if (array_key_exists('Publication Date', $pub)) {
+      $citation .= $pub['Publication Date'];
+    }
+    elseif (array_key_exists('Year', $pub)) {
+      $citation .= $pub['Year'];
+    }
+    $citation .= '.';
+  }
+  //----------------------
+  // Letter
+  //----------------------
+  elseif ($pub_type == 'Letter') {
+    $citation = $pub['Authors'] . '. ' . $pub['Title'] .  '. ';
+
+    if (array_key_exists('Journal Name', $pub)) {
+      $citation .= $pub['Journal Name'] . '. ';
+    }
+    elseif (array_key_exists('Journal Abbreviation', $pub)) {
+      $citation .= $pub['Journal Abbreviation'] . '. ';
+    }
+    elseif (array_key_exists('Series Name', $pub)) {
+      $citation .= $pub['Series Name'] . '. ';
+    }
+    elseif (array_key_exists('Series Abbreviation', $pub)) {
+      $citation .= $pub['Series Abbreviation'] . '. ';
+    }
+    if (array_key_exists('Publication Date', $pub)) {
+      $citation .= $pub['Publication Date'];
+    }
+    elseif (array_key_exists('Year', $pub)) {
+      $citation .= $pub['Year'];
+    }
+    if (array_key_exists('Volume', $pub) or array_key_exists('Issue', $pub) or array_key_exists('Pages',$pub)) {
+      $citation .= '; ';
+    }
+    if (array_key_exists('Volume', $pub)) {
+      $citation .= $pub['Volume'];
+    }
+    if (array_key_exists('Issue', $pub)) {
+      $citation .= '(' . $pub['Issue'] . ')';
+    }
+    if (array_key_exists('Pages', $pub)) {
+      if (array_key_exists('Volume', $pub)) {
+        $citation .= ':';
+      }
+      $citation .= $pub['Pages'];
+    }
+    $citation .= '.';
+  }
+  //----------------------
+  // Book
+  //----------------------
+  elseif ($pub_type == 'Book') {
+
+  }
+  //----------------------
+  // Book Chapter
+  //----------------------
+  elseif ($pub_type == 'Book Chapter') {
+
+  }
+  //----------------------
+  // Conference Proceedings
+  //----------------------
+  elseif ($pub_type == 'Conference Proceedings') {
+    $citation = $pub['Authors'] . '. ' . $pub['Title'] .  '. ';
+
+    if (array_key_exists('Conference Name', $pub)) {
+      $citation .= $pub['Conference Name'] . '. ';
+    }
+    elseif (array_key_exists('Series Name', $pub)) {
+      $citation .= $pub['Series Name'] . '. ';
+    }
+    elseif (array_key_exists('Series Abbreviation', $pub)) {
+      $citation .= $pub['Series Abbreviation'] . '. ';
+    }
+    if (array_key_exists('Publication Date', $pub)) {
+      $citation .= $pub['Publication Date'];
+    }
+    elseif (array_key_exists('Year', $pub)) {
+      $citation .= $pub['Year'];
+    }
+    if (array_key_exists('Volume', $pub) or array_key_exists('Issue', $pub) or array_key_exists('Pages',$pub)) {
+      $citation .= '; ';
+    }
+    if (array_key_exists('Volume', $pub)) {
+      $citation .= $pub['Volume'];
+    }
+    if (array_key_exists('Issue', $pub)) {
+      $citation .= '(' . $pub['Issue'] . ')';
+    }
+    if (array_key_exists('Pages', $pub)) {
+      if (array_key_exists('Volume', $pub)) {
+        $citation .= ':';
+      }
+      $citation .= $pub['Pages'];
+    }
+    $citation .= '.';
+  }
+
+  return $citation;
+}

+ 579 - 3
tripal_pub/includes/tripal_pub.pub_importers.inc

@@ -132,7 +132,7 @@ function tripal_pub_importer_setup_page($action = 'new', $pub_import_id = NULL)
 
       // get the list of publications from the remote database using the search criteria.
       $page = isset($_GET['page']) ? $_GET['page'] : '0';
-      $results = tripal_pub_get_remote_search_results($remote_db, $search_array, $limit, $page);
+      $results = tripal_get_remote_pubs($remote_db, $search_array, $limit, $page);
       $total_records = $results['total_records'];
       $search_str    = $results['search_str'];
       $pubs          = $results['pubs'];
@@ -706,7 +706,7 @@ function tripal_pub_importer_setup_form_submit($form, &$form_state) {
         // if the user wants to do the import now then do it (may time out
         // for long jobs)
         if ($form_state['values']['op'] == 'Save & Import Now') {
-          tripal_pub_import_publications($record['pub_import_id']);
+          tripal_execute_pub_importer($record['pub_import_id']);
         }
         drupal_goto('admin/tripal/chado/tripal_pub/import_list');
       }
@@ -812,7 +812,583 @@ function tripal_pub_importer_submit_job($import_id) {
 
   $args = array($import_id);
   tripal_add_job("Import publications $import->name", 'tripal_pub',
-    'tripal_pub_import_publications_by_import_id', $args, $user->uid);
+    'tripal_execute_pub_importer', $args, $user->uid);
 
   drupal_goto('admin/tripal/chado/tripal_pub/import_list');
 }
+
+/**
+ * Adds publications that have been retrieved from a remote database and
+ * consolidated into an array of details.
+ *
+ * @param $pubs
+ *   An array containing a list of publications to add to Chado.  The
+ *   array contains a set of details for the publication.
+ * @param $do_contact
+ *   Set to TRUE if authors should automatically have a contact record added
+ *   to Chado.
+ * @param $update
+ *   If set to TRUE then publications that already exist in the Chado database
+ *   will be updated, whereas if FALSE only new publications will be added
+ *
+ * @return
+ *   Returns an array containing the number of publications that were
+ *   inserted, updated, skipped and which had an error during import.
+ *
+ * @ingroup tripal_pub_api
+ */
+function tripal_pub_add_publications($pubs, $do_contact, $update = FALSE) {
+  $report = array();
+  $report['error'] = 0;
+  $report['inserted'] = array();
+  $report['skipped'] = array();
+  $total_pubs = count($pubs);
+
+  // iterate through the publications and add each one
+  $i = 1;
+  foreach ($pubs as $pub) {
+    $memory = number_format(memory_get_usage()) . " bytes";
+    print "Processing $i of $total_pubs. Memory usage: $memory.\r";
+
+    // add the publication to Chado
+    $action = '';
+    $pub_id = tripal_pub_add_publication($pub, $action, $do_contact, $update);
+    if ($pub_id){
+      // add the publication cross reference (e.g. to PubMed)
+      if ($pub_id and $pub['Publication Dbxref']) {
+        $pub_dbxref = tripal_pub_add_pub_dbxref($pub_id, $pub['Publication Dbxref']);
+      }
+      $pub['pub_id'] = $pub_id;
+    }
+
+    switch ($action) {
+      case 'error':
+        $report['error']++;
+        break;
+      case 'inserted':
+        $report['inserted'][] = $pub;
+        break;
+      case 'updated':
+        $report['updated'][] = $pub;
+        break;
+      case 'skipped':
+        $report['skipped'][] = $pub;
+        break;
+    }
+    $i++;
+  }
+  print "\n";
+  return $report;
+}
+
+/**
+ * Adds a new publication to the Chado, along with all properties and
+ * database cross-references. If the publication does not already exist
+ * in Chado then it is added.  If it does exist nothing is done.  If
+ * the $update parameter is TRUE then the publication is updated if it exists.
+ *
+ * @param $pub_details
+ *   An associative array containing all of the details about the publication.
+ * @param $action
+ *   This variable will get set to a text value indicating the action that was
+ *   performed. The values include 'skipped', 'inserted', 'updated' or 'error'.
+ * @param $do_contact
+ *   Optional. Set to TRUE if a contact entry should be added to the Chado contact table
+ *   for authors of the publication.
+ * @param $update_if_exists
+ *   Optional.  If the publication already exists then this function will return
+ *   without adding a new publication.  However, set this value to TRUE to force
+ *   the function to pudate the publication using the $pub_details that are provided.
+ *
+ * @return
+ *   If the publication already exists, is inserted or updated then the publication
+ *   ID is returned, otherwise FALSE is returned. If the publication already exists
+ *   and $update_if_exists is not TRUE then the $action variable is set to 'skipped'.
+ *   If the publication already exists and $update_if_exists is TRUE and if the update
+ *   was successful then $action is set to 'updated'.  Otherwise on successful insert
+ *   the $action variable is set to 'inserted'.  If the function failes then the
+ *   $action variable is set to 'error'
+ *
+ * @ingroup tripal_pub_api
+ */
+function tripal_pub_add_publication($pub_details, &$action, $do_contact = FALSE, $update_if_exists = FALSE) {
+  $pub_id = 0;
+
+  if (!is_array($pub_details)) {
+    return FALSE;
+  }
+
+  // before proceeding check to see if the publication already exists. If there is only one match
+  // and the $update_if_exists is NOT set then return FALSE
+  $pub_ids = chado_does_pub_exist($pub_details);
+  
+  if(count($pub_ids) == 1 and !$update_if_exists) {
+    tripal_report_error('tripal_pub', TRIPAL_NOTICE,
+     "There is a publication that is a duplicate of this publication. Cannot continue. It either ".
+     "has a matching Dbxref (e.g. PubMed ID), a non-unique citation or matches on the unique  " .
+     "constraint set by the Tripal publication module configuration page. \nCitation: %title %dbxref.\nMatching Pub id: %ids",
+       array(
+        '%title' => $pub_details['Citation'], 
+        '%dbxref' => $pub_details['Publication Dbxref'],
+        '%ids' => implode(",", $pub_ids),
+       )
+    );
+    $action = 'skipped';
+    return FALSE;
+  }
+  // if we have more than one matching pub then return an error as we don't know which to update even if
+  // update_if_exists is set to TRUE
+  if(count($pub_ids) > 1) {
+    tripal_report_error('tripal_pub', TRIPAL_NOTICE,
+      "There are %num publications that are duplicates of this publication. They either " .
+      "have a matching Dbxref (e.g. PubMed ID) or match on the unique constraint set by the Tripal publication module ".
+      "configuration page.  \nCitation: %title %dbxref.\nMatching Pub ids: %ids",
+       array(
+         '%num' => count($pub_ids), 
+         '%title' => $pub_details['Citation'], 
+         '%dbxref' => $pub_details['Publication Dbxref'],
+        '%ids' => implode(",", $pub_ids),
+       )
+    );
+    $action = 'skipped';
+    return FALSE;
+  }
+
+  // get the publication type (use the first publication type)
+  if (array_key_exists('Publication Type', $pub_details)) {
+    $pub_type = '';
+    if(is_array($pub_details['Publication Type'])) {
+      $pub_type = $pub_details['Publication Type'][0];
+    }
+    else {
+      $pub_type = $pub_details['Publication Type'];
+    }
+    $identifiers = array(
+      'name' => $pub_type,
+      'cv_id' => array(
+        'name' => 'tripal_pub'
+      ),
+    );
+    $pub_type = cvterm_retrieve($identifiers);
+  }
+  else {
+    tripal_report_error('tripal_pub', TRIPAL_ERROR, 
+      "The Publication Type is a required property but is missing", array());
+    $action = 'error';
+    return FALSE;
+  }
+  if (!$pub_type) {
+    tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot find publication type: '%type'",
+      array('%type' => $pub_details['Publication Type'][0]));
+    $action = 'error';
+    return FALSE;
+  }
+
+  // the series name field in the pub table is only 255 characters, so we should trim just in case
+  $series_name = '';
+  if (array_key_exists('Series_Name', $pub_details)) {
+    $series_name = substr($pub_details['Series Name'], 0, 255);
+  }
+  if (array_key_exists('Journal Name', $pub_details)) {
+    $series_name = substr($pub_details['Journal Name'], 0, 255);
+  }
+
+  // build the values array for inserting or updating
+  $values = array(
+    'title'       => $pub_details['Title'],
+    'volume'      => $pub_details['Volume'],
+    'series_name' => $series_name,
+    'issue'       => $pub_details['Issue'],
+    'pyear'       => $pub_details['Year'],
+    'pages'       => $pub_details['Pages'],
+    'uniquename'  => $pub_details['Citation'],
+    'type_id'     => $pub_type->cvterm_id,
+  );
+
+  // if there is no pub_id then we need to do an insert.
+  if (!$pub_id) {
+    $options = array('statement_name' => 'ins_pub_tivoseispypaunty');
+    $pub = chado_insert_record('pub', $values, $options);
+    if (!$pub) {
+      tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot insert the publication with title: %title",
+      array('%title' => $pub_details['Title']));
+      $action = 'error';
+      return FALSE;
+    }
+    $pub_id = $pub['pub_id'];
+    $action = 'inserted';
+  }
+
+  // if there is a pub_id and we've been told to update, then do the update
+  if ($pub_id and $update_if_exists) {
+    $match = array('pub_id' => $pub_id);
+    $options = array('statement_name' => 'up_pub_tivoseispypaunty');
+    $success = chado_update_record('pub', $match, $values, $options);
+    if (!$success) {
+      tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot update the publication with title: %title",
+      array('%title' => $pub_details['Title']));
+      $action = 'error';
+      return FALSE;
+    }
+    $action = 'updated';
+  }
+
+  // before we add any new properties we need to remove those that are there if this
+  // is an update.  The only thing we don't want to remove are the 'Publication Dbxref'
+  if ($update_if_exists) {
+    $sql = "
+      DELETE FROM {pubprop}
+      WHERE
+        pub_id = :pub_id AND
+        NOT type_id in (
+          SELECT cvterm_id
+          FROM {cvterm}
+          WHERE name = 'Publication Dbxref'
+        )
+    ";
+    chado_query($sql, array(':pub_id' => $pub_id));
+  }
+
+  // iterate through the properties and add them
+  foreach ($pub_details as $key => $value) {
+    // the pub_details may have the raw search data (e.g. in XML from PubMed.  We'll irgnore this for now
+    if($key == 'raw') {
+      continue;
+    }
+    
+    // get the cvterm by name
+    $identifiers = array(
+      'name' => $key,
+      'cv_id' => array(
+        'name' => 'tripal_pub'
+      ),
+    );
+    $cvterm = cvterm_retrieve($identifiers);
+    
+    // if we could not find the cvterm by name then try by synonym
+    //$cvterm = tripal_cv_get_cvterm_by_name($key, NULL, 'tripal_pub');
+    if (!$cvterm) {
+      $identifiers = array(
+        'synonym' => array(
+          'name' => $key,
+          'cv_name' => 'tripal_pub'
+        )
+      );
+      $cvterm = cvterm_retrieve($identifiers);
+    }
+    if (!$cvterm) {
+      tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot find term: '%prop'. Skipping.", array('%prop' => $key));
+      continue;
+    }
+
+    // skip details that won't be stored as properties
+    if ($key == 'Author List') {
+      tripal_pub_add_authors($pub_id, $value, $do_contact);
+      continue;
+    }
+    if ($key == 'Title' or $key == 'Volume' or $key == 'Journal Name' or $key == 'Issue' or
+    $key == 'Year' or $key == 'Pages') {
+      continue;
+    }
+
+    $success = 0;
+    if (is_array($value)) {
+      foreach ($value as $subkey => $subvalue) {
+        // if the key is an integer then this array is a simple list and
+        // we will insert using the primary key. Otheriwse, use the new key
+        if(is_int($subkey)) {
+          $success = chado_insert_property('pub', $pub_id, $key, 'tripal_pub', $subvalue, FALSE);
+        }
+        else {
+          $success = chado_insert_property('pub', $pub_id, $subkey, 'tripal_pub', $subvalue, FALSE);
+        }
+      }
+    }
+    else {
+      $success = chado_insert_property('pub', $pub_id, $key, 'tripal_pub', $value, TRUE);
+    }
+    if (!$success) {
+      tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot add property '%prop' to publication. Skipping.",
+      array('%prop' => $key));
+      continue;
+    }
+  }
+
+  return $pub_id;
+}
+
+
+
+/**
+ * Add one or more authors to a publication
+ *
+ * @param $pub_id
+ *   The publication ID of the pub in Chado.
+ * @param $authors
+ *   An array of authors.  Each author should have a set of keys/value pairs
+ *   describing the author.
+ * @param $do_contact
+ *   Optional. Set to TRUE if a contact entry should be added to the Chado contact table
+ *   for authors of the publication.
+ * @ingroup tripal_pub_api
+ */
+function tripal_pub_add_authors($pub_id, $authors, $do_contact) {
+  $rank = 0;
+
+  // first remove any of the existing pubauthor entires
+  $sql = "DELETE FROM {pubauthor} WHERE pub_id = :pub_id";
+  chado_query($sql, array(':pub_id' => $pub_id));
+
+  // iterate through the authors and add them to the pubauthors and contact
+  // tables of chado, then link them through the custom pubauthors_contact table
+  foreach ($authors as $author) {
+    // skip invalid author entires
+    if ($author['valid'] == 'N') {
+      continue;
+    }
+    // remove the 'valid' property as we don't have a CV term for it
+    unset($author['valid']);
+
+    // construct the contact.name field using the author information
+    $name = '';
+    $type = 'Person';
+    if ($author['Given Name']) {
+      $name .= $author['Given Name'];
+    }
+    if ($author['Surname']) {
+      $name .= ' ' . $author['Surname'];
+    }
+    if ($author['Suffix']) {
+      $name .= ' ' . $author['Suffix'];
+    }
+    if ($author['Collective']) {
+      $name = $author['Collective'];
+      $type = 'Collective';
+    }
+    $name = trim($name);
+
+    // add an entry to the pubauthors table
+    $values = array(
+      'pub_id' => $pub_id,
+      'rank' => $rank,
+      'surname' => $author['Surname'] ? substr($author['Surname'], 0, 100) : substr($author['Collective'], 0, 100),
+      'givennames' => $author['Given Name'],
+      'suffix' => $author['Suffix'],
+    );
+    $options = array('statement_name' => 'ins_pubauthor_idrasugisu');
+    $pubauthor = chado_insert_record('pubauthor', $values, $options);
+
+    // if the user wants us to create a contact for each author then do it.
+    if ($do_contact) {
+      // Add the contact
+      $contact = tripal_contact_add_contact($name, '', $type, $author);
+
+      // if we have succesfully added the contact and the pubauthor entries then we want to
+      // link them together
+      if ($contact and $pubauthor) {
+
+        // link the pubauthor entry to the contact
+        $values = array(
+          'pubauthor_id' => $pubauthor['pubauthor_id'],
+          'contact_id' => $contact['contact_id'],
+        );
+        $options = array('statement_name' => 'ins_pubauthorcontact_puco');
+        $pubauthor_contact = chado_insert_record('pubauthor_contact', $values, $options);
+        if (!$pubauthor_contact) {
+          tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot link pub authro and contact.", array());
+        }
+      }
+    }
+    $rank++;
+  }
+}
+
+/**
+ * This function generates an array suitable for use with the
+ * tripal_pub_create_citation function for any publication
+ * already stored in the Chado tables.
+ *
+ * @param $pub_id
+ *   The publication ID
+ * @param $skip_existing
+ *   Set to TRUE to skip publications that already have a citation
+ *   in the pubprop table.  Set to FALSE to generate a citation
+ *   regardless if the citation already exists.
+ *
+ * @return
+ *   An array suitable for the trpial_pub_create_citation function. On
+ *   failure returns FALSE.
+ *
+ * @ingroup tripal_pub_api
+ */
+function tripal_pub_get_publication_array($pub_id, $skip_existing = TRUE) {
+
+  $options = array('return_array' => 1);
+
+  // ---------------------------------
+  // get the publication
+  // ---------------------------------
+  $values = array('pub_id' => $pub_id);
+  $pub = chado_generate_var('pub', $values);
+
+  // expand the title
+  $pub = chado_expand_var($pub, 'field', 'pub.title');
+  $pub = chado_expand_var($pub, 'field', 'pub.volumetitle');
+  $pub = chado_expand_var($pub, 'field', 'pub.uniquename');
+  $pub_array = array();
+  if (trim($pub->title)) {
+    $pub_array['Title'] = $pub->title;
+  }
+  if (trim($pub->volumetitle)) {
+    $pub_array['Volume Title'] = $pub->volumetitle;
+  }
+  if (trim($pub->volume)) {
+    $pub_array['Volume'] = $pub->volume;
+  }
+  if (trim($pub->series_name)) {
+    $pub_array['Series Name'] = $pub->series_name;
+  }
+  if (trim($pub->issue)) {
+    $pub_array['Issue'] = $pub->issue;
+  }
+  if (trim($pub->pyear)) {
+    $pub_array['Year'] = $pub->pyear;
+  }
+  if (trim($pub->pages)) {
+    $pub_array['Pages'] = $pub->pages;
+  }
+  if (trim($pub->miniref)) {
+    $pub_array['Mini Ref'] = $pub->miniref;
+  }
+  if (trim($pub->uniquename)) {
+    $pub_array['Uniquename'] = $pub->uniquename;
+  }
+  $pub_array['Publication Type'][] = $pub->type_id->name;
+
+  // ---------------------------------
+  // get the citation
+  // ---------------------------------
+  $values = array(
+    'pub_id' => $pub->pub_id,
+    'type_id' => array(
+      'name' => 'Citation',
+    ),
+  );
+  $citation = chado_generate_var('pubprop', $values);
+  if ($citation) {
+    $citation = chado_expand_var($citation, 'field', 'pubprop.value', $options);
+    if (count($citation) > 1) {
+      tripal_report_error('tripal_pub', TRIPAL_ERROR, "Publication has multiple citations already: %pub_id",
+      array('%pub_id' => $pubid));
+      return FALSE;
+    }
+    elseif (count($citation) == 1 and $skip_existing == TRUE) {
+      // skip this publication, it already has a citation
+      return FALSE;
+    }
+  }
+
+  // ---------------------------------
+  // get the publication types
+  // ---------------------------------
+  $values = array(
+    'pub_id' => $pub->pub_id,
+    'type_id' => array(
+      'name' => 'Publication Type',
+    ),
+  );
+  $ptypes = chado_generate_var('pubprop', $values, $options);
+  if ($ptypes) {
+    $ptypes = chado_expand_var($ptypes, 'field', 'pubprop.value', $options);
+    foreach ($ptypes as $ptype) {
+      $pub_array['Publication Type'][] = $ptype->value;
+    }
+  }
+
+  // ---------------------------------
+  // get the authors list
+  // ---------------------------------
+  $values = array(
+    'pub_id' => $pub->pub_id,
+    'type_id' => array(
+      'name' => 'Authors',
+    ),
+  );
+  $authors = chado_generate_var('pubprop', $values);
+  $authors = chado_expand_var($authors, 'field', 'pubprop.value', $options);
+  if (count($authors) > 1) {
+    tripal_report_error('tripal_pub', TRIPAL_ERROR, "Publication has multiple author lists. It should have only one list: %pub_id",
+    array('%pub_id' => $pubid));
+    return FALSE;
+  }
+  else if (trim($authors->value)) {
+    $pub_array['Authors'] = $authors->value;
+  }
+  // if there is no 'Author's property then try to retreive authors from the pubauthor table
+  else {
+    $sql = "
+      SELECT string_agg(surname || ' ' || givennames, ', ')
+      FROM {pubauthor}
+      WHERE pub_id = :pub_id
+      GROUP BY pub_id
+    ";
+    $au = chado_query($sql, array(':pub_id' => $pub_id))->fetchField();
+    if ($au) {
+      $pub_array['Authors'] = $au;
+    }
+  }
+
+  //Get other props
+  $props = array(
+    'Journal Abbreviation',
+    'Elocation',
+    'Media Code',
+    'Conference Name',
+    'Keywords',
+    'Series Name',
+    'pISSN',
+    'Publication Date',
+    'Journal Code',
+    'Journal Alias',
+    'Journal Country',
+    'Published Location',
+    'Publication Model',
+    'Language Abbr',
+    'Alias',
+    'Publication Dbxref',
+    'Copyright',
+    'Abstract',
+    'Notes',
+    'Citation',
+    'Language',
+    'URL',
+    'eISSN',
+    'DOI',
+    'ISSN',
+    'Publication Code',
+    'Comments',
+    'Publisher',
+    'Media Alias',
+    'Original Title'
+  );
+  foreach ($props AS $prop) {
+    $sql =
+      "SELECT value FROM {pubprop}
+       WHERE type_id =
+         (SELECT cvterm_id
+          FROM {cvterm}
+          WHERE name = :cvtname AND cv_id =
+            (SELECT cv_id
+             FROM {cv}
+             WHERE name = 'tripal_pub'
+            )
+         )
+       AND pub_id = :pub_id
+    ";
+    $val = trim(chado_query($sql, array(':cvtname' => $prop, ':pub_id' => $pub->pub_id))->fetchField());
+    if ($val) {
+      $pub_array[$prop] =$val;
+    }
+  }
+  return $pub_array;
+}

+ 6 - 125
tripal_pub/includes/tripal_pub.pub_search.inc

@@ -39,11 +39,12 @@ function tripal_pub_search_page() {
     }
 
     // get the list of publications from the remote database using the search criteria.
-    $pubs = tripal_pub_get_search_results($search_array, $limit);
     $page = isset($_GET['page']) ? $_GET['page'] : '0';
-    $total_records = chado_pager_get_count(0);
-    $total_pages = (int) ($total_records / $limit) + 1;
-
+    $offset = $page * $limit;
+    $total_records = 0;
+    $pubs = pub_search($search_array, $offset, $limit, $total_records);
+    pager_default_initialize($total_records, $limit, 0);
+    
     // iterate through the results and construct the table displaying the publications
     $rows = array();
     $i = $page * $limit + 1;
@@ -98,7 +99,6 @@ function tripal_pub_search_page() {
     $results = theme_table($table);
 
     // generate the pager
-    pager_default_initialize($total_records, $limit);
     $pager = array(
       'tags' => array(),
       'element' => 0,
@@ -108,8 +108,7 @@ function tripal_pub_search_page() {
     $pager = theme_pager($pager);
 
     // join all to form the results
-    $output .= "<br><p><b>Found " . number_format($total_records) .
-      ". Page " . ($page + 1) . " of $total_pages. " .
+    $output .= "<p><b>Found " . number_format($total_records) .
       " Results</b></br>" . $results . $pager;
   }
   return $output;
@@ -452,125 +451,7 @@ function tripal_pub_search_form_submit($form, &$form_state) {
     unset($_SESSION['tripal_pub_search_form']);
   }
 }
-/**
- * Builds the SQL statement need to search Chado for the publications
- * that match the user supplied criteria
- *
- * @param $search_array
- *   An array of search criteria provided by the user
- * @param $limit
- *   The numbe of records to retrieve
- *
- * @ingroup tripal_pub
- */
-function tripal_pub_get_search_results($search_array, $limit) {
-
-  // build the SQL based on the criteria provided by the user
-  $select = "SELECT DISTINCT P.*, CP.nid ";
-  $from   = "FROM {pub} P
-               LEFT JOIN public.chado_pub CP on P.pub_id = CP.pub_id
-               INNER JOIN {cvterm} CVT on CVT.cvterm_id = P.type_id
-            ";
-  $where  = "WHERE (NOT P.title = 'null') "; // always exclude the dummy pub
-  $order  = "ORDER BY P.pyear DESC, P.title ASC";
-  $args = array();  // arguments for where clause
-  $join = 0;
-
-  $num_criteria = $search_array['num_criteria'];
-  $from_year    = $search_array['from_year'];
-  $to_year      = $search_array['to_year'];
-
-  for ($i = 1; $i <= $num_criteria; $i++) {
-    $value = $search_array['criteria'][$i]['search_terms'];
-    $type_id = $search_array['criteria'][$i]['scope'];
-    $mode = $search_array['criteria'][$i]['mode'];
-    $op = $search_array['criteria'][$i]['operation'];
-
-    // skip criteria with no values
-    if(!$value) {
-      continue;
-    }
-
-    // to prevent SQL injection make sure our operator is
-    // what we expect
-    if ($op and $op != "AND" and $op != "OR" and $op != 'NOT') {
-      $op = 'AND';
-    }
-    if ($op == 'NOT') {
-      $op = 'AND NOT';
-    }
-    if (!$op) {
-      $op = 'AND';
-    }
 
-    // get the scope type
-    $values = array('cvterm_id' => $type_id);
-    $cvterm = chado_select_record('cvterm', array('name'), $values);
-    $type_name = '';
-    if (count($cvterm) > 0) {
-      $type_name = $cvterm[0]->name;
-    }
-    if ($type_name == 'Title') {
-      $where .= " $op (lower(P.title) LIKE lower(:crit$i)) ";
-      $args[":crit$i"] = '%' . $value . '%';
-    }
-    elseif ($type_name == 'Year') {
-      $where .= " $op (lower(P.pyear) = lower(:crit$i)) ";
-      $args[":crit$i"] = '%' . $value . '%';
-    }
-    elseif ($type_name == 'Volume') {
-      $where .= " $op (lower(P.volume) = lower(:crit$i)) ";
-      $args[":crit$i"] = '%' . $value . '%';
-    }
-    elseif ($type_name == 'Issue') {
-      $where .= " $op (lower(P.issue) = lower(:crit$i)) ";
-      $args[":crit$i"] = '%' . $value . '%';
-    }
-    elseif ($type_name == 'Journal Name') {
-      $from .= " LEFT JOIN {pubprop} PP$i ON PP$i.pub_id = P.pub_id AND PP$i.type_id = :crit$i ";
-      $where .= " $op ((lower(P.series_name) = lower(:crit$i) and CVT.name = 'Journal Article') OR
-                       (lower(PP$i.value) = lower(:crit$i))) ";
-      $args[":crit$i"] = $type_id;
-    }
-    elseif ($type_name == 'Conference Name') {
-      $from .= " LEFT JOIN {pubprop} PP$i ON PP$i.pub_id = P.pub_id AND PP$i.type_id = :crit$i ";
-      $where .= " $op ((lower(P.series_name) = lower(:crit$i) and CVT.name = 'Conference Proceedings') OR
-                       (lower(PP$i.value) = lower(:crit$i))) ";
-      $args[":crit$i"] = $type_id;
-    }
-    elseif ($type_name == 'Publication Type') {
-      $where .= " $op (lower(CVT.name) = lower(:crit$i))";
-      $args[":crit$i"] = $value;
-    }
-    elseif ($type_id == 0) { //'Any Field'
-      $from .= " LEFT JOIN {pubprop} PP$i ON PP$i.pub_id = P.pub_id ";
-      $where .= " $op (lower(PP$i.value)  LIKE lower(:crit$i) OR
-                       lower(P.title) LIKE lower(:crit$i) OR
-                       lower(P.volumetitle) LIKE lower(:crit$i) OR
-                       lower(P.publisher) LIKE lower(:crit$i) OR
-                       lower(P.uniquename) LIKE lower(:crit$i) OR
-                       lower(P.pubplace) LIKE lower(:crit$i) OR
-                       lower(P.miniref) LIKE lower(:crit$i) OR
-                       lower(P.series_name) LIKE lower(:crit$i)) ";
-      $args[":crit$i"] = '%' . $value . '%';
-    }
-    // for all other properties
-    else {
-      $from .= " LEFT JOIN {pubprop} PP$i ON PP$i.pub_id = P.pub_id AND PP$i.type_id = :type_id$i ";
-      $where .= " $op (lower(PP$i.value) LIKE lower(:crit$i)) ";
-      $args[":crit$i"] = '%' . $value . '%';
-      $args[":type_id$i"] = $type_id;
-    }
-  }
-  if($from_year and $to_year) {
-    $where .= " AND (P.pyear ~ '....' AND to_number(P.pyear,'9999') >= :from$i AND to_number(P.pyear,'9999') <= :to$i) ";
-    $args[":from$i"] = $from_year;
-    $args[":to$i"] = $to_year;
-  }
-  $sql = "$select $from $where $order";
-  $count = "SELECT count(*) FROM ($select $from $where $order) as t1";
-  return chado_pager_query($sql, $args, $limit, 0, $count);
-}
 
 /**
  * Ajax callback to update the form

+ 3 - 3
tripal_pub/tripal_pub.drush.inc

@@ -82,10 +82,10 @@ function drush_tripal_pub_tripal_pubs_import() {
   }
 
   if ($dbxref) {
-    tripal_pub_import_by_dbxref($dbxref, $create_contacts, $update);
+    tripal_import_pub_by_dbxref($dbxref, $create_contacts, $update);
   }
   else {
-    tripal_pub_import_publications($do_report, $update);
+    tripal_execute_active_pub_importers($do_report, $update);
   }
 }
 
@@ -99,5 +99,5 @@ function drush_tripal_pub_tripal_pubs_update() {
   $dbxref = drush_get_option('dbxref');
   $db = drush_get_option('db');
 
-  tripal_pub_update_publications($create_contacts, $dbxref, $db);
+  chado_reimport_publications($create_contacts, $dbxref, $db);
 }

+ 7 - 8
tripal_pub/tripal_pub.module

@@ -5,7 +5,7 @@
  */
 
 require_once 'api/tripal_pub.api.inc';
-//require_once 'api/tripal_pub.DEPRECATED.inc';
+require_once 'api/tripal_pub.DEPRECATED.inc';
 
 require_once 'theme/tripal_pub.theme.inc';
 
@@ -99,7 +99,6 @@ function tripal_pub_menu() {
     'type' => MENU_LOCAL_TASK,
     'weight' => 2
   );
-  return $items;
 
   $items['admin/tripal/chado/tripal_pub/citation'] = array(
     'title' => 'Citations',
@@ -112,8 +111,8 @@ function tripal_pub_menu() {
   );
 
   $items['admin/tripal/chado/tripal_pub/import_list'] = array(
-    'title' => t('Importers'),
-    'description' => t('List all publication importers'),
+    'title' => t('Publication Importers'),
+    'description' => t('Create and modify importers that can connect to and retreive publications from remote databases.'),
     'page callback' => 'tripal_pub_importers_list',
     'access arguments' => array('administer tripal pub'),
     'type' => MENU_LOCAL_TASK,
@@ -122,8 +121,8 @@ function tripal_pub_menu() {
 
   // add a second link for the importer on the data loaders page
   $items['admin/tripal/loaders/pub_import'] = array(
-    'title' => 'Publications Importers',
-    'description' => 'Create importers that can periodically import publications from remote online publication databases.',
+    'title' => t('Publication Importers'),
+    'description' => t('Create and modify importers that can connect to and retreive publications from remote databases.'),
     'page callback' => 'tripal_pub_importers_list',
     'access arguments' => array('administer tripal pubs'),
     'type' => MENU_NORMAL_ITEM,
@@ -138,7 +137,7 @@ function tripal_pub_menu() {
   );
 
   $items['admin/tripal/chado/tripal_pub/import/raw/%'] = array(
-    'page callback' => 'tripal_pub_get_raw_data',
+    'page callback' => 'tripal_get_remote_pub',
     'page arguments' => array(6),
     'access arguments' => array('administer tripal pub'),
     'type ' => MENU_CALLBACK,
@@ -408,7 +407,7 @@ function tripal_pub_form_alter(&$form, &$form_state, $form_id) {
 function tripal_pub_job_describe_args($callback, $args) {
 
   $new_args = array();
-  if ($callback == 'tripal_pub_import_publications_by_import_id') {
+  if ($callback == 'tripal_execute_pub_importer') {
     // get all of the loaders
     $qargs = array(':import_id' => $args[0]);
     $sql = "SELECT * FROM {tripal_pub_import} WHERE pub_import_id = :import_id ";