Browse Source

Fixed bugs, changed the way authors lists are stored, updated ontology

spficklin 12 years ago
parent
commit
aa118aca79

+ 13 - 5
tripal_db/api/tripal_db.api.inc

@@ -103,11 +103,19 @@ function tripal_db_get_db_by_db_id($db_id) {
  */
 function tripal_db_get_db_by_name($name) {
 
-  $r = db_fetch_object(chado_query(
-    "SELECT * FROM {db} WHERE name='%s'", $name
-  ));
-
-  return $r;
+  $values = array('name' => $name);
+  $options = array('statement_name' => 'sel_db_na');
+  
+  $db = tripal_core_chado_select('db', array('*'), $values, $options);
+  if (count($db) == 1) {
+    return $db[0];
+  }
+  if (count($db) == 0) {
+    return FALSE;
+  }
+  if (count($db) > 1) {
+    return FALSE;
+  }
 }
 
 // Purpose: To retrieve a chado db object

+ 103 - 49
tripal_pub/api/tripal_pub.api.inc

@@ -100,7 +100,7 @@ function tripal_pub_update_publications($do_contact = FALSE) {
       INNER JOIN pub_dbxref PDBX ON P.pub_id = PDBX.pub_id
       INNER JOIN dbxref DBX      ON DBX.dbxref_id = PDBX.dbxref_id
       INNER JOIN db DB           ON DB.db_id = DBX.db_id
-    ORDER BY DB.name
+    ORDER BY DB.name, P.pub_id
   ";
   $results = chado_query($sql);
   
@@ -115,13 +115,19 @@ function tripal_pub_update_publications($do_contact = FALSE) {
     $accession = $pub->accession;
     $remote_db = $pub->db_name;
     
+    // here we need to only update publications for databases we support
+    $supported_dbs = variable_get('tripal_pub_supported_dbs', array());
+    if(!in_array($remote_db, $supported_dbs)) {
+      continue;
+    }
+    
     // if we're switching databases then reset the search array    
     if($remote_db != $curr_db) {
       // if we had a previous DB then do the update.
       if ($curr_db) {
         $search['num_criteria'] = $i - 1;
         $pubs = tripal_pub_get_remote_search_results($remote_db, $search, $i, 0);
-        tripal_pub_add_publications($pubs, $do_contact); 
+        tripal_pub_add_publications($pubs, $do_contact, TRUE); 
       }
       $curr_db = $remote_db;      
       $search = array(
@@ -136,7 +142,7 @@ function tripal_pub_update_publications($do_contact = FALSE) {
     if($i == $num_to_retrieve) {      
       $search['num_criteria'] = $i - 1;
       $pubs = tripal_pub_get_remote_search_results($remote_db, $search, $i, 0);
-      tripal_pub_add_publications($pubs, $do_contact);
+      tripal_pub_add_publications($pubs, $do_contact, TRUE);
       $search['criteria'] = array();
       $i = 0;
     }
@@ -152,7 +158,7 @@ function tripal_pub_update_publications($do_contact = FALSE) {
   // now update any remaining in the search criteria array
   $search['num_criteria'] = $i - 1;
   $pubs = tripal_pub_get_remote_search_results($remote_db, $search, $i, 0);
-  tripal_pub_add_publications($pubs, $do_contact);
+  tripal_pub_add_publications($pubs, $do_contact, TRUE);
   
   // sync the newly added publications with Drupal
   print "Syncing publications with Drupal...\n";
@@ -198,6 +204,7 @@ function tripal_pub_import_publications() {
   $results = db_query($sql);
   $do_contact = FALSE;
   while ($import = db_fetch_object($results)) {
+    print "Importing: " . $import->name . "\n";
     // keep track if any of the importers want to create contacts from authors
     if ($import->do_contact == 1) {
       $do_contact = TRUE;      
@@ -233,34 +240,52 @@ function tripal_pub_import_publications() {
 /*
  * 
  */
-function tripal_pub_add_publications($pubs, $do_contact) {
+function tripal_pub_add_publications($pubs, $do_contact, $update = FALSE) {
  
   // iterate through the publications and add each one
   foreach ($pubs as $pub) {
          
     // add the publication to Chado and sync it with Chado
-    $pub_id = tripal_pub_add_publication($pub, $do_contact);
-   
-    // add the publication cross reference (e.g. to PubMed)
-    if ($pub_id) {         
-      $pub_dbxref = tripal_pub_add_pub_dbxref($pub_id, $pub);
-    }                                      
-  
-    $num_pubs++;
-    print $num_pubs . ".  " . $pub['Publication Database'] . ' ' . $pub['Publication Accession'] . "\n";                          
-  } // end for loop        
+    $pub_id = tripal_pub_add_publication($pub, $do_contact, $update);
+    if (is_numeric($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']);
+      }                                        
+      $num_pubs++; 
+      print "Success: " . $pub['Publication Dbxref'] . "\n";  
+    } 
+    elseif($pub_id) {
+      print "Skipped: " . $pub['Publication Dbxref'] . "\n";  
+    }
+    else {
+      print "Failed: " . $pub['Publication Dbxref'] . "\n";  
+    } 
+    
+  }         
 }
 /*
  * 
  */
-function tripal_pub_add_pub_dbxref($pub_id, $pub) {
+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' => $pub['Publication Accession'],
+      'accession' => $accession,
       'db_id' => array(
-        'name' => $pub['Publication Database'],
+        'name' => $dbname,
       ),
     ), 
     'pub_id' => $pub_id,
@@ -274,18 +299,18 @@ function tripal_pub_add_pub_dbxref($pub_id, $pub) {
   }
   
   // make sure our database already exists
-  $db = tripal_db_add_db($pub['Publication Database']);
+  $db = tripal_db_add_db($dbname);
    
   // get the database cross-reference
   $dbxvalues = array(
-    'accession' => $pub['Publication Accession'],
+    'accession' => $accession,
     'db_id' => $db->db_id,
   );
   $dbxoptions = array('statement_name' => 'sel_dbxref_acdb');
   $results = tripal_core_chado_select('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, $pub['Publication Accession']);          
+    $dbxref = tripal_db_add_dbxref($db->db_id, $accession);          
   }
   else {
     $dbxref = $results[0];
@@ -296,7 +321,7 @@ function tripal_pub_add_pub_dbxref($pub_id, $pub) {
   $results = tripal_core_chado_insert('pub_dbxref', $values, $options);
   if (!$results) {
     watchdog('tripal_pub', "Cannot add publication dbxref: %db:%accession.",
-      array('%db' => $pub['Publication Database'], '%accession' => $pub['Publication Accession']). WATCHDOG_ERROR);
+      array('%db' => $dbname, '%accession' => $accession). WATCHDOG_ERROR);
     return FALSE;
   }
   return $results;
@@ -304,30 +329,40 @@ function tripal_pub_add_pub_dbxref($pub_id, $pub) {
 /*
  * 
  */
-function tripal_pub_add_publication($pub_details, $do_contact) {
+function tripal_pub_add_publication($pub_details, $do_contact, $update = FALSE) {
   
   $pub_id = 0;
 
-  // first try to find the publication using the accession number. It will ahve
+  // 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 ($pub_details['Publication Accession'] and $pub_details['Publication Database']) {
-    $values = array(
-      'dbxref_id' => array (
-        'accession' => $pub_details['Publication Accession'],
-        'db_id' => array(
-          'name' => $pub_details['Publication Database']
+  if ($pub_details['Publication Dbxref']) {
+    if(preg_match('/^(.*?):(.*?)$/', $pub_details['Publication 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 = tripal_core_chado_select('pub_dbxref', array('pub_id'), $values, $options);
-    if(count($results) == 1) {
-      $pub_id = $results[0]->pub_id;     
+      );
+      $options = array('statement_name' => 'sel_pubdbxref_db');
+      $results = tripal_core_chado_select('pub_dbxref', array('pub_id'), $values, $options);
+      if(count($results) == 1) {
+        $pub_id = $results[0]->pub_id;     
+      }
+      elseif(count($results) > 1) {
+        watchdog('tripal_pub', "There are two publications with this accession: %db:%accession. Cannot determine which to update.", 
+          array('%db' => $dbname, '%accession' => $accession), WATCHDOG_ERROR);     
+        return FALSE;    
+      }
     }
-    elseif(count($results) > 1) {
-      watchdog('tripal_pub', "There are two publications with this accession: %db:%accession. Cannot determine which to update.", 
-        array('%db' => $pub_details['Publication Database'], '%accession' => $pub_details['Publication Accession']), WATCHDOG_ERROR);     
-      return FALSE;    
+    // If we found the publication and we do not want to do the update then
+    // return true to indicate the publication has been added
+    if (!$update and $pub_id) {
+      return TRUE;
     }
   }   
   // if we couldn't find a publication by the accession (which means it doesn't
@@ -352,6 +387,11 @@ function tripal_pub_add_publication($pub_details, $do_contact) {
         "determine which to use.  Title: %title", array('%title' => $pub_details['Title']), WATCHDOG_ERROR);     
       return FALSE;          
     }
+    // If we found the publication and we do not want to do the update then
+    // return true to indicate the publication has been added
+    if (!$update and $pub_id) {
+      return TRUE;
+    }
   }
   
   // if we couldn't find the publication using the database accession or the title/year then add it
@@ -359,8 +399,8 @@ function tripal_pub_add_publication($pub_details, $do_contact) {
     // get the publication type (use the first publication type, any others will get stored as properties)
     $pub_type = tripal_cv_get_cvterm_by_name($pub_details['Publication Type'][0], NULL, 'tripal_pub');
     if (!$pub_type) {
-      watchdog('tripal_pub', "Cannot find publication type: %type", 
-        array('%type' => $pub_type), WATCHDOG_ERROR);
+      watchdog('tripal_pub', "Cannot find publication type: '%type'", 
+        array('%type' => $pub_details['Publication Type'][0]), WATCHDOG_ERROR);
       return FALSE;   
     }
     // if the publication does not exist then create it.      
@@ -384,29 +424,43 @@ function tripal_pub_add_publication($pub_details, $do_contact) {
     $pub_id = $pub['pub_id'];
   } 
   
-  // now add in any other items that remain as properties of the publication  
+  // 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) {
+    $sql = "
+      DELETE FROM {pubprop} 
+      WHERE 
+        pub_id = %d AND 
+        NOT type_id in (
+          SELECT cvterm_id
+          FROM {cvterm} 
+          WHERE name = 'Publication Dbxref' 
+        )
+    ";
+    chado_query($sql, $pub_id);
+  } 
+  
   foreach ($pub_details as $key => $value) {
      
-    // get the cvterm by name or synonym
+     // 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) {
-       print_r($cvterm);
        watchdog('tripal_pub', "Cannot find term: '%prop'. Skipping.", array('%prop' => $key), WATCHDOG_ERROR);
        continue;
      }
 
      // skip details that won't be stored as properties
-     if ($key == 'Authors') {
+     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)) {       
@@ -414,10 +468,10 @@ function tripal_pub_add_publication($pub_details, $do_contact) {
          // 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 = tripal_core_insert_property('pub', $pub_id, $key, 'tripal_pub', $subvalue, TRUE);
+           $success = tripal_core_insert_property('pub', $pub_id, $key, 'tripal_pub', $subvalue, FALSE);
          }
          else {
-           $success = tripal_core_insert_property('pub', $pub_id, $subkey, 'tripal_pub', $subvalue, TRUE);           
+           $success = tripal_core_insert_property('pub', $pub_id, $subkey, 'tripal_pub', $subvalue, FALSE);           
          }
        }  
      }

+ 4 - 9
tripal_pub/includes/pub_form.inc

@@ -85,12 +85,7 @@ function chado_pub_form($node, $form_state) {
   while ($prop = db_fetch_object($prop_types)) {
     // the 'Citation' term is special because it serves
     // both as a property and as the uniquename for the publiation table
-    // it is present by default in the initial fields of the form so
-    // we don't want it again in the drop-down list
-    // also remove other terms associated with the DBXref
-    if ($prop->name != "Citation" and
-        $prop->name != "Publication Accession" and
-        $prop->name != "Publication Database") {
+    if ($prop->name != "Citation") {
       $properties_select[$prop->cvterm_id] = $prop->name;
     }
     $properties_list[$prop->cvterm_id] = $prop;
@@ -267,7 +262,7 @@ function chado_pub_node_form_add_new_props(&$form, $form_state, $num_new, &$d_pr
           '#default_value' => $value,
           '#cols'          => 50,
           '#rows'          => $rows,
-          '#description'   => $description,
+          '#description'   => $cvterm->definition,
         );
         
         $form['properties']['new'][$new_id][$rank]["remove-$new_id-$rank"] = array(
@@ -324,7 +319,7 @@ function chado_pub_node_form_add_new_props(&$form, $form_state, $num_new, &$d_pr
       '#default_value' => $new_value,
       '#cols'          => 50,
       '#rows'          => $rows,
-      '#description'   => $description,
+      '#description'   => $cvterm->definition,
     );
     
     $form['properties']['new'][$new_id][$rank]["remove-$new_id-$rank"] = array(
@@ -410,7 +405,7 @@ function chado_pub_node_form_add_pubprop_table_props(&$form, $form_state, $pub_i
       '#default_value' => $prop->value,
       '#cols'          => 50,
       '#rows'          => $rows,
-      '#description'   => $description,
+      '#description'   => $prop->definition,
     );
     
     $form['properties'][$type_id][$rank]["remove-$type_id-$rank"] = array(

+ 21 - 23
tripal_pub/includes/pubmed.inc

@@ -241,8 +241,7 @@ function tripal_pub_PMID_parse_pubxml($pub_xml) {
       switch ($element) {
         case 'PMID':
           $xml->read(); // get the value for this element
-          $pub['Publication Accession'] = $xml->value;
-          $pub['Publication Database'] = 'PMID';
+          $pub['Publication Dbxref'] = 'PMID:' . $xml->value;
           break;        
         case 'Article':
           $pub_model = $xml->getAttribute('PubModel');
@@ -299,9 +298,8 @@ function tripal_pub_PMID_parse_pubxml($pub_xml) {
       }
     }
   }
-  $pub['Citation'] = $pub['Authors'] . 
-    '. <a href="http://www.ncbi.nlm.nih.gov/pubmed/' . $pub['Publication Accession'] . '" target="_blank">' . $pub['Title'] .  '</a> ' .
-    $pub['Journal ISO Abbreviation']. '. ' . $pub['Publication Date'];
+  $pub['Citation'] = $pub['Authors'] . '. ' . $pub['Title'] .  ' ' .
+    $pub['Journal ISO Abbreviation'] . '. ' . $pub['Publication Date'];
   if ($pub['Volume'] or $pub['Issue']) {
     $pub['Citation'] .= '; ';  
   }
@@ -314,7 +312,6 @@ function tripal_pub_PMID_parse_pubxml($pub_xml) {
   if ($pub['Pages']) {
     $pub['Citation'] .= ':' . $pub['Pages'];
   }
-  $pub['Citation'] .= '. PubMed PMID: ' . $pub['Publication Accession']; 
   
   //$pub['xml'] = $pub_xml;
   return $pub;
@@ -399,7 +396,7 @@ function tripal_pub_PMID_parse_article($xml, &$pub) {
         case 'Affiliation':
           // the affiliation tag at this level is meant solely for the first author
           $xml->read();
-          $pub['Authors'][0]['Affiliation'] = $xml->value;
+          $pub['Author List'][0]['Affiliation'] = $xml->value;
           break;
         case 'AuthorList':
           $complete = $xml->getAttribute('CompleteYN');
@@ -501,9 +498,10 @@ function tripal_pub_PMID_parse_abstract($xml, &$pub) {
         case 'AbstractText':
           $label = $xml->getAttribute('Label');
           $xml->read();
-          if ($label) {
-            $pub['Structured Abstract Part'][] = $xml->value;
-            $abstract .= "<p><b>$label</b></br>" . $xml->value . '</p>';
+          if ($label) { 
+            $part = "<p><b>$label</b></br>" . $xml->value . '</p>';           
+            $abstract .= $part;
+            $pub['Structured Abstract Part'][] = $part;
           }
           else {
             $abstract .= '<p>' . $xml->value . '</p>';
@@ -693,22 +691,22 @@ function tripal_pub_PMID_parse_authorlist($xml, &$pub) {
       // if we're at the </AuthorList> element then we're done with the article...
       if($element == 'AuthorList') {
         // build the author list before returning
-        $author_list = '';
-        foreach ($pub['Authors'] as $author) {
+        $authors = '';
+        foreach ($pub['Author List'] as $author) {
           if ($author['valid'] == 'N') {
             // skip non-valid entries.  A non-valid entry should have 
             // a corresponding corrected entry so we can saftely skip it.
             continue;
           }
           if ($author['Collective']) {
-            $author_list .= $author['Collective'] . ', ';
+            $authors .= $author['Collective'] . ', ';
           }
           else {
-            $author_list .= $author['Surname'] . ' ' . $author['First Initials'] . ', '; 
+            $authors .= $author['Surname'] . ' ' . $author['First Initials'] . ', '; 
           }             
         }
-        $author_list = substr($author_list, 0, -2);
-        $pub['Authors'] = $author_list;
+        $authors = substr($authors, 0, -2);
+        $pub['Authors'] = $authors;
         return;
       }
       // if we're at the end </Author> element then we're done with the author and we can
@@ -721,27 +719,27 @@ function tripal_pub_PMID_parse_authorlist($xml, &$pub) {
       switch ($element) {
         case 'Author':
           $valid = $xml->getAttribute('ValidYN');
-          $pub['Authors'][$num_authors]['valid'] = $valid;          
+          $pub['Author List'][$num_authors]['valid'] = $valid;          
           break;
         case 'LastName':  
           $xml->read(); 
-          $pub['Authors'][$num_authors]['Surname'] = $xml->value;         
+          $pub['Author List'][$num_authors]['Surname'] = $xml->value;         
           break;
         case 'ForeName': 
           $xml->read(); 
-          $pub['Authors'][$num_authors]['Given Name'] = $xml->value;          
+          $pub['Author List'][$num_authors]['Given Name'] = $xml->value;          
           break;
         case 'Initials': 
           $xml->read(); 
-          $pub['Authors'][$num_authors]['First Initials'] = $xml->value;          
+          $pub['Author List'][$num_authors]['First Initials'] = $xml->value;          
           break;
         case 'Suffix': 
           $xml->read(); 
-          $pub['Authors'][$num_authors]['Suffix'] = $xml->value;          
+          $pub['Author List'][$num_authors]['Suffix'] = $xml->value;          
           break;
         case 'CollectiveName': 
           $xml->read(); 
-          $pub['Authors'][$num_authors]['Collective'] = $xml->value;          
+          $pub['Author List'][$num_authors]['Collective'] = $xml->value;          
           break;
         case 'Identifier': 
           // according to the specification, this element is not yet used.                  
@@ -821,5 +819,5 @@ function tripal_pub_remote_search_get_language($lang_abbr) {
     'vie' => 'Vietnamese',
     'wel' => 'Welsh',
   );
-  return $languages[$lang_abbr];
+  return $languages[strtolower($lang_abbr)];
 }

+ 2 - 0
tripal_pub/tpub.obo

@@ -27,6 +27,7 @@ is_a: TPUB:0000015 ! Publication Type
 id: TPUB:0000005
 name: Publication Accession
 relationship: part_of TPUB:0000001 ! publication_dbxref
+is_obsolete: true
 
 [Term]
 id: TPUB:0000006
@@ -50,6 +51,7 @@ relationship: part_of TPUB:0000006 ! Collective
 id: TPUB:0000009
 name: Publication Database
 relationship: part_of TPUB:0000001 ! Publication Dbxref
+is_obsolete: true
 
 [Term]
 id: TPUB:0000010

+ 76 - 35
tripal_pub/tripal_pub.module

@@ -24,6 +24,10 @@ require_once "includes/agricola.inc";
 function tripal_pub_init() {
   drupal_add_js(drupal_get_path('theme', 'tripal') . '/js/tripal_pub.js');
   drupal_add_css(drupal_get_path('theme', 'tripal') . '/css/tripal_pub.css');
+  
+  // this variable indicates which databases are supported by the Tripal pub module
+  // for importing
+  variable_set('tripal_pub_supported_dbs', array('PMID'));
 }
 
 
@@ -270,6 +274,9 @@ function chado_pub_insert($node) {
     $pub['pub_id'] = $node->pub_id;
   }
   else {
+    $properties = array(); // stores all of the properties we need to add
+    $cross_refs = array(); // stores any cross references for this publication
+    
     // get the list of properties for easy lookup (without doing lots of database queries
     $properties_list = array();
     $sql = "
@@ -283,7 +290,6 @@ function chado_pub_insert($node) {
       ORDER BY CVTS.name ASC 
     ";
     $prop_types = chado_query($sql); 
-    $properties = array();
     while ($prop = db_fetch_object($prop_types)) {
       $properties_list[$prop->cvterm_id] = $prop->name;
       // The 'Citation' term is special because it serves
@@ -341,6 +347,11 @@ function chado_pub_insert($node) {
         $pubplace = $value;
         unset($properties[$name]);
       }
+      elseif ($name == "Publication Dbxref") {
+        // we will add the cross-references to the pub_dbxref table
+        // but we also want to keep the property in the pubprop table so don't unset it
+        $cross_refs[] = $value;
+      }
     }
     
     // insert the pub record
@@ -364,11 +375,12 @@ function chado_pub_insert($node) {
       drupal_set_message("Error inserting publication", "error");
       watchdog('tripal_pub', "Error inserting publication", array(), WATCHDOG_ERROR);
       return;
-    }
+    }       
     
     // now add in the properties 
     foreach ($properties as $property => $elements) {
-      foreach ($elements as $rank => $value) {      
+      foreach ($elements as $rank => $value) {   
+           
         $status = tripal_pub_insert_property($pub['pub_id'], $property, $value, FALSE);
         if (!$status) {
           drupal_set_message("Error cannot add property: $property", "error");
@@ -377,6 +389,16 @@ function chado_pub_insert($node) {
         }
       } 
     }
+    
+    // add in any database cross-references
+    foreach ($cross_refs as $index => $ref) {
+      $pub_dbxref = tripal_pub_add_pub_dbxref($pub_id, $ref);
+      if (!$pub_dbxref) { 
+        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);
+      }   
+    }          
   } // if ($node->pub_id) {} else 
 
   if ($pub) {   
@@ -418,6 +440,8 @@ function chado_pub_update($node) {
   
   // get the publication ID for this publication
   $pub_id = chado_get_id_for_node('pub', $node) ;
+  $properties = array(); // stores all of the properties we need to add
+  $cross_refs = array(); // stores any cross references for this publication  
    
   // get the list of properties for easy lookup (without doing lots of database queries
   $properties_list = array();
@@ -431,8 +455,7 @@ function chado_pub_update($node) {
       NOT CVTS.is_obsolete = 1    
     ORDER BY CVTS.name ASC 
   ";
-  $prop_types = chado_query($sql); 
-  $properties = array();
+  $prop_types = chado_query($sql);   
   while ($prop = db_fetch_object($prop_types)) {
     $properties_list[$prop->cvterm_id] = $prop->name;
     // The 'Citation' term is special because it serves
@@ -447,14 +470,15 @@ function chado_pub_update($node) {
   //  1) prop_value-[type id]-[index]
   //  2) new_value-[type id]-[index]
   //  3) new_id, new_value  
-  foreach ($node as $name => $value) {
-    if (preg_match('/^prop_value-(\d+)-(\d+)/', $name, $matches)) {
+//  dpm($node);
+  foreach ($node as $key => $value) {
+    if (preg_match('/^prop_value-(\d+)-(\d+)/', $key, $matches)) {
       $type_id = $matches[1];
       $index = $matches[2];  
       $name = $properties_list[$type_id];  
       $properties[$name][$index] = $value;     
     }
-    if (preg_match('/^new_value-(\d+)-(\d+)/', $name, $matches)) {
+    if (preg_match('/^new_value-(\d+)-(\d+)/', $key, $matches)) {
       $type_id = $matches[1];
       $index = $matches[2];
       $name = $properties_list[$type_id];
@@ -462,40 +486,46 @@ function chado_pub_update($node) {
     }      
   }
   if ($node->new_id and $node->new_value) {
-    $type_id = $node->new_id;
-    $index = count($properties[$name]);
+    $type_id = $node->new_id;    
     $name = $properties_list[$type_id];
+    $index = count($properties[$name]);
     $properties[$name][$index] = $node->new_value;    
   } 
   
   // iterate through all of the properties and remove those that really are
   // part of the pub table fields
   foreach ($properties as $name => $element) {
-    $value = $element[0];
-    if ($name == "Volume") {
-      $volume = $value;
-      unset($properties[$name]);
-    } 
-    elseif ($name == "Volume Title") {
-      $volumetitle = $value;
-      unset($properties[$name]);
-    }
-    elseif ($name == "Issue") {
-      $issue = $value;
-      unset($properties[$name]);
-    }
-    elseif ($name == "Pages") {
-      $pages = $value;
-      unset($properties[$name]);
-    }
-    elseif ($name == "Publisher") {
-      $publisher = $value;
-      unset($properties[$name]);
-    }
-    elseif ($name == "Journal Country" or $name == "Published Location") {
-      $pubplace = $value;
-      unset($properties[$name]);
-    }
+    foreach ($element as $index => $value) {
+      if ($name == "Volume") {
+        $volume = $value;
+        unset($properties[$name]);
+      } 
+      elseif ($name == "Volume Title") {
+        $volumetitle = $value;
+        unset($properties[$name]);
+      }
+      elseif ($name == "Issue") {
+        $issue = $value;
+        unset($properties[$name]);
+      }
+      elseif ($name == "Pages") {
+        $pages = $value;
+        unset($properties[$name]);
+      }
+      elseif ($name == "Publisher") {
+        $publisher = $value;
+        unset($properties[$name]);
+      }
+      elseif ($name == "Journal Country" or $name == "Published Location") {
+        $pubplace = $value;
+        unset($properties[$name]);
+      }
+      elseif ($name == "Publication Dbxref") {
+        // we will add the cross-references to the pub_dbxref table
+        // but we also want to keep the property in the pubprop table so don't unset it
+        $cross_refs[] = $value;
+      } 
+    }   
   }
   
   // update the pub record
@@ -537,6 +567,17 @@ function chado_pub_update($node) {
       }
     } 
   }
+  
+  // add in any database cross-references after first removing 
+  tripal_core_chado_delete('pub_dbxref', array('pub_id' => $pub_id));
+  foreach ($cross_refs as $index => $ref) {
+    $pub_dbxref = tripal_pub_add_pub_dbxref($pub_id, $ref);
+    if (!$pub_dbxref) { 
+      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);
+    }   
+  }   
 }