Prechádzať zdrojové kódy

Publication importer for PMID is now working. Added missing synonym.inc field file. Started new pub field

Stephen Ficklin 9 rokov pred
rodič
commit
05dd7daf1e

+ 13 - 1
legacy/tripal_core/tripal_core.drush.inc

@@ -72,7 +72,7 @@ function tripal_core_drush_command() {
       'table' => dt('The name of the materialized view table to update.'),
     ),
   );
- 
+
   $items['trp-get-cversion'] = array(
     'description' => dt('Returns the current installed version of Chado.'),
     'arguments' => array(),
@@ -466,3 +466,15 @@ function drush_tripal_core_trp_clean_nodes() {
 function drush_tripal_core_tripal_node_clean($module) {
   chado_cleanup_orphaned_nodes($module, 0);
 }
+
+
+/**
+ * Clean-up orphaned Drupal nodes and chado records.
+ *
+ * @ingroup tripal_drush
+ */
+function drush_tripal_chado_trp_clean_nodes() {
+  $table = drush_get_option('table');
+
+  chado_cleanup_orphaned_nodes($table, 0);
+}

+ 0 - 440
legacy/tripal_pub/includes/tripal_pub.pub_citation.inc

@@ -1,440 +0,0 @@
-<?php
-/**
- * @file
- * Functions to manage citations
- */
-
-/**
- * The admin form for submitting job to create citations
- *
- * @param $form_state
- *
- * @ingroup tripal_pub
- */
-function tripal_pub_citation_form($form, &$form_state) {
-
-  $form['instructions'] = array(
-    '#markup' => '<p>Use this form to unify publication citations. Citations are created automtically when
-      importing publications but citations are set by the user when publications are added manually.
-      Or publications added to the Chado database by tools other than the Tripal Publication Importer may
-      not have citations set. If you are certain that all necessary information for all publications is present (e.g.
-      authors, volume, issue, page numbers, etc.) but citations are not consistent, then you can
-      choose to update all citations for all publications using the form below. Alternatively, you
-      can update citations only for publication that do not already have one.</p>'
-  );
-
-  $form['options'] = array(
-    '#type' => 'radios',
-    '#options' => array(
-      'all' => 'Create citation for all publications. Replace the existing citation if it exists.',
-      'new' => 'Create citation for publication only if it does not already have one.'),
-    '#default_value' => 'all'
-  );
-
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Submit')
-  );
-
-  return $form;
-}
-
-/**
- * Submit form. Create Tripal job for citations
- *
- * @param $form_state
- *
- * @ingroup tripal_pub
- */
-function tripal_pub_citation_form_submit(&$form_state) {
-  $options [0] = $form_state['options']['#value'];
-  tripal_add_job("Create citations ($options[0])", 'tripal_pub', 'tripal_pub_create_citations', $options, $user->uid);
-}
-
-/**
- * Launch the Tripal job to generate citations. Called by tripal jobs
- *
- * @param $options
- *  Options pertaining to what publications to generate citations for.
- *  One of the following must be present:
- *   - all: Create and replace citation for all pubs
- *   - new: Create citation for pubs that don't already have one
- *
- * @ingroup tripal_pub
- */
-function tripal_pub_create_citations($options) {
-  $skip_existing = TRUE;
-  $sql = "
-    SELECT cvterm_id
-    FROM {cvterm}
-    WHERE
-      name = 'Citation' AND
-      cv_id = (SELECT cv_id FROM {cv} WHERE name = 'tripal_pub')
-  ";
-  $citation_type_id = chado_query($sql)->fetchField();
-
-  // Create and replace citation for all pubs
-  if ($options == 'all') {
-    $sql = "SELECT pub_id FROM {pub} P WHERE pub_id <> 1";
-    $skip_existing = FALSE;
-  }
-  // Create citation for pubs that don't already have one
-  else if ($options == 'new') {
-    $sql = "
-      SELECT pub_id
-      FROM {pub} P
-      WHERE
-        (SELECT value
-         FROM {pubprop} PB
-         WHERE type_id = :type_id AND P.pub_id = PB.pub_id AND rank = 0) IS NULL
-        AND  pub_id <> 1
-    ";
-    $skip_existing = TRUE;
-  }
-
-  $result = chado_query($sql, array(':type_id' => $citation_type_id));
-  $counter_updated = 0;
-  $counter_generated = 0;
-  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);
-      print $citation . "\n\n";
-      // Replace if citation exists. This condition is never TRUE if $skip_existing is TRUE
-      if ($pub_arr['Citation']) {
-        $sql = "
-          UPDATE {pubprop} SET value = :value
-          WHERE pub_id = :pub_id  AND type_id = :type_id AND rank = :rank
-        ";
-        chado_query($sql, array(':value' => $citation, ':pub_id' => $pub->pub_id,
-          ':type_id' => $citation_type_id, ':rank' => 0));
-        $counter_updated ++;
-      // Generate a new citation
-      } else {
-        $sql = "
-          INSERT INTO {pubprop} (pub_id, type_id, value, rank)
-          VALUES (:pub_id, :type_id, :value, :rank)
-        ";
-        chado_query($sql, array(':pub_id' => $pub->pub_id, ':type_id' => $citation_type_id,
-          ':value' => $citation, ':rank' => 0));
-        $counter_generated ++;
-      }
-    }
-  }
-  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
- */
-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 we don't have a recognized publication type, then just use the
-    // first one in the list.
-    if (!$pub_type) {
-      $pub_type = $pub['Publication Type'][0];
-    }
-  }
-  else {
-    $pub_type = $pub['Publication Type'];
-  }
-  //----------------------
-  // Journal Article
-  //----------------------
-  if ($pub_type == 'Journal Article') {
-    if (array_key_exists('Authors', $pub)) {
-      $citation = $pub['Authors'] . '. ';
-    }
-
-    $citation .= $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') {
-    if (array_key_exists('Authors', $pub)) {
-      $citation = $pub['Authors'] . '. ';
-    }
-
-    $citation .= $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") {
-    if (array_key_exists('Authors', $pub)) {
-      $citation = $pub['Authors'] . '. ';
-    }
-
-    $citation .= $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') {
-    if (array_key_exists('Authors', $pub)) {
-      $citation = $pub['Authors'] . '. ';
-    }
-
-    $citation .= $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 .= '.';
-  }
-  //-----------------------
-  // Conference Proceedings
-  //-----------------------
-  elseif ($pub_type == 'Conference Proceedings') {
-    if (array_key_exists('Authors', $pub)) {
-      $citation = $pub['Authors'] . '. ';
-    }
-
-    $citation .= $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 .= '.';
-  }
-  //-----------------------
-  // Default
-  //-----------------------
-  else {
-    if (array_key_exists('Authors', $pub)) {
-      $citation = $pub['Authors'] . '. ';
-    }
-    $citation .= $pub['Title'] .  '. ';
-    if (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;
-}

+ 1 - 68
legacy/tripal_pub/tripal_pub.drush.inc

@@ -32,37 +32,7 @@ function tripal_pub_drush_help($command) {
 function tripal_pub_drush_command() {
   $items = array();
 
-  $items['trp-import-pubs'] = array(
-    'description' => dt('Imports publications from remote databases using saved configuration settings.'),
-    'options' => array(
-      'create_contacts' => dt('provide this option to create or update contacts for authors. By default contacts are not created or updated.'),
-      'dbxref' => dt('An accession number for a publication from a remote database (e.g. PMID:23582642).'),
-      'report' => dt("Set to the email address of the recipient who should receive an HTML report of the publications that have been added."),
-      'update' => dt("Set to 'Y' to update existing pubs.  By default only new pubs are inserted."),
-      'username' => array(
-        'description' => dt('The Drupal user name for which the job should be run.  The permissions for this user will be used.'),
-      ),
-    ),
-    'examples' => array(
-      'Standard example' => 'drush tripal-pubs-import',
-      'Standard example' => 'drush -l http://[site url] tripal-pubs-import --report=[email]. Where [site url] is the URL of the website and [email] is the email address of the recipient to receive the HTML report',
-      'Import single publication' => 'drush tripal-pub-import --dbxref=PMID:23582642',
-    ),
-  );
-  $items['trp-update-pubs'] = array(
-    'description' => dt('Updates publication information for publications with a supported database cross-reference.'),
-    'options' => array(
-      'create_contacts' => dt('provide this option to create or update contacts for authors. By default contacts are not created or updated.'),
-      'dbxref' => dt('An accession number for a publication from a remote database (e.g. PMID:23582642)'),
-      'db' => dt('The database name (e.g. PMID or AGL)'),
-    ),
-    'examples' => array(
-      'Standard example' => 'drush tripal-pubs-update',
-      'Create contacts during update' => 'drush tripal-pubs-update --create_contacts=1',
-      'Update a single record' => 'drush tripal-pubs-update --dbxref=PMID:23582642',
-      'Update all records for a single database' => 'drush tripal-pubs-update --db=PMID'
-    ),
-  );
+
 
   // Deprecated commands
   $items['tripal-pubs-import'] = array(
@@ -99,33 +69,7 @@ function tripal_pub_drush_command() {
   return $items;
 }
 
-/**
- * Imports publications into Chado
- *
- * @ingroup tripal_drush
- */
-function drush_tripal_pub_trp_import_pubs() {
-  $create_contacts = drush_get_option('create_contacts');
-  $dbxref = drush_get_option('dbxref');
-  $do_report = drush_get_option('report');
-  $update = drush_get_option('update');
-  $uname = drush_get_option('username');
-  drush_tripal_core_set_user($uname);
-
-  if($update == 'Y') {
-    $update = TRUE;
-  }
-  else {
-    $update = FALSE;
-  }
 
-  if ($dbxref) {
-    tripal_import_pub_by_dbxref($dbxref, $create_contacts, $update);
-  }
-  else {
-    tripal_execute_active_pub_importers($do_report, $update);
-  }
-}
 /**
  * DEPRECATED. Imports publications into Chado
  *
@@ -138,18 +82,7 @@ function drush_tripal_pub_tripal_pubs_import() {
   drush_tripal_pub_trp_import_pubs();
 }
 
-/**
- * Imports publications into Chado
- *
- * @ingroup tripal_drush
- */
-function drush_tripal_pub_trp_update_pubs() {
-  $create_contacts = drush_get_option('create_contacts');
-  $dbxref = drush_get_option('dbxref');
-  $db = drush_get_option('db');
 
-  tripal_reimport_publications($create_contacts, $dbxref, $db);
-}
 
 /**
  * DEPRECATED. Imports publications into Chado

+ 0 - 19
legacy/tripal_pub/tripal_pub.install

@@ -82,26 +82,7 @@ function tripal_pub_uninstall() {
  * @ingroup tripal_pub
  */
 function tripal_pub_enable() {
-  // make sure we have our supported databases
-  tripal_insert_db(
-    array(
-      'name' => 'PMID',
-      'description' => 'PubMed',
-      'url' => 'http://www.ncbi.nlm.nih.gov/pubmed',
-      'urlprefix' => 'http://www.ncbi.nlm.nih.gov/pubmed/'
-    ),
-    array('update_existing' => TRUE)
-  );
-  tripal_insert_db(
-    array(
-      'name' => 'AGL',
-      'description' => 'USDA National Agricultural Library',
-      'url' => 'http://agricola.nal.usda.gov/'
-    ),
-    array('update_existing' => TRUE)
-  );
 
-  variable_set('tripal_pub_supported_dbs', array('PMID', 'AGL'));
 }
 
 /**

+ 1 - 76
legacy/tripal_pub/tripal_pub.module

@@ -11,11 +11,8 @@ require_once 'theme/tripal_pub.theme.inc';
 
 require_once 'includes/tripal_pub.admin.inc';
 require_once 'includes/tripal_pub.chado_node.inc';
-require_once 'includes/tripal_pub.pub_importers.inc';
 require_once 'includes/tripal_pub.pub_search.inc';
 require_once 'includes/tripal_pub.pub_citation.inc';
-require_once 'includes/importers/tripal_pub.PMID.inc';
-require_once 'includes/importers/tripal_pub.AGL.inc';
 
 /**
  * @defgroup tripal_pub Publication Module
@@ -133,73 +130,7 @@ function tripal_pub_menu() {
     'weight' => 1
   );
 
-  $items['admin/tripal/chado/tripal_pub/import_list'] = array(
-    '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,
-    'weight' => 0
-  );
-
-  // add a second link for the importer on the data loaders page
-  $items['admin/tripal/loaders/pub_import'] = array(
-    '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_NORMAL_ITEM,
-  );
 
-  $items['admin/tripal/chado/tripal_pub/import/new'] = array(
-    'title' => t('Add an Importer'),
-    'description' => t('Add a new publication importer.'),
-    'page callback' => 'tripal_pub_importer_setup_page',
-    'access arguments' => array('administer tripal pub'),
-    'type ' => MENU_CALLBACK,
-  );
-
-  $items['admin/tripal/chado/tripal_pub/import/raw/%'] = array(
-    'title' => t('Raw Data From Publication Import'),
-    'page callback' => 'tripal_get_remote_pub_raw_page',
-    'page arguments' => array(6),
-    'access arguments' => array('administer tripal pub'),
-    'type ' => MENU_CALLBACK,
-  );
-
-  $items['admin/tripal/chado/tripal_pub/import/edit/%'] = array(
-    'page callback' => 'tripal_pub_importer_setup_page',
-    'page arguments' => array(5, 6),
-    'access arguments' => array('administer tripal pub'),
-    'type ' => MENU_CALLBACK,
-  );
-
-  $items['admin/tripal/chado/tripal_pub/import/submit/%'] = array(
-    'page callback' => 'tripal_pub_importer_submit_job',
-    'page arguments' => array(6),
-    'access arguments' => array('administer tripal pub'),
-    'type ' => MENU_CALLBACK,
-  );
-
-  $items['admin/tripal/chado/tripal_pub/import/delete/%'] = array(
-    'page callback' => 'tripal_pub_importer_delete',
-    'page arguments' => array(5),
-    'access arguments' => array('administer tripal pub'),
-    'type ' => MENU_CALLBACK,
-  );
-  $items['admin/tripal/chado/tripal_pub/import/changedb'] = array(
-    'page callback' => 'tripal_pub_importer_setup_page_update_remotedb',
-    'page arguments' => array(),
-    'access arguments' => array('administer tripal pub'),
-    'type ' => MENU_CALLBACK,
-  );
-
-  $items['admin/tripal/chado/tripal_pub/import/criteria/%/%'] = array(
-    'page callback' => 'tripal_pub_importer_setup_page_update_criteria',
-    'page arguments' => array(5, 6),
-    'access arguments' => array('administer tripal pub'),
-    'type ' => MENU_CALLBACK,
-  );
 
   return $items;
 }
@@ -282,13 +213,7 @@ function tripal_pub_theme($existing, $type, $theme, $path) {
       'path' => "$path/theme/templates",
     ),
 
-    // themed forms
-    'tripal_pub_importer_setup_form_elements' => array(
-      'render element' => 'form',
-    ),
-    'tripal_pub_search_setup_form_elements' => array(
-      'render element' => 'form',
-    ),
+
 
     // teaser
     'tripal_pub_teaser' => array(

+ 10 - 4
tripal/api/tripal.jobs.api.inc

@@ -56,14 +56,19 @@
  *    The job_id of the registered job
  *
  * Example usage:
+ *
  * @code
- * $args = array($dfile, $organism_id, $type, $library_id, $re_name, $re_uname,
+ *   $args = array($dfile, $organism_id, $type, $library_id, $re_name, $re_uname,
  *         $re_accession, $db_id, $rel_type, $re_subject, $parent_type, $method,
  *         $user->uid, $analysis_id, $match_type);
- * $includes = module_load_include('inc', 'tripal_chado', 'includes/loaders/tripal_chado.fasta_loader');
- * tripal_add_job("Import FASTA file: $dfile", 'tripal_feature',
- *   'tripal_feature_load_fasta', $args, $user->uid, 10, $includes);
+ *
+ *   $includes = array()
+ *   $includes[] = module_load_include('inc', 'tripal_chado', 'includes/loaders/tripal_chado.fasta_loader');
+ *
+ *   tripal_add_job("Import FASTA file: $dfile", 'tripal_feature',
+ *     'tripal_feature_load_fasta', $args, $user->uid, 10, $includes);
  * @endcode
+ *
  * The code above is copied from the tripal_feature/fasta_loader.php file. The
  * snipped first builds an array of arguments that will then be passed to the
  * tripal_add_job function.  The number of arguments provided in the $arguments
@@ -324,6 +329,7 @@ function tripal_launch_job($do_parallel = 0, $job_id = NULL) {
     $job_res = db_query($sql);
   }
   foreach ($job_res as $job) {
+
     // Include the necessary files
     foreach (unserialize($job->includes) as $path) {
       require_once $path;

+ 2 - 1
tripal/includes/TripalEntityUIController.inc

@@ -42,10 +42,11 @@ class TripalEntityUIController extends EntityDefaultUIController {
         // Get the term for this bundle
         $term = entity_load('TripalTerm', array('id' => $matches[1]));
         $term = reset($term);
+        $default_description = $term->definition ? $term->definition : '';
         // Set a custom page for adding new tripal data entities.
         $items['bio-data/add/' . $term->id] = array(
           'title' => ucfirst($bundle->label),
-          'description' => tripal_get_bundle_variable('description', $bundle->id, $term->definition),
+          'description' => tripal_get_bundle_variable('description', $bundle->id, $default_description),
           'page callback'  => 'drupal_get_form',
           'page arguments' => array('tripal_entity_form', 2),
           'access callback'  => 'tripal_entity_access',

+ 329 - 0
tripal_chado/api/modules/tripal_chado.pub.api.inc

@@ -276,3 +276,332 @@ function tripal_publication_exists($pub_details) {
 
   return $return;
 }
+
+
+/**
+ * Used for autocomplete in forms for identifying for publications.
+ *
+ * @param $field
+ *   The field in the publication to search on.
+ * @param $string
+ *   The string to search for
+ *
+ * @return
+ *   A json array of terms that begin with the provided string
+ *
+ * @ingroup tripal_chado_api
+ */
+function tripal_autocomplete_pub($field, $string = '') {
+  $items = array();
+
+  $sql = "
+    SELECT uniquename, title
+    FROM {pub}
+    WHERE :field like :str
+    ORDER by title
+    LIMIT 25 OFFSET 0
+  ";
+  $pubs = chado_query($sql, array(':field' => $field, ':str' => $string . '%'));
+  foreach ($pubs as $pub) {
+    $items[$pub->uniquename] = $pub->$field;
+  }
+
+  drupal_json_output($items);
+}
+
+
+/**
+ * Imports a singe publication specified by a remote database cross reference.
+ *
+ * @param $pub_dbxref
+ *   The unique database ID for the record to update.  This value must
+ *   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.
+ * @param $do_contact
+ *   Set to TRUE if authors should automatically have a contact record added
+ *   to Chado.
+ * @param $do_update
+ *   If set to TRUE then the publication will be updated if it already exists
+ *   in the database.
+ *
+ * @ingroup tripal_pub
+ */
+function tripal_import_pub_by_dbxref($pub_dbxref, $do_contact = FALSE, $do_update) {
+  $num_to_retrieve = 1;
+  $pager_id = 0;
+  $page = 0;
+  $num_pubs = 0;
+
+  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";
+
+  $transaction = db_transaction();
+  try {
+    if(preg_match('/^(.*?):(.*?)$/', $pub_dbxref, $matches)) {
+      $dbname = $matches[1];
+      $accession = $matches[2];
+
+      $criteria = array(
+        'num_criteria' => 1,
+        'remote_db' => $dbname,
+        'criteria' => array(
+          '1' => array(
+            'search_terms' => "$dbname:$accession",
+            'scope' => 'id',
+            'operation' => '',
+            'is_phrase' => 0,
+          ),
+        ),
+      );
+      $remote_db = $criteria['remote_db'];
+      $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'];
+      $pub_id = tripal_pub_add_publications($pubs, $do_contact, $do_update);
+    }
+
+    // For backwards compatibility check to see if the legacy pub module
+    // is enabled. If so, then sync the nodes.
+    if (module_exists('tripal_pub')) {
+
+      // sync the newly added publications with Drupal
+      print "Syncing publications with Drupal...\n";
+      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";
+        chado_node_sync_records('contact');
+      }
+    }
+  }
+  catch (Exception $e) {
+    $transaction->rollback();
+    print "\n"; // make sure we start errors on new line
+    watchdog_exception('T_pub_import', $e);
+    print "FAILED: Rolling back database changes...\n";
+    return;
+  }
+
+  print "Done.\n";
+}
+
+/**
+ * Imports all publications for all active import setups.
+ *
+ * @param $report_email
+ *   A list of email address, separated by commas, that should be notified
+ *   once importing has completed
+ * @param $do_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
+ *
+ * @ingroup tripal_pub
+ */
+function tripal_execute_active_pub_importers($report_email = FALSE, $do_update = FALSE) {
+  $num_to_retrieve = 100;
+  $page = 0;
+
+  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";
+
+  // start the transaction
+  $transaction = db_transaction();
+
+  try {
+    // get all of the loaders
+    $args = array();
+    $sql = "SELECT * FROM {tripal_pub_import} WHERE disabled = 0 ";
+    $results = db_query($sql, $args);
+    $do_contact = FALSE;
+    $reports = array();
+    foreach ($results as $import) {
+      $page = 0;
+      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;
+      }
+      $criteria = unserialize($import->criteria);
+      $remote_db = $criteria['remote_db'];
+      do {
+        // retrieve the pubs for this page. We'll retreive 100 at a time
+        $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++;
+      }
+      // continue looping until we have a $pubs array that does not have
+      // our requested numer of records.  This means we've hit the end
+      while (count($pubs) == $num_to_retrieve);
+    }
+
+    // sync the newly added publications with Drupal. If the user
+    // requested a report then we don't want to print any syncing information
+    // so pass 'FALSE' to the sync call
+    // For backwards compatibility check to see if the legacy pub module
+    // is enabled. If so, then sync the nodes.
+    if (module_exists('tripal_pub')) {
+      print "Syncing publications with Drupal...\n";
+      chado_node_sync_records('pub');
+    }
+
+    // iterate through each of the reports and generate a final report with HTML links
+    $HTML_report = '';
+    if ($report_email) {
+      $HTML_report .= "<html>";
+      global $base_url;
+      foreach ($reports as $importer => $report) {
+        $total = count($report['inserted']);
+        $HTML_report .= "<b>$total new publications from importer: $importer</b><br><ol>\n";
+        foreach ($report['inserted'] as $pub) {
+          $item = $pub['Title'];
+          if (array_key_exists('pub_id', $pub)) {
+            $item = l($pub['Title'], "$base_url/pub/" . $pub['pub_id']);
+          }
+          $HTML_report .= "<li>$item</li>\n";
+        }
+        $HTML_report .= "</ol>\n";
+      }
+      $HTML_report .= "</html>";
+      $site_email = variable_get('site_mail', '');
+      $params = array(
+        'message' => $HTML_report
+      );
+      drupal_mail('tripal_pub', 'import_report', $report_email, language_default(), $params, $site_email, TRUE);
+    }
+
+    // For backwards compatibility check to see if the legacy pub module
+    // is enabled. If so, then sync the nodes.
+    if (module_exists('tripal_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";
+        chado_node_sync_records('contact');
+      }
+    }
+  }
+  catch (Exception $e) {
+    $transaction->rollback();
+    print "\n"; // make sure we start errors on new line
+    watchdog_exception('T_pub_import', $e);
+    print "FAILED: Rolling back database changes...\n";
+    return;
+  }
+  print "Done.\n";
+}
+
+/**
+ * Updates publication records.
+ *
+ * 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
+ *   to Chado. Contacts are added using the name provided by the remote
+ *   database.
+ * @param $dbxref
+ *   The unique database ID for the record to update.  This value must
+ *   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.
+ * @param $db
+ *   The name of the remote database to update.  If this value is provided and
+ *   no dbxref then all of the publications currently in the Chado database
+ *   for this remote database will be updated.
+ *
+ * @ingroup tripal_pub
+ */
+function tripal_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" .
+      "insertions/updates is rolled back and will not be found in the database\n\n";
+  $transaction = db_transaction();
+  try {
+
+    // get a list of all publications by their Dbxrefs that have supported databases
+    $sql = "
+      SELECT DB.name as db_name, DBX.accession
+      FROM pub P
+        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
+    ";
+    $args = array();
+    if ($dbxref and preg_match('/^(.*?):(.*?)$/', $dbxref, $matches)) {
+      $dbname = $matches[1];
+      $accession = $matches[2];
+      $sql .= "WHERE DBX.accession = :accession and DB.name = :dbname ";
+      $args[':accession'] = $accession;
+      $args[':dbname'] = $dbname;
+    }
+    elseif ($db) {
+      $sql .= " WHERE DB.name = :dbname ";
+      $args[':dbname'] = $db;
+    }
+    $sql .= "ORDER BY DB.name, P.pub_id";
+    $results = chado_query($sql, $args);
+
+    $num_to_retrieve = 100;
+    $i = 0;                 // count the number of IDs. When we hit $num_to_retrieve we'll do the query
+    $curr_db = '';          // keeps track of the current current database
+    $ids = array();         // the list of IDs for the database
+    $search = array();      // the search array passed to the search function
+
+    // iterate through the pub IDs
+    while ($pub = $results->fetchObject()) {
+      $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;
+      }
+      $search = array(
+        'num_criteria' => 1,
+        'remote_db' => $remote_db,
+        'criteria' => array(
+          '1' => array(
+            'search_terms' => "$remote_db:$accession",
+            'scope' => 'id',
+            'operation' => '',
+            'is_phrase' => 0,
+          ),
+        ),
+      );
+      $pubs = tripal_get_remote_pubs($remote_db, $search, 1, 0);
+      tripal_pub_add_publications($pubs, $do_contact, TRUE);
+
+      $i++;
+    }
+
+    // For backwards compatibility check to see if the legacy pub module
+    // is enabled. If so, then sync the nodes.
+    if (module_exists('tripal_pub')) {
+      // sync the newly added publications with Drupal
+      print "Syncing publications with Drupal...\n";
+      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";
+        chado_node_sync_records('contact');
+      }
+    }
+  }
+  catch (Exception $e) {
+    $transaction->rollback();
+    print "\n"; // make sure we start errors on new line
+    watchdog_exception('T_pub_import', $e);
+    print "FAILED: Rolling back database changes...\n";
+    return;
+  }
+  print "Done.\n";
+}

+ 266 - 0
tripal_chado/includes/fields/pub.inc

@@ -0,0 +1,266 @@
+<?php
+
+/**
+ *
+ * @param unknown $entity_type
+ * @param unknown $entity
+ * @param unknown $field
+ * @param unknown $instance
+ * @param unknown $langcode
+ * @param unknown $items
+ * @param unknown $display
+ */
+function tripal_chado_pub_formatter(&$element, $entity_type, $entity, $field,
+    $instance, $langcode, $items, $display) {
+
+  $chado_table = $field['settings']['chado_table'];
+  foreach ($items as $delta => $item) {
+    if ($chado_table . '__pub_id') {
+      $pub = chado_generate_var('pub', array('pub_id' => $item[$chado_table . '__pub_id']));
+      $name = $pub->name;
+      if ($pub->type_id->name != 'exact') {
+        $name .= ' (<i>' . $pub->type_id->name . '</i>)';
+      }
+      $element[$delta] = array(
+        '#type' => 'markup',
+        '#markup' => $name,
+      );
+    }
+  }
+}
+/**
+ *
+ * @param unknown $field_name
+ * @param unknown $widget
+ * @param unknown $form
+ * @param unknown $form_state
+ * @param unknown $field
+ * @param unknown $instance
+ * @param unknown $langcode
+ * @param unknown $items
+ * @param unknown $delta
+ * @param unknown $element
+ */
+function tripal_chado_pub_widget(&$widget, $form, $form_state, $field,
+    $instance, $langcode, $items, $delta, $element) {
+
+  $entity = $form['#entity'];
+  $field_name = $field['field_name'];
+
+  // Get the FK column that links to the base table.
+  $table_name = $field['settings']['chado_table'];
+  $base_table = $field['settings']['base_table'];
+  $schema = chado_get_schema($table_name);
+  $pkey = $schema['primary key'][0];
+  $fkey = array_values($schema['foreign keys'][$base_table]['columns'])[0];
+
+  // Get the field defaults.
+  $record_id = '';
+  $fkey_value = $element['#entity']->chado_record_id;
+  $pub_id = '';
+  $title = '';
+
+  // If the field already has a value then it will come through the $items
+  // array.  This happens when editing an existing record.
+  if (array_key_exists($delta, $items)) {
+    $record_id = $items[$delta]['value'];
+    $fkey_value = $items[$delta][$table_name . '__' . $fkey];
+    $pub_id = $items[$delta][$table_name . '__pub_id'];
+    $title = $items[$delta][$table_name . '__title'];
+  }
+
+  // Check $form_state['values'] to see if an AJAX call set the values.
+  if (array_key_exists('values', $form_state) and array_key_exists($delta, $form_state['values'])) {
+    $record_id = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name);
+    $fkey_value = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__' . $fkey);
+    $pub_id = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__pub_id');
+    $title = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__title');
+  }
+
+  $schema = chado_get_schema('pub');
+
+  $widget['#table_name'] = $table_name;
+  $widget['#fkey_field'] = $fkey;
+  $widget['#element_validate'] = array('tripal_chado_pub_widget_validate');
+  $widget['#theme'] = 'tripal_chado_pub_widget';
+  $widget['#prefix'] =  "<span id='$table_name-$delta'>";
+  $widget['#suffix'] =  "</span>";
+
+  $widget['value'] = array(
+    '#type' => 'value',
+    '#default_value' => $record_id,
+  );
+  $widget[$table_name . '__' . $fkey] = array(
+    '#type' => 'value',
+    '#default_value' => $fkey_value,
+  );
+  $widget[$table_name . '__pub_id'] = array(
+    '#type' => 'value',
+    '#default_value' => $pub_id,
+  );
+
+  $widget[$table_name . '__title'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Publication Title'),
+    '#default_value' => $title,
+    '#autocomplete_path' => 'admin/tripal/storage/chado/auto_name/pub/title',
+    '#ajax' => array(
+      'callback' => "tripal_chado_pub_widget_form_ajax_callback",
+      'wrapper' => "$table_name-$delta",
+      'effect' => 'fade',
+      'method' => 'replace'
+    ),
+  );
+}
+/**
+ * An Ajax callback for the pub widget.
+ */
+function tripal_chado_pub_widget_form_ajax_callback($form, $form_state) {
+
+  $field_name = $form_state['triggering_element']['#parents'][0];
+  $delta = $form_state['triggering_element']['#parents'][2];
+
+  return $form[$field_name]['und'][$delta];
+}
+
+/**
+ * Callback function for validating the tripal_chado_organism_select_widget.
+ */
+function tripal_chado_pub_widget_validate($element, &$form_state) {
+
+  $field_name = $element['#field_name'];
+  $delta = $element['#delta'];
+  $table_name = $element['#table_name'];
+  $fkey = $element['#fkey_field'];
+
+  // If the form ID is field_ui_field_edit_form, then the user is editing the
+  // field's values in the manage fields form of Drupal.  We don't want
+  // to validate it as if it were being used in a data entry form.
+  if ($form_state['build_info']['form_id'] =='field_ui_field_edit_form') {
+    return;
+  }
+
+  // Get the field values.
+  $fkey_value = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__' . $fkey);
+  $pub_id = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__pub_id');
+
+  // Make sure that if a pub is provided that a type is also
+  // provided.
+  if (!$title) {
+    form_set_error(implode('][', $element ['#parents']) . '][' . $table_name . '__title', t("Please set a pub type."));
+  }
+  // If the user provided a title then we want to set the
+  // foreign key value to be the chado_record_idd
+  if ($title) {
+
+    // Get the pub. If one with the same name and type is already present
+    // then use that. Otherwise, insert a new one.
+    if (!$pub_id) {
+      $pub = chado_generate_var('pub', array('name' => $syn_name, 'type_id' => $syn_type));
+      if (!$pub) {
+        $pub = chado_insert_record('pub', array(
+          'name' => $syn_name,
+          'type_id' => $syn_type,
+          'pub_sgml' => '',
+        ));
+        $pub = (object) $pub;
+      }
+
+      // Set the pub_id and FK value
+      tripal_chado_set_field_form_values($field_name, $form_state, $pub->pub_id, $delta, $table_name . '__pub_id');
+      $fkey_value = $element['#entity']->chado_record_id;
+      tripal_chado_set_field_form_values($field_name, $form_state, $fkey_value, $delta, $table_name . '__' . $fkey);
+    }
+
+    if (!$pub_id) {
+      $pub = chado_generate_var('pub', array('uniquename' => 'null'));
+      tripal_chado_set_field_form_values($field_name, $form_state, $pub->pub_id, $delta, $table_name . '__pub_id');
+    }
+  }
+  else {
+    // If the $syn_name is not set, then remove the linker FK value to the base table.
+    tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__' . $fkey);
+    tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__pub_id');
+    tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__is_internal');
+    tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__is_current');
+  }
+
+}
+/**
+ * Theme function for the pub widget.
+ *
+ * @param $variables
+ */
+function theme_tripal_chado_pub_widget($variables) {
+  $element = $variables['element'];
+
+  // These two fields were added to the widget to help identify the fields
+  // for layout.
+  $table_name = $element['#table_name'];
+  $fkey = $element['#fkey_field'];
+
+  $layout = "
+    <div class=\"pub-widget\">
+      <div class=\"pub-widget-item\">" .
+        drupal_render($element[$table_name . '__title']) . "
+      </div>
+    </div>
+  ";
+
+  return $layout;
+}
+
+/**
+ * Loads the field values with appropriate data.
+ *
+ * This function is called by the tripal_chado_field_storage_load() for
+ * each property managed by the field_chado_storage storage type.  This is
+ * an optional hook function that is only needed if the field has
+ * multiple form elements.
+ *
+ * @param $field
+ * @param $entity
+ * @param $base_table
+ * @param $record
+ */
+function tripal_chado_pub_field_load($field, $entity, $base_table, $record) {
+
+  $field_name = $field['field_name'];
+  $field_type = $field['type'];
+  $field_table = $field['settings']['chado_table'];
+  $field_column = $field['settings']['chado_column'];
+
+  // Get the FK that links to the base record.
+  $schema = chado_get_schema($field_table);
+  $pkey = $schema['primary key'][0];
+  $fkey_lcolumn = key($schema['foreign keys'][$base_table]['columns']);
+  $fkey_rcolumn = $schema['foreign keys'][$base_table]['columns'][$fkey_lcolumn];
+
+  // Set some defaults for the empty record.
+  $entity->{$field_name}['und'][0] = array(
+    'value' => '',
+    $field_table . '__' . $fkey_lcolumn => '',
+    $field_table . '__' . 'pub_id' => '',
+    $field_table . '__' . 'title' => '',
+  );
+
+  return;
+
+  $linker_table = $base_table . '_pub';
+  $options = array('return_array' => 1);
+  //$record = chado_expand_var($record, 'table', $linker_table, $options);
+  if (count($record->$linker_table) > 0) {
+    $i = 0;
+    foreach ($record->$linker_table as $index => $linker) {
+      $pub = $linker->pub_id;
+      $entity->{$field_name}['und'][$i] = array(
+        'value' => $linker->$pkey,
+        $field_table . '__' . $fkey_lcolumn => $linker->$fkey_lcolumn->$fkey_lcolumn,
+        $field_table . '__' . 'pub_id' => $pub->pub_id,
+        $field_table . '__' . 'title' => $pub->title,
+      );
+      $i++;
+    }
+  }
+}
+

+ 317 - 0
tripal_chado/includes/fields/synonym.inc

@@ -0,0 +1,317 @@
+<?php
+
+/**
+ *
+ * @param unknown $entity_type
+ * @param unknown $entity
+ * @param unknown $field
+ * @param unknown $instance
+ * @param unknown $langcode
+ * @param unknown $items
+ * @param unknown $display
+ */
+function tripal_chado_synonym_formatter(&$element, $entity_type, $entity, $field,
+    $instance, $langcode, $items, $display) {
+
+  $chado_table = $field['settings']['chado_table'];
+  foreach ($items as $delta => $item) {
+    $synonym = chado_generate_var('synonym', array('synonym_id' => $item[$chado_table . '__synonym_id']));
+    $name = $synonym->name;
+    if ($synonym->type_id->name != 'exact') {
+      $name .= ' (<i>' . $synonym->type_id->name . '</i>)';
+    }
+    $element[$delta] = array(
+      '#type' => 'markup',
+      '#markup' => $name,
+    );
+  }
+}
+/**
+ *
+ * @param unknown $field_name
+ * @param unknown $widget
+ * @param unknown $form
+ * @param unknown $form_state
+ * @param unknown $field
+ * @param unknown $instance
+ * @param unknown $langcode
+ * @param unknown $items
+ * @param unknown $delta
+ * @param unknown $element
+ */
+function tripal_chado_synonym_widget(&$widget, $form, $form_state, $field,
+    $instance, $langcode, $items, $delta, $element) {
+
+  $entity = $form['#entity'];
+  $field_name = $field['field_name'];
+
+  // Get the FK column that links to the base table.
+  $table_name = $field['settings']['chado_table'];
+  $base_table = $field['settings']['base_table'];
+  $schema = chado_get_schema($table_name);
+  $pkey = $schema['primary key'][0];
+  $fkey = array_values($schema['foreign keys'][$base_table]['columns'])[0];
+
+  // Get the field defaults.
+  $record_id = '';
+  $fkey_value = $element['#entity']->chado_record_id;
+  $synonym_id = '';
+  $pub_id = '';
+  $is_current = TRUE;
+  $is_internal = FALSE;
+  $syn_name = '';
+  $syn_type = '';
+
+  // If the field already has a value then it will come through the $items
+  // array.  This happens when editing an existing record.
+  if (array_key_exists($delta, $items)) {
+    $record_id = $items[$delta]['value'];
+    $fkey_value = $items[$delta][$table_name . '__' . $fkey];
+    $synonym_id = $items[$delta][$table_name . '__synonym_id'];
+    $pub_id = $items[$delta][$table_name . '__pub_id'];
+    $is_current = $items[$delta][$table_name . '__is_current'];
+    $is_internal = $items[$delta][$table_name . '__is_internal'];
+    $syn_name = $items[$delta][$table_name . '--synonym__name'];
+    $syn_type = $items[$delta][$table_name . '--synonym__type_id'];
+  }
+
+  // Check $form_state['values'] to see if an AJAX call set the values.
+  if (array_key_exists('values', $form_state) and array_key_exists($delta, $form_state['values'])) {
+    $record_id = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name);
+    $fkey_value = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__' . $fkey);
+    $synonym_id = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__synonym_id');
+    $pub_id = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__pub_id');
+    $is_current = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__is_current');
+    $is_internal = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__is_internal');
+    $syn_name = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '--synonym__name');
+    $syn_type = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '--synonym__type_id');
+  }
+
+  // Get the synonym type terms.  There shouldn't be too many.
+  $cv = tripal_get_default_cv('synonym', 'type_id');
+  $options = tripal_get_cvterm_select_options($cv->cv_id);
+
+  // Get the schema for the synonym table so we can make sure we limit the
+  // size of the name field to the proper size.
+  $schema = chado_get_schema('synonym');
+
+  $widget['#table_name'] = $table_name;
+  $widget['#fkey_field'] = $fkey;
+  $widget['#element_validate'] = array('tripal_chado_synonym_widget_validate');
+  $widget['#theme'] = 'tripal_chado_synonym_widget';
+  $widget['#prefix'] =  "<span id='$table_name-$delta'>";
+  $widget['#suffix'] =  "</span>";
+
+  $widget['value'] = array(
+    '#type' => 'value',
+    '#default_value' => $record_id,
+  );
+  $widget[$table_name . '__' . $fkey] = array(
+    '#type' => 'value',
+    '#default_value' => $fkey_value,
+  );
+
+  $widget[$table_name . '--synonym__type_id'] = array(
+    '#type' => 'select',
+    '#title' => t('Type'),
+    '#options' => $options,
+    '#default_value' => $syn_type,
+  );
+  $widget[$table_name . '--synonym__name'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Synonym Name'),
+    '#default_value' => $syn_name,
+    '#size' => 25,
+  );
+
+  $widget[$table_name . '__is_current'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Is Current'),
+    '#default_value' => $is_current,
+    '#required' => $element['#required'],
+  );
+
+  $widget[$table_name . '__is_internal'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Is Internal'),
+    '#default_value' => $is_internal,
+    '#required' => $element['#required'],
+  );
+
+}
+/**
+ * An Ajax callback for the synonym widget.
+ */
+function tripal_chado_synonym_widget_form_ajax_callback($form, $form_state) {
+
+  $field_name = $form_state['triggering_element']['#parents'][0];
+  $delta = $form_state['triggering_element']['#parents'][2];
+
+  return $form[$field_name]['und'][$delta];
+}
+
+/**
+ * Callback function for validating the tripal_chado_organism_select_widget.
+ */
+function tripal_chado_synonym_widget_validate($element, &$form_state) {
+
+  $field_name = $element['#field_name'];
+  $delta = $element['#delta'];
+  $table_name = $element['#table_name'];
+  $fkey = $element['#fkey_field'];
+
+  // If the form ID is field_ui_field_edit_form, then the user is editing the
+  // field's values in the manage fields form of Drupal.  We don't want
+  // to validate it as if it were being used in a data entry form.
+  if ($form_state['build_info']['form_id'] =='field_ui_field_edit_form') {
+    return;
+  }
+
+  // Get the field values.
+  $fkey_value = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__' . $fkey);
+  $synonym_id = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__synonym_id');
+  $pub_id = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__pub_id');
+  $is_current = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__is_current');
+  $is_internal = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '__is_internal');
+  $syn_name = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '--synonym__name');
+  $syn_type = tripal_chado_get_field_form_values($table_name, $form_state, $delta, $table_name . '--synonym__type_id');
+
+  // Make sure that if a synonym is provided that a type is also
+  // provided.
+  if ($syn_name and !$syn_type) {
+    form_set_error(implode('][', $element ['#parents']) . '][' . $table_name . '--synonym__type_id', t("Please set a synonym type."));
+  }
+  if (!$syn_name and $syn_type) {
+    form_set_error(implode('][', $element ['#parents']) . '][' . $table_name . '--synonym__name', t("Please set a synonym name."));
+  }
+  // If the user provided a cv_id and a name then we want to set the
+  // foreign key value to be the chado_record_idd
+  if ($syn_name and $syn_type) {
+
+    // Get the synonym. If one with the same name and type is already present
+    // then use that. Otherwise, insert a new one.
+    if (!$synonym_id) {
+      $synonym = chado_generate_var('synonym', array('name' => $syn_name, 'type_id' => $syn_type));
+      if (!$synonym) {
+        $synonym = chado_insert_record('synonym', array(
+          'name' => $syn_name,
+          'type_id' => $syn_type,
+          'synonym_sgml' => '',
+        ));
+        $synonym = (object) $synonym;
+      }
+
+      // Set the synonym_id and FK value
+      tripal_chado_set_field_form_values($field_name, $form_state, $synonym->synonym_id, $delta, $table_name . '__synonym_id');
+      $fkey_value = $element['#entity']->chado_record_id;
+      tripal_chado_set_field_form_values($field_name, $form_state, $fkey_value, $delta, $table_name . '__' . $fkey);
+    }
+
+    if (!$pub_id) {
+      $pub = chado_generate_var('pub', array('uniquename' => 'null'));
+      tripal_chado_set_field_form_values($field_name, $form_state, $pub->pub_id, $delta, $table_name . '__pub_id');
+    }
+  }
+  else {
+    // If the $syn_name is not set, then remove the linker FK value to the base table.
+    tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__' . $fkey);
+    tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__synonym_id');
+    tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__is_internal');
+    tripal_chado_set_field_form_values($field_name, $form_state, '', $delta, $table_name . '__is_current');
+  }
+
+}
+/**
+ * Theme function for the synonym widget.
+ *
+ * @param $variables
+ */
+function theme_tripal_chado_synonym_widget($variables) {
+  $element = $variables['element'];
+
+  // These two fields were added to the widget to help identify the fields
+  // for layout.
+  $table_name = $element['#table_name'];
+  $fkey = $element['#fkey_field'];
+
+  $layout = "
+    <div class=\"synonym-widget\">
+      <div class=\"synonym-widget-item\">" .
+        drupal_render($element[$table_name . '--synonym__name']) . "
+      </div>
+      <div>" .
+        drupal_render($element[$table_name . '--synonym__type_id']) . "
+      </div>
+      <div class=\"synonym-widget-item\">" .
+        drupal_render($element[$table_name . '__is_internal']) . "
+      </div>
+      <div>" .
+        drupal_render($element[$table_name . '__is_current']) . "
+      </div>
+    </div>
+  ";
+
+  return $layout;
+}
+
+/**
+ * Loads the field values with appropriate data.
+ *
+ * This function is called by the tripal_chado_field_storage_load() for
+ * each property managed by the field_chado_storage storage type.  This is
+ * an optional hook function that is only needed if the field has
+ * multiple form elements.
+ *
+ * @param $field
+ * @param $entity
+ * @param $base_table
+ * @param $record
+ */
+function tripal_chado_synonym_field_load($field, $entity, $base_table, $record) {
+
+  $field_name = $field['field_name'];
+  $field_type = $field['type'];
+  $field_table = $field['settings']['chado_table'];
+  $field_column = $field['settings']['chado_column'];
+
+  // Get the FK that links to the base record.
+  $schema = chado_get_schema($field_table);
+  $pkey = $schema['primary key'][0];
+  $fkey_lcolumn = key($schema['foreign keys'][$base_table]['columns']);
+  $fkey_rcolumn = $schema['foreign keys'][$base_table]['columns'][$fkey_lcolumn];
+
+  // Set some defaults for the empty record.
+  $entity->{$field_name}['und'][0] = array(
+    'value' => '',
+    $field_table . '__' . $fkey_lcolumn => '',
+    $field_table . '__' . 'synonym_id' => '',
+    $field_table . '__' . 'pub_id' => '',
+    $field_table . '__' . 'is_current' => TRUE,
+    $field_table . '__' . 'is_internal' => '',
+    $field_table . '--' . 'synonym__name' => '',
+    $field_table . '--' . 'synonym__type_id' => '',
+    // Ignore the synonym_sgml column for now.
+  );
+
+  $linker_table = $base_table . '_synonym';
+  $options = array('return_array' => 1);
+  $record = chado_expand_var($record, 'table', $linker_table, $options);
+  if (count($record->$linker_table) > 0) {
+    $i = 0;
+    foreach ($record->$linker_table as $index => $linker) {
+      $synonym = $linker->synonym_id;
+      $entity->{$field_name}['und'][$i] = array(
+        'value' => $linker->$pkey,
+        $field_table . '__' . $fkey_lcolumn => $linker->$fkey_lcolumn->$fkey_lcolumn,
+        $field_table . '__' . 'synonym_id' => $synonym->synonym_id,
+        $field_table . '__' . 'pub_id' => $linker->pub_id->pub_id,
+        $field_table . '__' . 'is_current' => $linker->is_current,
+        $field_table . '__' . 'is_internal' => $linker->is_internal,
+        $field_table . '--' . 'synonym__name' => $synonym->name,
+        $field_table . '--' . 'synonym__type_id' => $synonym->type_id->cvterm_id,
+      );
+      $i++;
+    }
+  }
+}
+

+ 0 - 0
legacy/tripal_pub/includes/importers/tripal_pub.AGL.inc → tripal_chado/includes/loaders/tripal_chado.pub_importer_AGL.inc


+ 0 - 0
legacy/tripal_pub/includes/importers/tripal_pub.PMID.inc → tripal_chado/includes/loaders/tripal_chado.pub_importer_PMID.inc


+ 467 - 271
legacy/tripal_pub/includes/tripal_pub.pub_importers.inc → tripal_chado/includes/loaders/tripal_chado.pub_importers.inc

@@ -4,6 +4,10 @@
  * Management of importers
  */
 
+require_once('tripal_chado.pub_importer_AGL.inc');
+require_once('tripal_chado.pub_importer_PMID.inc');
+
+
 /**
  * A function to generate a table containing the list of publication importers
  *
@@ -13,7 +17,7 @@ function tripal_pub_importers_list() {
   // clear out the session variable when we view the list.
   unset($_SESSION['tripal_pub_import']);
 
-  $header = array('', 'Importer Name', 'Database', 'Search String', 'Disabled', 'Create Contact', '');
+  $headers = array('', 'Importer Name', 'Database', 'Search String', 'Disabled', 'Create Contact', '');
   $rows = array();
   $importers = db_query("SELECT * FROM {tripal_pub_import} ORDER BY name");
 
@@ -31,8 +35,8 @@ function tripal_pub_importers_list() {
 
     $rows[] = array(
       array(
-        'data' => l(t('Edit/Test'), "admin/tripal/chado/tripal_pub/import/edit/$importer->pub_import_id") . '<br>' .
-                  l(t('Import Pubs'), "admin/tripal/chado/tripal_pub/import/submit/$importer->pub_import_id"),
+        'data' => l(t('Edit/Test'), "admin/tripal/storage/chado/loaders/pub/edit/$importer->pub_import_id") . '<br>' .
+                  l(t('Import Pubs'), "admin/tripal/storage/chado/loaders/pub/submit/$importer->pub_import_id"),
         'nowrap' => 'nowrap'
       ),
       $importer->name,
@@ -40,13 +44,13 @@ function tripal_pub_importers_list() {
       $criteria_str,
       $importer->disabled ? 'Yes' : 'No',
       $importer->do_contact ? 'Yes' : 'No',
-      l(t('Delete'), "admin/tripal/chado/tripal_pub/import/delete/$importer->pub_import_id"),
+      l(t('Delete'), "admin/tripal/storage/chado/loaders/pub/delete/$importer->pub_import_id"),
     );
   }
 
 
   $page  = "<ul class='action-links'>";
-  $page .= '  <li>' . l('New Importer', 'admin/tripal/chado/tripal_pub/import/new') . '</li>';
+  $page .= '  <li>' . l('New Importer', 'admin/tripal/storage/chado/loaders/pub/new') . '</li>';
   $page .= '</ul>';
 
   $page .= '<p>' . t(
@@ -64,7 +68,19 @@ function tripal_pub_importers_list() {
      set the importers to run automatically.") . '</li>
      </ol><br>';
 
-  $page .= theme('table', array('header' => $header, 'rows' => $rows));
+
+  $table = array(
+    'header' => $headers,
+    'rows' => $rows,
+    'attributes' => array(
+    ),
+    'caption' => '',
+    'sticky' => TRUE,
+    'colgroups' => array(),
+    'empty' => 'There are currently importers',
+  );
+
+  $page .= theme_table($table);
 
   return $page;
 }
@@ -105,7 +121,7 @@ function tripal_pub_importer_setup_page($action = 'new', $pub_import_id = NULL)
   // generate the search form
   $form = drupal_get_form('tripal_pub_importer_setup_form',  $pub_import_id, $action);
 
-  $output = l("Return to publication importers list", "admin/tripal/chado/tripal_pub/import_list");
+  $output = l("Return to publication importers list", "admin/tripal/storage/chado/loaders/pub");
   $output .= drupal_render($form);
 
   // retrieve any results
@@ -145,7 +161,7 @@ function tripal_pub_importer_setup_page($action = 'new', $pub_import_id = NULL)
           $citation = htmlspecialchars($pub['Citation']);
           $raw_link = '';
           if($pub['Publication Dbxref']) {
-            $raw_link = l('raw', 'admin/tripal/chado/tripal_pub/import/raw/' . $pub['Publication Dbxref'], array('attributes' => array('target' => '_blank')));
+            $raw_link = l('raw', 'admin/tripal/storage/chado/loaders/pub/raw/' . $pub['Publication Dbxref'], array('attributes' => array('target' => '_blank')));
           }
           $rows[] = array(
             number_format($i),
@@ -308,8 +324,6 @@ function tripal_pub_importer_setup_form($form, &$form_state = NULL, $pub_import_
     $num_criteria--;
   }
 
-
-
   // set the values we need for later but that should not be shown on the form
   $form['num_criteria']= array(
     '#type'  => 'value',
@@ -333,7 +347,7 @@ function tripal_pub_importer_setup_form($form, &$form_state = NULL, $pub_import_
     '#required'      => TRUE,
   );
 
-  $supported_dbs = variable_get('tripal_pub_supported_dbs', array());
+  $supported_dbs = variable_get('tripal_pub_supported_dbs', array('PMID'));
   $remote_dbs = array();
   $values = array(
     'name' => $supported_dbs,
@@ -693,7 +707,7 @@ function tripal_pub_importer_setup_form_submit($form, &$form_state) {
       if(drupal_write_record('tripal_pub_import', $record, 'pub_import_id')){
         unset($_SESSION['tripal_pub_import']);
         drupal_set_message('Publication import settings updated.');
-        drupal_goto('admin/tripal/chado/tripal_pub/import_list');
+        drupal_goto('admin/tripal/storage/chado/loaders/pub');
       }
       else {
         drupal_set_message('Could not update publication import settings.', 'error');
@@ -709,7 +723,7 @@ function tripal_pub_importer_setup_form_submit($form, &$form_state) {
         if ($form_state['values']['op'] == 'Save & Import Now') {
           tripal_execute_pub_importer($record['pub_import_id']);
         }
-        drupal_goto('admin/tripal/chado/tripal_pub/import_list');
+        drupal_goto('admin/tripal/storage/chado/loaders/pub');
       }
       else {
         drupal_set_message('Could not save publication import settings.', 'error');
@@ -721,7 +735,7 @@ function tripal_pub_importer_setup_form_submit($form, &$form_state) {
     $success = db_query($sql, array(':pub_import_id' => $pub_import_id));
     if ($success) {
       drupal_set_message('Publication importer deleted.');
-      drupal_goto('admin/tripal/chado/tripal_pub/import_list');
+      drupal_goto('admin/tripal/storage/chado/loaders/pub');
     }
     else {
       drupal_set_message('Could not delete publication importer.', 'error');
@@ -807,19 +821,37 @@ function theme_tripal_pub_importer_setup_form_elements($variables) {
  */
 function tripal_pub_importer_submit_job($import_id) {
   global $user;
-
   // get all of the loaders
   $args = array(':import_id' => $import_id);
   $sql = "SELECT * FROM {tripal_pub_import} WHERE pub_import_id = :import_id ";
   $import = db_query($sql, $args)->fetchObject();
 
   $args = array($import_id);
-  tripal_add_job("Import publications $import->name", 'tripal_pub',
-    'tripal_execute_pub_importer', $args, $user->uid);
+  $includes = array();
+  $includes[] = module_load_include('inc', 'tripal_chado', 'includes/loaders/tripal_chado.pub_importers');
+  tripal_add_job("Import publications $import->name", 'tripal_chado',
+    'tripal_execute_pub_importer', $args, $user->uid, 10, $includes);
 
-  drupal_goto('admin/tripal/chado/tripal_pub/import_list');
+  drupal_goto('admin/tripal/storage/chado/loaders/pub');
 }
+/**
+ * Deletes a publication importer.
+ *
+ */
+function tripal_pub_importer_delete($import_id) {
 
+  $args = array(':import_id' => $import_id);
+  $sql = "DELETE FROM {tripal_pub_import} WHERE pub_import_id = :import_id";
+  $success = db_query($sql, $args);
+
+  if ($success) {
+    drupal_set_message('Publication importer deleted.');
+    drupal_goto('admin/tripal/storage/chado/loaders/pub');
+  }
+  else {
+    drupal_set_message('Could not delete publication importer.', 'error');
+  }
+}
 /**
  * Adds publications that have been retrieved from a remote database and
  * consolidated into an array of details.
@@ -1424,103 +1456,7 @@ function tripal_pub_get_publication_array($pub_id, $skip_existing = TRUE) {
   return $pub_array;
 }
 
-/**
- * Imports all publications for all active import setups.
- *
- * @param $report_email
- *   A list of email address, separated by commas, that should be notified
- *   once importing has completed
- * @param $do_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
- *
- * @ingroup tripal_pub
- */
-function tripal_execute_active_pub_importers($report_email = FALSE, $do_update = FALSE) {
-  $num_to_retrieve = 100;
-  $page = 0;
-
-  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";
 
-  // start the transaction
-  $transaction = db_transaction();
-
-  try {
-    // get all of the loaders
-    $args = array();
-    $sql = "SELECT * FROM {tripal_pub_import} WHERE disabled = 0 ";
-    $results = db_query($sql, $args);
-    $do_contact = FALSE;
-    $reports = array();
-    foreach ($results as $import) {
-      $page = 0;
-      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;
-      }
-      $criteria = unserialize($import->criteria);
-      $remote_db = $criteria['remote_db'];
-      do {
-        // retrieve the pubs for this page. We'll retreive 100 at a time
-        $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++;
-      }
-      // continue looping until we have a $pubs array that does not have
-      // our requested numer of records.  This means we've hit the end
-      while (count($pubs) == $num_to_retrieve);
-    }
-
-    // sync the newly added publications with Drupal. If the user
-    // 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";
-    chado_node_sync_records('pub');
-
-    // iterate through each of the reports and generate a final report with HTML links
-    $HTML_report = '';
-    if ($report_email) {
-      $HTML_report .= "<html>";
-      global $base_url;
-      foreach ($reports as $importer => $report) {
-        $total = count($report['inserted']);
-        $HTML_report .= "<b>$total new publications from importer: $importer</b><br><ol>\n";
-        foreach ($report['inserted'] as $pub) {
-          $item = $pub['Title'];
-          if (array_key_exists('pub_id', $pub)) {
-            $item = l($pub['Title'], "$base_url/pub/" . $pub['pub_id']);
-          }
-          $HTML_report .= "<li>$item</li>\n";
-        }
-        $HTML_report .= "</ol>\n";
-      }
-      $HTML_report .= "</html>";
-      $site_email = variable_get('site_mail', '');
-      $params = array(
-        'message' => $HTML_report
-      );
-      drupal_mail('tripal_pub', 'import_report', $report_email, language_default(), $params, $site_email, TRUE);
-    }
-
-    // if any of the importers wanted to create contacts from the authors then sync them
-    if($do_contact) {
-      print "Syncing contacts with Drupal...\n";
-      chado_node_sync_records('contact');
-    }
-  }
-  catch (Exception $e) {
-    $transaction->rollback();
-    print "\n"; // make sure we start errors on new line
-    watchdog_exception('T_pub_import', $e);
-    print "FAILED: Rolling back database changes...\n";
-    return;
-  }
-  print "Done.\n";
-}
 
 /**
  * Imports all publications for a given publication import setup.
@@ -1568,16 +1504,20 @@ function tripal_execute_pub_importer($import_id, $job_id = NULL) {
     // our requested numer of records.  This means we've hit the end
     while (count($pubs) == $num_to_retrieve);
 
-    // sync the newly added publications with Drupal. If the user
-    // 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";
-    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";
-      chado_node_sync_records('contact');
+    // For backwards compatibility check to see if the legacy pub module
+    // is enabled. If so, then sync the nodes.
+    if (module_exists('tripal_pub')) {
+      // sync the newly added publications with Drupal. If the user
+      // 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";
+      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";
+        chado_node_sync_records('contact');
+      }
     }
     tripal_set_job_progress($job_id, '100');
   }
@@ -1614,7 +1554,7 @@ function tripal_get_remote_pub($dbxref) {
     $accession = $matches[2];
 
     // check that the database is supported
-    $supported_dbs = variable_get('tripal_pub_supported_dbs', array());
+    $supported_dbs = variable_get('tripal_pub_supported_dbs', array('PMID'));
     if(!in_array($remote_db, $supported_dbs)) {
       return FALSE;
     }
@@ -1694,180 +1634,436 @@ function tripal_get_remote_pubs($remote_db, $search_array, $num_to_retrieve, $pa
 }
 
 /**
- * Imports a singe publication specified by a remote database cross reference.
+ * The admin form for submitting job to create citations
  *
- * @param $pub_dbxref
- *   The unique database ID for the record to update.  This value must
- *   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.
- * @param $do_contact
- *   Set to TRUE if authors should automatically have a contact record added
- *   to Chado.
- * @param $do_update
- *   If set to TRUE then the publication will be updated if it already exists
- *   in the database.
+ * @param $form_state
  *
  * @ingroup tripal_pub
  */
-function tripal_import_pub_by_dbxref($pub_dbxref, $do_contact = FALSE, $do_update) {
-  $num_to_retrieve = 1;
-  $pager_id = 0;
-  $page = 0;
-  $num_pubs = 0;
+function tripal_pub_citation_form($form, &$form_state) {
+
+  $form['instructions'] = array(
+    '#markup' => '<p>Use this form to unify publication citations. Citations are created automtically when
+      importing publications but citations are set by the user when publications are added manually.
+      Or publications added to the Chado database by tools other than the Tripal Publication Importer may
+      not have citations set. If you are certain that all necessary information for all publications is present (e.g.
+      authors, volume, issue, page numbers, etc.) but citations are not consistent, then you can
+      choose to update all citations for all publications using the form below. Alternatively, you
+      can update citations only for publication that do not already have one.</p>'
+  );
 
-  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";
+  $form['options'] = array(
+    '#type' => 'radios',
+    '#options' => array(
+      'all' => 'Create citation for all publications. Replace the existing citation if it exists.',
+      'new' => 'Create citation for publication only if it does not already have one.'),
+    '#default_value' => 'all'
+  );
 
-  $transaction = db_transaction();
-  try {
-    if(preg_match('/^(.*?):(.*?)$/', $pub_dbxref, $matches)) {
-      $dbname = $matches[1];
-      $accession = $matches[2];
-
-      $criteria = array(
-        'num_criteria' => 1,
-        'remote_db' => $dbname,
-        'criteria' => array(
-          '1' => array(
-            'search_terms' => "$dbname:$accession",
-            'scope' => 'id',
-            'operation' => '',
-            'is_phrase' => 0,
-          ),
-        ),
-      );
-      $remote_db = $criteria['remote_db'];
-      $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'];
-      $pub_id = tripal_pub_add_publications($pubs, $do_contact, $do_update);
-    }
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Submit')
+  );
 
-    // sync the newly added publications with Drupal
-    print "Syncing publications with Drupal...\n";
-    chado_node_sync_records('pub');
+  return $form;
+}
 
-    // if any of the importers wanted to create contacts from the authors then sync them
-    if($do_contact) {
-      print "Syncing contacts with Drupal...\n";
-      chado_node_sync_records('contact');
-    }
+/**
+ * Submit form. Create Tripal job for citations
+ *
+ * @param $form_state
+ *
+ * @ingroup tripal_pub
+ */
+function tripal_pub_citation_form_submit(&$form_state) {
+  $options [0] = $form_state['options']['#value'];
+  tripal_add_job("Create citations ($options[0])", 'tripal_pub', 'tripal_pub_create_citations', $options, $user->uid);
+}
+
+/**
+ * Launch the Tripal job to generate citations. Called by tripal jobs
+ *
+ * @param $options
+ *  Options pertaining to what publications to generate citations for.
+ *  One of the following must be present:
+ *   - all: Create and replace citation for all pubs
+ *   - new: Create citation for pubs that don't already have one
+ *
+ * @ingroup tripal_pub
+ */
+function tripal_pub_create_citations($options) {
+  $skip_existing = TRUE;
+  $sql = "
+    SELECT cvterm_id
+    FROM {cvterm}
+    WHERE
+      name = 'Citation' AND
+      cv_id = (SELECT cv_id FROM {cv} WHERE name = 'tripal_pub')
+  ";
+  $citation_type_id = chado_query($sql)->fetchField();
+
+  // Create and replace citation for all pubs
+  if ($options == 'all') {
+    $sql = "SELECT pub_id FROM {pub} P WHERE pub_id <> 1";
+    $skip_existing = FALSE;
   }
-  catch (Exception $e) {
-    $transaction->rollback();
-    print "\n"; // make sure we start errors on new line
-    watchdog_exception('T_pub_import', $e);
-    print "FAILED: Rolling back database changes...\n";
-    return;
+  // Create citation for pubs that don't already have one
+  else if ($options == 'new') {
+    $sql = "
+      SELECT pub_id
+      FROM {pub} P
+      WHERE
+        (SELECT value
+         FROM {pubprop} PB
+         WHERE type_id = :type_id AND P.pub_id = PB.pub_id AND rank = 0) IS NULL
+        AND  pub_id <> 1
+    ";
+    $skip_existing = TRUE;
   }
 
-  print "Done.\n";
+  $result = chado_query($sql, array(':type_id' => $citation_type_id));
+  $counter_updated = 0;
+  $counter_generated = 0;
+  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);
+      print $citation . "\n\n";
+      // Replace if citation exists. This condition is never TRUE if $skip_existing is TRUE
+      if ($pub_arr['Citation']) {
+        $sql = "
+          UPDATE {pubprop} SET value = :value
+          WHERE pub_id = :pub_id  AND type_id = :type_id AND rank = :rank
+        ";
+        chado_query($sql, array(':value' => $citation, ':pub_id' => $pub->pub_id,
+          ':type_id' => $citation_type_id, ':rank' => 0));
+        $counter_updated ++;
+        // Generate a new citation
+      } else {
+        $sql = "
+          INSERT INTO {pubprop} (pub_id, type_id, value, rank)
+          VALUES (:pub_id, :type_id, :value, :rank)
+        ";
+        chado_query($sql, array(':pub_id' => $pub->pub_id, ':type_id' => $citation_type_id,
+          ':value' => $citation, ':rank' => 0));
+        $counter_generated ++;
+      }
+    }
+  }
+  print "$counter_generated citations generated. $counter_updated citations updated.\n";
 }
 
+
 /**
- * Updates publication records that currently exist in the Chado pub table
- * with the most recent data in the remote database.
+ * 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 $do_contact
- *   Set to TRUE if authors should automatically have a contact record added
- *   to Chado. Contacts are added using the name provided by the remote
- *   database.
- * @param $dbxref
- *   The unique database ID for the record to update.  This value must
- *   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.
- * @param $db
- *   The name of the remote database to update.  If this value is provided and
- *   no dbxref then all of the publications currently in the Chado database
- *   for this remote database will be updated.
+ * @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
  */
-function tripal_reimport_publications($do_contact = FALSE, $dbxref = NULL, $db = NULL) {
+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 we don't have a recognized publication type, then just use the
+    // first one in the list.
+    if (!$pub_type) {
+      $pub_type = $pub['Publication Type'][0];
+    }
+  }
+  else {
+    $pub_type = $pub['Publication Type'];
+  }
+  //----------------------
+  // Journal Article
+  //----------------------
+  if ($pub_type == 'Journal Article') {
+    if (array_key_exists('Authors', $pub)) {
+      $citation = $pub['Authors'] . '. ';
+    }
 
-  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";
-  $transaction = db_transaction();
-  try {
+    $citation .= $pub['Title'] .  '. ';
 
-    // get a list of all publications by their Dbxrefs that have supported databases
-    $sql = "
-      SELECT DB.name as db_name, DBX.accession
-      FROM pub P
-        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
-    ";
-    $args = array();
-    if ($dbxref and preg_match('/^(.*?):(.*?)$/', $dbxref, $matches)) {
-      $dbname = $matches[1];
-      $accession = $matches[2];
-      $sql .= "WHERE DBX.accession = :accession and DB.name = :dbname ";
-      $args[':accession'] = $accession;
-      $args[':dbname'] = $dbname;
+    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 .= '; ';
     }
-    elseif ($db) {
-      $sql .= " WHERE DB.name = :dbname ";
-      $args[':dbname'] = $db;
+    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') {
+    if (array_key_exists('Authors', $pub)) {
+      $citation = $pub['Authors'] . '. ';
     }
-    $sql .= "ORDER BY DB.name, P.pub_id";
-    $results = chado_query($sql, $args);
 
-    $num_to_retrieve = 100;
-    $i = 0;                 // count the number of IDs. When we hit $num_to_retrieve we'll do the query
-    $curr_db = '';          // keeps track of the current current database
-    $ids = array();         // the list of IDs for the database
-    $search = array();      // the search array passed to the search function
-
-    // iterate through the pub IDs
-    while ($pub = $results->fetchObject()) {
-      $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;
+    $citation .= $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 .= ':';
       }
-      $search = array(
-        'num_criteria' => 1,
-        'remote_db' => $remote_db,
-        'criteria' => array(
-          '1' => array(
-            'search_terms' => "$remote_db:$accession",
-            'scope' => 'id',
-            'operation' => '',
-            'is_phrase' => 0,
-          ),
-        ),
-      );
-      $pubs = tripal_get_remote_pubs($remote_db, $search, 1, 0);
-      tripal_pub_add_publications($pubs, $do_contact, TRUE);
+      $citation .= $pub['Pages'];
+    }
+    $citation .= '.';
+  }
+  //----------------------
+  // Research Support, Non-U.S. Gov't
+  //----------------------
+  elseif ($pub_type == "Research Support, Non-U.S. Gov't") {
+    if (array_key_exists('Authors', $pub)) {
+      $citation = $pub['Authors'] . '. ';
+    }
+
+    $citation .= $pub['Title'] .  '. ';
 
-      $i++;
+    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') {
+    if (array_key_exists('Authors', $pub)) {
+      $citation = $pub['Authors'] . '. ';
     }
 
-    // sync the newly added publications with Drupal
-    print "Syncing publications with Drupal...\n";
-    chado_node_sync_records('pub');
+    $citation .= $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 .= '.';
+  }
+  //-----------------------
+  // Conference Proceedings
+  //-----------------------
+  elseif ($pub_type == 'Conference Proceedings') {
+    if (array_key_exists('Authors', $pub)) {
+      $citation = $pub['Authors'] . '. ';
+    }
 
-    // if the caller wants to create contacts then we should sync them
-    if ($do_contact) {
-      print "Syncing contacts with Drupal...\n";
-      chado_node_sync_records('contact');
+    $citation .= $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 .= '.';
   }
-  catch (Exception $e) {
-    $transaction->rollback();
-    print "\n"; // make sure we start errors on new line
-    watchdog_exception('T_pub_import', $e);
-    print "FAILED: Rolling back database changes...\n";
-    return;
+  //-----------------------
+  // Default
+  //-----------------------
+  else {
+    if (array_key_exists('Authors', $pub)) {
+      $citation = $pub['Authors'] . '. ';
+    }
+    $citation .= $pub['Title'] .  '. ';
+    if (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 .= '.';
   }
-  print "Done.\n";
-}
+
+  return $citation;
+}

+ 29 - 0
tripal_chado/includes/tripal_chado.setup.inc

@@ -459,6 +459,7 @@ function tripal_chado_prepare_chado() {
     //tripal_submit_obo_job(array('obo_id' => $obo_id));
 
     tripal_pub_add_cvs();
+    tripal_pub_add_dbs();
 
     // add the custom tables
     tripal_pub_add_custom_tables();
@@ -468,6 +469,9 @@ function tripal_chado_prepare_chado() {
     tripal_set_default_cv('pubprop', 'type_id', 'tripal_pub');
     tripal_set_default_cv('pub_relationship', 'type_id', 'pub_relationship');
 
+    // Add the supported loaders
+    variable_set('tripal_pub_supported_dbs', array('PMID', 'AGL'));
+
     /////////////////////////////////////////////////////////////////////////////
       //                          Chado Stock Module
       /////////////////////////////////////////////////////////////////////////////
@@ -945,6 +949,31 @@ function tripal_pub_add_custom_tables() {
   chado_create_custom_table('pubauthor_contact', $schema, TRUE);
 }
 
+/**
+ * Adds dbs related to publications
+ *
+ * @ingroup tripal_pub
+ */
+function tripal_pub_add_dbs() {
+  // make sure we have our supported databases
+  tripal_insert_db(
+      array(
+        'name' => 'PMID',
+        'description' => 'PubMed',
+        'url' => 'http://www.ncbi.nlm.nih.gov/pubmed',
+        'urlprefix' => 'http://www.ncbi.nlm.nih.gov/pubmed/'
+      ),
+      array('update_existing' => TRUE)
+  );
+  tripal_insert_db(
+      array(
+        'name' => 'AGL',
+        'description' => 'USDA National Agricultural Library',
+        'url' => 'http://agricola.nal.usda.gov/'
+      ),
+      array('update_existing' => TRUE)
+  );
+}
 /**
  * Add cvs related to publications
  *

+ 77 - 9
tripal_chado/tripal_chado.drush.inc

@@ -84,10 +84,87 @@ function tripal_chado_drush_command() {
     ),
   );
 
+  // Drush commands for publications
+  $items['trp-import-pubs'] = array(
+    'description' => dt('Imports publications from remote databases using saved configuration settings.'),
+    'options' => array(
+      'create_contacts' => dt('provide this option to create or update contacts for authors. By default contacts are not created or updated.'),
+      'dbxref' => dt('An accession number for a publication from a remote database (e.g. PMID:23582642).'),
+      'report' => dt("Set to the email address of the recipient who should receive an HTML report of the publications that have been added."),
+      'update' => dt("Set to 'Y' to update existing pubs.  By default only new pubs are inserted."),
+      'username' => array(
+        'description' => dt('The Drupal user name for which the job should be run.  The permissions for this user will be used.'),
+      ),
+    ),
+    'examples' => array(
+      'Standard example' => 'drush tripal-pubs-import',
+      'Standard example' => 'drush -l http://[site url] tripal-pubs-import --report=[email]. Where [site url] is the URL of the website and [email] is the email address of the recipient to receive the HTML report',
+      'Import single publication' => 'drush tripal-pub-import --dbxref=PMID:23582642',
+    ),
+  );
+  $items['trp-update-pubs'] = array(
+    'description' => dt('Updates publication information for publications with a supported database cross-reference.'),
+    'options' => array(
+      'create_contacts' => dt('provide this option to create or update contacts for authors. By default contacts are not created or updated.'),
+      'dbxref' => dt('An accession number for a publication from a remote database (e.g. PMID:23582642)'),
+      'db' => dt('The database name (e.g. PMID or AGL)'),
+    ),
+    'examples' => array(
+      'Standard example' => 'drush tripal-pubs-update',
+      'Create contacts during update' => 'drush tripal-pubs-update --create_contacts=1',
+      'Update a single record' => 'drush tripal-pubs-update --dbxref=PMID:23582642',
+      'Update all records for a single database' => 'drush tripal-pubs-update --db=PMID'
+    ),
+  );
+
 
   return $items;
 }
 
+/**
+ * Imports publications into Chado
+ *
+ * @ingroup tripal_drush
+ */
+function drush_tripal_chado_trp_import_pubs() {
+  $create_contacts = drush_get_option('create_contacts');
+  $dbxref = drush_get_option('dbxref');
+  $do_report = drush_get_option('report');
+  $update = drush_get_option('update');
+  $uname = drush_get_option('username');
+
+  drush_tripal_set_user($uname);
+
+  if($update == 'Y') {
+    $update = TRUE;
+  }
+  else {
+    $update = FALSE;
+  }
+
+  module_load_include('inc', 'tripal_chado', 'includes/loaders/tripal_chado.pub_importers');
+  if ($dbxref) {
+    tripal_import_pub_by_dbxref($dbxref, $create_contacts, $update);
+  }
+  else {
+    tripal_execute_active_pub_importers($do_report, $update);
+  }
+}
+
+/**
+ * Imports publications into Chado
+ *
+ * @ingroup tripal_drush
+ */
+function drush_tripal_chado_trp_update_pubs() {
+  $create_contacts = drush_get_option('create_contacts');
+  $dbxref = drush_get_option('dbxref');
+  $db = drush_get_option('db');
+
+  module_load_include('inc', 'tripal_chado', 'includes/loaders/tripal_chado.pub_importers');
+  tripal_reimport_publications($create_contacts, $dbxref, $db);
+}
+
 /**
  * Set the user to run a drush job.
  *
@@ -180,14 +257,5 @@ function drush_tripal_chado_trp_get_table() {
   }
 }
 
-/**
- * Clean-up orphaned Drupal nodes and chado records.
- *
- * @ingroup tripal_drush
- */
-function drush_tripal_chado_trp_clean_nodes() {
-  $table = drush_get_option('table');
 
-  chado_cleanup_orphaned_nodes($table, 0);
-}
 

+ 201 - 3
tripal_chado/tripal_chado.module

@@ -345,6 +345,88 @@ function tripal_chado_menu() {
     'file path' => drupal_get_path('module', 'tripal_chado'),
     'type' => MENU_NORMAL_ITEM,
   );
+  $items['admin/tripal/storage/chado/loaders/pub'] = array(
+    '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'),
+    'file' => 'includes/loaders/tripal_chado.pub_importers.inc',
+    'file path' => drupal_get_path('module', 'tripal_chado'),
+    'type' => MENU_NORMAL_ITEM,
+    'weight' => 0
+  );
+
+  $items['admin/tripal/storage/chado/loaders/pub/new'] = array(
+    'title' => t('Add an Importer'),
+    'description' => t('Add a new publication importer.'),
+    'page callback' => 'tripal_pub_importer_setup_page',
+    'access arguments' => array('administer tripal pub'),
+    'type ' => MENU_CALLBACK,
+    'file' => 'includes/loaders/tripal_chado.pub_importers.inc',
+    'file path' => drupal_get_path('module', 'tripal_chado'),
+  );
+  $items['admin/tripal/storage/chado/loaders/pub/edit/%'] = array(
+    'page callback' => 'tripal_pub_importer_setup_page',
+    'page arguments' => array(6, 7),
+    'access arguments' => array('administer tripal pub'),
+    'type ' => MENU_CALLBACK,
+    'file' => 'includes/loaders/tripal_chado.pub_importers.inc',
+    'file path' => drupal_get_path('module', 'tripal_chado'),
+  );
+  $items['admin/tripal/storage/chado/loaders/pub/raw/%'] = array(
+    'title' => t('Raw Data From Publication Import'),
+    'page callback' => 'tripal_get_remote_pub_raw_page',
+    'page arguments' => array(6),
+    'access arguments' => array('administer tripal pub'),
+    'type ' => MENU_CALLBACK,
+    'file' => 'includes/loaders/tripal_chado.pub_importers.inc',
+    'file path' => drupal_get_path('module', 'tripal_chado'),
+  );
+
+  // add a second link for the importer on the data loaders page
+  $items['admin/tripal/storage/chado/loaders/pub/import'] = array(
+    'title' => t('Publication Importers'),
+    'page callback' => 'tripal_pub_importers_list',
+    'access arguments' => array('administer tripal pub'),
+    'type' => MENU_CALLBACK,
+    'file' => 'includes/loaders/tripal_chado.pub_importers.inc',
+    'file path' => drupal_get_path('module', 'tripal_chado'),
+  );
+
+  $items['admin/tripal/storage/chado/loaders/pub/submit/%'] = array(
+    'page callback' => 'tripal_pub_importer_submit_job',
+    'page arguments' => array(7),
+    'access arguments' => array('administer tripal pub'),
+    'type ' => MENU_CALLBACK,
+    'file' => 'includes/loaders/tripal_chado.pub_importers.inc',
+    'file path' => drupal_get_path('module', 'tripal_chado'),
+  );
+
+  $items['admin/tripal/storage/chado/loaders/pub/delete/%'] = array(
+    'page callback' => 'tripal_pub_importer_delete',
+    'page arguments' => array(7),
+    'access arguments' => array('administer tripal pub'),
+    'type ' => MENU_CALLBACK,
+    'file' => 'includes/loaders/tripal_chado.pub_importers.inc',
+    'file path' => drupal_get_path('module', 'tripal_chado'),
+  );
+  $items['admin/tripal/storage/chado/loaders/pub/changedb'] = array(
+    'page callback' => 'tripal_pub_importer_setup_page_update_remotedb',
+    'page arguments' => array(),
+    'access arguments' => array('administer tripal pub'),
+    'type ' => MENU_CALLBACK,
+    'file' => 'includes/loaders/tripal_chado.pub_importers.inc',
+    'file path' => drupal_get_path('module', 'tripal_chado'),
+  );
+
+  $items['admin/tripal/storage/chado/loaders/pub/criteria/%/%'] = array(
+    'page callback' => 'tripal_pub_importer_setup_page_update_criteria',
+    'page arguments' => array(7, 8),
+    'access arguments' => array('administer tripal pub'),
+    'type ' => MENU_CALLBACK,
+    'file' => 'includes/loaders/tripal_chado.pub_importers.inc',
+    'file path' => drupal_get_path('module', 'tripal_chado'),
+  );
 
   //////////////////////////////////////////////////////////////////////////////
   //                           Auto Completes
@@ -365,6 +447,14 @@ function tripal_chado_menu() {
     'file path' => drupal_get_path('module', 'tripal_chado'),
     'type' => MENU_CALLBACK,
   );
+  $items['admin/tripal/storage/chado/auto_name/pub/%/%'] = array(
+    'page callback' => 'tripal_autocomplete_pub',
+    'page arguments' => array(6, 7),
+    'access arguments' => array('access content'),
+    'file' => 'api/modules/tripal_chado.pub.api.inc',
+    'file path' => drupal_get_path('module', 'tripal_chado'),
+    'type' => MENU_CALLBACK,
+  );
   return $items;
 
 }
@@ -553,7 +643,7 @@ function tripal_chado_field_info() {
 
     'synonym' => array(
       'label' => t('Synonyms'),
-      'description' => t('Adds an alternative name (synonym or alias) to this record..'),
+      'description' => t('Adds an alternative name (synonym or alias) to this record.'),
       'default_widget' => 'tripal_chado_synonym_widget',
       'default_formatter' => 'tripal_chado_synonym_formatter',
       'settings' => array(),
@@ -563,6 +653,19 @@ function tripal_chado_field_info() {
         'active' => TRUE
       ),
     ),
+
+    'pub' => array(
+      'label' => t('Publications'),
+      'description' => t('Associates a publication (e.g. journal article, conference proceedings, book chapter, etc.) with this record.'),
+      'default_widget' => 'tripal_chado_pub_widget',
+      'default_formatter' => 'tripal_chado_pub_formatter',
+      'settings' => array(),
+      'storage' => array(
+        'type' => 'field_chado_storage',
+        'module' => 'tripal_chado',
+        'active' => TRUE
+      ),
+    ),
   );
   return $fields;
 }
@@ -626,6 +729,10 @@ function tripal_chado_field_widget_info() {
       'label' => t('Synonyms'),
       'field types' => array('synonym'),
     ),
+    'tripal_chado_pub_widget' => array(
+      'label' => t('Publications'),
+      'field types' => array('pub'),
+    ),
   );
 }
 /**
@@ -677,6 +784,10 @@ function tripal_chado_field_formatter_info() {
       'label' => t('Synonyms'),
       'field types' => array('synonym')
     ),
+    'tripal_chado_pub_formatter' => array(
+      'label' => t('Publications'),
+      'field types' => array('pub')
+    ),
   );
 }
 
@@ -776,6 +887,11 @@ function tripal_chado_field_formatter_view($entity_type, $entity, $field,
       tripal_chado_synonym_formatter($element, $entity_type, $entity, $field,
           $instance, $langcode, $items, $display);
       break;
+    case 'tripal_chado_pub_formatter':
+      module_load_include('inc', 'tripal_chado', 'includes/fields/pub');
+      tripal_chado_pub_formatter($element, $entity_type, $entity, $field,
+          $instance, $langcode, $items, $display);
+      break;
   }
   return $element;
 }
@@ -845,6 +961,11 @@ function tripal_chado_field_widget_form(&$form, &$form_state, $field,
       module_load_include('inc', 'tripal_chado', 'includes/fields/synonym');
       tripal_chado_synonym_widget($widget, $form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
       break;
+    case 'tripal_chado_pub_widget':
+      form_load_include($form_state, 'inc', 'tripal_chado', 'includes/fields/pub');
+      module_load_include('inc', 'tripal_chado', 'includes/fields/pub');
+      tripal_chado_pub_widget($widget, $form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
+      break;
   }
   return $widget;
 }
@@ -980,6 +1101,7 @@ function tripal_chado_set_field_form_values($field_name, &$form_state, $newvalue
  */
 function tripal_chado_theme($existing, $type, $theme, $path) {
   return array(
+    // Theme fields.
     'tripal_chado_dbxref_id_widget' => array(
       'render element' => 'element',
       'file' => 'includes/fields/dbxref_id.inc',
@@ -996,6 +1118,10 @@ function tripal_chado_theme($existing, $type, $theme, $path) {
       'render element' => 'element',
       'file' => 'includes/fields/synonym.inc',
     ),
+    'tripal_chado_pub_widget' => array(
+      'render element' => 'element',
+      'file' => 'includes/fields/pub.inc',
+    ),
     'tripal_chado_kvproperty_addr_widget' => array(
       'render element' => 'element',
       'file' => 'includes/fields/dbxref_id.inc',
@@ -1004,6 +1130,16 @@ function tripal_chado_theme($existing, $type, $theme, $path) {
       'render element' => 'element',
       'file' => 'theme/tripal_chado.theme.inc',
     ),
+
+    // Themed forms
+    'tripal_pub_importer_setup_form_elements' => array(
+      'render element' => 'form',
+      'file' => 'includes/loaders/tripal_chado.pub_importers.inc',
+    ),
+    'tripal_pub_search_setup_form_elements' => array(
+      'render element' => 'form',
+      'file' => 'includes/loaders/tripal_chado.pub_importers.inc',
+    ),
   );
 }
 
@@ -1138,12 +1274,23 @@ function tripal_chado_add_bundle_fields($entity_type, $bundle, $term) {
   //
   // Synonym table fields.
   //
-  // Check to see if there are any cvterm tables with FKs to this
+  // Check to see if there are any synonym tables with FKs to this
   // base table. If so, add the fields for that type of table.
   $syn_table = $bundle_data['data_table'] . '_synonym';
-  if (chado_table_exists($cvterm_table)) {
+  if (chado_table_exists($syn_table)) {
     tripal_chado_add_bundle_synonym_field($entity_type, $bundle_name, $syn_table, $bundle_data['data_table']);
   }
+
+  ////
+  //
+  // Pub table fields.
+  //
+  // Check to see if there are any pub tables with FKs to this
+  // base table. If so, add the fields for that type of table.
+  $pub_table = $bundle_data['data_table'] . '_pub';
+  if (chado_table_exists($pub_table)) {
+    tripal_chado_add_bundle_pub_field($entity_type, $bundle_name, $pub_table, $bundle_data['data_table']);
+  }
 }
 
 /**
@@ -1242,6 +1389,51 @@ function tripal_chado_add_bundle_synonym_field($entity_type_name, $bundle_name,
 
   tripal_add_bundle_field($field_name, $field_info, $entity_type_name, $bundle_name);
 }
+/**
+ * Adds the fields for managing xrefs that are stored in a [base]_dbxref table.
+ *
+ * @param $entity_type
+ * @param $bundle_name
+ * @param $base_table
+ * @param $dbxref_table
+ */
+function tripal_chado_add_bundle_pub_field($entity_type_name, $bundle_name, $pub_table, $base_table) {
+  // We already have a dbxref_id field.
+  $field_name = $pub_table;
+  $schema = chado_get_schema($pub_table);
+  $pkey = $schema['primary key'][0];
+
+  // Initialize the field array.
+  $field_info = array(
+    'field_type' => 'pub',
+    'widget_type' => 'tripal_fields_pub_widget',
+    'widget_settings' => array('display_label' => 1),
+    'description' => '',
+    'label' => 'Publications',
+    'is_required' => 0,
+    'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+    'storage' => 'field_chado_storage',
+    'field_settings' => array(
+      // The Chado table that this field maps to.
+      'chado_table' => $pub_table,
+      // The column in the chado table that this field maps to.
+      'chado_column' => $pkey,
+      // The base table that this field is connected to.
+      'base_table' => $base_table,
+      'semantic_web' => array(
+        // The type is the term from a vocabulary that desribes this field..
+        'type' => '',
+        // The namepsace for the vocabulary (e.g. 'foaf').
+        'ns' => '',
+        // The URL for the namespace.  It must be that the type can be
+        // appended to the URL.
+        'nsurl' => '',
+      ),
+    ),
+  );
+
+  tripal_add_bundle_field($field_name, $field_info, $entity_type_name, $bundle_name);
+}
 /**
  * Adds the fields for managing properties that are stored in a prop table.
  *
@@ -1559,6 +1751,12 @@ function tripal_chado_get_table_column_field_default($table_name, $schema, $colu
     $field['label'] = 'Program Version';
     $field['description'] = 'The version of the program used to perform this analysis. (e.g. TBLASTX 2.0MP-WashU [09-Nov-2000]. Enter "n/a" if no version is available or applicable.';
   }
+  //
+  // PROJECT TABLE
+  //
+  elseif ($field['field_settings']['chado_table'] == 'project' and $field['field_settings']['chado_column'] == 'description') {
+    $field['label'] = 'Short Description';
+  }
   return $field;
 }