Эх сурвалжийг харах

Continued development of Contact and Publiation modules

spficklin 12 жил өмнө
parent
commit
b405ae3afb

+ 85 - 2
tripal_contact/api/tripal_contact.api.inc

@@ -1,6 +1,89 @@
 <?php
-
 /**
  * @file
- * @todo Add file header description
+ * Provides an application programming interface (API) to manage libraries
+ *
+ * @defgroup tripal_contact_api contact Module API
+ * @ingroup tripal_api
+ */
+
+/**
+ * Retrieve properties of a given type for a given contact
+ *
+ * @param $contact_id
+ *    The contact_id of the properties you would like to retrieve
+ * @param $property
+ *    The cvterm name of the properties to retrieve
+ *
+ * @return
+ *    An contact chado variable with the specified properties expanded
+ *
+ * @ingroup tripal_contact_api
+ */
+function tripal_contact_get_property($contact_id, $property) {
+  return tripal_core_get_property('contact', $contact_id, $property, 'tripal_contact');
+}
+
+/**
+ * Insert a given property
+ *
+ * @param $contact_id
+ *   The contact_id of the property to insert
+ * @param $property
+ *   The cvterm name of the property to insert
+ * @param $value
+ *   The value of the property to insert
+ * @param $update_if_present
+ *   A boolean indicated whether to update the record if it's already present
+ *
+ * @return
+ *   True of success, False otherwise
+ *
+ * @ingroup tripal_contact_api
+ */
+function tripal_contact_insert_property($contact_id, $property, $value, $update_if_present = 0) {
+  return tripal_core_insert_property('contact', $contact_id, $property, 'tripal_contact', $value, $update_if_present);
+}
+
+/**
+ * Update a given property
+ *
+ * @param $contact_id
+ *   The contact_id of the property to update
+ * @param $property
+ *   The cvterm name of the property to update
+ * @param $value
+ *   The value of the property to update
+ * @param $insert_if_missing
+ *   A boolean indicated whether to insert the record if it's absent
+ *
+ * Note: The property will be identified using the unique combination of the $contact_id and $property
+ * and then it will be updated with the supplied value
+ *
+ * @return
+ *   True of success, False otherwise
+ *
+ * @ingroup tripal_contact_api
+ */
+function tripal_contact_update_property($contact_id, $property, $value, $insert_if_missing = 0) {
+  return tripal_core_update_property('contact', $contact_id, $property, 'tripal_contact', $value, $insert_if_missing);
+}
+/**
+ * Delete a given property
+ *
+ * @param $contact_id
+ *   The contact_id of the property to delete
+ * @param $property
+ *   The cvterm name of the property to delete
+ *
+ * Note: The property will be identified using the unique combination of the $contact_id and $property
+ * and then it will be deleted
+ *
+ * @return
+ *   True of success, False otherwise
+ *
+ * @ingroup tripal_contact_api
  */
+function tripal_contact_delete_property($contact_id, $property) {
+  return tripal_core_delete_property('contact', $contact_id, $property, 'tripal_contact');
+}

+ 160 - 0
tripal_contact/tcontact.obo

@@ -0,0 +1,160 @@
+format-version: 1.2
+default-namespace: tripal_contact
+
+[Term]
+id: TContact:0000001
+name: Contact Type
+
+
+[Term]
+id: TContact:0000002
+name: Collective
+def: Used when a contact is a collective of individuals rather than a person.
+is_a: TContact:0000001 ! Contact Type
+
+[Term]
+id: TContact:0000003
+name: Person
+is_a: TContact:0000001 ! Contact Type
+
+[Term]
+id: TContact:0000004
+name: Organization
+is_a: TContact:0000001 ! Contact Type
+
+[Term]
+id: TContact:0000005
+name: University
+is_a: TContact:0000001 ! Contact Type
+
+[Term]
+id: TContact:0000006
+name: Lab
+is_a: TContact:0000001 ! Contact Type
+
+[Term]
+id: TContact:0000007
+name: Institute
+is_a: TContact:0000001 ! Contact Type
+
+[Term]
+id: TContact:0000008
+name: Research Group
+is_a: TContact:0000001 ! Contact Type
+
+[Term]
+id: TContact:0000009
+name: Department
+is_a: TContact:0000001 ! Contact Type
+
+[Term]
+id: TContact:0000010
+name: First Initials
+def: The first initials for the author including the initial for the first name and any middle names (not the initial for the last name).
+relationship: part_of TContact:0000003 ! Person
+
+[Term]
+id: TContact:0000011
+name: Surname
+synonym: "family_name" EXACT []
+synonym: "last_name" EXACT []
+relationship: part_of TContact:0000003 ! Person
+
+[Term]
+id: TContact:0000012
+name: Given Name
+synonym: "first_name" EXACT []
+relationship: part_of TContact:0000003 ! Person
+
+[Term]
+id: TContact:0000013
+name: Middle Names
+def: One or more middle names for this person.
+relationship: part_of TContact:0000003 ! Person
+
+[Term]
+id: TContact:0000014
+name: Middle Initials
+def: The middle initials for this person excluding the initial for the given name and the surname.
+relationship: part_of TContact:0000003 ! Person
+
+[Term]
+id: TContact:0000015
+name: Affiliation
+
+[Term]
+id: TContact:0000016
+name: Department
+def: The department of an institution or organization.
+relationship: part_of TContact:0000015 ! Affiliation
+
+[Term]
+id: TContact:0000017
+name: Institution
+relationship: part_of TContact:0000015 ! Affiliation
+
+[Term]
+id: TContact:0000018
+name: Organization
+def: A generic term for any organization.
+relationship: part_of TContact:0000015 ! Affiliation
+
+[Term]
+id: TContact:0000019
+name: Address
+
+[Term]
+id: TContact:0000020
+name: Address Line 1
+relationship: part_of TContact:0000019 ! Address
+
+[Term]
+id: TContact:0000021
+name: Address Line 2
+relationship: part_of TContact:0000019 ! Address
+
+[Term]
+id: TContact:0000022
+name: Address Line 3
+relationship: part_of TContact:0000019 ! Address
+
+[Term]
+id: TContact:0000023
+name: City
+relationship: part_of TContact:0000019 ! Address
+
+[Term]
+id: TContact:0000024
+name: State
+relationship: part_of TContact:0000019 ! Address
+
+[Term]
+id: TContact:0000025
+name: Province
+relationship: part_of TContact:0000019 ! Address
+
+[Term]
+id: TContact:0000026
+name: Country
+relationship: part_of TContact:0000019 ! Address
+
+[Term]
+id: TContact:0000027
+name: Postal Code
+relationship: part_of TContact:0000019 ! Address
+
+[Term]
+id: TContact:0000028
+name: contact_description
+def: A description of the contact
+
+
+[Typedef]
+id: is_a
+name: is a
+is_transitive: true
+
+[Typedef]
+id: part_of
+name: part of
+is_transitive: true

+ 163 - 0
tripal_contact/tripal_contact.install

@@ -0,0 +1,163 @@
+<?php
+
+/**
+ * @file
+ * This file contains all the functions which describe and implement drupal database tables
+ * needed by this module. This module was developed by Chad N.A. Krilow and Lacey-Anne Sanderson,
+ * University of Saskatchewan.
+ *
+ * The contact manamgenet module allows you to sync data in a chado/Tripal instance with
+ * multiple contact/mysql instances as well as manage and create such contact instances
+ */
+
+/**
+ * Implementation of hook_install().
+ */
+function tripal_contact_install() {
+  // add the tripal_contact table to Drupal
+  drupal_install_schema('tripal_contact');
+  
+  // add the contactprop table to Chado
+  tripal_contact_add_custom_tables();
+  
+  // add loading of the the tripal contact ontology to the job queue
+  $obo_path =  realpath('./') . '/' . drupal_get_path('module', 'tripal_contact') . '/tcontact.obo';
+  $obo_id = tripal_cv_add_obo_ref('Tripal Contacts', $obo_path);
+  tripal_cv_submit_obo_job($obo_id);
+}
+
+/**
+ * Implementation of hook_uninstall().
+ */
+function tripal_contact_uninstall() {
+  drupal_uninstall_schema('tripal_contact');
+}
+
+/**
+ * Implementation of hook_schema().
+ */
+function tripal_contact_schema() {
+  $schema['chado_contact'] = array(
+    'fields' => array(
+      'nid' => array(
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'vid' => array(
+          'type' => 'int',
+          'not null' => TRUE,
+      ),
+      'contact_id' => array(
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+    ),
+    'primary key' => array('nid', 'vid', 'contact_id'),
+  );
+  return $schema;
+}
+
+/**
+ * Implementation of hook_requirements(). 
+ *
+ */
+function tripal_contact_requirements($phase) {
+  $requirements = array();
+  if ($phase == 'install') {
+    // make sure chado is installed
+    if (!tripal_core_is_chado_installed()) {
+      $requirements ['tripal_contact'] = array(
+            'title' => "tripal_contact",
+            'value' => "ERROR: Chado most be installed before this module can be enabled",
+            'severity' => REQUIREMENT_ERROR,
+      );
+    }
+  }
+  return $requirements;
+}
+/*
+ * 
+ */
+function tripal_contact_add_custom_tables(){
+  $schema = array (
+    'table' => 'contactprop',
+    'fields' => array (
+      'contactprop_id' => array (
+        'type' => 'serial',
+        'not null' => true,
+      ),
+      'contact_id' => array (
+        'type' => 'int',
+        'not null' => true,
+      ),
+      'type_id' => array (
+        'type' => 'int',
+        'not null' => true,
+      ),
+      'value' => array (
+        'type' => 'text',
+        'not null' => false,
+      ),
+      'rank' => array (
+        'type' => 'int',
+        'not null' => true,
+        'default' => 0,
+      ),
+    ),
+    'primary key' => array (
+      0 => 'contactprop_id',
+    ),
+    'unique keys' => array (
+      'contactprop_c1' => array (
+        0 => 'contact_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array (
+      'contactprop_idx1' => array (
+        0 => 'contact_id',
+      ),
+      'contactprop_idx2' => array (
+        0 => 'type_id',
+      ),
+    ),
+    'foreign keys' => array (
+      'cvterm' => array (
+        'table' => 'cvterm',
+        'columns' => array (
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+      'contact' => array (
+        'table' => 'contact',
+        'columns' => array (
+          'contact_id' => 'contact_id',
+        ),
+      ),
+    ),
+  );
+  tripal_core_create_custom_table(&$ret, 'contactprop', $schema, TRUE);
+}
+/**
+ *  Update for Drupal 6.x, Tripal 1.0
+ *  This update
+ *   - adds a new contact node
+ *
+ * @ingroup tripal_contact
+ */
+function tripal_contact_update_6001() {
+  // add the tripal_contact table
+  drupal_install_schema('tripal_contact');
+  
+  // add the custom tables
+  tripal_contact_add_custom_tables();
+
+  // add loading of the the tripal contact ontology to the job queue
+  $obo_path =  realpath('./') . '/' . drupal_get_path('module', 'tripal_contact') . '/tcontact.obo';
+  $obo_id = tripal_cv_add_obo_ref('Tripal Contacts', $obo_path);
+  tripal_cv_submit_obo_job($obo_id);
+  return $ret;
+}

+ 490 - 1
tripal_contact/tripal_contact.module

@@ -9,6 +9,8 @@
  * @see http://gmod.org/wiki/Chado_General_Module
  */
 
+require('api/tripal_contact.api.inc');
+
 /**
  * @defgroup tripal_contact Contact Module
  * @ingroup tripal_modules
@@ -22,7 +24,6 @@
  * @}
  */
 
-require('api/tripal_contact.api.inc');
 
 /*************************************************************************
  * Implements hook_views_api()
@@ -37,3 +38,491 @@ function tripal_contact_views_api() {
       'api' => 2.0,
   );
 }
+
+/**
+ *
+ * @ingroup tripal_contact
+ */
+function tripal_contact_init() {
+
+}
+
+/**
+ * Implementation of hook_tripal_contact_node_info().
+ *
+ * This node_info, is a simple node that describes the functionallity of the module.
+ *
+ */
+function tripal_contact_node_info() {
+
+  return array(
+    'chado_contact' => array(
+      'name' => t('Contact'),
+      'module' => 'chado_contact',
+      'description' => t('A contact from the Chado database'),
+      'title_label' => t('Article Title'),
+      'body_label' => t('Abstract'),
+      'has_title' => TRUE,
+      'has_body' => FALSE,
+    ),
+  );
+}
+
+/**
+ * Tripal-contact-Menu
+ *
+ * Implemets hook_menu(): Adds menu items for the tripal_contact module menu. This section
+ * gives the outline for the main menu of the Tripal-contact module
+ *
+ * @return
+ *   An array of menu items that is visible within the Drupal Menu, returned as soon
+ *   as the program is ran
+ */
+function tripal_contact_menu() {
+
+  $items = array();
+
+  $items[ 'admin/tripal/tripal_contact' ]= array(
+    'title' => 'Contacts',
+    'description' => ('A module for interfacing the GMOD chado database with Drupal, providing viewing of contacts'),
+    'page callback' => 'theme',
+    'page arguments' => array('tripal_contact_admin'),
+    'access arguments' => array('administer tripal contacts'),
+    'type' => MENU_NORMAL_ITEM
+  );
+
+  return $items;
+}
+  
+/**
+ * Implements hook_theme(): Register themeing functions for this module
+ *
+ *
+ * @return
+ *   An array of themeing functions to register
+ *
+ */
+function tripal_contact_theme() {
+
+  return array(
+    'tripal_contact_base' => array(
+      'arguments' => array('node' => NULL),
+    ),
+    'tripal_contact_properties' => array(
+      'arguments' => array('node' => NULL)
+    ),
+    'tripal_contact_relationships' => array(
+      'arguments' => array('node' => NULL)
+    ),
+    'tripal_contact_admin' => array(
+      'template' => 'tripal_contact_admin',  
+      'arguments' =>  array(NULL),  
+      'path' => drupal_get_path('module', 'tripal_contact') . '/theme' 
+    ),
+  );
+}
+
+/**
+ * Implement hook_perm().
+ */
+function tripal_contact_perm() {
+  return array(
+    'access chado_contact content',
+    'create chado_contact content',
+    'delete chado_contact content',
+    'edit chado_contact content',
+    'administer tripal contacts',
+  );
+}
+
+/**
+ * Implement hook_access().
+ *
+ * This hook allows node modules to limit access to the node types they define.
+ *
+ *  @param $op
+ *  The operation to be performed
+ *
+ *  @param $node
+ *  The node on which the operation is to be performed, or, if it does not yet exist, the
+ *  type of node to be created
+ *
+ *  @param $account
+ *  A user object representing the user for whom the operation is to be performed
+ *
+ *  @return
+ *  TRUE
+ *
+ */
+function chado_contact_access($op, $node, $account ) {
+  if ($op == 'create') {
+    if (!user_access('create chado_contact content', $account)) {
+      return FALSE;
+      }
+  }
+
+  if ($op == 'update') {
+    if (!user_access('edit chado_contact content', $account)) {
+      return FALSE;
+    }
+  }
+  if ($op == 'delete') {
+    if (!user_access('delete chado_contact content', $account)) {
+      return FALSE;
+    }
+  }
+  if ($op == 'view') {
+    if (!user_access('access chado_contact content', $account)) {
+      return FALSE;
+    }
+  }
+  return NULL;
+}
+
+/**
+ * Implementation of tripal_contact_form().
+ *
+ *
+ *
+ *  @parm &$node
+ *    The node that is created when the database is initialized
+ *
+ *  @parm $form_state
+ *    The state of the form, that has the user entered information that is neccessary for, setting
+ *    up the database tables for the contact
+ *
+ *  @return $form
+ *    The information that was enterd allong with
+ *
+ */
+function chado_contact_form(&$node, $form_state) {
+
+  $form = array();
+
+  $contact = $node->contact;
+
+  // get the contact default values.  When this module was first created
+  // the contact description was incorrectly stored in the $node->body field.
+  // It is better to store it in the Chado tables.  However, the 'description'
+  // field of the contact table is only 255 characters.  So, we are going
+  // to follow the same as the contact module and store the description in
+  // the contactprop table and leave the contact.description field blank.
+  // however, for backwards compatibitily, we check to see if the description
+  // is in the $node->body field. If it is we'll use that.  When the node is
+  // edited the text will be moved out of the body and into the contactprop
+  // table where it should belong.
+  if ($node->body) {
+    $contact_description = $node->body;
+  }
+  else {
+    $contact_description = $node->contact_description;
+  }
+  if (!$contact_description) {
+    $contactprop = tripal_contact_get_property($contact->contact_id, 'contact_description');
+    $contact_description = $contactprop->value;
+  }
+
+  $form['contact_id'] = array(
+    '#type' => 'hidden',
+    '#value' => (isset($node->contact_id)) ? $node->contact_id->contact_id : NULL ,
+  );
+  
+  $sql = "
+    SELECT CVTS.cvterm_id, CVTS.name
+    FROM {cvtermpath} CVTP
+      INNER JOIN {cvterm} CVTS ON CVTP.subject_id = CVTS.cvterm_id
+      INNER JOIN {cvterm} CVTO ON CVTP.object_id = CVTO.cvterm_id
+      INNER JOIN {cv} CV       ON CVTO.cv_id = CV.cv_id
+    WHERE 
+      CV.name = 'tripal_contact' AND 
+      CVTO.name = 'Contact Type' AND
+      CVTP.pathdistance = 1      
+    ORDER BY CVTS.name ASC 
+  ";
+  $results = chado_query($sql);
+  $contact_types = array();
+  $default_type = '';
+  while ($contact_type = db_fetch_object($results)) {
+    $contact_types[$contact_type->cvterm_id] = $contact_type->name;
+    if (strcmp($contact_type->name,"Person") == 0) {
+      $default_type = $contact_type->cvterm_id;
+    }
+  }
+  $form['type_id'] = array(
+    '#type' => 'select',
+    '#title' => t('Contact Type'),
+    '#options' => $contact_types,
+    '#required' => TRUE,
+    '#default_value' => isset($contact->contact_id->type_id) ? $contact->contact_id->type_id : $default_type,
+  );
+  
+  $form['title']= array(
+    '#type'          => 'textfield',
+    '#title'         => t('Contact Name'),
+    '#description'   => t('Enter the name of this contact'),
+    '#required'      => TRUE,
+    '#default_value' => $contact->name,
+    '#weight'        => 1
+  );
+
+  $form['contact_description']= array(
+    '#type'          => 'textarea',
+    '#title'         => t('Contact Description'),
+    '#description'   => t('A brief description of the contact'),
+    '#required'      => TRUE,
+    '#default_value' => $contact_description,
+    '#weight'        => 5
+  );
+  return $form;
+
+}
+
+
+/**
+ * Implementation of tripal_contact_insert().
+ *
+ * This function inserts user entered information pertaining to the contact instance into the
+ * 'contactauthor', 'contactprop', 'chado_contact', 'contact' talble of the database.
+ *
+ *  @parm $node
+ *    Then node which contains the information stored within the node-ID
+ *
+ *
+ */
+function chado_contact_insert($node) {
+ 
+  // if a contact_id already exists for this node then it already exists in Chado and 
+  // we get here because we are syncing the node.  Therefore, we can skip the insert
+  if ($node->contact_id) {
+    $contact['contact_id'] = $node->contact_id;
+  }
+  else {
+    // check to see if this contact name already exists.    
+    $values =  array('name' => $node->contact_name);
+    $options = array('statement_name' => 'sel_contact_na');
+    $contact = tripal_core_chado_select('contact', array('contact_id'), $values, $options);
+    if (count($contact) > 0) {
+      drupal_set_message(t('A contact with this name already exists.', 'error'));
+      watchdog('tripal_contact','Insert Contact: A contact with this name already exists. %name',
+        array('%name' => $node->contact_name), WATCHDOG_ERROR);
+      return FALSE;  
+    }
+    else {
+      $values =  array(
+        'name' => $node->title,
+        'description' => '',
+        'type_id' => $node->type_id
+      );
+      $options = array('statement_name' => 'ins_contact_nadety');
+      $contact = tripal_core_chado_insert('contact', $values, $options);
+      if (!$contact) {
+        drupal_set_message(t('Could not add the contact'), 'error');
+        watchdog('tripal_contact','Could not add the contact',
+          array(), WATCHDOG_ERROR);
+        return FALSE; 
+      }
+    }
+  }
+
+  if ($contact) {   
+   
+    // add the description property
+    tripal_contact_insert_property($contact['contact_id'], 'contact_description',
+      $node->contact_description);
+    
+    // make sure the entry for this contact doesn't already exist in the chado_contact table
+    // if it doesn't exist then we want to add it.
+    $contact_id = chado_get_id_for_node('contact', $node) ;
+    if (!$contact_id) {
+       // next add the item to the drupal table
+      $sql = "INSERT INTO {chado_contact} (nid, vid, contact_id) ".
+             "VALUES (%d, %d, %d)";
+      db_query($sql, $node->nid, $node->vid, $contact['contact_id']);
+    }
+  }
+  else {
+    drupal_set_message(t('Unable to add contact.', 'warning'));
+    watchdog('tripal_contact', 'Insert contact: Unable to create contact where values: %values',
+      array('%values' => print_r($values, TRUE)), WATCHDOG_WARNING);
+  }
+  return TRUE;
+}
+
+/*
+ *
+ * Implements hook_update
+ *
+ * The purpose of the function is to allow the module to take action when an edited node is being
+ * updated. It updates any name changes to the database tables that werec reated upon registering a contact.
+ * As well, the database will be changed, so the user changed information will be saved to the database.
+ *
+ * @param $node
+ *   The node being updated
+ *
+ * @ingroup tripal_contact
+ */
+function chado_contact_update($node) {
+  if ($node->revision) {
+    // there is no way to handle revisions in Chado but leave
+    // this here just to make not we've addressed it.
+  }
+  
+  $contact_id = chado_get_id_for_node('contact', $node) ;
+  
+  // check to see if this contact name doens't already exists.    
+  $sql = "SELECT contact_id FROM {contact} WHERE NOT contact_id = %d AND name = '%s'";
+  $contact = db_fetch_object(chado_query($sql, $contact_id, $node->contact_name));
+  if ($contact) {
+    drupal_set_message(t('A contact with this name already exists. Cannot perform update.'), 'warning');
+    return;  
+  }    
+  
+  // update the contact record
+  $match = array(
+     'contact_id' => $contact_id,
+  );
+  $values = array(
+    'name' => $node->title,
+    'description' => '',
+    'type_id' => $node->type_id
+  );
+  $status = tripal_core_chado_update('contact', $match, $values);
+  tripal_contact_update_property($contact_id, 'contact_description', $node->contact_description, 1);
+}
+
+
+/**
+ * Implementation of tripal_contact_load().
+ *
+ *
+ * @param $node
+ *   The node that is to be accessed from the database
+ *
+ * @return $node
+ *   The node with the information to be loaded into the database
+ *
+ */
+function chado_contact_load($node) {
+  // get the feature details from chado
+  $contact_id = chado_get_id_for_node('contact', $node);
+
+  $values = array('contact_id' => $contact_id);
+  $contact = tripal_core_generate_chado_var('contact', $values); 
+
+  $additions = new stdClass();
+  $additions->contact = $contact;
+  return $additions;
+
+}
+
+/**
+ * Implementation of tripal_contact_delete().
+ *
+ * This function takes a node and if the delete button has been chosen by the user, the contact
+ * and it's details will be removed.Following,given the node-ID, the instance will be deleted from
+ * the 'chado_contact' table.
+ *
+ *  @parm $node
+ *    Then node which contains the information stored within the node-ID
+ *
+ */
+function chado_contact_delete(&$node) {
+
+  $contact_id = chado_get_id_for_node('contact', $node);
+
+  // if we don't have a contact id for this node then this isn't a node of
+  // type chado_contact or the entry in the chado_contact table was lost.
+  if (!$contact_id) {
+    return;
+  }
+
+  // Remove data from {chado_contact}, {node} and {node_revisions} tables of
+  // drupal database
+  $sql_del = "DELETE FROM {chado_contact} ".
+             "WHERE nid = %d ".
+             "AND vid = %d";
+  db_query($sql_del, $node->nid, $node->vid);
+  $sql_del = "DELETE FROM {node_revisions} ".
+             "WHERE nid = %d ".
+             "AND vid = %d";
+  db_query($sql_del, $node->nid, $node->vid);
+  $sql_del = "DELETE FROM {node} ".
+             "WHERE nid = %d ".
+             "AND vid = %d";
+  db_query($sql_del, $node->nid, $node->vid);
+
+  // Remove data from contact and contactprop tables of chado database as well
+  chado_query("DELETE FROM {contactprop} WHERE contact_id = %d", $contact_id);
+  chado_query("DELETE FROM {contact} WHERE contact_id = %d", $contact_id);
+}
+/**
+ *
+ *
+ * @ingroup tripal_contact
+ */
+function tripal_contact_preprocess_tripal_contact_relationships(&$variables) {
+  // we want to provide a new variable that contains the matched contacts.
+  $contact = $variables['node']->contact;
+
+  // normally we would use tripal_core_expand_chado_vars to expand our
+  // organism object and add in the relationships, however whan a large
+  // number of relationships are present this significantly slows the
+  // query, therefore we will manually perform the query
+  $sql = "
+    SELECT C.name, C.contact_id, CP.nid, CVT.name as rel_type
+    FROM contact_relationship PR
+      INNER JOIN {contact} C              ON PR.object_id  = C.contact_id
+      INNER JOIN {cvterm} CVT             ON PR.type_id    = CVT.cvterm_id
+      LEFT  JOIN public.chado_contact CP  ON C.contact_id  = CP.contact_id
+    WHERE PR.subject_id = %d
+  ";
+  $as_subject = chado_query($sql, $contact->contact_id);
+  $sql = "
+    SELECT C.name, C.contact_id, CP.nid, CVT.name as rel_type
+    FROM contact_relationship PR
+      INNER JOIN {contact} C              ON PR.subject_id = C.contact_id
+      INNER JOIN {cvterm} CVT             ON PR.type_id    = CVT.cvterm_id
+      LEFT  JOIN public.chado_contact CP  ON C.contact_id  = CP.contact_id
+    WHERE PR.object_id = %d
+  ";
+  $as_object = chado_query($sql, $contact->contact_id);
+
+  // combine both object and subject relationshisp into a single array
+  $relationships = array();
+  $relationships['object'] = array();
+  $relationships['subject'] = array();
+
+  // iterate through the object relationships
+  while ($relationship = db_fetch_object($as_object)) {
+
+     // get the relationship and child types
+     $rel_type = t(preg_replace('/_/', " ", $relationship->rel_type));
+     $sub_type = t(preg_replace('/_/', " ", $relationship->sub_type));
+
+     if (!array_key_exists($rel_type, $relationships['object'])) {
+       $relationships['object'][$rel_type] = array();
+     }
+     if (!array_key_exists($sub_type, $relationships['object'][$rel_type])) {
+       $relationships['object'][$rel_type][$sub_type] = array();
+     }
+     $relationships['object'][$rel_type][$sub_type][] = $relationship;
+  }
+
+  // now add in the subject relationships
+  while ($relationship = db_fetch_object($as_subject)) {
+
+     // get the relationship and child types
+     $rel_type = t(preg_replace('/_/', " ", $relationship->rel_type));
+     $obj_type = t(preg_replace('/_/', " ", $relationship->obj_type));
+
+     if (!array_key_exists($rel_type, $relationships['subject'])) {
+       $relationships['subject'][$rel_type] = array();
+     }
+     if (!array_key_exists($obj_type, $relationships['subject'][$rel_type])) {
+       $relationships['subject'][$rel_type][$obj_type] = array();
+     }
+     $relationships['subject'][$rel_type][$obj_type][] = $relationship;
+  }
+
+  $contact->all_relationships = $relationships;
+}

+ 28 - 38
tripal_core/api/tripal_core_chado.api.inc

@@ -73,7 +73,7 @@ require_once "tripal_core.schema_v1.11.api.inc";
  *
  * @return
  *  On success this function returns the inserted record with the new primary keys
- *  add to the returned array. On failure, it returns FALSE.
+ *  added to the returned array. On failure, it returns FALSE.
  *
  * Example usage:
  * @code
@@ -318,7 +318,7 @@ function tripal_core_chado_insert($table, $values, $options = array()) {
   }
 
   // create the SQL
-  $sql = "INSERT INTO {$table} (" . implode(", ", $ifields) . ") VALUES (" . implode(", ", $itypes) . ")";
+  $sql = 'INSERT INTO {' . $table . '} (' . implode(", ", $ifields) . ") VALUES (" . implode(", ", $itypes) . ")";
 
   // if this is a prepared statement then execute it
   if ($prepared) {
@@ -326,7 +326,7 @@ function tripal_core_chado_insert($table, $values, $options = array()) {
     // then we need to do the prepare, otherwise just execute
     if ($options['is_prepared'] != TRUE) {
       // prepare the statement
-      $psql = "PREPARE " . $options['statement_name'] . " (" . implode(', ', $idatatypes) . ") AS INSERT INTO {$table} (" . implode(", ", $ifields) . ") VALUES (" . implode(", ", $iplaceholders) . ")";
+      $psql = "PREPARE " . $options['statement_name'] . " (" . implode(', ', $idatatypes) . ') AS INSERT INTO {' . $table . '} (' . implode(", ", $ifields) . ") VALUES (" . implode(", ", $iplaceholders) . ")";
       $status = tripal_core_chado_prepare($options['statement_name'], $psql, $idatatypes);
 
       if (!$status) {
@@ -334,12 +334,11 @@ function tripal_core_chado_insert($table, $values, $options = array()) {
         return FALSE;
       }
     }
-
     $sql = "EXECUTE " . $options['statement_name'] . "(" . implode(", ", $itypes) . ")";
     $result = tripal_core_chado_execute_prepared($options['statement_name'], $sql, $ivalues);
   }
   // if it's not a prepared statement then insert normally
-  else {
+  else {        
     $result = chado_query($sql, $ivalues);
   }
 
@@ -377,7 +376,8 @@ function tripal_core_chado_insert($table, $values, $options = array()) {
     return TRUE;
   }
   else {
-    watchdog('tripal_core', "tripal_core_chado_insert: Cannot insert record into $table table: " . print_r($values, 1), array(), 'WATCHDOG_ERROR');
+    watchdog('tripal_core', "tripal_core_chado_insert: Cannot insert record into '%table': " . print_r($values, 1), 
+      array('%table' => $table), 'WATCHDOG_ERROR');
     return FALSE;
   }
 
@@ -604,8 +604,8 @@ function tripal_core_chado_update($table, $match, $values, $options = NULL) {
   }
 
   // now build the SQL statement
-  $sql  = "UPDATE {$table} SET ";
-  $psql = "UPDATE {$table} SET ";
+  $sql  = 'UPDATE {' . $table . '} SET ';
+  $psql = 'UPDATE {' . $table . '} SET ';
   $uargs = array();
   $idatatypes = array();
   $pvalues = array();
@@ -934,7 +934,7 @@ function tripal_core_chado_delete($table, $match, $options = NULL) {
   }
 
   // now build the SQL statement
-  $sql = "DELETE FROM {$table} WHERE ";
+  $sql = 'DELETE FROM {' . $table . '} WHERE ';
   $psql = $sql;
   $uargs = array();
   $idatatypes = array();
@@ -1352,7 +1352,7 @@ function tripal_core_chado_select($table, $columns, $values, $options = NULL) {
         // select the value from the foreign key relationship for this value
         $foreign_options = array(
           'regex_columns' => $options['regex_columns'],
-          'case_insensitive_columns' => $options['case_insensitive_columns']
+//          'case_insensitive_columns' => $options['case_insensitive_columns']
         );
         if (array_key_exists('statement_name', $options) and $options['statement_name']) {
           // add the fk relationship info to the prepared statement name so that
@@ -1367,17 +1367,6 @@ function tripal_core_chado_select($table, $columns, $values, $options = NULL) {
 
         $results = tripal_core_chado_get_foreign_key($table_desc, $field, $value, $foreign_options);
         if (!$results or count($results)==0) {
-
-          // foreign key records are required
-          // thus if none matched then return FALSE and alert the admin through watchdog
-          /*watchdog('tripal_core',
-           'tripal_core_chado_select: no record in the table referenced by the foreign key (!field)   exists. tripal_core_chado_select table=!table, columns=!columns, values=!values',
-           array('!table' => $table,
-             '!columns' => '<pre>' . print_r($columns, TRUE) . '</pre>',
-             '!values' => '<pre>' . print_r($values, TRUE) . '</pre>',
-             '!field' => $field,
-           ),
-           WATCHDOG_WARNING);*/
           return array();
         }
         else {
@@ -1406,13 +1395,13 @@ function tripal_core_chado_select($table, $columns, $values, $options = NULL) {
   if (empty($where)) {
     // sometimes want to select everything
     $sql  = "SELECT " . implode(', ', $columns) . " ";
-    $sql .= "FROM {$table} ";
+    $sql .= 'FROM {' . $table . '} ';
     // we don't prepare a statement if there is no where clause
     $prepared = FALSE;
   }
   else {
     $sql  = "SELECT " . implode(', ', $columns) . " ";
-    $sql .= "FROM {$table} ";
+    $sql .= 'FROM {' . $table . '} ';
 
     // if $values is empty then we want all results so no where clause
     if (!empty($values)) {
@@ -1453,8 +1442,8 @@ function tripal_core_chado_select($table, $columns, $values, $options = NULL) {
         // get the types for the prepared statement. First check if the type
         // is an integer
         if (strcasecmp($table_desc['fields'][$field]['type'], 'serial')==0 OR
-        strcasecmp($table_desc['fields'][$field]['type'], 'int')==0 OR
-        strcasecmp($table_desc['fields'][$field]['type'], 'integer')==0) {
+            strcasecmp($table_desc['fields'][$field]['type'], 'int')==0 OR
+            strcasecmp($table_desc['fields'][$field]['type'], 'integer')==0) {
           $sql .= "$field $operator %d AND ";
           $psql .= "$field $operator \$" . $i . " AND ";
           $args[] = $value[0];
@@ -1485,7 +1474,7 @@ function tripal_core_chado_select($table, $columns, $values, $options = NULL) {
         else {
           if (in_array($field, $options['case_insensitive_columns'])) {
             $sql .= "lower($field) $operator lower('%s') AND ";
-            $psql .= "lower($field) $operator lower('\$" . $i . "') AND ";
+            $psql .= "lower($field) $operator lower(\$" . $i . ") AND ";
             $args[] = $value[0];
           }
           else {
@@ -2464,8 +2453,9 @@ function chado_query($sql) {
     // 'substring' function of postgres. But since table names can't start with
     // a number we exclude words numeric values. We also exclude tables that
     // already have a schema prefix.
-    $sql = preg_replace('/FROM\s+([^0123456789\(][^\.]*?)(\s|$)/i', 'FROM chado.\1 ', $sql);
-    $sql = preg_replace('/INNER\s+JOIN\s+([^\.]*?)\s/i', 'INNER JOIN chado.\1 ', $sql);
+//    $sql = preg_replace('/FROM\s+([^0123456789\(][^\.]*?)(\s|$)/i', 'FROM chado.\1 ', $sql);
+//    $sql = preg_replace('/INNER\s+JOIN\s+([^\.]*?)\s/i', 'INNER JOIN chado.\1 ', $sql);
+    $sql = preg_replace('/\{.*?\}/', 'chado.$1', $sql);
   }
   //print "$sql\n";
 
@@ -2629,7 +2619,7 @@ function tripal_core_get_property($basetable, $record_id, $property, $cv_name) {
  *   The base table for which the property should be inserted. Thus to insert a property
  *   for a feature the basetable=feature and property is inserted into featureprop
  * @param $record_id
- *   The foriegn key field of the base table. This should be in integer.
+ *   The foriegn key value of the base table. This should be in integer.
  * @param $property
  *   The cvterm name describing the type of properties to be inserted
  * @param $cv_name
@@ -2653,9 +2643,10 @@ $cv_name, $value, $update_if_present = 0) {
   // then we can do that, but otherwise we want to increment the rank and
   // insert
   $props = tripal_core_get_property($basetable, $record_id, $property, $cv_name);
-  if (!is_array($props)) {
+  if (!is_array($props) and $props) {
     $props = array($props);
   }
+  
   $rank = 0;
   if (count($props) > 0) {
     if ($update_if_present) {
@@ -2669,18 +2660,14 @@ $cv_name, $value, $update_if_present = 0) {
         if ($p->rank > $rank) {
           $rank = $p->rank;
         }
-        if (strcmp($p->value, $value) == 0) {
+        if (strcmp($p->value, $value) == 0) {          
           return TRUE;
         }
       }
       // now add 1 to the rank
       $rank++;
     }
-  }
-  else {
-    watchdog('tripal_core', "Cannot find property '!prop_name'.",
-    array('!prop_name' => $property), WATCHDOG_ERROR);
-  }
+  } 
 
   // make sure the cvterm exists.  Otherwise we'll get an error with
   // prepared statements not matching
@@ -2690,9 +2677,12 @@ $cv_name, $value, $update_if_present = 0) {
     ),
     'name' => $property,    
   );
+  
   $options = array('statement_name' => 'sel_cvterm_cv');
   $term = tripal_core_chado_select('cvterm', array('cvterm_id'), $values, $options);  
   if(!$term or count($term) == 0) {
+    watchdog('tripal_core', "Cannot find property '%prop_name'.",
+      array('%prop_name' => $property), WATCHDOG_ERROR);
     return FALSE;
   }
   
@@ -2772,9 +2762,9 @@ function tripal_core_update_property($basetable, $record_id, $property,
     'type_id' => array(
       'cv_id' => array(
         'name' => $cv_name,
-  ),
+      ),
       'name' => $property,
-  ),
+    ),
   );
 
   // construct the array of values to be updated

+ 2 - 1
tripal_core/api/tripal_core_misc.api.inc

@@ -29,7 +29,7 @@ function tripal_pager_callback($func, $limit = 9, $element = 0, $cfunc) {
   
   global $pager_page_array, $pager_total, $pager_total_items;
   $page = isset($_GET['page']) ? $_GET['page'] : '';
-  
+   
   // Substitute in query arguments.
   $args = func_get_args();
   $args = array_slice($args, 4);
@@ -38,6 +38,7 @@ function tripal_pager_callback($func, $limit = 9, $element = 0, $cfunc) {
     $args = $args[0];
   }
 
+  // count the number of records by calling the counting callbackup function
   $count = $cfunc($args);  
   
   // Convert comma-separated $page to an array, used by other functions.

+ 144 - 5
tripal_cv/api/tripal_cv.api.inc

@@ -205,7 +205,11 @@ function tripal_cv_get_cvterm_by_name($name, $cv_id = 0, $cv_name = 'tripal') {
        'name' => $name,
        'cv_id' => $cv_id,
     );
-    $r = tripal_core_chado_select('cvterm', array('*'), $values);
+    $options = array(
+      'statement_name' => 'sel_cvterm_nacv', 
+      'case_insensitive_columns' => array('name')
+    );
+    $r = tripal_core_chado_select('cvterm', array('*'), $values, $options);
   }
   elseif ($cv_name) {
     $values = array(
@@ -213,25 +217,83 @@ function tripal_cv_get_cvterm_by_name($name, $cv_id = 0, $cv_name = 'tripal') {
       'cv_id' => array(
         'name' => $cv_name,
       ),
+    );    
+    $options = array(
+      'statement_name' => 'sel_cvterm_nacv', 
+      'case_insensitive_columns' => array('name')
     );
-    $r = tripal_core_chado_select('cvterm', array('*'), $values);
+    $r = tripal_core_chado_select('cvterm', array('*'), $values, $options);  
   }
   else {
     $values = array(
       'name' => $name,
     );
-    $r = tripal_core_chado_select('cvterm', array('*'), $values);
+    $options = array(
+      'statement_name' => 'sel_cvterm_na', 
+      'case_insensitive_columns' => array('name')
+    );
+    $r = tripal_core_chado_select('cvterm', array('*'), $values, $options);
   }
 
   if (!$r) {
     return FALSE;
   }
-  if (count($r) > 0) {
+  if (count($r) > 1) {
     return FALSE;
   }
   return $r[0];
 }
 
+/**
+ * Retrieve a chado cvterm object with a given name
+ *
+ * @param $synonym
+ *   the synonym of the term
+ * @param $cv_id
+ *   the cv_id of the term you are looking for
+ * @param $cv_name
+ *   the name of the CV
+ *
+ * @return
+ *   cvterm object
+ *
+ * @ingroup tripal_cv_api
+ */
+function tripal_cv_get_cvterm_by_synonym($synonym, $cv_id = NULL, $cv_name = 'tripal') {
+
+  // first find the CVTerm synonym
+  $values = array(
+     'synonym' => $synonym,
+  );
+  $statement = "sel_cvtermsynonym_sy";
+  if ($cv_id) {
+    $values['cvterm_id'] = array('cv_id' => $cv_id);
+    $statement = "sel_cvtermsynonym_sycv";    
+  }
+  if ($cv_name) {
+    $values['cvterm_id'] = array('cv_id' => array('name' => $cv_name));
+    $statement = "sel_cvtermsynonym_sycv";
+  }
+  $options = array(
+    'statement_name' => $statement,
+    'case_insensitive_columns' => array('name')
+  );
+  $synonym = tripal_core_chado_select('cvtermsynonym', array('cvterm_id'), $values, $options);
+  
+  // if the synonym doens't exist or more than one record is returned then return false
+  if(count($synonym) == 0) {
+    return FALSE;
+  }
+  if(count($synonym) > 1) {
+    return FALSE;
+  }
+  
+  // get the cvterm
+  $values = array('cvterm_id' => $synonym[0]->cvterm_id);
+  $options = array('statement_name' => 'sel_cvterm_id');
+  $cvterm = tripal_core_chado_select('cvterm', array('*'), $values, $options);
+  return $cvterm[0]; 
+}
 /**
  * Create an options array to be used in a form element
  *   which provides a list of all chado cvterms
@@ -676,7 +738,7 @@ function tripal_cv_add_cvterm($term, $defaultcv = '_global', $is_relationship =
  * This function defines the custom tables that will be created 
  * in the chado schema.
  *
- * @ingroup tripal_cv
+ * @ingroup tripal_cv_api
  */
 function tripal_cv_get_custom_tables($table = NULL) {
 
@@ -709,4 +771,81 @@ function tripal_cv_get_custom_tables($table = NULL) {
     );
   }
   return $schema;
+}
+
+/**
+ * This function allows other modules to programatically
+ * submit an ontology for loading into Chado.  This function
+ * will add a job to the Jobs subsystem for parsing the ontology.
+ * You can either pass a known OBO ID to the function or the URL
+ * or full path the the ontology file.  If a URL or file name is
+ * passed then the $obo_name argument must also be provided.  If
+ * this is the first time the ontology has been provided to Tripal
+ * then it will be added to the database and will be assigned a
+ * unique OBO ID.
+ * 
+ * @param $obo_id
+ *   If the ontology is already loaded into the Tripal tables then
+ *   use this argument to specify the unique ID for the ontology
+ *   that will be loaded
+ * @param $obo_name
+ *   If the OBO has not been added before then use this argument
+ *   to specify the human readable name of the ontology.
+ * @param $obo_url
+ *   If the OBO to be loaded is located on a remote server then
+ *   use this argument to provide the URL.
+ * @param $obo_file
+ *   If the OBO is housed on the local file system of the server then
+ *   use this argument to specify the full path.  
+ *   
+ * @return
+ *   returns the job_id of the submitted job or FALSE if the job was not added
+ *   
+ * @ingroup tripal_cv_api
+ */
+function tripal_cv_submit_obo_job($obo_id = NULL, $obo_name = NULL, $obo_url = NULL, $obo_file = NULL) {
+  global $user;
+
+  if ($obo_id) {
+    $sql = "SELECT * FROM {tripal_cv_obo} WHERE obo_id = %d";
+    $obo = db_fetch_object(db_query($sql, $obo_id));
+    
+    $args = array($obo_id);
+    return tripal_add_job("Load OBO $obo->name", 'tripal_cv',
+       "tripal_cv_load_obo_v1_2_id", $args, $user->uid);
+  }
+  else {
+    if ($obo_url) {
+      $args = array($obo_name, $obo_url);
+      return tripal_add_job("Load OBO $obo_name", 'tripal_cv',
+        "tripal_cv_load_obo_v1_2_url", $args, $user->uid);
+    }
+    elseif ($obo_file) {
+      $args = array($obo_name, $obo_file);
+      return tripal_add_job("Load OBO $obo_name", 'tripal_cv',
+        "tripal_cv_load_obo_v1_2_file", $args, $user->uid);
+    }
+  }
+  return FALSE;
+}
+
+/**
+ * Add the obo to the tripal_cv_obo table in the Drupal database
+ * 
+ * @param $name
+ * The human readable name of this ontology
+ * @param $path
+ * The file path or URL of the ontology
+ * 
+ * @return
+ * Returns the ontology ID
+ * 
+ * @ingroup tripal_cv_api
+ */
+function tripal_cv_add_obo_ref($name, $path) {
+  $record = new stdClass;
+  $record->name = $name;
+  $record->path = $path;
+  drupal_write_record('tripal_cv_obo', $record);
+  return $record->obo_id;
 }

+ 8 - 35
tripal_cv/includes/obo_loader.inc

@@ -104,33 +104,12 @@ function tripal_cv_obo_form(&$form_state = NULL) {
    * @ingroup tripal_obo_loader
  */
 function tripal_cv_obo_form_submit($form, &$form_state) {
-  global $user;
-
   $obo_id =  $form_state['values']['obo_id'];
   $obo_name =  $form_state['values']['obo_name'];
   $obo_url =  $form_state['values']['obo_url'];
   $obo_file  = $form_state['values']['obo_file'];
-
-  $sql = "SELECT * FROM {tripal_cv_obo} WHERE obo_id = %d";
-  $obo = db_fetch_object(db_query($sql, $obo_id));
-
-  if ($obo_id) {
-    $args = array($obo_id);
-    tripal_add_job("Load OBO $obo->name", 'tripal_cv',
-       "tripal_cv_load_obo_v1_2_id", $args, $user->uid);
-  }
-  else {
-    if ($obo_url) {
-      $args = array($obo_name, $obo_url);
-      tripal_add_job("Load OBO $obo_name", 'tripal_cv',
-        "tripal_cv_load_obo_v1_2_url", $args, $user->uid);
-    }
-    elseif ($obo_file) {
-      $args = array($obo_name, $obo_file);
-      tripal_add_job("Load OBO $obo_name", 'tripal_cv',
-        "tripal_cv_load_obo_v1_2_file", $args, $user->uid);
-    }
-  }
+  
+  tripal_cv_submit_obo_job($obo_id, $obo_name, $obo_url, $obo_file);
 }
 
 /**
@@ -220,9 +199,9 @@ function tripal_cv_load_obo_v1_2_file($obo_name, $file, $jobid = NULL, $is_new =
   
   tripal_cv_load_obo_v1_2($file, $jobid, $newcvs);
   if ($is_new) {
-    tripal_cv_load_obo_add_ref($obo_name, $file);
+    tripal_cv_add_obo_ref($obo_name, $file);
   }
-  print "\nOntology Sucessfully loaded!\n";
+  print "\nDone\n";
 
   // update the cvtermpath table
   tripal_cv_load_update_cvtermpath($newcvs, $jobid);
@@ -262,13 +241,13 @@ function tripal_cv_load_obo_v1_2_url($obo_name, $url, $jobid = NULL, $is_new = T
   unlink($temp);
 
   if ($is_new) {
-    tripal_cv_load_obo_add_ref($obo_name, $url);
+    tripal_cv_add_obo_ref($obo_name, $url);
   }
 
   // update the cvtermpath table
   tripal_cv_load_update_cvtermpath($newcvs, $jobid);
 
-  print "Ontology Sucessfully loaded!\n";
+  print "Done\n";
 }
 
 /**
@@ -283,13 +262,7 @@ function tripal_cv_load_update_cvtermpath($newcvs, $jobid) {
   }
 }
 
-/**
- * Add the obo to the tripal_cv_obo table in the Drupal database
- */
-function tripal_cv_load_obo_add_ref($name, $path) {
-  $isql = "INSERT INTO {tripal_cv_obo} (name,path) VALUES ('%s','%s')";
-  db_query($isql, $name, $path);
-}
+
 
 /**
  *
@@ -514,7 +487,7 @@ function tripal_cv_obo_process_term($term, $defaultcv, $is_relationship = 0, &$n
   // add the cvterm
   $cvterm = tripal_cv_add_cvterm($t, $defaultcv, $is_relationship, 1, $default_db); 
   if (!$cvterm) {
-    tripal_cv_obo_quiterror("Cannot add the term " . $term['id']);
+    tripal_cv_obo_quiterror("Cannot add the term " . $term['id'][0]);
   }  
  
   if (array_key_exists('namespace', $term)) {

+ 0 - 2
tripal_feature/includes/tripal_feature.admin.inc

@@ -344,9 +344,7 @@ function get_tripal_feature_admin_form_url_set(&$form) {
                         'example http://my-tripal-site.org/ID1034, where the '.
                         'element just after the final slash is the unique '.
                         'identifier for the feature.'),
-
   );
-
   $options = array(
     'internal ID'          => 'Internal ID (Chado feature_id)',
     'feature unique name'  => 'Feature unique name',

+ 2 - 5
tripal_organism/tripal_organism.module

@@ -284,11 +284,8 @@ function chado_organism_insert($node) {
     $organism = tripal_core_chado_insert('organism', $values);
     if (!$organism) {
       drupal_set_message(t('Unable to add organism.', 'warning'));
-      watchdog('tripal_organism',
-        'Insert Organism: Unable to create organism where values:%values',
-        array('%values' => print_r($values, TRUE)),
-        WATCHDOG_WARNING
-      );
+      watchdog('tripal_organism', 'Insert Organism: Unable to create organism where values:%values',
+        array('%values' => print_r($values, TRUE)), WATCHDOG_ERROR);
       return;
     }
     $organism_id = $organism['organism_id'];

+ 4 - 4
tripal_project/tripal_project.module

@@ -498,8 +498,8 @@ function tripal_project_preprocess_tripal_project_relationships(&$variables) {
   $sql = "
     SELECT P.name, P.project_id, CP.nid, CVT.name as rel_type
     FROM project_relationship PR
-      INNER JOIN {project} P       ON PR.object_project_id = P.project_id
-      INNER JOIN {cvterm} CVT      ON PR.type_id           = CVT.cvterm_id
+      INNER JOIN {project} P            ON PR.object_project_id = P.project_id
+      INNER JOIN {cvterm} CVT           ON PR.type_id           = CVT.cvterm_id
       LEFT JOIN public.chado_project CP ON P.project_id         = CP.project_id
     WHERE PR.subject_project_id = %d
   ";
@@ -507,8 +507,8 @@ function tripal_project_preprocess_tripal_project_relationships(&$variables) {
   $sql = "
     SELECT P.name, P.project_id, CP.nid, CVT.name as rel_type
     FROM project_relationship PR
-      INNER JOIN {project P}       ON PR.subject_project_id = P.project_id
-      INNER JOIN {cvterm CVT}      ON PR.type_id            = CVT.cvterm_id
+      INNER JOIN {project} P            ON PR.subject_project_id = P.project_id
+      INNER JOIN {cvterm} CVT           ON PR.type_id            = CVT.cvterm_id
       LEFT JOIN public.chado_project CP ON P.project_id          = CP.project_id
     WHERE PR.object_project_id = %d
   ";

+ 2 - 1
tripal_project/tripal_project.views.inc

@@ -102,7 +102,8 @@ function tripal_project_views_default_views() {
     return $views;
   }
 
-  $description_type_id = tripal_core_chado_select('cvterm',array('cvterm_id'),array('name' => 'project_description'));
+  $values = array('name' => 'project_description');
+  $description_type_id = tripal_core_chado_select('cvterm', array('cvterm_id'), $values);
   $description_type_id = $description_type_id[0]->cvterm_id;
 
   // Main default view

+ 180 - 86
tripal_pub/api/tripal_pub.api.inc

@@ -17,6 +17,7 @@
  * @param search_array
  *    An associate array containing the search criteria. The following key 
  *    are expected
+ *      'remote_db':     Specifies the name of the remote publication database
  *      'num_criteria':  Specifies the number of criteria present in the search array
  *      'days':          The number of days to include in the search starting from today
  *      'criteria':      An associate array containing the search critiera. There should
@@ -39,7 +40,7 @@
  *    of drupal. Simply provide a unique integer value for this argument.  Each
  *    form on a single page should have a unique $pager_id.
  * @param $page
- *    Optional.  If this function is called on the command-line where the 
+ *    Optional.  If this function is called where the 
  *    page for the pager cannot be set using the $_GET variable, use this
  *    argument to specify the page to retrieve. 
  *    
@@ -57,7 +58,7 @@ function tripal_pub_get_remote_search_results($remote_db, $search_array,
 
   // manually set the $_GET['page'] parameter to trick the pager
   // into giving us the requested page
-  if (is_numeric($page) and $page > 0) {
+  if (is_int($page) and $page > 0) {
     $_GET['page'] = $page;
   }  
   
@@ -75,72 +76,110 @@ function tripal_pub_get_remote_search_results($remote_db, $search_array,
 function tripal_pub_import_publications() {
   $num_to_retrieve = 10;
   $pager_id = 0;
-  $page = 1;
+  $page = 0;
   $num_pubs = 0;
   
+  // get a persistent connection
+  $connection = tripal_db_persistent_chado();
+  if (!$connection) {
+     print "A persistant connection was not obtained. Loading will be slow\n";
+  }
+          
+  // if we cannot get a connection then let the user know the loading will be slow
+  tripal_db_start_transaction();
+  if ($connection) {
+     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";
+  }
+  
+  
   // get all of the loaders
   $sql = "SELECT * FROM {tripal_pub_import} WHERE disabled = 0";
   $results = db_query($sql);
   while ($import = db_fetch_object($results)) {
      $criteria = unserialize($import->criteria); 
      $remote_db = $criteria['remote_db'];
-     print_r($search_array);
      do {       
-       // retrieve the pubs for this page
+       // get the number of records
+       
+       // retrieve the pubs for this page. We'll retreive 10 at a time
        $pubs = tripal_pub_get_remote_search_results($remote_db, $criteria, $num_to_retrieve, $pager_id, $page);
+       
        // now add the publications
        foreach ($pubs as $pub) {
                
-         $p = tripal_pub_add_publication($pub);
-         $pub_id = $p->pub_id;                    
-         
-         // check to see if the pub_dbxref record already exist
-         $values = array(
-           'dbxref_id' => array(
-             'accession' => $pub['pub_accession'],
-             'db_id' => array(
-                'name' => $pub['pub_database'],
-             ),
-           ), 
-           'pub_id' => $pub_id,
-         );
-         $options = array('statement_name' => 'sel_pubdbxref_db');
-         $results = tripal_core_chado_select('pub_dbxref', array('*'), $values, $options);
-         
-         // if the pub_dbxref record doesn't exist then we need to add the associate
-         if(count($results) == 0) {
-           
-           // make sure our database already exists
-           $db = tripal_db_add_db($pub['pub_database']);
-           
-           // get the database cross-reference
-           $values = array(
-             'accession' => $pub['pub_accession'],
-             'db_id' => $db->db_id,
-           );
-           $options = array('statement_name' => 'sel_dbxref_acdb');
-           $results = tripal_core_chado_select('dbxref', array('dbxref_id'), $values, $options);
-           // if the accession doesn't exist then add it
-           if(count($results) == 0){
-             $dbxref = tripal_db_add_dbxref($db->db_id, $pub['pub_accession']);          
-           }
-           else {
-             $dbxref = $results[0];
-           }
-           
-         }
-         else {
-           $pub_dbxref = $results[0];
-         }
-         
+         $pub_id = tripal_pub_add_publication($pub);
+         if ($pub_id) {         
+           $pub_dbxref = tripal_pub_add_pub_dbxref($pub_id, $pub);
+         }                                      
 
-         print $num_pubs . ".  " . $pub['pub_database'] . ' ' . $pub['pub_accession'] . "\n";                 
          $num_pubs++;
-       }       
+         print $num_pubs . ".  " . $pub['Publication Database'] . ' ' . $pub['Pub Accession'] . "\n";                          
+       } // end for loop       
        $page++;
      } 
-     while (count($pubs) > 0);    
+     // 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);    
+  }
+  
+  // transaction is complete
+  tripal_db_commit_transaction();
+  
+  print "Done.\n";
+}
+
+/*
+ * 
+ */
+function tripal_pub_add_pub_dbxref($pub_id, $pub) {
+  
+  // check to see if the pub_dbxref record already exist
+  $values = array(
+    'dbxref_id' => array(
+      'accession' => $pub['Pub Accession'],
+      'db_id' => array(
+        'name' => $pub['Publication Database'],
+      ),
+    ), 
+    'pub_id' => $pub_id,
+  );
+  $options = array('statement_name' => 'sel_pubdbxref_dbpu');
+  $results = tripal_core_chado_select('pub_dbxref', array('*'), $values, $options);
+  
+  // if the pub_dbxref record  exist then we don't need to re-add it.
+  if(count($results) > 0) {
+    return $results[0];  
+  }
+  
+  // make sure our database already exists
+  $db = tripal_db_add_db($pub['Publication Database']);
+   
+  // get the database cross-reference
+  $dbxvalues = array(
+    'accession' => $pub['Pub Accession'],
+    'db_id' => $db->db_id,
+  );
+  $dbxoptions = array('statement_name' => 'sel_dbxref_acdb');
+  $results = tripal_core_chado_select('dbxref', array('dbxref_id'), $dbxvalues, $dbxoptions);
+  // if the accession doesn't exist then add it
+  if(count($results) == 0){
+    $dbxref = tripal_db_add_dbxref($db->db_id, $pub['Pub Accession']);          
+  }
+  else {
+    $dbxref = $results[0];
   }
+  
+  // now add the record
+  $options = array('statement_name' => 'ins_pubdbxref_dbpu');
+  $results = tripal_core_chado_insert('pub_dbxref', $values, $options);
+  if (!$results) {
+    watchdog('tripal_pub', "Cannot add publication dbxref: %db:%accession.",
+      array('%db' => $pub['Publication Database'], '%accession' => $pub['Pub Accession']). WATCHDOG_ERROR);
+    return FALSE;
+  }
+  return $results;
 }
 /*
  * 
@@ -150,50 +189,105 @@ function tripal_pub_add_publication($pub_details) {
    // check to see if the publication already exists
    $pub_id = 0;
    $values = array(
-     'title' => $pub['title'],
-     'pyear' => $pub['pyear'],
+     'title' => $pub_details['Title'],
+     'pyear' => $pub_details['Year'],
    );
-   $options = array('statement_name' => 'pub_tipy');
+   $options = array('statement_name' => 'sel_pub_tipy');
    $results = tripal_core_chado_select('pub', array('*'), $values, $options);
-   
-   // if the publication exists then return the record
-   if(count($results) == 1) {
-      return $results[0];   
+
+   if (count($results) == 1) {
+     $pub_id = $results[0]->pub_id;
    }
-   if(count($results) > 1) {
+   elseif (count($results) > 1) {
      watchdog('tripal_pub', "The publication with the same title is present multiple times. Cannot ".
-       "determine which to use.  Title: %title", array('%title' => $pub_details['title']), WATCHDOG_ERROR);     
+       "determine which to use.  Title: %title", array('%title' => $pub_details['Title']), WATCHDOG_ERROR);     
      return FALSE;          
    }
+   // add the publication if it doens't exist
+   elseif(count($results) == 0) {  
+     // get the publication type (use the first publication type, any others will get stored as properties)
+     $pub_type = tripal_cv_get_cvterm_by_name($pub_details['Publication Type'][0], NULL, 'tripal_pub');
+     if (!$pub_type) {
+       watchdog('tripal_pub', "Cannot find publication type: %type", 
+         array('%type' => $pub_type), WATCHDOG_ERROR);
+       return FALSE;   
+     }
+     // if the publication does not exist then create it.      
+     $values = array(
+       'title' => $pub_details['Title'],
+       'volume' => $pub_details['Volume'],
+       'series_name' => $pub_details['Journal Name'],
+       'issue' => $pub_details['Issue'],
+       'pyear' => $pub_details['Year'],
+       'pages' => $pub_details['Pages'],
+       'uniquename' => $pub_details['Citation'],
+       'type_id' => $pub_type->cvterm_id,
+     );
+
+     $options = array('statement_name' => 'ins_pub_tivoseispypaunty');
+     $pub = tripal_core_chado_insert('pub', $values, $options);     
+     if (!$pub) {
+       watchdog('tripal_pub', "Cannot insert the publication with title: %title", 
+         array('%title' => $pub_details['Title']), WATCHDOG_ERROR);
+       return FALSE;   
+     }
+     $pub_id = $pub['pub_id'];
+   } 
   
-   // if the publication does not exist then create it.      
-   $values = array(
-    'title' => $pub_details['title'],
-    'volume' => $pub_details['volume'],
-    'series_name' => $pub_details['journal_name'],
-    'issue' => $pub_details['issue'],
-    'pyear' => $pub_details['year'],
-    'pages' => $pub_details['pages'],
-    'uniquename' => $pub_details['citation'],
-    'type_id' => array(
-      'name' => 'XXXX',
-      'cv_id' => array(
-        'name' => 'tripal_pub',
-      ),
-    ),     
-  );  
-  $options = array('statment_name' => 'ins_pub_tivoseispypaunty');
-  $pub = tripal_core_chado_insert('pub', $values, $options);
-  if ($pub) {
-    watchdog('tripal_pub', "Cannot insert the publication with title: %title", array('%title' => $pub_details['title']), WATCHDOG_ERROR);
-    return FALSE;   
-  }
- 
-  
-  // now add in any other items that remain as properties of the publication
+  // now add in any other items that remain as properties of the publication  
   foreach ($pub_details as $key => $value) {
-    
+     
+    // get the cvterm by name or synonym
+     $cvterm = tripal_cv_get_cvterm_by_name($key, NULL, 'tripal_pub');
+     if (!$cvterm) {
+       $cvterm = tripal_cv_get_cvterm_by_synonym($key, NULL, 'tripal_pub');
+     }
+     if (!$cvterm) {
+       watchdog('tripal_pub', "Cannot find term: '%prop'. Skipping.", 
+         array('%prop' => $key), WATCHDOG_ERROR);
+       continue;
+     }
+
+     // skip details that won't be stored as properties
+     if ($key == 'Authors') {
+       tripal_pub_add_authors($pub_id, $value);
+       continue;
+     }
+     if ($key == 'Title' or $key == 'Volume' or $key == 'Journal Name' or $key == 'Issue' or
+         $key == 'Year' or $key == 'Pages') {
+       continue;      
+     }
+     
+     $success = 0;
+     if (is_array($value)) {       
+       foreach ($value as $subkey => $subvalue) {
+         // if the key is an integer then this array is a simple list and
+         // we will insert using the primary key. Otheriwse, use the new key 
+         if(is_int($subkey)) {
+           $success = tripal_core_insert_property('pub', $pub_id, $key, 'tripal_pub', $subvalue, TRUE);
+         }
+         else {
+           $success = tripal_core_insert_property('pub', $pub_id, $subkey, 'tripal_pub', $subvalue, TRUE);           
+         }
+       }  
+     }
+     else {
+       $success = tripal_core_insert_property('pub', $pub_id, $key, 'tripal_pub', $value, TRUE);
+     }
+     if (!$success) { 
+       print_r($success); 
+       watchdog('tripal_pub', "Cannot add property '%prop' to publication. Skipping.", 
+         array('%prop' => $key), WATCHDOG_ERROR);
+         continue;
+     }
   }
   
-  return $pub;
+  return $pub_id;
 }
+
+/*
+ * 
+ */
+function tripal_pub_add_authors($pub_id, $authors) {
+  print_r($authors);
+}

+ 1 - 0
tripal_pub/includes/agricoloa.inc

@@ -0,0 +1 @@
+<?php

+ 80 - 0
tripal_pub/includes/pub_sync.inc

@@ -0,0 +1,80 @@
+<?php
+/*
+ * 
+ */
+function tripal_pub_sync_form() {
+
+  $form['sync_all'] = array(
+    '#type' => 'item',
+    '#value' => t('Syncing a publication will create a Drupal page for every publicatoin record in the Chado database. Click the button below to sync all publications in Chado that currently are not already synced with Drupal.'),
+  );
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#weight' => 10,
+    '#value' => t('Sync Publications')
+  );
+
+  return $form;
+}
+
+
+/*
+ * 
+ */
+function tripal_pub_sync_form_submit($form, $form_state) {
+  global $user;    //needed to make the current users details available so access of user id is available
+  $job_args = array();
+  $job_id = tripal_add_job('Sync Publications', 'tripal_pub', 'tripal_pub_sync_pubs', $job_args, $user->uid);
+
+}
+/**
+ *
+ *
+ * @ingroup tripal_pub
+ */
+function tripal_pub_sync_pubs($job_id = NULL) {
+
+  global $user;
+  $page_content = '';
+
+  // get the list of pubs that have not yet been synced
+  // and ignore the default 'NULL' pub. we don't want
+  // to sync that one.
+  $sql = "
+    SELECT P.*
+    FROM chado.pub P
+      LEFT JOIN {chado_pub} CP ON CP.pub_id = P.pub_id
+    WHERE CP.pub_id IS NULL and NOT P.title = 'NULL'
+  ";
+  $results = db_query($sql);
+
+
+  while ($pub = db_fetch_object($results)) {
+
+    $new_node = new stdClass();
+    $new_node->pub_id = $pub->pub_id;
+    $new_node->type = 'chado_pub';
+    $new_node->uid = $user->uid;
+    $new_node->title = $pub->title;
+    $new_node->pyear = $pub->pyear;
+    $new_node->uniquename = $pub->uniquename;
+    $new_node->type_id = $pub->type_id;
+
+    node_validate($new_node);
+    $errors = form_get_errors();
+    if (!$errors) {
+      $node = node_submit($new_node);
+      node_save($node);
+      if ($node->nid) {
+        print "Added " . $pub->pub_id . "\n";
+      }
+      else {
+        print "ERROR: Unable to create " . $pub->name . "\n";
+      }
+    }
+    else {
+      print "ERROR: Unable to create " . $pub->name . "\n" . print_r($errors, TRUE) . "\n";
+    }   
+  }
+}

+ 93 - 80
tripal_pub/includes/pubmed.inc

@@ -44,8 +44,8 @@ function tripal_pub_remote_search_pubmed($search_array, $num_to_retrieve, $pager
   $search_array['search_terms'] = $search_str;
 
   // we want to get the list of pubs using the search terms but using a Drupal style pager
-  $pubs = tripal_pager_callback('tripal_pub_remote_search_pubmed_range',  
-    $num_to_retrieve, $pager_id, 'tripal_pub_remote_search_pubmed_count', $search_array);
+  $pubs = tripal_pager_callback('tripal_pub_pubmed_range',  
+    $num_to_retrieve, $pager_id, 'tripal_pub_pubmed_count', $search_array);
  
   return $pubs;
 }
@@ -55,12 +55,12 @@ function tripal_pub_remote_search_pubmed($search_array, $num_to_retrieve, $pager
  * tripal_pager_callback function.  This function returns a count of
  * the dataset to be paged.
  */
-function tripal_pub_remote_search_pubmed_count($search_array) {
+function tripal_pub_pubmed_count($search_array) {
   $terms = $search_array['search_terms'];
   $days = $search_array['days'];
   $limit = $search_array['limit'];
   
-  $results = tripal_pub_remote_search_pubmed_search_init($terms, $limit, $days);
+  $results = tripal_pub_pubmed_search_init($terms, $limit, $days);
   $_SESSION['tripal_pub_pubmed_query'][$terms]['Count'] = $results['Count'];
   $_SESSION['tripal_pub_pubmed_query'][$terms]['WebEnv'] = $results['WebEnv'];
   $_SESSION['tripal_pub_pubmed_query'][$terms]['QueryKey'] = $results['QueryKey'];
@@ -74,11 +74,13 @@ function tripal_pub_remote_search_pubmed_count($search_array) {
  * tripal_pager_callback function.  This function returns the results
  * within the specified range
  */
-function tripal_pub_remote_search_pubmed_range($search_array, $start = 0, $limit = 10) {
+function tripal_pub_pubmed_range($search_array, $start = 0, $limit = 10) {
   $terms = $search_array['search_terms'];
   $days = $search_array['days'];
   $limit = $search_array['limit'];
   
+  $count = $_SESSION['tripal_pub_pubmed_query'][$terms]['Count'];
+    
   // get the query_key and the web_env from the previous count query.
   $query_key = $_SESSION['tripal_pub_pubmed_query'][$terms]['QueryKey'];
   $web_env = $_SESSION['tripal_pub_pubmed_query'][$terms]['WebEnv'];
@@ -86,7 +88,7 @@ function tripal_pub_remote_search_pubmed_range($search_array, $start = 0, $limit
   // if this function has been called without calling the count function
   // then we need to do the query.
   if (!$query_key) {
-    $results = tripal_pub_remote_search_pubmed_search_init($terms, $limit, $days);
+    $results = tripal_pub_pubmed_search_init($terms, $limit, $days);
     $_SESSION['tripal_pub_pubmed_query']['WebEnv'] = $results['WebEnv'];
     $_SESSION['tripal_pub_pubmed_query']['QueryKey'] = $results['QueryKey']; 
     $query_key =  $results['QueryKey'];
@@ -94,15 +96,15 @@ function tripal_pub_remote_search_pubmed_range($search_array, $start = 0, $limit
   }
 
   // now get the list of PMIDs from the previous search
-  $pmids_txt = tripal_pub_remote_search_pubmed_fetch($query_key, $web_env, 'uilist', 'text', $start, $limit);  
+  $pmids_txt = tripal_pub_pubmed_fetch($query_key, $web_env, 'uilist', 'text', $start, $limit);  
   
   // iterate through each PMID and get the publication record. This requires a new search and new fetch
   $pmids = explode("\n", trim($pmids_txt));
   $pubs = array();
   foreach ($pmids as $pmid) {
     // now retrieve the individual record
-    $pub_xml = tripal_pub_remote_search_pubmed_fetch($query_key, $web_env, 'null', 'xml', 0, 1, array('id' => $pmid));
-    $pub = tripal_pub_remote_search_pubmed_parse_pubxml($pub_xml);
+    $pub_xml = tripal_pub_pubmed_fetch($query_key, $web_env, 'null', 'xml', 0, 1, array('id' => $pmid));
+    $pub = tripal_pub_pubmed_parse_pubxml($pub_xml);
     $pubs[] = $pub;    
   } 
   return $pubs;
@@ -111,7 +113,7 @@ function tripal_pub_remote_search_pubmed_range($search_array, $start = 0, $limit
 /*
  * 
  */
-function tripal_pub_remote_search_pubmed_search_init($terms, $retmax, $days = 0){
+function tripal_pub_pubmed_search_init($terms, $retmax, $days = 0){
    
   // do a search for a single result so that we can establish a history, and get
   // the number of records. Once we have the number of records we can retrieve
@@ -171,7 +173,7 @@ function tripal_pub_remote_search_pubmed_search_init($terms, $retmax, $days = 0)
 /*
  * 
  */
-function tripal_pub_remote_search_pubmed_fetch($query_key, $web_env, $rettype = 'null', 
+function tripal_pub_pubmed_fetch($query_key, $web_env, $rettype = 'null', 
   $retmod = 'null', $start = 0, $limit = 10, $args = array()){
 
   // repeat the search performed previously (using WebEnv & QueryKey) to retrieve
@@ -219,7 +221,7 @@ function tripal_pub_remote_search_pubmed_fetch($query_key, $web_env, $rettype =
  * Information about PubMed's citation format can be found here
  * http://www.nlm.nih.gov/bsd/policy/cit_format.html
  */
-function tripal_pub_remote_search_pubmed_parse_pubxml($pub_xml) {
+function tripal_pub_pubmed_parse_pubxml($pub_xml) {
   $pub = array();
   
   if (!$pub_xml) {
@@ -236,16 +238,16 @@ function tripal_pub_remote_search_pubmed_parse_pubxml($pub_xml) {
       switch ($element) {
         case 'PMID':
           $xml->read(); // get the value for this element
-          $pub['pub_accession'] = $xml->value;
-          $pub['pub_database'] = 'PMID';
+          $pub['Pub Accession'] = $xml->value;
+          $pub['Publication Database'] = 'PMID';
           break;        
         case 'Article':
           $pub_model = $xml->getAttribute('PubModel');
-          $pub['publication_model'] = $pub_model;
-          tripal_pub_remote_search_pubmed_parse_article($xml, $pub);
+          $pub['Publication Model'] = $pub_model;
+          tripal_pub_pubmed_parse_article($xml, $pub);
           break;
         case 'MedlineJournalInfo':
-          tripal_pub_remote_search_pubmed_parse_medline_journal_info($xml, $pub);
+          tripal_pub_pubmed_parse_medline_journal_info($xml, $pub);
           break;
         case 'ChemicalList':
           // TODO: handle this
@@ -294,31 +296,31 @@ function tripal_pub_remote_search_pubmed_parse_pubxml($pub_xml) {
       }
     }
   }
-  $pub['citation'] = $pub['author_list'] . 
-    '. <a href="http://www.ncbi.nlm.nih.gov/pubmed/' . $pub['pub_accession'] . '" target="_blank">' . $pub['title'] .  '</a> ' .
-    $pub['journal_iso_abbreviation']. '. ' . $pub['publication_date'];
-  if ($pub['volume'] or $pub['issue']) {
-    $pub['citation'] .= '; ';  
+  $pub['Citation'] = $pub['Author List'] . 
+    '. <a href="http://www.ncbi.nlm.nih.gov/pubmed/' . $pub['Pub Accession'] . '" target="_blank">' . $pub['Title'] .  '</a> ' .
+    $pub['Journal ISO Abbreviation']. '. ' . $pub['Publication Date'];
+  if ($pub['Volume'] or $pub['Issue']) {
+    $pub['Citation'] .= '; ';  
   }
-  if ($pub['volume']) {
-    $pub['citation'] .= $pub['volume'];
+  if ($pub['Volume']) {
+    $pub['Citation'] .= $pub['Volume'];
   }
-  if ($pub['issue']) {
-    $pub['citation'] .= '(' . $pub['issue'] . ')';
+  if ($pub['Issue']) {
+    $pub['Citation'] .= '(' . $pub['Issue'] . ')';
   }
-  if ($pub['pages']) {
-    $pub['citation'] .= ':' . $pub['pages'];
+  if ($pub['Pages']) {
+    $pub['Citation'] .= ':' . $pub['Pages'];
   }
-  $pub['citation'] .= '. PubMed PMID: ' . $pub['pub_accession']; 
+  $pub['Citation'] .= '. PubMed PMID: ' . $pub['Pub Accession']; 
   
-  $pub['xml'] = $pub_xml;
+  //$pub['xml'] = $pub_xml;
   return $pub;
 }
 
 /*
  * 
  */
-function tripal_pub_remote_search_pubmed_parse_medline_journal_info($xml, &$pub) {
+function tripal_pub_pubmed_parse_medline_journal_info($xml, &$pub) {
   while ($xml->read()) {
     // get this element name
     $element = $xml->name;     
@@ -332,7 +334,7 @@ function tripal_pub_remote_search_pubmed_parse_medline_journal_info($xml, &$pub)
         case 'Country':
           // the place of publication of the journal
           $xml->read();
-          $pub['journal_country'] = $xml->value;
+          $pub['Journal Country'] = $xml->value;
           break;
         case 'MedlineTA':
           // TODO: not sure how this is different from ISOAbbreviation
@@ -353,7 +355,7 @@ function tripal_pub_remote_search_pubmed_parse_medline_journal_info($xml, &$pub)
 /*
  * 
  */
-function tripal_pub_remote_search_pubmed_parse_article($xml, &$pub) {
+function tripal_pub_pubmed_parse_article($xml, &$pub) {
     
   while ($xml->read()) {
     // get this element name
@@ -366,17 +368,17 @@ function tripal_pub_remote_search_pubmed_parse_article($xml, &$pub) {
     if ($xml->nodeType == XMLReader::ELEMENT) {    
       switch ($element) {
         case 'Journal':
-          tripal_pub_remote_search_pubmed_parse_journal($xml, $pub);
+          tripal_pub_pubmed_parse_journal($xml, $pub);
           break;
         case 'ArticleTitle':
           $xml->read();
-          $pub['title'] = $xml->value;
+          $pub['Title'] = $xml->value;
           break;
         case 'Abstract':
-          tripal_pub_remote_search_pubmed_parse_abstract($xml, $pub);
+          tripal_pub_pubmed_parse_abstract($xml, $pub);
           break;
         case 'Pagination':
-          tripal_pub_remote_search_pubmed_parse_pagination($xml, $pub);
+          tripal_pub_pubmed_parse_pagination($xml, $pub);
           break;  
         case 'ELocationID':
           $type = $xml->getAttribute('EIdType');
@@ -389,16 +391,16 @@ function tripal_pub_remote_search_pubmed_parse_article($xml, &$pub) {
           if ($type == 'pii' and $valid == 'Y') {
             $pub['PII'] = $elocation;
           }
-          $pub['elocation'] = $elocation;
+          $pub['Elocation'] = $elocation;
           break;        
         case 'Affiliation':
           // the affiliation tag at this level is meant solely for the first author
           $xml->read();
-          $pub['authors'][0]['affiliation'] = $xml->value;
+          $pub['Authors'][0]['Affiliation'] = $xml->value;
           break;
         case 'AuthorList':
           $complete = $xml->getAttribute('CompleteYN');
-          tripal_pub_remote_search_pubmed_parse_authorlist($xml, $pub);
+          tripal_pub_pubmed_parse_authorlist($xml, $pub);
           break;
         case 'InvestigatorList':
           // TODO: perhaps handle this one day.  The investigator list is to list the names of people who 
@@ -408,8 +410,8 @@ function tripal_pub_remote_search_pubmed_parse_article($xml, &$pub) {
           $xml->read();
           $lang_abbr = $xml->value;
           // there may be multiple languages so we store these in an array
-          $pub['language'][] = tripal_pub_remote_search_get_language($lang_abbr);
-          $pub['language_abbr'][] = $lang_abbr;
+          $pub['Language'][] = tripal_pub_remote_search_get_language($lang_abbr);
+          $pub['Language Abbr'][] = $lang_abbr;
           break;
         case 'DataBankList':
           // TODO: handle this case
@@ -418,11 +420,11 @@ function tripal_pub_remote_search_pubmed_parse_article($xml, &$pub) {
           // TODO: handle this case
           break;
         case 'PublicationTypeList':
-          tripal_pub_remote_search_pubmed_parse_publication_type($xml, $pub);
+          tripal_pub_pubmed_parse_publication_type($xml, $pub);
           break;
         case 'VernacularTitle':
           $xml->read();
-          $pub['vernacular_title'][] = $xml->value;;
+          $pub['Vernacular Title'][] = $xml->value;
           break;
         case 'ArticleDate': 
           // TODO: figure out what to do with this element. We already have the
@@ -442,7 +444,7 @@ function tripal_pub_remote_search_pubmed_parse_article($xml, &$pub) {
  * The Tripal Pub ontology doesn't yet have terms for all of the 
  * publication types so we store the value in the 'publication_type' term.
  */
-function tripal_pub_remote_search_pubmed_parse_publication_type($xml, &$pub) {
+function tripal_pub_pubmed_parse_publication_type($xml, &$pub) {
   
   while ($xml->read()) {
     $element = $xml->name;    
@@ -454,8 +456,19 @@ function tripal_pub_remote_search_pubmed_parse_publication_type($xml, &$pub) {
     if ($xml->nodeType == XMLReader::ELEMENT) {
       switch ($element) {
         case 'PublicationType':  
-          $xml->read();          
-          $pub['publication_type'][] = $xml->value;
+          $xml->read();
+          $pub_cvterm = tripal_cv_get_cvterm_by_name($xml->value, NULL, 'tripal_pub');
+          if (!$pub_cvterm) {
+            // see if this we can find the name using a synonym
+            $pub_cvterm = tripal_cv_get_cvterm_by_synonym($xml->value, NULL, 'tripal_pub');
+            if (!$pub_cvterm) {
+              watchdog('tpub_pubmed', 'Cannot find a valid vocabulary term for the publication type: "%term".', 
+                array('%term' => $xml->value), WATCHDOG_ERROR);
+            }
+          }
+          else {
+            $pub['Publication Type'][] = $pub_cvterm->name;
+          }            
           break;          
         default:
           break;
@@ -466,7 +479,7 @@ function tripal_pub_remote_search_pubmed_parse_publication_type($xml, &$pub) {
 /*
  * 
  */
-function tripal_pub_remote_search_pubmed_parse_abstract($xml, &$pub) {
+function tripal_pub_pubmed_parse_abstract($xml, &$pub) {
   $abstract = '';
   
   while ($xml->read()) {
@@ -474,7 +487,7 @@ function tripal_pub_remote_search_pubmed_parse_abstract($xml, &$pub) {
       
     if ($xml->nodeType == XMLReader::END_ELEMENT and $element == 'Abstract') {
       // we've reached the </Abstract> element so return   
-      $pub['abstract'] = $abstract;        
+      $pub['Abstract'] = $abstract;        
       return;
     }
     // the abstract text can be just a singe paragraph or be broken into multiple
@@ -486,7 +499,7 @@ function tripal_pub_remote_search_pubmed_parse_abstract($xml, &$pub) {
           $label = $xml->getAttribute('Label');
           $xml->read();
           if ($label) {
-            $pub['structured_abstract_part'][][$label] = $xml->value;
+            $pub['Structured Abstract Part'][] = $xml->value;
             $abstract .= "<p><b>$label</b></br>" . $xml->value . '</p>';
           }
           else {
@@ -495,7 +508,7 @@ function tripal_pub_remote_search_pubmed_parse_abstract($xml, &$pub) {
           break;
         case 'CopyrightInformation':
           $xml->read();
-          $pub['copyright'] = $xml->value;
+          $pub['Copyright'] = $xml->value;
           break;          
         default:
           break;
@@ -506,7 +519,7 @@ function tripal_pub_remote_search_pubmed_parse_abstract($xml, &$pub) {
 /*
  * 
  */
-function tripal_pub_remote_search_pubmed_parse_pagination($xml, &$pub) {
+function tripal_pub_pubmed_parse_pagination($xml, &$pub) {
   while ($xml->read()) {
     $element = $xml->name;
       
@@ -519,7 +532,7 @@ function tripal_pub_remote_search_pubmed_parse_pagination($xml, &$pub) {
         case 'MedlinePgn':  
           $xml->read();
           if(trim($xml->value)) {
-            $pub['pages'] = $xml->value;
+            $pub['Pages'] = $xml->value;
           }
           break;          
         default:
@@ -531,7 +544,7 @@ function tripal_pub_remote_search_pubmed_parse_pagination($xml, &$pub) {
 /*
  * 
  */
-function tripal_pub_remote_search_pubmed_parse_journal($xml, &$pub) {
+function tripal_pub_pubmed_parse_journal($xml, &$pub) {
   
   while ($xml->read()) {
     $element = $xml->name;
@@ -556,15 +569,15 @@ function tripal_pub_remote_search_pubmed_parse_journal($xml, &$pub) {
         case 'JournalIssue':   
           // valid values of cited_medium are 'Internet' and 'Print'
           $cited_medium = $xml->getAttribute('CitedMedium');                    
-          tripal_pub_remote_search_pubmed_parse_journal_issue($xml, $pub);       
+          tripal_pub_pubmed_parse_journal_issue($xml, $pub);       
           break;        
         case 'Title': 
           $xml->read();
-          $pub['journal_name'] = $xml->value;          
+          $pub['Journal Name'] = $xml->value;          
           break;
         case 'ISOAbbreviation': 
           $xml->read();
-          $pub['journal_iso_abbreviation'] = $xml->value;         
+          $pub['Journal ISO Abbreviation'] = $xml->value;         
           break;
         default:
           break;
@@ -575,7 +588,7 @@ function tripal_pub_remote_search_pubmed_parse_journal($xml, &$pub) {
 /*
  * 
  */
-function tripal_pub_remote_search_pubmed_parse_journal_issue($xml, &$pub) {
+function tripal_pub_pubmed_parse_journal_issue($xml, &$pub) {
   
   while ($xml->read()) {
     $element = $xml->name;
@@ -588,34 +601,34 @@ function tripal_pub_remote_search_pubmed_parse_journal_issue($xml, &$pub) {
       switch ($element) {
         case 'Volume': 
           $xml->read();
-          $pub['volume'] = $xml->value;         
+          $pub['Volume'] = $xml->value;         
           break;
         case 'Issue':
           $xml->read();
-          $pub['issue'] = $xml->value;           
+          $pub['Issue'] = $xml->value;           
           break;
         case 'PubDate':
-          $date = tripal_pub_remote_search_pubmed_parse_date($xml, 'PubDate');
+          $date = tripal_pub_pubmed_parse_date($xml, 'PubDate');
           $year = $date['year'];
           $month = $date['month'];
           $day = $date['day']; 
           $medline = $date['medline'];
            
-          $pub['year'] = $year;            
+          $pub['Year'] = $year;            
           if ($month and $day and $year) {
-            $pub['publication_date'] = "$year $month $day";
+            $pub['Publication Date'] = "$year $month $day";
           }
           elseif ($month and !$day and $year) {
-            $pub['publication_date'] = "$year $month";
+            $pub['Publication Date'] = "$year $month";
           }
           elseif (!$month and !$day and $year) {
-            $pub['publication_date'] = $year;
+            $pub['Publication Date'] = $year;
           } 
           elseif ($medline) {
-            $pub['publication_date'] = $medline;
+            $pub['Publication Date'] = $medline;
           }
           else {
-            $pub['publication_date'] = "Date Unknown";
+            $pub['Publication Date'] = "Date Unknown";
           }             
           break;
         default:
@@ -628,7 +641,7 @@ function tripal_pub_remote_search_pubmed_parse_journal_issue($xml, &$pub) {
 /*
  * 
  */
-function tripal_pub_remote_search_pubmed_parse_date ($xml, $element_name) {
+function tripal_pub_pubmed_parse_date ($xml, $element_name) {
   $date = array();
   
   while ($xml->read()) {
@@ -667,7 +680,7 @@ function tripal_pub_remote_search_pubmed_parse_date ($xml, $element_name) {
 /*
  * 
  */
-function tripal_pub_remote_search_pubmed_parse_authorlist($xml, &$pub) {
+function tripal_pub_pubmed_parse_authorlist($xml, &$pub) {
   $num_authors = 0;
   
   while ($xml->read()) {
@@ -678,21 +691,21 @@ function tripal_pub_remote_search_pubmed_parse_authorlist($xml, &$pub) {
       if($element == 'AuthorList') {
         // build the author list before returning
         $author_list = '';
-        foreach ($pub['authors'] as $author) {
+        foreach ($pub['Authors'] as $author) {
           if ($author['valid'] == 'N') {
             // skip non-valid entries.  A non-valid entry should have 
             // a corresponding corrected entry so we can saftely skip it.
             continue;
           }
-          if ($author['collective']) {
-            $author_list .= $author['collective'] . ', ';
+          if ($author['Collective']) {
+            $author_list .= $author['Collective'] . ', ';
           }
           else {
-            $author_list .= $author['surname'] . ' ' . $author['first_initials'] . ', '; 
+            $author_list .= $author['Surname'] . ' ' . $author['First Initials'] . ', '; 
           }             
         }
         $author_list = substr($author_list, 0, -2);
-        $pub['author_list'] = $author_list;
+        $pub['Author List'] = $author_list;
         return;
       }
       // if we're at the end </Author> element then we're done with the author and we can
@@ -705,27 +718,27 @@ function tripal_pub_remote_search_pubmed_parse_authorlist($xml, &$pub) {
       switch ($element) {
         case 'Author':
           $valid = $xml->getAttribute('ValidYN');
-          $pub['authors'][$num_authors]['valid'] = $valid;          
+          $pub['Authors'][$num_authors]['valid'] = $valid;          
           break;
         case 'LastName':  
           $xml->read(); 
-          $pub['authors'][$num_authors]['surname'] = $xml->value;         
+          $pub['Authors'][$num_authors]['Surname'] = $xml->value;         
           break;
         case 'ForeName': 
           $xml->read(); 
-          $pub['authors'][$num_authors]['given_name'] = $xml->value;          
+          $pub['Authors'][$num_authors]['Given Name'] = $xml->value;          
           break;
         case 'Initials': 
           $xml->read(); 
-          $pub['authors'][$num_authors]['first_initials'] = $xml->value;          
+          $pub['Authors'][$num_authors]['First Initials'] = $xml->value;          
           break;
         case 'Suffix': 
           $xml->read(); 
-          $pub['authors'][$num_authors]['suffix'] = $xml->value;          
+          $pub['Authors'][$num_authors]['Suffix'] = $xml->value;          
           break;
         case 'CollectiveName': 
           $xml->read(); 
-          $pub['authors'][$num_authors]['collective'] = $xml->value;          
+          $pub['Authors'][$num_authors]['Collective'] = $xml->value;          
           break;
         case 'Identifier': 
           // according to the specification, this element is not yet used.                  

+ 0 - 312
tripal_pub/includes/remote_search.inc

@@ -1,312 +0,0 @@
-<?php
-
-/*
- * 
- */
-function tripal_pub_remote_search_page() {
-  global $pager_total, $pager_total_items;
-  
-  $pager_id = 0;
-  $limit = 10;
-  
-  // generate the search form 
-  $form = drupal_get_form('tripal_pub_remote_search_form');
-  $output = $form;
-
-  // retrieve any results
-  $remote_db = $_SESSION['tripal_pub_search']['remote_db'];
-  $num_criteria = $_SESSION['tripal_pub_search']['num_criteria'];
-  $days = $_SESSION['tripal_pub_search']['days'];
- 
-  $search_array = array();
-  $search_array['remote_db'] = $remote_db;
-  $search_array['num_criteria'] = $num_criteria;
-  $search_array['days'] = $days; 
-  for ($i = 0; $i <= $num_criteria; $i++) {
-    $search_array['criteria'][$i]['search_terms'] = $_SESSION['tripal_pub_search']['criteria'][$i]['search_terms'];
-    $search_array['criteria'][$i]['scope'] = $_SESSION['tripal_pub_search']['criteria'][$i]['scope'];  
-    $search_array['criteria'][$i]['operation'] = $_SESSION['tripal_pub_search']['criteria'][$i]['operation'];
-  }
-  
-    
-  if ($_SESSION['tripal_pub_search']['perform_search']) {
-    // get the list of publications from the remote database using the search criteria.  
-    $pubs = tripal_pub_get_remote_search_results($remote_db, $search_array, $limit, $pager_id);
-  
-    // generate the pager
-    $total_pages = $pager_total[$pager_id];
-    $total_items = $pager_total_items[$pager_id];
-    $page = isset($_GET['page']) ? $_GET['page'] : '0';
-    $pager = theme('pager');
-    
-    // iterate through the results and construct the table displaying the publications
-    $rows = array();
-    $i = $page * $limit + 1;
-    if (count($pubs) > 0) {
-      foreach ($pubs as $pub) {
-        $rows[] = array(number_format($i), $pub['citation']);
-        $i++;
-      }
-    }
-    $headers = array('', 'Citation');
-    $table = theme('table', $headers, $rows);   
-  
-    // join all to form the results
-    $output .= "<br><p><b>Found " . number_format($total_items) .  
-      ". Page " . ($page + 1) . " of $total_pages. " .
-      " Results</b></br>" . $table . '</p>' . $pager;    
-  }
-  return $output;
-}
-/*
- * 
- */
-function theme_tripal_pub_remote_search_form($form) {
-  $rows = array();
-  foreach ($form['criteria'] as $i => $element) {
-    if(is_numeric($i)) {
-      $rows[] = array(  
-        array('data' => drupal_render($element["operation-$i"]), 'width' => '10%'),    
-        array('data' => drupal_render($element["scope-$i"]), 'width' => '10%'),
-        drupal_render($element["search_terms-$i"]),
-        array('data' => drupal_render($element["add-$i"]) . drupal_render($element["remove-$i"]), 'width' => '5%'),
-      );
-    }
-  } 
-  $headers = array('Operation','Scope', 'Search Terms', '');
-  
-  $markup  = '<div id="pub-search-form-row1">';
-  $markup .= '  <div id="pub-search-form-col1">' . drupal_render($form['loader_name']) . '</div>';
-  $markup .= '  <div id="pub-search-form-col2">' . drupal_render($form['remote_db']) . '</div>';
-  $markup .= '  <div id="pub-search-form-col3">' . drupal_render($form['days']) . '</div>';
-  $markup .= '</div>';
-  $markup .= theme('table', $headers, $rows);
-  
-  $form['criteria'] = array(
-    '#type' => 'markup',
-    '#value' =>  $markup,
-    '#weight' => -10,
-  );
-  return drupal_render($form);
-}
-/**
- * Purpose: Provides the form to search pubmed
- *
-  * @ingroup tripal_pub
- */
-function tripal_pub_remote_search_form(&$form_state = NULL) {
-  tripal_core_ahah_init_form();
-
-  // set default values.  First use what is in the form_state['values'] array. If nothing there then use the session variable.
-  $remote_db = $form_state['values']['remote_db'] ? $form_state['values']['remote_db'] : $_SESSION['tripal_pub_search']['remote_db'];
-  $days = $form_state['values']['days'] ? $form_state['values']['days'] : $_SESSION['tripal_pub_search']['days']; 
-  $num_criteria = $form_state['values']['num_criteria'] ? $form_state['values']['num_criteria'] : $_SESSION['tripal_pub_search']['num_criteria'];
-  $loader_name = $form_state['values']['loader_name'] ? $form_state['values']['loader_name'] : $_SESSION['tripal_pub_search']['loader_name'];
-  
-  // change the number of criteria based on form_state post data.
-  if (!$num_criteria) {
-    $num_criteria = 0;
-  }
-  if($form_state['post']["add-$num_criteria"]) {    
-    $num_criteria++;
-  }
-  if($form_state['post']["remove-$num_criteria"]) {    
-    $num_criteria--;
-  }
-  
-  $form['loader_name'] = array(
-    '#type'          => 'textfield',
-    '#title'         => t('Loader Name'),
-    '#description'   => t('Please provide a name for this loader setup..'),
-    '#default_value' => $loader_name,
-    '#required'      => TRUE,
-  );
-   
-  $remote_dbs = array('Pubmed' => 'Pubmed');
-  $form['remote_db'] = array(
-    '#title' => t('Remote Database'),
-    '#type' => 'select',
-    '#options' => $remote_dbs,
-    '#default_value' => $remote_db,
-  );
-
-  $form['num_criteria']= array(
-    '#type'          => 'hidden',
-    '#default_value' => $num_criteria,
-  );
-  
-  $form['days'] = array(
-    '#type'          => 'textfield',
-    '#title'         => t('Days'),
-    '#description'   => t('The number of days <br>from today to search.'),
-    '#default_value' => $days,
-    '#size'          => 5,
-  );
-  
-  for($i = 0; $i <= $num_criteria; $i++) {
-    $search_terms = $form_state['values']["search_terms-$i"] ? $form_state['values']["search_terms-$i"] : $_SESSION['tripal_pub_search']['criteria'][$i]['search_terms'];
-    $scope = $form_state['values']["scope-$i"] ? $form_state['values']["scope-$i"] : $_SESSION['tripal_pub_search']['criteria'][$i]['scope'];
-    $operation = $form_state['values']["operation-$i"] ? $form_state['values']["operation-$i"] : $_SESSION['tripal_pub_search']['criteria'][$i]['operation'];
-    
-    // default to searching the title and abstract
-    if (!$scope) {
-      $scope = 'abstract';
-    }
-  
-    $form['criteria'][$i]["search_terms-$i"] = array(
-      '#type'          => 'textfield',
-      '#description'   => t('Please provide a list of words, separated by spaces for searching.'),
-      '#default_value' => $search_terms,
-      '#required'      => TRUE,
-    );
-    $form['criteria'][$i]["scope-$i"] = array(
-      '#type'          => 'select',
-      '#description'   => t('Please select the fields to search for this term.'),
-      '#options'       => array(
-        'any'      => 'Any Field',
-        'title'    => 'Title',
-        'abstract' => 'Title/Abstract',
-        'author'   => 'Author'),
-      '#default_value' => $scope,
-    );    
-    
-    if ($i > 0) {
-      $form['criteria'][$i]["operation-$i"] = array(
-        '#type'          => 'select',
-        '#options'       => array(
-          'AND' => 'AND',
-          'OR'  => 'OR',
-          'NOT' => 'NOT'),
-        '#default_value' => $operation,
-      );
-    }
-    if ($i == $num_criteria) {    
-      if($i > 0) {
-        $form['criteria'][$i]["remove-$i"] = array(
-          '#type'         => 'image_button',
-          '#value'        => t('Remove'),
-          '#src'          => drupal_get_path('theme', 'tripal') . '/images/minus.png',
-          '#ahah' => array(
-            'path'    => "admin/tripal/tripal_pub/import_setup/criteria/minus/$i",
-            'wrapper' => 'tripal-pub-remote-search-form',
-            'event'   => 'click',
-            'method'  => 'replace',
-          ), 
-          '#attributes' => array('onClick' => 'return false;'),
-        );
-      }
-      $form['criteria'][$i]["add-$i"] = array(
-        '#type'         => 'image_button',      
-        '#value'        => t('Add'),
-        '#src'          => drupal_get_path('theme', 'tripal') . '/images/add.png',
-        '#ahah' => array(
-          'path'    => "admin/tripal/tripal_pub/import_setup/criteria/add/$i",
-          'wrapper' => 'tripal-pub-remote-search-form',
-          'event'   => 'click',
-          'method'  => 'replace',          
-        ),   
-        '#attributes' => array('onClick' => 'return false;'),
-      );
-    }
-  }
-  
-  $form['test'] = array(
-    '#type'         => 'submit',
-    '#value'        => t('Test Criteria'),
-  );
-  $form['save'] = array(
-    '#type'         => 'submit',
-    '#value'        => t('Save Criteria'),
-  );
-
-  return $form;
-}
-
-/**
- *
- */
-function tripal_pub_remote_search_form_validate($form, &$form_state) {
-  $num_criteria = $form_state['values']['num_criteria'];
-  $remote_db =  $form_state['values']["remote_db"];
-  $days =  trim($form_state['values']["days"]);
-  $loader_name =  trim($form_state['values']["loader_name"]);
-
-  for ($i = 0; $i <= $num_criteria; $i++) {            
-    $search_terms =  trim($form_state['values']["search_terms-$i"]);
-    $scope =  $form_state['values']["scope-$i"];
-    $operation =  $form_state['values']["operation-$i"];
-    
-    if ($days and !is_numeric($days) or preg_match('/\./', $days)) {
-      form_set_error("days-$i", "Please enter a numeric, non decimal value, for the number of days.");
-    }
-  }
-}
-
-/**
- *
- */
-function tripal_pub_remote_search_form_submit($form, &$form_state) {
-   
-  $num_criteria = $form_state['values']['num_criteria'];
-  $remote_db =  $form_state['values']["remote_db"];
-  $days =  trim($form_state['values']["days"]);
-  $loader_name =  trim($form_state['values']["loader_name"]);
-    
-  $_SESSION['tripal_pub_search']['remote_db'] = $remote_db;
-  $_SESSION['tripal_pub_search']['days'] = $days;
-  $_SESSION['tripal_pub_search']['num_criteria'] = $num_criteria;
-  $_SESSION['tripal_pub_search']['loader_name'] = $loader_name;
-  unset($_SESSION['tripal_pub_search']['criteria']);
-  for ($i = 0; $i <= $num_criteria; $i++) {
-    $search_terms =  trim($form_state['values']["search_terms-$i"]);
-    $scope =  $form_state['values']["scope-$i"];
-    $operation =  $form_state['values']["operation-$i"];
-    
-    $_SESSION['tripal_pub_search']['criteria'][$i] = array(
-      'search_terms' => $search_terms,
-      'scope' => $scope,
-      'operation' => $operation
-    );
-  }   
-
-  if ($form_state['values']['op'] == 'Test Criteria') {
-    $_SESSION['tripal_pub_search']['perform_search'] = 1;
-  }
-  if ($form_state['values']['op'] == 'Save Criteria') {
-    unset($_SESSION['tripal_pub_search']['perform_search']);
-    $record = array(
-      'name' => $loader_name,
-      'criteria' => serialize($_SESSION['tripal_pub_search']),
-    );
-    if(drupal_write_record('tripal_pub_import', $record)){
-      drupal_set_message('Publication import settings saved');
-    }
-    else {
-      drupal_set_message('Could not save publication import settings', 'error');
-    }
-  }  
-}
-
-/*
- * AHAH callback
- */
-function tripal_pub_remote_search_page_update_criteria($action, $i) {
-  $status = TRUE;
-
-  // prepare and render the form
-  $form = tripal_core_ahah_prepare_form();   
-  $data = theme('tripal_pub_remote_search_form', $form);  
-
-  // bind javascript events to the new objects that will be returned 
-  // so that AHAH enabled elements will work.
-  $settings = tripal_core_ahah_bind_events();
-
-  // return the updated JSON
-  drupal_json(
-    array(
-      'status'   => $status, 
-      'data'     => $data,
-      'settings' => $settings,
-    )  
-  );
-}

+ 442 - 86
tripal_pub/includes/tripal_pub.admin.inc

@@ -1,119 +1,475 @@
 <?php
+
 /**
- * Implementation of tripal_pub_form().
- *
- *  This form takes the following information:A Publication Title,Volume title,Volume,Series Name,
- *  Issue,Publication Year,Pages where the Article is located, Miniref,Type-Id, if the article is Obsolete,
- *  Publishing company,Pubplication Place and a Uniquename for the the instance. It then puts the
- *  infromation into the Chado_project database table based on its 'pub_id'.
- *
- *
- *  @return $form
- *    An array of menu items '$form'
+ * A function to render a listing of all publication importers
  *
+ * @ingroup tripal_pub
  */
-function tripal_pub_configuration_form() {
+function tripal_pub_importers_list() {
+  $header = array('', 'Importer Name', 'Database', 'Search String', 'Disabled', '');
+  $rows = array();
+  $importers = db_query("SELECT * FROM {tripal_pub_import} ORDER BY name");    
 
-  $cv_options = tripal_cv_get_cv_options();
+  while ($importer = db_fetch_object($importers)) {
+    $criteria = unserialize($importer->criteria);
+    $num_criteria = $criteria['num_criteria'];
+    $criteria_str = '';
+    for ($i = 0; $i <= $num_criteria; $i++) {
+      $search_terms = $criteria['criteria'][$i]['search_terms'];
+      $scope = $criteria['criteria'][$i]['scope'];
+      $operation = $criteria['criteria'][$i]['operation'];
+      $criteria_str .= "$operation ($scope: $search_terms) ";
+    }
+ 
+    $rows[] = array(
+      l(t('Edit/Test'), "admin/tripal/tripal_pub/import/edit/$importer->pub_import_id"),
+      $importer->name,
+      $criteria['remote_db'],
+      $criteria_str,
+      $importer->disabled ? 'Yes' : 'No',
+      l(t('Delete'), "admin/tripal/tripal_pub/import/delete/$importer->pub_import_id"),
+    );
+  }
 
-  //Creating Fieldset for multiple fields in form
-  $form['node_form'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Create/Edit Publication Settings'),
+  $rows[] = array(
+    'data' => array(
+      array('data' => l(t('Create a new publication importer.'), "admin/tripal/tripal_pub/import/new"),
+        'colspan' => 6),
+    )
   );
 
-  $form['node_form']['tripal_pub_types_cv'] = array(
-    '#type' => 'select',
-    '#title' => t('Controlled Vocabularies'),
-    '#options' => $cv_options,
-    '#default_value' => variable_get('tripal_pub_types_cv', 0),
-    '#description' => 'Set the controlled vocabulary to pull publication type options from. Terms in this vocabulary will be available is the Publication Type select box on both the create and edit pages.',
-  );
+  $page = theme('table', $header, $rows);
+  return $page;
+}
 
-  $form['pubmed'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Create Nodes via PubMed Search'),
-  );
+/*
+ * 
+ */
+function tripal_pub_importer_setup($action = 'new', $pub_import_id = NULL) {
+  global $pager_total, $pager_total_items;
+  
+  $pager_id = 0;
+  $limit = 10;
+  
+  // 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/tripal_pub/import_list");
+  $output .= $form;
 
-  $form['pubmed']['description'] = array(
-    '#type' => 'item',
-    '#value' => 'Publication nodes are created based on the results of a PubMed publication search using '
-      .'the keywords entered below. No content is created until the sync is clicked below and the registered tripal job is '
-      .'run. This script attempts to only load new publications (ones which don\'t already have nodes from a previous search) '
-      .'by comparing the pub_id thus if a publication is added manually which also appears in the pubmed search it will likely '
-      .'get added twice.'
+  // retrieve any results
+  $remote_db = $_SESSION['tripal_pub_search']['remote_db'];
+  $num_criteria = $_SESSION['tripal_pub_search']['num_criteria'];
+  $days = $_SESSION['tripal_pub_search']['days'];
+ 
+  $search_array = array();
+  $search_array['remote_db'] = $remote_db;
+  $search_array['num_criteria'] = $num_criteria;
+  $search_array['days'] = $days; 
+  for ($i = 0; $i <= $num_criteria; $i++) {
+    $search_array['criteria'][$i]['search_terms'] = $_SESSION['tripal_pub_search']['criteria'][$i]['search_terms'];
+    $search_array['criteria'][$i]['scope'] = $_SESSION['tripal_pub_search']['criteria'][$i]['scope'];  
+    $search_array['criteria'][$i]['operation'] = $_SESSION['tripal_pub_search']['criteria'][$i]['operation'];
+  }
+  
+    
+  if ($_SESSION['tripal_pub_search']['perform_search']) {
+    // get the list of publications from the remote database using the search criteria.  
+    $pubs = tripal_pub_get_remote_search_results($remote_db, $search_array, $limit, $pager_id);
+  
+    // generate the pager
+    $total_pages = $pager_total[$pager_id];
+    $total_items = $pager_total_items[$pager_id];
+    $page = isset($_GET['page']) ? $_GET['page'] : '0';
+    $pager = theme('pager');
+    
+    // iterate through the results and construct the table displaying the publications
+    $rows = array();
+    $i = $page * $limit + 1;
+    if (count($pubs) > 0) {
+      foreach ($pubs as $pub) {
+        $rows[] = array(number_format($i), $pub['citation']);
+        $i++;
+      }
+    }
+    $headers = array('', 'Citation');
+    $table = theme('table', $headers, $rows);   
+  
+    // join all to form the results
+    $output .= "<br><p><b>Found " . number_format($total_items) .  
+      ". Page " . ($page + 1) . " of $total_pages. " .
+      " Results</b></br>" . $table . '</p>' . $pager;    
+  }
+  return $output;
+}
+/*
+ * 
+ */
+function theme_tripal_pub_importer_setup_form($form) {
+  $rows = array();
+  foreach ($form['criteria'] as $i => $element) {
+    if(is_numeric($i)) {
+      $rows[] = array(  
+        array('data' => drupal_render($element["operation-$i"]), 'width' => '10%'),    
+        array('data' => drupal_render($element["scope-$i"]), 'width' => '10%'),
+        drupal_render($element["search_terms-$i"]),
+        array('data' => drupal_render($element["add-$i"]) . drupal_render($element["remove-$i"]), 'width' => '5%'),
+      );
+    }
+  } 
+  $headers = array('Operation','Scope', 'Search Terms', '');
+  
+  $markup  = '<div id="pub-search-form-row1">';
+  $markup .= '  <div id="pub-search-form-col1">' . drupal_render($form['loader_name']) . '</div>';
+  $markup .= '  <div id="pub-search-form-col2">' . drupal_render($form['remote_db']) . '</div>';
+  $markup .= '  <div id="pub-search-form-col3">' . drupal_render($form['days']) . '</div>';
+  $markup .= '  <div id="pub-search-form-col4">' . drupal_render($form['disabled']) . '</div>';
+  $markup .= '</div>';
+  $markup .= theme('table', $headers, $rows);
+  
+  $form['criteria'] = array(
+    '#type' => 'markup',
+    '#value' =>  $markup,
+    '#weight' => -10,
   );
+  return drupal_render($form);
+}
+/**
+ * Purpose: Provides the form to search pubmed
+ *
+  * @ingroup tripal_pub
+ */
+function tripal_pub_importer_setup_form(&$form_state = NULL, $import_id = NULL, $action = 'new') {
+  tripal_core_ahah_init_form();
 
-  //define form elements for the node's title and body.
-  $form['pubmed']['unique_name'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Search Keywords'),
-    '#description' => t('Specific search terms. Must be seperated by a single space.'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('unique_name', NULL)
-  );
+  
+  // Set the default values. If the pub_import_id isn't already defined by the form values 
+  // and one is provided then look it up in the database
+  $criteria = NULL;
+  if ($action == "edit" and !$form_state['values']) {
+    $pub_import_id = $form_state['values']['$pub_import_id'];    
+    $sql = "SELECT * FROM {tripal_pub_import} WHERE pub_import_id = %d";
+    $importer = db_fetch_object(db_query($sql, $import_id));
+    
+    $criteria     = unserialize($importer->criteria);
+    $remote_db    = $criteria['remote_db'];
+    $days         = $criteria['days'];
+    $disabled     = $criteria['disabled'];
+    $num_criteria = $criteria['num_criteria'];    
+    $loader_name  = $criteria['loader_name'];  
+  }
 
-  //define form elements for the node's title and body.
-  /**
-  $form['set']['time_interval'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Time Search Interval (Minutes)'),
-    '#description'=>t(' The “Search Interval” set here determines when a drupal cron job should
-    schedule a tripal job. As such, in reality the time until publications are sync’d is “Search Interval”
-    + time remaining until drupal cron is run + time between drupal cron run and next tripal jobs run'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('time_interval', NULL)
+  // if the session has variables then use those.  This should only happen when
+  // the 'Test Criteria' button is clicked.
+  $num_criteria = $_SESSION['tripal_pub_search']['num_criteria'] ? $_SESSION['tripal_pub_search']['num_criteria'] : $num_criteria;    
+  $loader_name  = $_SESSION['tripal_pub_search']['loader_name']  ? $_SESSION['tripal_pub_search']['loader_name']  : $loader_name;
+  $remote_db    = $_SESSION['tripal_pub_search']['remote_db']    ? $_SESSION['tripal_pub_search']['remote_db']    : $remote_db;
+  $disabled     = $_SESSION['tripal_pub_search']['disabled']     ? $_SESSION['tripal_pub_search']['disabled']     : $disabled;    
+  $days         = $_SESSION['tripal_pub_search']['days']         ? $_SESSION['tripal_pub_search']['days']         : $days;    
+  
+  
+  // If the form_state has variables then use those.  This happens when an error occurs on the form or the 
+  // form is resbumitted using AJAX
+  $num_criteria = $form_state['values']['num_criteria'] ? $form_state['values']['num_criteria'] : $num_criteria;    
+  $loader_name  = $form_state['values']['loader_name']  ? $form_state['values']['loader_name']  : $loader_name;
+  $remote_db    = $form_state['values']['remote_db']    ? $form_state['values']['remote_db']    : $remote_db;
+  $disabled     = $form_state['values']['disabled']     ? $form_state['values']['disabled']     : $disabled;    
+  $days         = $form_state['values']['days']         ? $form_state['values']['days']         : $days;    
+  
+   
+  // change the number of criteria based on form_state post data.
+  if (!$num_criteria) {
+    $num_criteria = 0;
+  }
+  if($form_state['post']["add-$num_criteria"]) {    
+    $num_criteria++;
+  }
+  if($form_state['post']["remove-$num_criteria"]) {    
+    $num_criteria--;
+  }
+  
+  $form['pub_import_id'] = array(
+    '#type'          => 'hidden',
+    '#value'         => $pub_import_id,
+    '#required'      => TRUE,
   );
-  */
-
-  $form['pubmed']['sync_info'] = array(
-      '#type' => 'submit',
-      '#title' => t('Sync Publications Jobs'),
-      '#value' => t('Sync'),
+  $form['action'] = array(
+    '#type'          => 'hidden',
+    '#value'         => $action,
+    '#required'      => TRUE,
+  );
+  
+  $form['loader_name'] = array(
+    '#type'          => 'textfield',
+    '#title'         => t('Loader Name'),
+    '#description'   => t('Please provide a name for this loader setup..'),
+    '#default_value' => $loader_name,
+    '#required'      => TRUE,
+  );
+   
+  $remote_dbs = array('Pubmed' => 'Pubmed');
+  $form['remote_db'] = array(
+    '#title' => t('Remote Database'),
+    '#type' => 'select',
+    '#options' => $remote_dbs,
+    '#default_value' => $remote_db,
   );
 
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#weight' => 10,
-    '#value' => t('Save Configuration')
+  $form['num_criteria']= array(
+    '#type'          => 'hidden',
+    '#default_value' => $num_criteria,
+  );
+  $form['pub_import_id']= array(
+    '#type'          => 'hidden',
+    '#default_value' => $pub_import_id,
+  );
+  
+  $form['days'] = array(
+    '#type'          => 'textfield',
+    '#title'         => t('Days'),
+    '#description'   => t('The number of days <br>from today to search.'),
+    '#default_value' => $days,
+    '#size'          => 5,
+  );
+  $form['disabled'] = array(
+    '#type'          => 'checkbox',
+    '#title'         => t('Disabled'),
+    '#default_value' => $disabled,
+    '#size'          => 5,
+  );
+  
+  for($i = 0; $i <= $num_criteria; $i++) {
+    // if we have criteria supplied from the database then use that, othrewise look from the form_state or the session
+    if ($criteria) {
+      $search_terms = $criteria['criteria'][$i]['search_terms'];
+      $scope = $criteria['criteria'][$i]['scope'];
+      $operation = $criteria['criteria'][$i]['operation'];
+    }
+    // first populate defaults using any values in the SESSION variable
+    $search_terms = $_SESSION['tripal_pub_search']['criteria'][$i]['search_terms'] ? $_SESSION['tripal_pub_search']['criteria'][$i]['search_terms'] : $search_terms;
+    $scope        = $_SESSION['tripal_pub_search']['criteria'][$i]['scope']        ? $_SESSION['tripal_pub_search']['criteria'][$i]['scope']        : $scope;
+    $operation    = $_SESSION['tripal_pub_search']['criteria'][$i]['operation']    ? $_SESSION['tripal_pub_search']['criteria'][$i]['operation']    : $operation;
+    
+    // next populate defaults using any form values
+    $search_terms = $form_state['values']["search_terms-$i"] ? $form_state['values']["search_terms-$i"] : $search_terms;
+    $scope        = $form_state['values']["scope-$i"]        ? $form_state['values']["scope-$i"]        : $scope;
+    $operation    = $form_state['values']["operation-$i"]    ? $form_state['values']["operation-$i"]    : $operation;
+    
+    // default to searching the title and abstract
+    if (!$scope) {
+      $scope = 'abstract';
+    }
+  
+    $form['criteria'][$i]["search_terms-$i"] = array(
+      '#type'          => 'textfield',
+      '#description'   => t('Please provide a list of words, separated by spaces for searching.'),
+      '#default_value' => $search_terms,
+      '#required'      => TRUE,
+    );
+    $form['criteria'][$i]["scope-$i"] = array(
+      '#type'          => 'select',
+      '#description'   => t('Please select the fields to search for this term.'),
+      '#options'       => array(
+        'any'      => 'Any Field',
+        'title'    => 'Title',
+        'abstract' => 'Title/Abstract',
+        'author'   => 'Author'),
+      '#default_value' => $scope,
+    );    
+    
+    if ($i > 0) {
+      $form['criteria'][$i]["operation-$i"] = array(
+        '#type'          => 'select',
+        '#options'       => array(
+          'AND' => 'AND',
+          'OR'  => 'OR',
+          'NOT' => 'NOT'),
+        '#default_value' => $operation,
+      );
+    }
+    if ($i == $num_criteria) {    
+      if($i > 0) {
+        $form['criteria'][$i]["remove-$i"] = array(
+          '#type'         => 'image_button',
+          '#value'        => t('Remove'),
+          '#src'          => drupal_get_path('theme', 'tripal') . '/images/minus.png',
+          '#ahah' => array(
+            'path'    => "admin/tripal/tripal_pub/import/criteria/minus/$i",
+            'wrapper' => 'tripal-pub-importer-setup-form',
+            'event'   => 'click',
+            'method'  => 'replace',
+          ), 
+          '#attributes' => array('onClick' => 'return false;'),
+        );
+      }
+      $form['criteria'][$i]["add-$i"] = array(
+        '#type'         => 'image_button',      
+        '#value'        => t('Add'),
+        '#src'          => drupal_get_path('theme', 'tripal') . '/images/add.png',
+        '#ahah' => array(
+          'path'    => "admin/tripal/tripal_pub/import/criteria/add/$i",
+          'wrapper' => 'tripal-pub-importer-setup-form',
+          'event'   => 'click',
+          'method'  => 'replace',          
+        ),   
+        '#attributes' => array('onClick' => 'return false;'),
+      );
+    }
+  }
+  
+  $form['test'] = array(
+    '#type'         => 'submit',
+    '#value'        => t('Test Importer'),
+  );
+  $form['save'] = array(
+    '#type'         => 'submit',
+    '#value'        => t('Save Importer'),
+  );
+  $form['delete'] = array(
+    '#type'         => 'submit',
+    '#value'        => t('Delete Importer'),
   );
 
   return $form;
-
 }
 
-
-/*
- * Pub Configuration-Form
- * This form submit uses variable_set to set the vocabularies that are used, as well as the
- * unique_name and time interval that was entered by the user. If the user selects the option
- * to Sync Publicatin Jobs, the 'tripal_add_job' function is called, and a tripal job
- * will be added.
+/**
  *
- * @param $form
- *    -The submitted form containing the user entered infromation
- * @param $form_state
- *    -Is the state of the form: i.e what button was pressed, what infromation was entered,etc.
- *    The key is the 'values'
  */
-function tripal_pub_configuration_form_submit($form, $form_state) {
+function tripal_pub_importer_setup_form_validate($form, &$form_state) {
+  $num_criteria = $form_state['values']['num_criteria'];
+  $remote_db =  $form_state['values']["remote_db"];
+  $days =  trim($form_state['values']["days"]);
+  $disabled =  $form_state['values']["disabled"];
+  $loader_name =  trim($form_state['values']["loader_name"]);
 
-    global $user;    //needed to make the current users details available so access of user id is available
+  for ($i = 0; $i <= $num_criteria; $i++) {            
+    $search_terms =  trim($form_state['values']["search_terms-$i"]);
+    $scope =  $form_state['values']["scope-$i"];
+    $operation =  $form_state['values']["operation-$i"];
+    
+    if ($days and !is_numeric($days) or preg_match('/\./', $days)) {
+      form_set_error("days-$i", "Please enter a numeric, non decimal value, for the number of days.");
+    }
+  }
+}
 
-    if ($form_state['values']['op'] == t('Save Configuration')) {
+/**
+ *
+ */
+function tripal_pub_importer_setup_form_submit($form, &$form_state) {
+   
+  $pub_import_id = $form_state['values']['pub_import_id'];
+  $num_criteria = $form_state['values']['num_criteria'];
+  $remote_db =  $form_state['values']["remote_db"];
+  $days =  trim($form_state['values']["days"]);
+  $loader_name =  trim($form_state['values']["loader_name"]);
+  $disabled =  $form_state['values']["disabled"];
 
-        variable_set('tripal_pub_types_cv', $form_state['values']['tripal_pub_types_cv']);
-        variable_set('unique_name', $form_state['values']['unique_name'] );
+  // set the session variables
+  $_SESSION['tripal_pub_search']['remote_db'] = $remote_db;
+  $_SESSION['tripal_pub_search']['days'] = $days;
+  $_SESSION['tripal_pub_search']['num_criteria'] = $num_criteria;
+  $_SESSION['tripal_pub_search']['loader_name'] = $loader_name;
+  $_SESSION['tripal_pub_search']['disabled'] = $disabled;
+  unset($_SESSION['tripal_pub_search']['criteria']);
+  for ($i = 0; $i <= $num_criteria; $i++) {
+    $search_terms =  trim($form_state['values']["search_terms-$i"]);
+    $scope =  $form_state['values']["scope-$i"];
+    $operation =  $form_state['values']["operation-$i"];
+    
+    $_SESSION['tripal_pub_search']['criteria'][$i] = array(
+      'search_terms' => $search_terms,
+      'scope' => $scope,
+      'operation' => $operation
+    );
+  }
 
+  // now perform the appropriate action for the button clicked
+  if ($form_state['values']['op'] == 'Test Importer') {
+    $_SESSION['tripal_pub_search']['perform_search'] = 1;
+  }
+  if ($form_state['values']['op'] == 'Save Importer') {    
+    $record = array(
+      'name' => $loader_name,
+      'criteria' => serialize($_SESSION['tripal_pub_search']),
+      'disabled' => $disabled,
+    );
+    // first check to see if this pub_import_id is already present. If so,
+    // do an update rather than an insert    
+    $sql = "SELECT * FROM {tripal_pub_import} WHERE pub_import_id = %d";
+    $importer = db_fetch_object(db_query($sql, $pub_import_id));
+    if($importer) {
+      // do the update
+      $record['pub_import_id'] = $pub_import_id;
+      if(drupal_write_record('tripal_pub_import', $record, 'pub_import_id')){
+        unset($_SESSION['tripal_pub_search']);
+        drupal_set_message('Publication import settings updated.');
+        drupal_goto('admin/tripal/tripal_pub/import_list');       
+      }
+      else {
+        drupal_set_message('Could not update publication import settings.', 'error');
+      }
+    }     
+    else {         
+      // do the insert        
+      if(drupal_write_record('tripal_pub_import', $record)){
+        unset($_SESSION['tripal_pub_search']);
+        drupal_set_message('Publication import settings saved.');
+        drupal_goto('admin/tripal/tripal_pub/import_list');
+      }
+      else {
+        drupal_set_message('Could not save publication import settings.', 'error');
+      }
+    }    
+  }
+  if ($form_state['values']['op'] == 'Delete Importer') {
+    $sql = "DELETE FROM {tripal_pub_import} WHERE pub_import_id = %d";
+    $success = db_query($sql, $pub_import_id);
+    if ($success) {
+      drupal_set_message('Publication importer deleted.');
+      drupal_goto('admin/tripal/tripal_pub/import_list');  
     }
+    else {
+      drupal_set_message('Could not delete publication importer.', 'error');
+    }
+  }  
+}
 
-    //adding a tripal job if the user selects to Sync the Publications
-    if ($form_state['values']['op'] == t('Sync')) {
+/*
+ * 
+ */
+function tripal_pub_importer_delete($pub_import_id) {
+  $sql = "DELETE FROM {tripal_pub_import} WHERE pub_import_id = %d";
+  $success = db_query($sql, $pub_import_id);
+  if ($success) {
+    drupal_set_message('Publication importer deleted.');
+    drupal_goto('admin/tripal/tripal_pub/import_list');  
+  }
+  else {
+    drupal_set_message('Could not delete publication importer.', 'error');
+  }
+}
+/*
+ * AHAH callback
+ */
+function tripal_pub_importer_setup_page_update_criteria($action, $i) {
+  $status = TRUE;
 
-        variable_set('unique_name', $form_state['values']['unique_name'] );
-        $job_args = array($form_state['values']['unique_name']);
-        $job_id = tripal_add_job('Search & Load PubMed Publications', 'tripal_pub', 'tripal_pub_search_load_pubmed_publications', $job_args, $user->uid);
+  // prepare and render the form
+  $form = tripal_core_ahah_prepare_form();   
+  $data = theme('tripal_pub_importer_setup_form', $form);  
 
-    }
+  // bind javascript events to the new objects that will be returned 
+  // so that AHAH enabled elements will work.
+  $settings = tripal_core_ahah_bind_events();
 
+  // return the updated JSON
+  drupal_json(
+    array(
+      'status'   => $status, 
+      'data'     => $data,
+      'settings' => $settings,
+    )  
+  );
 }

+ 932 - 0
tripal_pub/pub_types.txt

@@ -0,0 +1,932 @@
+[Term]
+id: TPUB:0000100
+name: abbreviations
+def: Works consisting of lists of shortened forms of written words or phrases used for brevity. Acronyms are included here.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: abstracts
+def: Works consisting of lists of publications on a subject and that provide full annotated bibliographical information together with substantive summaries or condensations of the facts, ideas, or opinions presented in each publication listed. (From LC Subject Cataloging Manual)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: academic_dissertations
+def: Works consisting of formal presentations made usually to fulfill requirements for an academic degree.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: addresses
+def: Works consisting of speeches, orations, or written statements, usually formal, directed to a particular group of persons. These are different from LECTURES that are usually delivered to classes for instructional purposes.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: almanacs
+def: Works consisting of a calendar of days, weeks, and months, together with information such as astronomical data, various statistics, etc. (From Genre Terms: A Thesaurus for Use in Rare Book and Special Collections Cataloguing, 2d ed)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: anecdotes
+def: Works consisting of brief accounts or narratives of incidents or events.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: animation
+def: A film or video wholly or partially created by photographing drawings, sculptures, or other inanimate things in sequence to create the illusion of motion. Animations are also generated by computers. (From Moving Image Materials: Genre Terms, 1988)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: annual_reports
+def: Works consisting of annual statements concerning the administrative and operational functions of an institution or organization.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: atlases
+def: Works consisting of collections of illustrative plates, charts, etc., usually with explanatory captions.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: autobiography
+def: Works consisting of self-described accounts.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: bibliography
+def: A work consisting of a list of books, articles, documents, publications, and other items, usually on a single subject or related subjects.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: biobibliography
+def: Works consisting of biographical information as well as lists of the writings of those persons.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: biography
+def: Works consisting of an account of the events, works, and achievements, personal and professional, during a person's life. It includes articles on the activities and accomplishments of living persons as well as the presentation of an obituary.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: book_illustrations
+def: Works consisting of photographs, prints, drawings, portraits, plates, diagrams, facsimiles, maps, tables, or other representations or systematic arrangements of data designed to elucidate or decorate the contents of a publication. (From The ALA Glossary of Library and Information Science, 1983, p114)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: book_reviews
+def: Works consisting of critical analyses of books or other monographic works.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: bookplates
+def: Works consisting of book owner's identification labels. They are usually intended for attaching inside a book or similar object. (From Thesaurus for Graphic Materials II: Genre and Physical Characteristic Terms, 1995)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: cartoons
+def: Images used to comment on such things as contemporary events, social habits, or political trends; usually executed in a broad or abbreviated manner.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: case_reports
+def: Clinical presentations that may be followed by evaluative studies that eventually lead to a diagnosis.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: catalogs
+def: Works consisting of bibliographic records, created according to specific and uniform principles of construction and under the control of an authority file, which describe the materials contained in a collection, library, or group of libraries. Catalogs include also lists of materials prepared for a particular purpose, such as exhibition catalogs, sales catalogs, garden catalogs, medical supply catalogs. (From The ALA Glossary of Library and Information Sciences, 1983)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: charts
+def: Information presented in graphic form, for example, graphs or diagrams.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: chronology
+def: Works consisting of lists of events arranged in chronological order.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: classical_article
+def: Works consisting of a current presentation of a previously printed seminal article marking a milestone in the history of medicine or science. It is usually accompanied by introductory remarks heralding its reprinting, often on the anniversary of its original publication or on an anniversary of the author's birth or death. It is usually reprinted in full, with complete bibliographical reference to the original appearance.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: clinical_conference
+def: Work that consists of a conference of physicians on their observations of a patient at the bedside, regarding the physical state, laboratory and other diagnostic findings, clinical manifestations, results of current therapy, etc. A clinical conference usually ends with a confirmation or correction of clinical findings by a pathological diagnosis performed by a pathologist. "Clinical conference" is often referred to as a "clinico-pathological conference."
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: clinical_trial
+def: Work that is the report of a pre-planned clinical study of the safety, efficacy, or optimum dosage schedule of one or more diagnostic, therapeutic, or prophylactic drugs, devices, or techniques in humans selected according to predetermined criteria of eligibility and observed for predefined evidence of favorable and unfavorable effects. While most clinical trials concern humans, this publication type may be used for clinical veterinary articles meeting the requisites for humans. Specific headings for specific types and phases of clinical trials are also available.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: clinical_trial_phase_I
+def: Work that is the report of a pre-planned, usually controlled, clinical study of the safety and efficacy of diagnostic, therapeutic, or prophylactic drugs, devices, or techniques based on a small number of healthy persons and conducted over the period of about a year in either the United States or a foreign country.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+synonym: "Clinical Trial, Phase I" EXACT []
+
+[Term]
+id: TPUB:0000100
+name: clinical_trial_phase_II
+def: Work that is a report of a pre-planned, usually controlled, clinical study of the safety and efficacy of diagnostic, therapeutic, or prophylactic drugs, devices, or techniques based on several hundred volunteers, including a limited number of patients, and conducted over a period of about two years in either the United States or a foreign country.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+synonym: "Clinical Trial, Phase II" EXACT []
+
+[Term]
+id: TPUB:0000100
+name: clinical_trial_phase_III
+def: Work that is a report of a pre-planned, usually controlled, clinical study of the safety and efficacy of diagnostic, therapeutic, or prophylactic drugs, devices, or techniques after phase II trials. A large enough group of patients is studied and closely monitored by physicians for adverse response to long-term exposure, over a period of about three years in either the United States or a foreign country.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+synonym: "Clinical Trial, Phase III" EXACT []
+
+[Term]
+id: TPUB:0000100
+name: clinical_trial_phase_IV
+def: Work that is a report of a planned post-marketing study of diagnostic, therapeutic, or prophylactic drugs, devices, or techniques that have been approved for general sale after clinical trials, phases I, II, and III. These studies, conducted in the United States or a foreign country, often garner additional data about the safety and efficacy of a product.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+synonym: "Clinical Trial, Phase IV" EXACT []
+
+[Term]
+id: TPUB:0000100
+name: collected_correspondence
+def: Works consisting of collected letters by or about a person or on a subject.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: collected_works
+def: Works consisting of collections of previously published works.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: collections
+def: Works that consist of collections of objects.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: comment
+def: Work consisting of a critical or explanatory note written to discuss, support, or dispute an article or other presentation previously published. It may take the form of an article, letter, editorial, etc. It appears in publications under a variety of names: comment, commentary, editorial comment, viewpoint, etc.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: comparative_study
+def: Comparison of outcomes, results, responses, etc for different techniques, therapeutic approaches or other inputs.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: congresses
+def: Published records of the papers delivered at or issued on the occasion of individual congresses, symposia, and meetings; abstracts of papers delivered at such congresses; reports of the officers and delegates of such congresses; combinations of the foregoing; or proceedings of the conference of a society if they are not limited to matters of internal organization.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: consensus_development_conference
+def: A work that consists of summary statements representing the majority and current agreement of physicians, scientists, and other professionals meeting to reach a consensus on a selected subject.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: controlled_clinical_trial
+def: Work consisting of a clinical trial involving one or more test treatments, at least one control treatment, specified outcome measures for evaluating the studied intervention, and a bias-free method for assigning patients to the test treatment. The treatment may be drugs, devices, or procedures studied for diagnostic, therapeutic, or prophylactic effectiveness. Control measures include placebos, active medicine, no-treatment, dosage forms and regimens, historical comparisons, etc. When randomization using mathematical techniques, such as the use of a random numbers table, is employed to assign patients to test or control treatments, the trial is characterized as a RANDOMIZED CONTROLLED TRIAL.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: cookbooks
+def: Collections of recipes or instructions for preparation of food and organization of meals.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: corrected_and_republished_article
+def: Work that is the republication of an article to correct, amplify, or restore text and data of the originally published article.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: database
+def: Work consisting of a structured file of information or a set of logically related data stored and retrieved using computer-based means.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: diaries
+def: Works consisting of records, usually private, of writers' experiences, observations, feelings, attitudes, etc. They may also be works marked in calendar order in which to note appointments and the like. (From Random House Unabridged Dictionary, 2d ed)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: dictionary
+def: A reference book containing a list of words - usually in alphabetical order - giving information about form, pronunciation, etymology, grammar, and meaning. A foreign-language dictionary is an alphabetical list of words of one language with their meaning and equivalents in another language.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: directory
+def: Work consisting of an alphabetical or classified list of names, organizations, subjects, etc., giving usually titles, addresses, affiliations, and other professional data.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: documentary
+def: Works consisting of films, videos, and programs which depict actual persons or actual events. They do not include frank historical re-creations and do not attempt to judge the truth of the depiction in a film purporting to be factual or documentary in character. (From Moving Image Materials: Genre Terms, 1988)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+synonym: "Documentaries and Factual Films" EXACT []
+
+[Term]
+id: TPUB:0000100
+name: drawings
+def: Works consisting of graphic representations of objects or ideas by lines.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: duplicate_publication
+def: Work consisting of an article or book of identical or nearly identical material published simultaneously or successively to material previously published elsewhere, without acknowledgment of the prior publication.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: editorial
+def: Work consisting of a statement of the opinions, beliefs, and policy of the editor or publisher of a journal, usually on current matters of medical or scientific significance to the medical community or society at large. The editorials published by editors of journals representing the official organ of a society or organization are generally substantive.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: electronic_supplementary_materials
+def: Supporting content or information, such as animation, datasets, multimedia files, video, movies, audio files, text files, or software, which is submitted for publication in an online journal or an online edition of a journal. This information may be referenced in the text of the article with a link to the supplementary data provided. CATALOG: do not use
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: encyclopedias
+def: Works containing informational articles on subjects in every field of knowledge, usually arranged in alphabetical order, or a similar work limited to a special field or subject. (From The ALA Glossary of Library and Information Science, 1983)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: ephemera
+def: Works consisting of transient everyday items, usually printed on paper, that are produced for a specific limited use and then often thrown away. (From Genre Terms: A Thesaurus for Use in Rare Book and Special Collections Cataloguing, 2d ed & The ALA Glossary of Library and Information Science, 1983)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: essays
+def: Works consisting of collections of papers or interpretive literary compositions not previously published.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: evaluation_studies
+def: Works consisting of studies determining the effectiveness or utility of processes, personnel, and equipment.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: examination_questions
+def: Works consisting of compilations of questions and answers pertaining to a particular subject, used for study and review.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: exhibitions
+def: Public displays or items representative of a given subject.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: festschrift
+def: Work consisting of a collection of essays or other writings contributed by students, teachers, colleagues, and associates to honor a person or institution, usually on the occasion of an anniversary celebration or other event of importance.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: fictional_works
+def: Works consisting of creative writing, not presented as factual.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: forms
+def: Works consisting of or containing a substantial number of blank forms.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: formularies
+def: Works that consist of lists of drugs or collections of recipes, formulas, and prescriptions for the compounding of medicinal preparations.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: government_publications
+def: Works consisting of documents issued by local, regional, or national governments or by their agencies or subdivisions.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: guidebooks
+def: Works consisting of publications for travelers that give information about a city, region, or country, or similar handbooks about buildings, museums, etc. (The ALA Glossary of Library and Information Science, 1983)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: guideline
+def: Work consisting of a set of statements, directions, or principles presenting current or future rules or policy. Guidelines may be developed by government agencies at any level, institutions, organizations such as professional societies or governing boards, or by the convening of expert panels. The text may be cursive or in outline form, but it is generally a comprehensive guide to problems and approaches in any discipline or activity. This concept relates to the general conduct and administration of health care activities rather than to specific decisions for a particular clinical condition. For that aspect, PRACTICE GUIDELINE is available.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: handbooks
+def: Works consisting of concise reference works in which facts and information pertaining to a certain subject or field are arranged for ready reference and consultation rather than for continuous reading and study.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: herbals
+def: Works such as books on herbs or plants usually describing their medicinal value. (Random House Unabridged Dictionary, 2d ed)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: historical_article
+def: An article or portion of an article giving an account of past events or circumstances significant in a field of study, a profession, a discovery, an invention, etc. The concept of history is very wide, ranging from the dawn of time to the present. This publication type is often checked in conjunction with BIOGRAPHY.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: humor
+def: Works consisting of jokes and facetiae relating to a subject.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: in_vitro
+def: Studies using excised tissues.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: incunabula
+def: Books printed before 1501.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: indexes
+def: Works providing an analytical subject approach to materials in a field of knowledge.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: instructional_films
+def: Works consisting of nonfiction films and video designed to teach, instruct, or train. (From Moving Image Materials: Genre Terms, 1988)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: interactive_tutorial
+def: Video recordings or other files in which the progress of the instruction or content is determined by user response.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: interview
+def: Work consisting of a conversation with an individual regarding his or her background and other personal and professional details, opinions on specific subjects posed by the interviewer, etc.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: introductory_journal_article
+def: Prefactory summary to a special issue or section of a journal devoted to a specific topic. This introductory text can be of varying length and substance.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: journal_article
+def: The predominant publication type for articles and other items indexed for NLM databases.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: juvenile_literature
+def: Works produced for children through age 15 or through the ninth grade.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: laboratory_manuals
+def: Works containing concise background information and directions for activities, including conducting experiments or diagnostic tests in the laboratory.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: lecture_notes
+def: Works consisting of notes taken at the delivery or reading of a speech before an audience or class, usually given to instruct. (From Random House Unabridged Dictionary, 2d ed)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: lectures
+def: Works consisting of speeches read or delivered before an audience or class, especially for instruction or to set forth some subject. They are differentiated from ADDRESSES [PUBLICATION TYPE] which are less didactic and more informational, entertaining, inspirational, or polemic. (From Random House Unabridged Dictionary, 2d ed)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: legal_cases
+def: Works consisting of collections of law reports or the published reports of decided cases and documents or filings related to those cases.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: legislation
+def: Works consisting of the text of proposed or enacted legislation that may be in the form of bills, laws, statutes, ordinances, or government regulations.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: letter
+def: Work consisting of written or printed communication between individuals or between persons and representatives of corporate bodies. The correspondence may be personal or professional. In medical and other scientific publications the letter is usually from one or more authors to the editor of the journal or book publishing the item being commented upon or discussed. LETTER is often accompanied by COMMENT.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: manuscripts
+def: Works prepared by hand including handwritten or typescript drafts of pre-publication papers or works not otherwise reproduced in multiple copies.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: maps
+def: Works consisting of representations, normally to scale and on a flat medium, of a selection of material or abstract features on the surface of the earth. They may be used also in delineating the heavens and celestial bodies. (From Anglo-American Cataloguing Rules, 2d ed, p619)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: meeting_abstracts
+def: For individual abstracts of presentations at meetings, congresses, conferences, symposia, colloquia, seminars, workshops, round tables, and other professional gatherings.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: meta_analysis
+def: Works consisting of studies using a quantitative method of combining the results of independent studies (usually drawn from the published literature) and synthesizing summaries and conclusions which may be used to evaluate therapeutic effectiveness, plan new studies, etc. It is often an overview of clinical trials. It is usually called a meta-analysis by the author or sponsoring body and should be differentiated from reviews of literature.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: monograph
+def: Work that is any publication that is not a serial or integrating resource. In cataloging usage, It is usually on a single subject or related subjects and is complete in itself, whether constructed of chapters, sections, or parts. While any article encountered in indexing journals can be, strictly speaking, a monograph, as a publication type, a monograph will refer to a cataloging item.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: multicenter_study
+def: Work consisting of a controlled study executed by several cooperating institutions.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: news
+def: Works consisting of an announcement or statement of recent or current events of new data and matters of interest in the field of medicine or science. In some publications, such as "Nature" or "Science," the news reports are substantively written and herald medical and scientific data of vital or controversial importance.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: newspaper_article
+def: Work consisting of a news item appearing in a general-interest newspaper or other general news periodical, containing information of current and timely interest in the field of medicine or science. This publication type should not be confused with NEWS Publication Type, reserved for news reports published in various medical or other scientific journals, such as "Nature".
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: nurses_instruction
+def: Works consisting of materials developed for a nursing audience.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+synonym: "Nurses' Instruction" EXACT []
+
+[Term]
+id: TPUB:0000100
+name: outlines
+def: Works consisting of brief statements of the principal elements of a subject, usually arranged by heads and subheads.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: overall
+def: A single citation covering papers or abstracts presented at a meeting. The publication type may be used for a single citation with or without the additional indexing or cataloging of individual papers. The individual papers, however, are not labeled OVERALL.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: patents
+def: Works consisting of documents granted by a government giving exclusive rights to an inventor or assignee to manufacture, use, or sell an invention for a certain number of years.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: patient_education_handout
+def: Works consisting of a handout or self-contained informative material used to explain a procedure or a condition or the contents of a specific article in a biomedical journal and written in non-technical language for the patient or consumer.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: periodical_index
+def: Work consisting of a subject approach to the contents of a periodical issuing an annual, biennial, quinquennial, decennial, etc., index. The heading is used for the overall body of articles published by a periodical in the same sense that BIBLIOGRAPHY is useful when published as a single article.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: periodicals
+def: Publications intended to be issued on an ongoing basis, generally more frequently than annually, containing separate articles, stories, or writings.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: personal_narratives
+def: Works consisting of accounts of individual experience in relation to a particular field or of participation in related activities.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: pharmacopoeias
+def: Authoritative works containing lists of drugs and preparations, their description, formulation, analytic composition, main chemical properties, standards for strength, purity, and dosage, chemical tests for determining identity, etc. They have the status of a standard.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: photographs
+def: Still images produced from radiation-sensitive materials (sensitive to light, electron beams, or nuclear radiation), generally by means of the chemical action of light on a sensitive film, paper, glass, or metal. Photographs may be positive or negative, opaque or transparent.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: phrases
+def: Works consisting of common terms, phrases, idioms, and typical conversations, e.g., between health professional and patients. These are often intended for use by non-native speakers of a language.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: pictorial_works
+def: Works consisting exclusively or mainly of pictures but not technical drawings.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: poetry
+def: Works that consist of literary and oral genre expressing meaning via symbolism and following formal or informal patterns.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: popular_works
+def: Works written for non-professional or lay audiences.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: portraits
+def: Works consisting of graphic representations, especially of the face, of real persons, usually posed, living or dead. They are pictures whose purpose is the portrayal of an individual or group of individuals, not pictures which merely include people as part of an event or scene. (From Thesaurus for Graphic Materials II, p540, 1995)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: Postcards
+def: Cards on which a message may be written or printed for mailing without an envelope. Art & Architectural Thesaurus Online www.getty.edu/research/conducting_research/vocabularies/aat/ accessed 12/18/2008
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: posters
+def: Works consisting of single or multi-sheet notices made to attract attention to events, activities, causes, goods, or services. They are for posting, usually in a public place and are chiefly pictorial. They are intended to make an immediate impression from a distance. Posters do not include poster presentations at conferences and meetings. (From Thesaurus for Graphic Materials II: Genre and Physical Characteristic Headings, 1995)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: practice_guideline
+def: Work consisting of a set of directions or principles to assist the health care practitioner with patient care decisions about appropriate diagnostic, therapeutic, or other clinical procedures for specific clinical circumstances. Practice guidelines may be developed by government agencies at any level, institutions, organizations such as professional societies or governing boards, or by the convening of expert panels. They can provide a foundation for assessing and evaluating the quality and effectiveness of health care in terms of measuring improved health, reduction of variation in services or procedures performed, and reduction of variation in outcomes of health care delivered.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: price_lists
+def: Works consisting of lists giving the prices of items for sale, including drugs, equipment, books, etc. Price lists are less detailed than catalogs and not as long.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: problems_and_exercises
+def: Works consisting of collections of practice questions and drills, generally for instructional or review use.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: programmed_instruction
+def: Works consisting of sequenced self-correction texts.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: programs
+def: Works consisting of lists of the events, pieces, performers, speakers, etc., of an entertainment, ceremony, or the like. (From: Genre Terms: A Thesaurus for Use in Rare Book and Special Collections Cataloging, 2d ed)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: prospectuses
+def: Works consisting of advertisements separately printed and distributed by a publisher to describe and solicit orders for a recent or forthcoming publication. In the case of books, they may include sample pages. (From: ALA Glossary of Library and Information Science, 1983)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: publication_components
+def: Specific parts of publications.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: publication_formats
+def: Specific genre of publication.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: published_erratum
+def: Work consisting of an acknowledgment of an error, issued by a publisher, editor, or author. It customarily cites the source where the error occurred, giving complete bibliographic data for retrieval. In the case of books and monographs, author, title, imprint, paging, and other helpful references will be given; in the case of journal articles, the author, title, paging, and journal reference will be shown. An erratum notice is variously cited as Errata or Corrigenda.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: randomized_controlled_trial
+def: Work consisting of a clinical trial that involves at least one test treatment and one control treatment, concurrent enrollment and follow-up of the test- and control-treated groups, and in which the treatments to be administered are selected by a random process, such as the use of a random-numbers table.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: resource_guides
+def: Works listing and describing various sources of information, from multiple media or in different formats, on a given subject.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: retracted_publication
+def: Work consisting of the designation of an article or book as retracted in whole or in part by an author or authors or an authorized representative. It identifies a citation previously published and now retracted through a formal issuance from the author, publisher, or other authorized agent, and is distinguished from RETRACTION OF PUBLICATION, which identifies the citation retracting the original published item.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: retraction_of_publication
+def: Work consisting of a statement issued by one or more authors of an article or a book, withdrawing or disavowing acknowledgment of their participation in performing research or writing the results of their study. In indexing, the retraction is sent to the editor of the publication in which the article appeared and is published under the rubric "retraction" or in the form of a letter. This publication type designates the author's statement of retraction: it should be differentiated from RETRACTED PUBLICATION which labels the retracted publication.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: review
+def: An article or book published after examination of published material on a subject. It may be comprehensive to various degrees and the time range of material scrutinized may be broad or narrow, but the reviews most often desired are reviews of the current literature. The textual material examined may be equally broad and can encompass, in medicine specifically, clinical material as well as experimental research or case reports. State-of-the-art reviews tend to address more current matters. A review of the literature must be differentiated from HISTORICAL ARTICLE on the same subject, but a review of historical literature is also within the scope of this publication type.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: scientific_integrity_review
+def: Work consisting of reports by the United States Office of Research Integrity, identifying questionable research published in articles or books. Notification of the questionable data is carried in the NIH Guide for Grants and Contracts.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: statistics
+def: Works consisting of presentations of numerical data on particular subjects.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: support_of_research
+def: Organizational source for funding of research activity.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: tables
+def: Presentations of nonstatistical data in tabular form.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: technical_report
+def: Work consisting of a formal report giving details of the investigation and results of a medical or other scientific problem. When issued by a government agency or comparable official body, its contents may be classified, unclassified, or declassified with regard to security clearance. This publication type may also cover a scientific paper or article that records the current state or current position of scientific research and development. If so labeled by the editor or publisher, this publication type may be properly used for journal articles.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: terminology
+def: Work consisting of lists of the technical terms or expressions used in a specific field. These lists may or may not be formally adopted or sanctioned by usage.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: textbooks
+def: Books intended for use in the study of specific subjects, containing systematic presentation of the principles and essential knowledge of the subjects.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: twin_study
+def: Work consisting of reporting using a method of detecting genetic causes in human traits and genetic factors in behavior using sets of twins.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: unedited_footage
+def: Work consisting of untitled raw motion picture and video footage which has not been edited or assembled into a finished work. (From: Moving Image Materials: Genre Terms, 1988)
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: union_lists
+def: Works consisting of records of the holdings or items owned by two or more libraries.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: unpublished_works
+def: Works that have not been formally published.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: validation_studies
+def: Works consisting of research using processes by which the reliability and relevance of a procedure for a specific purpose are established.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: video_audio_media
+def: Used with articles which include video files or clips, or for articles which are entirely video.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+
+[Term]
+id: TPUB:0000100
+name: webcasts
+def: Content from transmission of live or pre-recorded audio or video via connection or download from the INTERNET.
+is_a: TPUB:0000015 ! publication_type
+namespace: MeSH_publication_type
+

+ 1107 - 240
tripal_pub/tpub.obo

@@ -1,317 +1,215 @@
 format-version: 1.2
-date: 22:03:2013 17:53
-saved-by: ficklin
-auto-generated-by: OBO-Edit 2.1-beta18
 default-namespace: tripal_pub
+subsetdef: MeSH_Publication_Type "MeSH Publication Types"
 
 [Term]
 id: TPUB:0000001
-name: publication_dbxref
-relationship: part_of TPUB:0000037 ! publication_details
+name: Publication Dbxref
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000002
-name: publication
+name: Publication
 
 [Term]
 id: TPUB:0000003
-name: citation
-relationship: part_of TPUB:0000037 ! publication_details
+name: Citation
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000004
-name: book
-is_a: TPUB:0000015 ! publication_type
+name: Book
+is_a: TPUB:0000015 ! Publication Type
 
 [Term]
 id: TPUB:0000005
-name: pub_accession
+name: Pub Accession
 relationship: part_of TPUB:0000001 ! publication_dbxref
 
 [Term]
 id: TPUB:0000006
-name: collective
-comment: Used when an author is a collective of individuals rather than a person.
-is_a: TPUB:0000015 ! publication_type
-relationship: part_of TPUB:0000016 ! author
+name: Collective
+def: Used when an author is a collective of individuals rather than a person.
+is_a: TPUB:0000015 ! Publication Type
+relationship: part_of TPUB:0000016 ! Author
 
 [Term]
 id: TPUB:0000007
-name: masters_thesis
-relationship: part_of TPUB:0000006 ! collective
+name: Master's Thesis
+relationship: part_of TPUB:0000006 ! Collective
 
 [Term]
 id: TPUB:0000008
-name: PhD_thesis
-comment: PhD thesis or dissertation.
-relationship: part_of TPUB:0000006 ! collective
+name: PhD Thesis
+def: PhD thesis or dissertation.
+relationship: part_of TPUB:0000006 ! Collective
 
 [Term]
 id: TPUB:0000009
-name: pub_database
-relationship: part_of TPUB:0000001 ! publication_dbxref
+name: Publication Database
+relationship: part_of TPUB:0000001 ! Publication Dbxref
 
 [Term]
 id: TPUB:0000010
-name: received_date
-is_a: TPUB:0000046 ! publication_date
+name: Received Date
+is_a: TPUB:0000046 ! Publication Date
 
 [Term]
 id: TPUB:0000011
-name: conference_name
-relationship: part_of TPUB:0000037 ! publication_details
+name: Conference Name
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000012
-name: book_chapter
-is_a: TPUB:0000015 ! publication_type
+name: Book Chapter
+is_a: TPUB:0000015 ! Publication Type
 
 [Term]
 id: TPUB:0000013
-name: unknown_type
-is_a: TPUB:0000015 ! publication_type
+name: Unknown Type
+is_a: TPUB:0000015 ! Publication Type
 
 [Term]
 id: TPUB:0000014
-name: web_page
-is_a: TPUB:0000015 ! publication_type
+name: Web Page
+is_a: TPUB:0000015 ! Publication Type
 
 [Term]
 id: TPUB:0000015
-name: publication_type
-relationship: part_of TPUB:0000002 ! publication
+name: Publication Type
+relationship: part_of TPUB:0000002 ! Publication
 
 [Term]
 id: TPUB:0000016
-name: author
-relationship: part_of TPUB:0000002 ! publication
-
-[Term]
-id: TPUB:0000017
-name: first_initials
-comment: The first initials for the author including the initial for the first name and any middle names (not the initial for the last name).
-relationship: part_of TPUB:0000016 ! author
-
-[Term]
-id: TPUB:0000018
-name: surname
-synonym: "family_name" EXACT []
-synonym: "last_name" EXACT []
-relationship: part_of TPUB:0000016 ! author
-
-[Term]
-id: TPUB:0000019
-name: given_name
-synonym: "first_name" EXACT []
-relationship: part_of TPUB:0000016 ! author
-
-[Term]
-id: TPUB:0000020
-name: middle_names
-comment: One or more middle names for this person.
-relationship: part_of TPUB:0000016 ! author
-
-[Term]
-id: TPUB:0000021
-name: middle_initials
-comment: The middle initials for this person excluding the initial for the given name and the surname.
-relationship: part_of TPUB:0000016 ! author
-
-[Term]
-id: TPUB:0000022
-name: affiliation
-relationship: part_of TPUB:0000016 ! author
-
-[Term]
-id: TPUB:0000023
-name: department
-comment: The department of an institution or organization.
-relationship: part_of TPUB:0000022 ! affiliation
-
-[Term]
-id: TPUB:0000024
-name: institution
-relationship: part_of TPUB:0000022 ! affiliation
-
-[Term]
-id: TPUB:0000025
-name: organization
-comment: A generic term for any organization.
-relationship: part_of TPUB:0000022 ! affiliation
-
-[Term]
-id: TPUB:0000026
-name: address
-relationship: part_of TPUB:0000016 ! author
-
-[Term]
-id: TPUB:0000027
-name: address_line1
-relationship: part_of TPUB:0000026 ! address
-
-[Term]
-id: TPUB:0000028
-name: address_line2
-relationship: part_of TPUB:0000026 ! address
-
-[Term]
-id: TPUB:0000029
-name: address_line3
-relationship: part_of TPUB:0000026 ! address
-
-[Term]
-id: TPUB:0000030
-name: city
-relationship: part_of TPUB:0000026 ! address
-
-[Term]
-id: TPUB:0000031
-name: state
-relationship: part_of TPUB:0000026 ! address
-
-[Term]
-id: TPUB:0000032
-name: province
-relationship: part_of TPUB:0000026 ! address
-
-[Term]
-id: TPUB:0000033
-name: country
-relationship: part_of TPUB:0000026 ! address
-
-[Term]
-id: TPUB:0000034
-name: postal_code
-relationship: part_of TPUB:0000026 ! address
+name: Author
+relationship: part_of TPUB:0000002 ! Publication
 
 [Term]
 id: TPUB:0000035
-name: epub_date
-is_a: TPUB:0000046 ! publication_date
+name: Epub Date
+is_a: TPUB:0000046 ! Publication Date
 
 [Term]
 id: TPUB:0000036
-name: accepted_date
-is_a: TPUB:0000046 ! publication_date
+name: Accepted Date
+is_a: TPUB:0000046 ! Publication Date
 
 [Term]
 id: TPUB:0000037
-name: publication_details
-relationship: part_of TPUB:0000002 ! publication
+name: Publication Details
+relationship: part_of TPUB:0000002 ! Publication
 
 [Term]
 id: TPUB:0000038
-name: journal_ISO_abbreviation
-relationship: part_of TPUB:0000037 ! publication_details
-created_by: stephen
-creation_date: 2013-03-20T07:02:18Z
+name: Journal ISO Abbreviation
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000039
-name: title
-relationship: part_of TPUB:0000037 ! publication_details
+name: Title
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000040
-name: journal
-is_a: TPUB:0000015 ! publication_type
+name: Journal
+is_a: TPUB:0000015 ! Publication Type
 
 [Term]
 id: TPUB:0000041
-name: patent
-is_a: TPUB:0000015 ! publication_type
+name: Patent
+is_a: TPUB:0000015 ! Publication Type
 
 [Term]
 id: TPUB:0000042
-name: volume
-relationship: part_of TPUB:0000037 ! publication_details
+name: Volume
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000043
-name: issue
-relationship: part_of TPUB:0000037 ! publication_details
+name: Issue
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000044
-name: pages
-relationship: part_of TPUB:0000037 ! publication_details
+name: Pages
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000045
-name: start_page
-relationship: part_of TPUB:0000037 ! publication_details
+name: Start Page
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000046
-name: publication_date
-relationship: part_of TPUB:0000037 ! publication_details
+name: Publication Date
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000047
-name: authors
-relationship: part_of TPUB:0000037 ! publication_details
+name: Authors
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000048
 name: ISSN
-comment: International Standard Serial Number (ISSN) is an eight-character value that uniquely identifies a periodicals in print or other media. There are two sub categories of ISSN: print, p-ISSN and electronic e-ISSN.
-relationship: part_of TPUB:0000037 ! publication_details
+def: International Standard Serial Number (ISSN) is an eight-character value that uniquely identifies a periodicals in print or other media. There are two sub categories of ISSN: print, p-ISSN and electronic e-ISSN.
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000049
 name: DOI
-comment: Digital Object Identifier.
-is_a: TPUB:0000080 ! elocation
+def: Digital Object Identifier.
+is_a: TPUB:0000080 ! Elocation
 
 [Term]
 id: TPUB:0000050
-name: abstract
-relationship: part_of TPUB:0000037 ! publication_details
+name: Abstract
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000051
-name: comments
-relationship: part_of TPUB:0000037 ! publication_details
+name: Comments
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000052
 name: URL
-relationship: part_of TPUB:0000037 ! publication_details
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000053
-name: file_attachment
-relationship: part_of TPUB:0000037 ! publication_details
+name: File Attachment
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000059
-name: year
-relationship: part_of TPUB:0000046 ! publication_date
+name: Year
+relationship: part_of TPUB:0000046 ! Publication Date
 
 [Term]
 id: TPUB:0000064
-name: language
-relationship: part_of TPUB:0000037 ! publication_details
+name: Language
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000065
-name: keywords
-relationship: part_of TPUB:0000037 ! publication_details
+name: Keywords
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000066
-name: original_title
-relationship: part_of TPUB:0000037 ! publication_details
+name: Original Title
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000067
-name: alias
-relationship: part_of TPUB:0000037 ! publication_details
+name: Alias
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000068
-name: journal_code
-relationship: part_of TPUB:0000037 ! publication_details
+name: Journal Code
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000069
@@ -320,14 +218,9 @@ is_a: TPUB:0000048 ! ISSN
 
 [Term]
 id: TPUB:0000070
-name: conference_proceedings
-comment: A generic term for any article, talk, workshop or poster that is part of a conference proceedings.
-is_a: TPUB:0000015 ! publication_type
-
-[Term]
-id: TPUB:0000071
-name: journal_article
-is_a: TPUB:0000015 ! publication_type
+name: Conference Proceedings
+def: A generic term for any article, talk, workshop or poster that is part of a conference proceedings.
+is_a: TPUB:0000015 ! Publication Type
 
 [Term]
 id: TPUB:0000072
@@ -336,101 +229,1075 @@ is_a: TPUB:0000048 ! ISSN
 
 [Term]
 id: TPUB:0000073
-name: proceedings_talk
-is_a: TPUB:0000070 ! conference_proceedings
+name: Proceedings Talk
+is_a: TPUB:0000070 ! Conference Proceedings
 
 [Term]
 id: TPUB:0000074
-name: proceedings_article
-is_a: TPUB:0000070 ! conference_proceedings
+name: Proceedings Article
+is_a: TPUB:0000070 ! Conference Proceedings
 
 [Term]
 id: TPUB:0000075
-name: journal_name
-relationship: part_of TPUB:0000037 ! publication_details
+name: Journal Name
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000076
-name: proceedings_poster
-is_a: TPUB:0000070 ! conference_proceedings
+name: Proceedings Poster
+is_a: TPUB:0000070 ! Conference Proceedings
 
 [Term]
 id: TPUB:0000077
-name: conference_year
-relationship: part_of TPUB:0000037 ! publication_details
+name: Conference Year
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000078
-name: proceedings_computer_demo
-is_a: TPUB:0000070 ! conference_proceedings
+name: Proceedings Computer Demo
+is_a: TPUB:0000070 ! Conference Proceedings
 
 [Term]
 id: TPUB:0000079
-name: vernacular_title
-comment: The title of a publication in its original foreign language.
-relationship: part_of TPUB:0000037 ! publication_details
-creation_date: 2013-03-22T05:35:02Z
+name: Vernacular Title
+def: The title of a publication in its original foreign language.
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000080
-name: elocation
-comment: Provides an electronic location for the items. This includes Digital Object Identifiers (DOI) or Publisher Item Identifiers (PII).
-relationship: part_of TPUB:0000037 ! publication_details
-creation_date: 2013-03-22T05:36:24Z
+name: Elocation
+def: Provides an electronic location for the items. This includes Digital Object Identifiers (DOI) or Publisher Item Identifiers (PII).
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000081
-name: publication_model
-comment: This term is used to identify the medium/media in which the item is published. There are four possible values which are the same as used by: print, print-electronic, electronic,  electronic-print.  Further explanation:  "print", the journal is published in print format only; "print-electronic",  the journal is published in both print and electronic format; "electronic", the journal is published in electronic format only; "electronic-print", the journal is published first in electronic format followed by print.
-relationship: part_of TPUB:0000037 ! publication_details
-creation_date: 2013-03-22T02:37:00Z
+name: Publication Model
+def: This term is used to identify the medium/media in which the item is published. There are four possible values which are the same as used by: print, print-electronic, electronic,  electronic-print.  Further explanation:  "print", the journal is published in print format only; "print-electronic",  the journal is published in both print and electronic format; "electronic", the journal is published in electronic format only; "electronic-print", the journal is published first in electronic format followed by print.
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000082
 name: PII
-comment: Publisher Item Identifier.
-is_a: TPUB:0000081 ! publication_model
+def: Publisher Item Identifier.
+is_a: TPUB:0000081 ! Publication Model
 
 [Term]
 id: TPUB:0000083
-name: structured_abstract_part
-comment: A subset of an abstract.  For example, abstracts that have section headers such as 'Purpose', 'Results', etc., each of these sections would be an individual part of a structured abstract.
-relationship: part_of TPUB:0000050 ! abstract
+name: Structured Abstract Part
+def: A subset of an abstract.  For example, abstracts that have section headers such as 'Purpose', 'Results', etc., each of these sections would be an individual part of a structured abstract.
+relationship: part_of TPUB:0000050 ! Abstract
 
 [Term]
 id: TPUB:0000084
-name: copyright
-comment: Information regarding the copyright of the publication.
-relationship: part_of TPUB:0000037 ! publication_details
+name: Copyright
+def: Information regarding the copyright of the publication.
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000085
-name: suffix
-comment: Name suffix such as 2nd, 3rd, Jr, Sr., etc.
-relationship: part_of TPUB:0000016 ! author
-creation_date: 2013-03-22T04:10:15Z
+name: Suffix
+def: Name suffix such as 2nd, 3rd, Jr, Sr., etc.
+relationship: part_of TPUB:0000016 ! Author
 
 [Term]
 id: TPUB:0000087
-name: language_abbr
-comment: An abbreviation for a language (e.g. 3 letters)
-is_a: TPUB:0000064 ! language
+name: Language Abbr
+def: An abbreviation for a language (e.g. 3 letters)
+is_a: TPUB:0000064 ! Language
 
 [Term]
 id: TPUB:0000100
-name: journal_country
-comment: The country where the journal was published.
-relationship: part_of TPUB:0000037 ! publication_details
-created_by: ficklin
-creation_date: 2013-03-22T05:52:57Z
+name: Journal Country
+def: The country where the journal was published.
+relationship: part_of TPUB:0000037 ! Publication Details
+
+
+[Term]
+id: TPUB0000101
+name: Abbreviations
+def: Works consisting of lists of shortened forms of written words or phrases used for brevity. Acronyms are included here.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000102
+name: Abstracts
+def: Works consisting of lists of publications on a subject and that provide full annotated bibliographical information together with substantive summaries or condensations of the facts, ideas, or opinions presented in each publication listed. (From LC Subject Cataloging Manual)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000103
+name: Academic Dissertations
+def: Works consisting of formal presentations made usually to fulfill requirements for an academic degree.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000104
+name: Addresses
+def: Works consisting of speeches, orations, or written statements, usually formal, directed to a particular group of persons. These are different from LECTURES that are usually delivered to classes for instructional purposes.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000105
+name: Almanacs
+def: Works consisting of a calendar of days, weeks, and months, together with information such as astronomical data, various statistics, etc. (From Genre Terms: A Thesaurus for Use in Rare Book and Special Collections Cataloguing, 2d ed)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000106
+name: Anecdotes
+def: Works consisting of brief accounts or narratives of incidents or events.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000107
+name: Animation
+def: A film or video wholly or partially created by photographing drawings, sculptures, or other inanimate things in sequence to create the illusion of motion. Animations are also generated by computers. (From Moving Image Materials: Genre Terms, 1988)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000108
+name: Annual Reports
+def: Works consisting of annual statements concerning the administrative and operational functions of an institution or organization.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000109
+name: Atlases
+def: Works consisting of collections of illustrative plates, charts, etc., usually with explanatory captions.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000110
+name: Autobiography
+def: Works consisting of self-described accounts.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000111
+name: Bibliography
+def: A work consisting of a list of books, articles, documents, publications, and other items, usually on a single subject or related subjects.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000112
+name: Biobibliography
+def: Works consisting of biographical information as well as lists of the writings of those persons.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000113
+name: Biography
+def: Works consisting of an account of the events, works, and achievements, personal and professional, during a person's life. It includes articles on the activities and accomplishments of living persons as well as the presentation of an obituary.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000114
+name: Book Illustrations
+def: Works consisting of photographs, prints, drawings, portraits, plates, diagrams, facsimiles, maps, tables, or other representations or systematic arrangements of data designed to elucidate or decorate the contents of a publication. (From The ALA Glossary of Library and Information Science, 1983, p114)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000115
+name: Book Reviews
+def: Works consisting of critical analyses of books or other monographic works.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000116
+name: Bookplates
+def: Works consisting of book owner's identification labels. They are usually intended for attaching inside a book or similar object. (From Thesaurus for Graphic Materials II: Genre and Physical Characteristic Terms, 1995)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000117
+name: Cartoons
+def: Images used to comment on such things as contemporary events, social habits, or political trends; usually executed in a broad or abbreviated manner.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000118
+name: Case Reports
+def: Clinical presentations that may be followed by evaluative studies that eventually lead to a diagnosis.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000119
+name: Catalogs
+def: Works consisting of bibliographic records, created according to specific and uniform principles of construction and under the control of an authority file, which describe the materials contained in a collection, library, or group of libraries. Catalogs include also lists of materials prepared for a particular purpose, such as exhibition catalogs, sales catalogs, garden catalogs, medical supply catalogs. (From The ALA Glossary of Library and Information Sciences, 1983)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000120
+name: Charts
+def: Information presented in graphic form, for example, graphs or diagrams.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000121
+name: Chronology
+def: Works consisting of lists of events arranged in chronological order.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000122
+name: Classical Article
+def: Works consisting of a current presentation of a previously printed seminal article marking a milestone in the history of medicine or science. It is usually accompanied by introductory remarks heralding its reprinting, often on the anniversary of its original publication or on an anniversary of the author's birth or death. It is usually reprinted in full, with complete bibliographical reference to the original appearance.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000123
+name: Clinical Conference
+def: Work that consists of a conference of physicians on their observations of a patient at the bedside, regarding the physical state, laboratory and other diagnostic findings, clinical manifestations, results of current therapy, etc. A clinical conference usually ends with a confirmation or correction of clinical findings by a pathological diagnosis performed by a pathologist. "Clinical conference" is often referred to as a "clinico-pathological conference."
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000124
+name: Clinical Trial
+def: Work that is the report of a pre-planned clinical study of the safety, efficacy, or optimum dosage schedule of one or more diagnostic, therapeutic, or prophylactic drugs, devices, or techniques in humans selected according to predetermined criteria of eligibility and observed for predefined evidence of favorable and unfavorable effects. While most clinical trials concern humans, this publication type may be used for clinical veterinary articles meeting the requisites for humans. Specific headings for specific types and phases of clinical trials are also available.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000125
+name: Clinical Trial, Phase I
+def: Work that is the report of a pre-planned, usually controlled, clinical study of the safety and efficacy of diagnostic, therapeutic, or prophylactic drugs, devices, or techniques based on a small number of healthy persons and conducted over the period of about a year in either the United States or a foreign country.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000126
+name: Clinical Trial, Phase II
+def: Work that is a report of a pre-planned, usually controlled, clinical study of the safety and efficacy of diagnostic, therapeutic, or prophylactic drugs, devices, or techniques based on several hundred volunteers, including a limited number of patients, and conducted over a period of about two years in either the United States or a foreign country.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+
+[Term]
+id: TPUB0000127
+name: Clinical Trial, Phase III
+def: Work that is a report of a pre-planned, usually controlled, clinical study of the safety and efficacy of diagnostic, therapeutic, or prophylactic drugs, devices, or techniques after phase II trials. A large enough group of patients is studied and closely monitored by physicians for adverse response to long-term exposure, over a period of about three years in either the United States or a foreign country.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+
+[Term]
+id: TPUB0000128
+name: Clinical Trial, Phase IV
+def: Work that is a report of a planned post-marketing study of diagnostic, therapeutic, or prophylactic drugs, devices, or techniques that have been approved for general sale after clinical trials, phases I, II, and III. These studies, conducted in the United States or a foreign country, often garner additional data about the safety and efficacy of a product.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+
+[Term]
+id: TPUB0000129
+name: Collected Correspondence
+def: Works consisting of collected letters by or about a person or on a subject.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000130
+name: Collected Works
+def: Works consisting of collections of previously published works.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000131
+name: Collections
+def: Works that consist of collections of objects.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000132
+name: Comment
+def: Work consisting of a critical or explanatory note written to discuss, support, or dispute an article or other presentation previously published. It may take the form of an article, letter, editorial, etc. It appears in publications under a variety of names: comment, commentary, editorial comment, viewpoint, etc.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000133
+name: Comparative Study
+def: Comparison of outcomes, results, responses, etc for different techniques, therapeutic approaches or other inputs.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000134
+name: Congresses
+def: Published records of the papers delivered at or issued on the occasion of individual congresses, symposia, and meetings; abstracts of papers delivered at such congresses; reports of the officers and delegates of such congresses; combinations of the foregoing; or proceedings of the conference of a society if they are not limited to matters of internal organization.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000135
+name: Consensus Development Conference
+def: A work that consists of summary statements representing the majority and current agreement of physicians, scientists, and other professionals meeting to reach a consensus on a selected subject.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000136
+name: Controlled Clinical Trial
+def: Work consisting of a clinical trial involving one or more test treatments, at least one control treatment, specified outcome measures for evaluating the studied intervention, and a bias-free method for assigning patients to the test treatment. The treatment may be drugs, devices, or procedures studied for diagnostic, therapeutic, or prophylactic effectiveness. Control measures include placebos, active medicine, no-treatment, dosage forms and regimens, historical comparisons, etc. When randomization using mathematical techniques, such as the use of a random numbers table, is employed to assign patients to test or control treatments, the trial is characterized as a RANDOMIZED CONTROLLED TRIAL.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000137
+name: Cookbooks
+def: Collections of recipes or instructions for preparation of food and organization of meals.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000138
+name: Corrected and Republished Article
+def: Work that is the republication of an article to correct, amplify, or restore text and data of the originally published article.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000139
+name: Database
+def: Work consisting of a structured file of information or a set of logically related data stored and retrieved using computer-based means.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000140
+name: Diaries
+def: Works consisting of records, usually private, of writers' experiences, observations, feelings, attitudes, etc. They may also be works marked in calendar order in which to note appointments and the like. (From Random House Unabridged Dictionary, 2d ed)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000141
+name: Dictionary
+def: A reference book containing a list of words - usually in alphabetical order - giving information about form, pronunciation, etymology, grammar, and meaning. A foreign-language dictionary is an alphabetical list of words of one language with their meaning and equivalents in another language.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000142
+name: Directory
+def: Work consisting of an alphabetical or classified list of names, organizations, subjects, etc., giving usually titles, addresses, affiliations, and other professional data.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000143
+name: Documentaries and Factual Films
+def: Works consisting of films, videos, and programs which depict actual persons or actual events. They do not include frank historical re-creations and do not attempt to judge the truth of the depiction in a film purporting to be factual or documentary in character. (From Moving Image Materials: Genre Terms, 1988)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+
+[Term]
+id: TPUB0000144
+name: Drawings
+def: Works consisting of graphic representations of objects or ideas by lines.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000145
+name: Duplicate Publication
+def: Work consisting of an article or book of identical or nearly identical material published simultaneously or successively to material previously published elsewhere, without acknowledgment of the prior publication.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000146
+name: Editorial
+def: Work consisting of a statement of the opinions, beliefs, and policy of the editor or publisher of a journal, usually on current matters of medical or scientific significance to the medical community or society at large. The editorials published by editors of journals representing the official organ of a society or organization are generally substantive.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000147
+name: Electronic Supplementary Materials
+def: Supporting content or information, such as animation, datasets, multimedia files, video, movies, audio files, text files, or software, which is submitted for publication in an online journal or an online edition of a journal. This information may be referenced in the text of the article with a link to the supplementary data provided. CATALOG: do not use
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000148
+name: Encyclopedias
+def: Works containing informational articles on subjects in every field of knowledge, usually arranged in alphabetical order, or a similar work limited to a special field or subject. (From The ALA Glossary of Library and Information Science, 1983)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000149
+name: Ephemera
+def: Works consisting of transient everyday items, usually printed on paper, that are produced for a specific limited use and then often thrown away. (From Genre Terms: A Thesaurus for Use in Rare Book and Special Collections Cataloguing, 2d ed & The ALA Glossary of Library and Information Science, 1983)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000150
+name: Essays
+def: Works consisting of collections of papers or interpretive literary compositions not previously published.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000151
+name: Evaluation Studies
+def: Works consisting of studies determining the effectiveness or utility of processes, personnel, and equipment.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000152
+name: Examination Questions
+def: Works consisting of compilations of questions and answers pertaining to a particular subject, used for study and review.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000153
+name: Exhibitions
+def: Public displays or items representative of a given subject.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000154
+name: Festschrift
+def: Work consisting of a collection of essays or other writings contributed by students, teachers, colleagues, and associates to honor a person or institution, usually on the occasion of an anniversary celebration or other event of importance.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000155
+name: Fictional Works
+def: Works consisting of creative writing, not presented as factual.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000156
+name: Forms
+def: Works consisting of or containing a substantial number of blank forms.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000157
+name: Formularies
+def: Works that consist of lists of drugs or collections of recipes, formulas, and prescriptions for the compounding of medicinal preparations.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000158
+name: Government Publications
+def: Works consisting of documents issued by local, regional, or national governments or by their agencies or subdivisions.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000159
+name: Guidebooks
+def: Works consisting of publications for travelers that give information about a city, region, or country, or similar handbooks about buildings, museums, etc. (The ALA Glossary of Library and Information Science, 1983)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000160
+name: Guideline
+def: Work consisting of a set of statements, directions, or principles presenting current or future rules or policy. Guidelines may be developed by government agencies at any level, institutions, organizations such as professional societies or governing boards, or by the convening of expert panels. The text may be cursive or in outline form, but it is generally a comprehensive guide to problems and approaches in any discipline or activity. This concept relates to the general conduct and administration of health care activities rather than to specific decisions for a particular clinical condition. For that aspect, PRACTICE GUIDELINE is available.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000161
+name: Handbooks
+def: Works consisting of concise reference works in which facts and information pertaining to a certain subject or field are arranged for ready reference and consultation rather than for continuous reading and study.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000162
+name: Herbals
+def: Works such as books on herbs or plants usually describing their medicinal value. (Random House Unabridged Dictionary, 2d ed)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000163
+name: Historical Article
+def: An article or portion of an article giving an account of past events or circumstances significant in a field of study, a profession, a discovery, an invention, etc. The concept of history is very wide, ranging from the dawn of time to the present. This publication type is often checked in conjunction with BIOGRAPHY.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000164
+name: Humor
+def: Works consisting of jokes and facetiae relating to a subject.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000165
+name: In Vitro
+def: Studies using excised tissues.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000166
+name: Incunabula
+def: Books printed before 1501.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000167
+name: Indexes
+def: Works providing an analytical subject approach to materials in a field of knowledge.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000168
+name: Instructional Films
+def: Works consisting of nonfiction films and video designed to teach, instruct, or train. (From Moving Image Materials: Genre Terms, 1988)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000169
+name: Interactive Tutorial
+def: Video recordings or other files in which the progress of the instruction or content is determined by user response.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000170
+name: Interview
+def: Work consisting of a conversation with an individual regarding his or her background and other personal and professional details, opinions on specific subjects posed by the interviewer, etc.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000171
+name: Introductory Journal Article
+def: Prefactory summary to a special issue or section of a journal devoted to a specific topic. This introductory text can be of varying length and substance.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000172
+name: Journal Article
+def: The predominant publication type for articles and other items indexed for NLM databases.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000173
+name: Juvenile Literature
+def: Works produced for children through age 15 or through the ninth grade.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000174
+name: Laboratory Manuals
+def: Works containing concise background information and directions for activities, including conducting experiments or diagnostic tests in the laboratory.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000175
+name: Lecture Notes
+def: Works consisting of notes taken at the delivery or reading of a speech before an audience or class, usually given to instruct. (From Random House Unabridged Dictionary, 2d ed)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000176
+name: Lectures
+def: Works consisting of speeches read or delivered before an audience or class, especially for instruction or to set forth some subject. They are differentiated from ADDRESSES [PUBLICATION TYPE] which are less didactic and more informational, entertaining, inspirational, or polemic. (From Random House Unabridged Dictionary, 2d ed)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000177
+name: Legal Cases
+def: Works consisting of collections of law reports or the published reports of decided cases and documents or filings related to those cases.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000178
+name: Legislation
+def: Works consisting of the text of proposed or enacted legislation that may be in the form of bills, laws, statutes, ordinances, or government regulations.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000179
+name: Letter
+def: Work consisting of written or printed communication between individuals or between persons and representatives of corporate bodies. The correspondence may be personal or professional. In medical and other scientific publications the letter is usually from one or more authors to the editor of the journal or book publishing the item being commented upon or discussed. LETTER is often accompanied by COMMENT.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000180
+name: Manuscripts
+def: Works prepared by hand including handwritten or typescript drafts of pre-publication papers or works not otherwise reproduced in multiple copies.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000181
+name: Maps
+def: Works consisting of representations, normally to scale and on a flat medium, of a selection of material or abstract features on the surface of the earth. They may be used also in delineating the heavens and celestial bodies. (From Anglo-American Cataloguing Rules, 2d ed, p619)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000182
+name: Meeting Abstracts
+def: For individual abstracts of presentations at meetings, congresses, conferences, symposia, colloquia, seminars, workshops, round tables, and other professional gatherings.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000183
+name: Meta Analysis
+def: Works consisting of studies using a quantitative method of combining the results of independent studies (usually drawn from the published literature) and synthesizing summaries and conclusions which may be used to evaluate therapeutic effectiveness, plan new studies, etc. It is often an overview of clinical trials. It is usually called a meta-analysis by the author or sponsoring body and should be differentiated from reviews of literature.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000184
+name: Monograph
+def: Work that is any publication that is not a serial or integrating resource. In cataloging usage, It is usually on a single subject or related subjects and is complete in itself, whether constructed of chapters, sections, or parts. While any article encountered in indexing journals can be, strictly speaking, a monograph, as a publication type, a monograph will refer to a cataloging item.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000185
+name: Multicenter Study
+def: Work consisting of a controlled study executed by several cooperating institutions.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000186
+name: News
+def: Works consisting of an announcement or statement of recent or current events of new data and matters of interest in the field of medicine or science. In some publications, such as "Nature" or "Science," the news reports are substantively written and herald medical and scientific data of vital or controversial importance.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000187
+name: Newspaper Article
+def: Work consisting of a news item appearing in a general-interest newspaper or other general news periodical, containing information of current and timely interest in the field of medicine or science. This publication type should not be confused with NEWS Publication Type, reserved for news reports published in various medical or other scientific journals, such as "Nature".
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000188
+name: Nurses' Instruction
+def: Works consisting of materials developed for a nursing audience.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000189
+name: Outlines
+def: Works consisting of brief statements of the principal elements of a subject, usually arranged by heads and subheads.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000190
+name: Overall
+def: A single citation covering papers or abstracts presented at a meeting. The publication type may be used for a single citation with or without the additional indexing or cataloging of individual papers. The individual papers, however, are not labeled OVERALL.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000191
+name: Patents
+def: Works consisting of documents granted by a government giving exclusive rights to an inventor or assignee to manufacture, use, or sell an invention for a certain number of years.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000192
+name: Patient Education Handout
+def: Works consisting of a handout or self-contained informative material used to explain a procedure or a condition or the contents of a specific article in a biomedical journal and written in non-technical language for the patient or consumer.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000193
+name: Periodical Index
+def: Work consisting of a subject approach to the contents of a periodical issuing an annual, biennial, quinquennial, decennial, etc., index. The heading is used for the overall body of articles published by a periodical in the same sense that BIBLIOGRAPHY is useful when published as a single article.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000194
+name: Periodicals
+def: Publications intended to be issued on an ongoing basis, generally more frequently than annually, containing separate articles, stories, or writings.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000195
+name: Personal Narratives
+def: Works consisting of accounts of individual experience in relation to a particular field or of participation in related activities.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000196
+name: Pharmacopoeias
+def: Authoritative works containing lists of drugs and preparations, their description, formulation, analytic composition, main chemical properties, standards for strength, purity, and dosage, chemical tests for determining identity, etc. They have the status of a standard.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000197
+name: Photographs
+def: Still images produced from radiation-sensitive materials (sensitive to light, electron beams, or nuclear radiation), generally by means of the chemical action of light on a sensitive film, paper, glass, or metal. Photographs may be positive or negative, opaque or transparent.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000198
+name: Phrases
+def: Works consisting of common terms, phrases, idioms, and typical conversations, e.g., between health professional and patients. These are often intended for use by non-native speakers of a language.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000199
+name: Pictorial Works
+def: Works consisting exclusively or mainly of pictures but not technical drawings.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000200
+name: Poetry
+def: Works that consist of literary and oral genre expressing meaning via symbolism and following formal or informal patterns.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000201
+name: Popular Works
+def: Works written for non-professional or lay audiences.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000202
+name: Portraits
+def: Works consisting of graphic representations, especially of the face, of real persons, usually posed, living or dead. They are pictures whose purpose is the portrayal of an individual or group of individuals, not pictures which merely include people as part of an event or scene. (From Thesaurus for Graphic Materials II, p540, 1995)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000203
+name: Postcards
+def: Cards on which a message may be written or printed for mailing without an envelope. Art & Architectural Thesaurus Online www.getty.edu/research/conducting_research/vocabularies/aat/ accessed 12/18/2008
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000204
+name: Posters
+def: Works consisting of single or multi-sheet notices made to attract attention to events, activities, causes, goods, or services. They are for posting, usually in a public place and are chiefly pictorial. They are intended to make an immediate impression from a distance. Posters do not include poster presentations at conferences and meetings. (From Thesaurus for Graphic Materials II: Genre and Physical Characteristic Headings, 1995)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000205
+name: Practice Guideline
+def: Work consisting of a set of directions or principles to assist the health care practitioner with patient care decisions about appropriate diagnostic, therapeutic, or other clinical procedures for specific clinical circumstances. Practice guidelines may be developed by government agencies at any level, institutions, organizations such as professional societies or governing boards, or by the convening of expert panels. They can provide a foundation for assessing and evaluating the quality and effectiveness of health care in terms of measuring improved health, reduction of variation in services or procedures performed, and reduction of variation in outcomes of health care delivered.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000206
+name: Price Lists
+def: Works consisting of lists giving the prices of items for sale, including drugs, equipment, books, etc. Price lists are less detailed than catalogs and not as long.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000207
+name: Problems and Exercises
+def: Works consisting of collections of practice questions and drills, generally for instructional or review use.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000208
+name: Programmed Instruction
+def: Works consisting of sequenced self-correction texts.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000209
+name: Programs
+def: Works consisting of lists of the events, pieces, performers, speakers, etc., of an entertainment, ceremony, or the like. (From: Genre Terms: A Thesaurus for Use in Rare Book and Special Collections Cataloging, 2d ed)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000210
+name: Prospectuses
+def: Works consisting of advertisements separately printed and distributed by a publisher to describe and solicit orders for a recent or forthcoming publication. In the case of books, they may include sample pages. (From: ALA Glossary of Library and Information Science, 1983)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000211
+name: Publication Components
+def: Specific parts of publications.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000212
+name: Publication Formats
+def: Specific genre of publication.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000213
+name: Published Erratum
+def: Work consisting of an acknowledgment of an error, issued by a publisher, editor, or author. It customarily cites the source where the error occurred, giving complete bibliographic data for retrieval. In the case of books and monographs, author, title, imprint, paging, and other helpful references will be given; in the case of journal articles, the author, title, paging, and journal reference will be shown. An erratum notice is variously cited as Errata or Corrigenda.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000214
+name: Randomized Controlled Trial
+def: Work consisting of a clinical trial that involves at least one test treatment and one control treatment, concurrent enrollment and follow-up of the test- and control-treated groups, and in which the treatments to be administered are selected by a random process, such as the use of a random-numbers table.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000215
+name: Resource guides
+def: Works listing and describing various sources of information, from multiple media or in different formats, on a given subject.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000216
+name: Retracted Publication
+def: Work consisting of the designation of an article or book as retracted in whole or in part by an author or authors or an authorized representative. It identifies a citation previously published and now retracted through a formal issuance from the author, publisher, or other authorized agent, and is distinguished from RETRACTION OF PUBLICATION, which identifies the citation retracting the original published item.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000217
+name: Retraction of Publication
+def: Work consisting of a statement issued by one or more authors of an article or a book, withdrawing or disavowing acknowledgment of their participation in performing research or writing the results of their study. In indexing, the retraction is sent to the editor of the publication in which the article appeared and is published under the rubric "retraction" or in the form of a letter. This publication type designates the author's statement of retraction: it should be differentiated from RETRACTED PUBLICATION which labels the retracted publication.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000218
+name: Review
+def: An article or book published after examination of published material on a subject. It may be comprehensive to various degrees and the time range of material scrutinized may be broad or narrow, but the reviews most often desired are reviews of the current literature. The textual material examined may be equally broad and can encompass, in medicine specifically, clinical material as well as experimental research or case reports. State-of-the-art reviews tend to address more current matters. A review of the literature must be differentiated from HISTORICAL ARTICLE on the same subject, but a review of historical literature is also within the scope of this publication type.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000219
+name: Scientific Integrity Review
+def: Work consisting of reports by the United States Office of Research Integrity, identifying questionable research published in articles or books. Notification of the questionable data is carried in the NIH Guide for Grants and Contracts.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000220
+name: Statistics
+def: Works consisting of presentations of numerical data on particular subjects.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000221
+name: Support of Research
+def: Organizational source for funding of research activity.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000222
+name: Tables
+def: Presentations of nonstatistical data in tabular form.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000223
+name: Technical Report
+def: Work consisting of a formal report giving details of the investigation and results of a medical or other scientific problem. When issued by a government agency or comparable official body, its contents may be classified, unclassified, or declassified with regard to security clearance. This publication type may also cover a scientific paper or article that records the current state or current position of scientific research and development. If so labeled by the editor or publisher, this publication type may be properly used for journal articles.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000224
+name: Terminology
+def: Work consisting of lists of the technical terms or expressions used in a specific field. These lists may or may not be formally adopted or sanctioned by usage.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000225
+name: Textbooks
+def: Books intended for use in the study of specific subjects, containing systematic presentation of the principles and essential knowledge of the subjects.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000226
+name: Twin Study
+def: Work consisting of reporting using a method of detecting genetic causes in human traits and genetic factors in behavior using sets of twins.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000227
+name: Unedited Footage
+def: Work consisting of untitled raw motion picture and video footage which has not been edited or assembled into a finished work. (From: Moving Image Materials: Genre Terms, 1988)
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000228
+name: Union Lists
+def: Works consisting of records of the holdings or items owned by two or more libraries.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000229
+name: Unpublished Works
+def: Works that have not been formally published.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000230
+name: Validation Studies
+def: Works consisting of research using processes by which the reliability and relevance of a procedure for a specific purpose are established.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000231
+name: Video Audio Media
+def: Used with articles which include video files or clips, or for articles which are entirely video.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000232
+name: Webcasts
+def: Content from transmission of live or pre-recorded audio or video via connection or download from the INTERNET.
+is_a: TPUB:0000015 ! Publication Type
+subset: MeSH_Publication_Type
+
+[Term]
+id: TPUB0000233
+name: Research Support, American Recovery and Reinvestment Act
+subset: MeSH_Publication_Type
+is_a: TPUB:0000015 ! Publication Type
+
+[Term]
+id: TPUB0000234
+name: Research Support, N.I.H., Extramural
+def: A designation for publications of research resulting from extramural research funded by the National Institutes of Health.
+subset: MeSH_Publication_Type
+is_a: TPUB:0000015 ! Publication Type
+
+[Term]
+id: TPUB0000235
+name: Research Support, N.I.H., Intramural
+def: A designation for publications of research resulting from intramural research at the National Institutes of Health.
+subset: MeSH_Publication_Type
+is_a: TPUB:0000015 ! Publication Type
+
+[Term]
+id: TPUB0000236
+name: Research Support, Non-U.S. Gov't
+subset: MeSH_Publication_Type
+is_a: TPUB:0000015 ! Publication Type
+
+[Term]
+id: TPUB0000237
+name: Research Support, U.S. Gov't, Non-P.H.S.
+subset: MeSH_Publication_Type
+is_a: TPUB:0000015 ! Publication Type
+
+[Term]
+id: TPUB0000238
+name: Research Support, U.S. Gov't, P.H.S.
+subset: MeSH_Publication_Type
+is_a: TPUB:0000015 ! Publication Type
+
+[Term]
+id: TPUB0000239
+name: Research Support, U.S. Government
+def: For publications noted as supported by US Government.
+subset: MeSH_Publication_Type
+is_a: TPUB:0000015 ! Publication Type
+
+[Term]
+id: TPUB:0000240
+name: Author List
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Typedef]
 id: is_a
-name: is_a
+name: is a
 is_transitive: true
 
 [Typedef]
 id: part_of
-name: part_of
+name: part of
 is_transitive: true
-

+ 1 - 0
tripal_pub/tripal_pub.info

@@ -7,3 +7,4 @@ version = 6.x-1.0-fix1
 dependencies[] = tripal_core
 dependencies[] = tripal_cv
 dependencies[] = tripal_db
+dependencies[] = tripal_contact

+ 55 - 0
tripal_pub/tripal_pub.install

@@ -24,6 +24,14 @@ function tripal_pub_install() {
   
   // add any cvterms we need for this module
   tripal_pub_add_cvterms();  
+  
+  // add loading of the the tripal pub ontology to the job queue
+  $obo_path =  realpath('./') . '/' . drupal_get_path('module', 'tripal_pub') . '/tpub.obo';
+  $obo_id = tripal_cv_add_obo_ref('Tripal Publication', $obo_path);
+  tripal_cv_submit_obo_job($obo_id);
+  
+  // add the custom tables
+  tripal_pub_add_custom_tables();
 }
 
 
@@ -103,3 +111,50 @@ function tripal_pub_requirements($phase) {
   }
   return $requirements;
 }
+
+/*
+ * 
+ */
+function tripal_pub_add_custom_tables() {
+  $schema = array (
+    'table' => 'pubauthor_contact',
+    'fields' => array (
+      'pubauthor_contact_id' => array (
+        'type' => 'serial',
+        'not null' => true,
+      ),
+      'contact_id' => array (
+        'type' => 'int',
+        'not null' => true,
+      ),
+      'pubauthor_id' => array (
+        'type' => 'int',
+        'not null' => true,
+      ),
+    ),
+    'primary key' => array (
+      0 => 'pubauthor_contact_id',
+    ),
+    'unique keys' => array (
+      'pubauthor_contact_c1' => array (
+        0 => 'contact_id',
+        1 => 'pubauthor_id',
+      ),
+    ),
+    'foreign keys' => array (
+      'contact' => array (
+        'table' => 'contact',
+        'columns' => array (
+          'contact_id' => 'contact_id',
+        ),
+      ),
+      'pubauthor' => array (
+        'table' => 'pubauthor',
+        'columns' => array (
+          'pubauthor_id' => 'pubauthor_id',
+        ),
+      ),
+    ),
+  );
+  tripal_core_create_custom_table(&$ret, 'pubauthor_contact', $schema, TRUE);
+}

+ 270 - 926
tripal_pub/tripal_pub.module

@@ -3,7 +3,8 @@
 require_once "api/tripal_pub.api.inc";
 require_once "includes/tripal_pub.admin.inc";
 require_once "includes/pubmed.inc";
-require_once "includes/remote_search.inc";
+require_once "includes/pub_search.inc";
+require_once "includes/pub_sync.inc";
 
 /**
  * @file
@@ -37,7 +38,7 @@ function tripal_pub_node_info() {
     'chado_pub' => array(
       'name' => t('Publication'),
       'module' => 'chado_pub',
-      'description' => t('A module for interfacing the GMOD chado database with Drupal, providing viewing of publications'),
+      'description' => t('A publication from the Chado database'),
       'title_label' => t('Article Title'),
       'body_label' => t('Abstract'),
       'has_title' => TRUE,
@@ -68,26 +69,50 @@ function tripal_pub_menu() {
     'access arguments' => array('administer tripal pubs'),
     'type' => MENU_NORMAL_ITEM
   );
- 
-  $items['admin/tripal/tripal_pub/configuration'] = array(
-    'title' => 'Configuration',
-    'description' => 'Configuration for this module',
+  
+    $items['admin/tripal/tripal_pub/sync'] = array(
+    'title' => ' Sync Publications',
+    'description' => 'Sync publications in Chado with Drupal',
     'page callback' => 'drupal_get_form',
-    'page arguments' => array('tripal_pub_configuration_form'),
+    'page arguments' => array('tripal_pub_sync_form'),
     'access arguments' => array('administer tripal pubs'),
-    'type' => MENU_NORMAL_ITEM  
+    'type' => MENU_NORMAL_ITEM,
   );
+  
 
-  $items['admin/tripal/tripal_pub/import_setup'] = array(
-    'title' => t('Pub Loader Setup'),
-    'description' => t('Finds publications using remote publication databases (e.g. PubMed).'),
-    'page callback' => 'tripal_pub_remote_search_page',
+  $items['admin/tripal/tripal_pub/import_list'] = array(
+    'title' => t('Importers List'),
+    'description' => t('List all publication importers'),
+    'page callback' => 'tripal_pub_importers_list',
+    'access arguments' => array('administer tripal pubs'),
+    'type ' => MENU_CALLBACK,
+  );
+  
+  $items['admin/tripal/tripal_pub/import/new'] = array(
+    'title' => t('Add an Importer'),
+    'description' => t('Add a new publication importer.'),
+    'page callback' => 'tripal_pub_importer_setup',
+    'page arguments' => array(4, NULL),
+    'access arguments' => array('administer tripal pubs'),
+    'type ' => MENU_CALLBACK,
+  );
+  
+  $items['admin/tripal/tripal_pub/import/edit/%'] = array(    
+    'page callback' => 'tripal_pub_importer_setup',
+    'page arguments' => array(4, 5),
+    'access arguments' => array('administer tripal pubs'),
+    'type ' => MENU_CALLBACK,
+  );
+  
+  $items['admin/tripal/tripal_pub/import/delete/%'] = array(    
+    'page callback' => 'tripal_pub_importer_delete',
+    'page arguments' => array(5),
     'access arguments' => array('administer tripal pubs'),
     'type ' => MENU_CALLBACK,
   );
   
-  $items['admin/tripal/tripal_pub/import_setup/criteria/%/%'] = array(
-    'page callback' => 'tripal_pub_remote_search_page_update_criteria',
+  $items['admin/tripal/tripal_pub/import/criteria/%/%'] = array(
+    'page callback' => 'tripal_pub_importer_setup_page_update_criteria',
     'page arguments' => array(5, 6),
     'access arguments' => array('administer tripal pubs'),    
     'type ' => MENU_CALLBACK,
@@ -125,16 +150,22 @@ function tripal_pub_menu() {
 function tripal_pub_theme() {
 
   return array(
-    'tripal_pub_author_table' => array(
-      'arguments' => array('form' => NULL),
+    'tripal_pub_base' => array(
+      'arguments' => array('node' => NULL),
+    ),
+    'tripal_pub_properties' => array(
+      'arguments' => array('node' => NULL)
     ),
-    'publication_author' => array(
-      'arguments' => array('element' => NULL)
+    'tripal_pub_authors' => array(
+      'arguments' => array('node' => NULL)
     ),
-    'publication_author' => array(
-      'arguments' => array('element' => NULL)
+    'tripal_pub_references' => array(
+      'arguments' => array('node' => NULL)
     ),
-    'tripal_pub_remote_search_form' => array(
+    'tripal_pub_relationships' => array(
+      'arguments' => array('node' => NULL)
+    ),
+    'tripal_pub_importer_setup_form' => array(
        'arguments' => array('form'),
     ),
     'tripal_pub_admin' => array(
@@ -224,223 +255,62 @@ function chado_pub_form(&$node, $form_state) {
 
   $type = node_get_types('type', $node);
 
-  // Article Title.
-  $form['title'] = array(
-    '#type' => 'textfield',
-    '#title' => check_plain($type->title_label),
-    '#default_value' => $node->title,
-    '#required' => TRUE,
-    '#weight' => 0,
-  );
-
-  // Abstract
-  $form['abstract'] = array(
-    '#title' => 'Abstract',
-    '#type' => 'textarea',
-    '#default_value' => isset($node->abstract) ? $node->abstract : ''
-  );
-
   $form['pub_id'] = array(
     '#type' => 'hidden',
     '#value' => (isset($node->pub_id)) ? $node->pub_id->pub_id : NULL ,
   );
-
-  $form['uniquename'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Unique Name'),
-    '#required' => TRUE,
-    '#description' => 'A unique name/identifier for this publication. If this article exists in pubmed, entering the pubmed ID here will ensure duplicate publication pages are not created.',
-    '#default_value' => isset($node->pub_id->uniquename) ? $node->pub_id->uniquename : ''
-  );
-
-  $values= array(
-    'cv_id' => variable_get('tripal_pub_types_cv', NULL),
-  );
-
-  //population select list with 'cvterm' names
-  $result = tripal_core_chado_select('cvterm', array('cvterm_id', 'name'), $values);
-
-  foreach ($result as $value) {
-    $newArray[$value->cvterm_id]=$value->name;     //options for the select list
+  
+  $sql = "
+    SELECT CVTS.cvterm_id, CVTS.name
+    FROM {cvtermpath} CVTP
+      INNER JOIN {cvterm} CVTS ON CVTP.subject_id = CVTS.cvterm_id
+      INNER JOIN {cvterm} CVTO ON CVTP.object_id = CVTO.cvterm_id
+      INNER JOIN {cv} ON CVTO.cv_id = CV.cv_id
+    WHERE CV.name = 'tripal_pub' and CVTO.name = 'Publication Type'
+    ORDER BY CVTS.name ASC 
+  ";
+  $results = chado_query($sql);
+  $pub_types = array();
+  $default_type = '';
+  while ($pub_type = db_fetch_object($results)) {
+    $pub_types[$pub_type->cvterm_id] = $pub_type->name;
+    if (strcmp($pub_type->name,"Journal Article") == 0) {
+      $default_type = $pub_type->cvterm_id;
+    }
   }
-
   $form['type_id'] = array(
     '#type' => 'select',
     '#title' => t('Publication Type'),
-    '#options' => $newArray,
+    '#options' => $pub_types,
     '#required' => TRUE,
-    '#default_value' => isset($node->pub_id->type_id) ? $node->pub_id->type_id : ''
+    '#default_value' => isset($node->pub_id->type_id) ? $node->pub_id->type_id : $default_type,
   );
-
-  $form['author_wrapper'] = array(
-    '#tree' => FALSE,
-    '#prefix' => '<div class="clear-block" id="author-wrapper">',
-    '#suffix' => '</div>',
+  
+  // Article Title.
+  $form['title'] = array(
+    '#type' => 'textfield',
+    '#title' => check_plain($type->title_label),
+    '#default_value' => $node->title,
+    '#required' => TRUE,
   );
-
-  // Get number of authors
-  $author_count = empty($node->authors) ? 0 : count($node->authors);
-
-  // If a new author added, add to list and update the author count.
-  if (isset($form_state['new_author'])) {
-
-    if (!isset($node->authors)) {
-      $node->authors = array();
-    }
-
-    $node->authors = array_merge($node->authors, array($form_state['new_author']));
-    $author_count++;
-
-  }
-
-  // If a author removed, remove from list and update the author count.
-  $remove_delta = -1;
-
-  if (!empty($form_state['remove_delta'])) {
-
-      $remove_delta = $form_state['remove_delta'] - 1;
-
-      unset($node->authors[$remove_delta]);
-
-      // Re-number the values.
-      $node->authors = array_values($node->authors);
-
-      $author_count--;
-
-  }
-
-  // Container to display existing authors.
-  $form['author_wrapper']['authors'] = array(
-    '#prefix' => '<div id="publication-authors">',
-    '#suffix' => '</div>',
-    '#theme' => 'tripal_pub_author_table',
+  
+  $form['volume'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Volume'),
+    '#default_value' => isset($node->pub_id->volume) ? $node->pub_id->volume : ''
   );
-
-  if (!isset($node->authors)) {
-
-    if (isset($node->new_author['new_author_name'])) {
-
-      $node->authors = array();
-
-      $node->authors[]['author_name'] = $node->new_author['new_author_name'];
-
-    }
-
-  }
-
-  //Add the existing authors to the form.
-  for ($delta = 0; $delta < $author_count; $delta++) {
-
-      $author = isset($node->authors[$delta]['author_name']) ? $node->authors[$delta] : array();
-
-      $form['author_wrapper']['authors'][$delta] = tripal_pub_author_display_form($delta, $author);
-
-  }
-
-
-  if (isset($form_state['values']['edit_author'])) {
-
-      // Add new authors
-      $form['author_wrapper']['edit_author'] = array(
-        '#type' => 'fieldset',
-        '#title' => t('Current Publication Authors'),
-        '#tree' => FALSE,
-      );
-
-      // Define the form fields for the new author
-      $form['author_wrapper']['edit_author']['edit_author'] = array(
-        '#tree' => TRUE,
-        //'#default_value'=> '',
-        //'#theme' => 'author_add_author_form',
-      );
-
-      $form['author_wrapper']['edit_author']['edit_author']['delta'] = array(
-        '#type' => 'hidden',
-        '#value' => $form_state['values']['edit_author']['delta']
-      );
-
-      $form['author_wrapper']['edit_author']['edit_author']['edit_author_name'] = array(
-        '#type' => 'publication_author',
-        '#title' => t('Contributing Authors'),
-        '#default_value' => array(
-            'givennames' => $form_state['values']['edit_author']['author_name']['givennames'],
-            'surname' => $form_state['values']['edit_author']['author_name']['surname'],
-            'suffix' => $form_state['values']['edit_author']['author_name']['suffix'],
-          ),
-        '#weight' => 1,
-      );
-
-      // We name our button 'author_more' to avoid conflicts with other modules using
-      // AHAH-enabled buttons with the id 'more'.
-      $form['author_wrapper']['edit_author']['author_save'] = array(
-        '#type' => 'submit',
-        '#value' => t('Save Author'),
-        '#weight' => 0,
-        '#submit' => array('tripal_pub_edit_author_submit'),
-        '#ahah' => array(
-          'path' => 'tripal_pub/js/0',
-          'wrapper' => 'author-wrapper',
-          'method' => 'replace',
-          'effect' => 'fade',
-        ),
-      );
-  }
-  else{
-
-      // Add new authors
-      $form['author_wrapper']['add_author'] = array(
-        '#type' => 'fieldset',
-        '#title' => t('Publication Authors'),
-        '#tree' => FALSE,
-      );
-
-      // Define the form fields for the new author
-      $form['author_wrapper']['add_author']['new_author'] = array(
-        '#tree' => TRUE,
-        //'#default_value'=> '',
-        '#theme' => 'author_add_author_form',
-      );
-
-      $form['author_wrapper']['add_author']['new_author']['new_author_name'] = array(
-        '#type' => 'publication_author',
-        '#title' => t('Contributing Authors'),
-        '#default_value' => '',
-        '#weight' => 1,
-      );
-
-      // We name our button 'author_more' to avoid conflicts with other modules using
-      // AHAH-enabled buttons with the id 'more'.
-      $form['author_wrapper']['add_author']['author_more'] = array(
-        '#type' => 'submit',
-        '#value' => t('Add Author'),
-        '#weight' => 0,
-        '#submit' => array('tripal_pub_add_author_submit'),
-        '#ahah' => array(
-          'path' => 'tripal_pub/js/0',
-          'wrapper' => 'author-wrapper',
-          'method' => 'replace',
-          'effect' => 'fade',
-        ),
-      );
-
-  }
-
+  
   $form['volumetitle'] = array(
     '#type' => 'textfield',
     '#title' => t('Volume Title'),
     '#description' => t('Title of part if one of a series.'),
     '#default_value' => isset($node->pub_id->volumetitle) ? $node->pub_id->volumetitle : ''
   );
-
-  $form['volume'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Volume'),
-    '#default_value' => isset($node->pub_id->volume) ? $node->pub_id->volume : ''
-  );
-
+  
   $form['series_name'] = array(
     '#type' => 'textfield',
     '#title' => t('Series Name'),
+    '#description' => t('Full name of (journal) series.'),
     '#default_value' => isset($node->pub_id->series_name) ? $node->pub_id->series_name : ''
   );
 
@@ -470,13 +340,6 @@ function chado_pub_form(&$node, $form_state) {
     '#default_value' => isset($node->pub_id->miniref) ? $node->pub_id->miniref : ''
   );
 
-  $form['is_obsolete'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Is Obsolete?(Check for Yes)'),
-    '#required' => TRUE,
-    '#default_value' => isset($node->pub_id->is_obsolete) ? $node->pub_id->is_obsolete : FALSE
-  );
-
   $form['publisher'] = array(
     '#type' => 'textfield',
     '#title' => t('Publisher Name'),
@@ -490,7 +353,13 @@ function chado_pub_form(&$node, $form_state) {
     '#required' => FALSE,
     '#default_value' => isset($node->pub_id->pubplace) ? $node->pub_id->pubplace  : ''
   );
-
+  
+  $form['is_obsolete'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Is Obsolete? (Check for Yes)'),
+    '#required' => TRUE,
+    '#default_value' => isset($node->pub_id->is_obsolete) ? $node->pub_id->is_obsolete : FALSE
+  );
   return $form;
 
 }
@@ -508,130 +377,50 @@ function chado_pub_form(&$node, $form_state) {
  *
  */
 function chado_pub_insert($node) {
+ 
+  // if a pub_id already exists for this node then it already exists in Chado and 
+  // we get here because we are syncing the node.  Therefore, we can skip the insert
+  if ($node->pub_id) {
+    $pub['pub_id'] = $node->pub_id;
+  }
+  else {
+    $values =  array(
+      'title' => $node->title,
+      'volumetitle' => $node->volumetitle,
+      'volume' => $node->volume,
+      'series_name' => $node->series_name,
+      'issue' => $node->issue,
+      'pyear' => $node->pyear,
+      'pages' => $node->pages,
+      'miniref' => $node->miniref,
+      'type_id' => $node->type_id,
+      'is_obsolete' => $node->is_obsolete,
+      'publisher' => $node->publisher,
+      'pubplace' => $node->pubplace,
+      'uniquename' => $node->uniquename,
+      'type_id' => $node->type_id
+    );
+    $pub = tripal_core_chado_insert('pub', $values);
+  }
 
-  $values =  array(
-    'title' => $node->title,
-    'volumetitle' => $node->volumetitle,
-    'volume' => $node->volume,
-    'series_name' => $node->series_name,
-    'issue' => $node->issue,
-    'pyear' => $node->pyear,
-    'pages' => $node->pages,
-    'miniref' => $node->miniref,
-    'type_id' => $node->type_id,
-    'is_obsolete' => $node->is_obsolete,
-    'publisher' => $node->publisher,
-    'pubplace' => $node->pubplace,
-    'uniquename' => $node->uniquename,
-    'type_id' => $node->type_id
-  );
-
-  //inserts info into chado table
-  $result = tripal_core_chado_insert('pub', $values);
-
-
-  if (isset($result)) {
-
-          //inserts the row of vid,nid,project_id into the chado_pub table
-          db_query("INSERT INTO {chado_pub} (nid, vid, pub_id) VALUES (%d, %d, %d)",
-            $node->nid,
-            $node->vid,
-            $result['pub_id']
-          );
-
-          //Aquiring information for the abstract
-          $abstract_info = tripal_core_chado_select('cvterm', array('cvterm_id'),
-            array('name' => 'abstract', 'cv_id' => array('name' => 'tripal')
-            )
-          );
-
-          //Extracting the type_id
-          $type_id = $abstract_info[0]->cvterm_id;
-
-          //setting the abstract values
-          $abstract = array(
-            'pub_id' => $result['pub_id'],
-            'type_id' => $type_id,
-            'value' => $node->abstract,
-            'rank' => 1
-          );
-
-          //inserts info into chado pubpro table for abstract
-          tripal_core_chado_insert('pubprop', $abstract);
-
-          //counter for loop
-          for ($i=0; $i<=sizeof($node->authors); $i++) {
-
-              if (isset($node->authors[$i]['author_name'] )) {
-
-                $authors = array(
-                  'pub_id' => $result['pub_id'],
-                  'rank' => $i,
-                  'surname' => $node->authors[$i]['author_name']['surname'],
-                  'givennames' => $node->authors[$i]['author_name']['givennames'],
-                  'suffix' => $node->authors[$i]['author_name']['suffix'],
-                );
-
-                  //inserts info into chado pubpro table for abstract
-                  tripal_core_chado_insert('pubauthor', $authors);
-              }
-
-          }
-
-
-          if (!empty($node->new_author['new_author_name']['surname'])) {
-
-              $authors = array(
-                  'pub_id' => $result['pub_id'],
-                  'rank' => $i+1,
-                  'surname' => $node->new_author['new_author_name']['surname'],
-                  'givennames' => $node->new_author['new_author_name']['givennames'],
-                  'suffix' => $node->new_author['new_author_name']['suffix'],
-                );
-
-                  //inserts info into chado pubpro table for abstract
-                  tripal_core_chado_insert('pubauthor', $authors);
-
-          }
-
-
-      }
-      else{
-
-        druapl_set_message('Pub_id was not set, No information has been set.');
-
+  if ($pub) {   
+    // make sure the entry for this feature doesn't already exist in the chado_pub table
+    // if it doesn't exist then we want to add it.
+    $pub_id = chado_get_id_for_node('pub', $node) ;
+    if (!$pub_id) {
+       // next add the item to the drupal table
+      $sql = "INSERT INTO {chado_pub} (nid, vid, pub_id) ".
+             "VALUES (%d, %d, %d)";
+      db_query($sql, $node->nid, $node->vid, $pub['pub_id']);
     }
-
-}
-
-
-/**
- * Implementation of tripal_pub_delete().
- *
- * This function takes a node and if the delete button has been chosen by the user, the publication
- * and it's details will be removed.Following,given the node-ID, the instance will be deleted from
- * the 'chado_pub' table.
- *
- *  @parm $node
- *    Then node which contains the information stored within the node-ID
- *
- */
-function chado_pub_delete(&$node) {
-
-  // Matching all revision, by using the node's pub_id.
-  $values =  array(
-    'pub_id' => $node->pub_id->pub_id,
-  );
-
-  //deleting row in chado table
-  tripal_core_chado_delete('pub', $values);
-
-  //deleteing in drupal chado_project table
-  db_query('DELETE FROM {chado_pub} WHERE nid = %d', $node->nid);
-
+  }
+  else {
+    drupal_set_message(t('Unable to add publication.', 'warning'));
+    watchdog('tripal_pub', 'Insert publication: Unable to create pub where values: %values',
+      array('%values' => print_r($values, TRUE)), WATCHDOG_WARNING);
+  }
 }
 
-
 /*
  *
  * Implements hook_update
@@ -643,88 +432,36 @@ function chado_pub_delete(&$node) {
  * @param $node
  *   The node being updated
  *
+ * @ingroup tripal_pub
  */
 function chado_pub_update($node) {
+  if ($node->revision) {
+    // there is no way to handle revisions in Chado but leave
+    // this here just to make not we've addressed it.
+  }
 
-
-  $values =  array(
-      'title' => $node->title,
-      'volumetitle' => $node->volumetitle,
-      'volume' => $node->volume,
-      'series_name' => $node->series_name,
-      'issue' => $node->issue,
-      'pyear' => $node->pyear,
-      'pages' => $node->pages,
-      'miniref' => $node->miniref,
-      'uniquename' => $node->uniquename,
-      'type_id' => $node->type_id,
-      'is_obsolete' => $node->is_obsolete,
-      'publisher' => $node->publisher,
-      'pubplace' => $node->pubplace,
-      'type_id' => $node->type_id
-    );
-
-  $result = db_fetch_object(db_query('SELECT pub_id FROM {chado_pub} WHERE nid=%d AND vid=%d ', $node->nid, $node->vid));
-
-  //extract pub_id from the chado table for update function
-  $match = array( 'pub_id' => $result->pub_id );
-
-  //$table to be updated, $match is the 'pub_id', $value are the values that are to be updated
-  $update_result = tripal_core_chado_update('pub', $match, $values);
-
-   //Aquiring information for the abstract
-  $abstract_info = tripal_core_chado_select('cvterm', array('cvterm_id'),
-    array('name' => 'abstract', 'cv_id' => array('name' => 'tripal')
-    )
+  $pub_id = chado_get_id_for_node('pub', $node) ;
+  // update the pub record
+  $match = array(
+     'pub_id' => $pub_id,
   );
-
-  //Grabbing the type id of the old abstract
-  $type_id = $abstract_info[0]->cvterm_id;
-
-  //Aquiring information for the abstract
-  $abstract = array(
-    'pub_id' => $result->pub_id,
-    'type_id' => $type_id,
-    'value' => $node->abstract,
-    'rank' => 1
+  $values = array(
+    'title' => $node->title,
+    'volumetitle' => $node->volumetitle,
+    'volume' => $node->volume,
+    'series_name' => $node->series_name,
+    'issue' => $node->issue,
+    'pyear' => $node->pyear,
+    'pages' => $node->pages,
+    'miniref' => $node->miniref,
+    'uniquename' => $node->uniquename,
+    'type_id' => $node->type_id,
+    'is_obsolete' => $node->is_obsolete,
+    'publisher' => $node->publisher,
+    'pubplace' => $node->pubplace,
+    'type_id' => $node->type_id
   );
-
-  //$table to be updated, $match is the 'pub_id', $value are the values that are to be updated
-  tripal_core_chado_update('pubprop', array('pub_id' => $result->pub_id, 'type_id' => $type_id, 'rank' => 1), $abstract);
-
-  //counter for loop
-  for ($i=0; $i<=sizeof($node->authors); $i++) {
-
-      if (isset($node->authors[$i]['author_name'] )) {
-
-          //if new insert
-          if (isset($node->authors[$i]['is_new'])) {
-
-              $authors = array(
-                  'pub_id' => $match['pub_id'],
-                  'rank' => $i+1,
-                  'surname' => $node->authors[$i]['author_name']['surname'],
-                  'givennames' => $node->authors[$i]['author_name']['givennames'],
-                  'suffix' => $node->authors[$i]['author_name']['suffix'],
-              );
-
-              //inserts info into chado pubpro table for abstract
-              tripal_core_chado_insert('pubauthor', $authors);
-
-          }
-          else{
-
-            //update
-            //$table=pubauthor to be updated, $match=author_match is the 'pub_id', $value=author are the values that are to be updated
-            tripal_core_chado_update('pubauthor', array('pub_id' => $match['pub_id'], 'rank' => $node->authors[$i]['author_name']['rank']), $node->authors[$i]['author_name']);
-
-          }
-
-      }
-
-  }
-
-
+  $status = tripal_core_chado_update('pub', $match, $values);
 }
 
 
@@ -740,538 +477,145 @@ function chado_pub_update($node) {
  *
  */
 function chado_pub_load($node) {
+  // get the feature details from chado
+  $pub_id = chado_get_id_for_node('pub', $node);
 
-  $result = db_fetch_object(db_query('SELECT * FROM {chado_pub} WHERE nid=%d AND vid=%d ', $node->nid, $node->vid));
-
-  $values = array(
-    'pub_id' => $result->pub_id,
-  );
+  $values = array('pub_id' => $pub_id);
+  $pub = tripal_core_generate_chado_var('pub', $values); 
 
-
-  if (empty($result->pub_id)) {
-
-    drupal_set_message(t("Unable to find publication"), 'error');
-
-  }
-  else{
-
-    $node->pub = tripal_core_generate_chado_var('pub', $values);
-
-    // add in authors
-    $authors = tripal_core_chado_select(
-      'pubauthor',
-      array('rank', 'surname', 'givennames', 'suffix'),
-      array('pub_id' => $node->pub->pub_id)
-    );
-    foreach ($authors as $author) {
-        $node->pub->authors[$author->rank] = $author;
-    }
-    ksort($node->pub->authors);
-
-  }
-
-  return $node;
-
-}
-
-/**
- * Submit handler for 'Add Author' button on node form.
- */
-function tripal_pub_add_author_submit($form, &$form_state) {
-
-    $form_state['remove_delta'] = 0;
-
-    // Set the form to rebuild and run submit handlers.
-    node_form_submit_build_node($form, $form_state);
-
-    // Make the changes we want to the form state.
-    if ($form_state['values']['author_more']) {
-
-      $new_author = array();
-
-      $new_author['author_name'] = $form_state['values']['new_author']['new_author_name'];
-      $new_author['is_new'] = TRUE;
-
-      $form_state['new_author'] = $new_author;
-
-    }
-
-
-
-}
-
-
-/**
- * Submit handler for 'Edit' button on node form.
- */
-function tripal_pub_edit_author_submit($form, &$form_state) {
-
-    // remember which author we're editing
-    $delta = $form_state['values']['edit_author']['delta'];
-
-    //add changes author details back
-    $rank = $form_state['values']['authors'][$delta]['author_name']['rank'];
-    $form_state['values']['authors'][$delta]['author_name'] = $form_state['values']['edit_author']['edit_author_name'];
-    $form_state['values']['authors'][$delta]['author_name']['rank'] = $rank;
-
-    //ensures that after they save their changes the edit fieldstate goes away
-    unset($form_state['values']['edit_author']);
-
-    // Set the form to rebuild and run submit handlers.
-    node_form_submit_build_node($form, $form_state);
-
-}
-
-
-/**
- * Submit handler for 'Edit' button on node form.
- */
-function tripal_pub_set_edit_author_submit($form, &$form_state) {
-
-  $form_state['remove_delta'] = 0;
-
-  // Make the changes we want to the form state
-  $edit_author = array();
-
-  if (preg_match('/edit_author_(\d+)/', $form_state['clicked_button']['#name'], $matches)) {
-
-
-    $delta = $matches[1];
-
-    $form_state['values']['edit_author'] = $form_state['values']['authors'][$delta];
-
-    $form_state['values']['edit_author']['delta'] = $delta;
-
-  }
-
-  // Set the form to rebuild and run submit handlers.
-  node_form_submit_build_node($form, $form_state);
+  $additions = new stdClass();
+  $additions->pub = $pub;
+  return $additions;
 
 }
 
-
 /**
- * Submit handler for 'Remove' button on node form.
- */
-function tripal_pub_remove_row_submit($form, &$form_state) {
-
-
-  if (preg_match('/remove_author_(\d+)/', $form_state['clicked_button']['#name'], $matches)) {
-
-    $delta = $matches[1];
-
-    $form_state['values']['remove_author'] = $form_state['values']['authors'][$delta];
-
-    $form_state['values']['remove_author']['delta'] = $delta;
-
-  }
-
-  $values =  array(
-    'pub_id' => $form_state['values']['pub_id'],
-    'rank' => $form_state['values']['authors'][$delta]['author_name']['rank']
-
-    );
-
-  //deleting row in chado table
-  tripal_core_chado_delete('pubauthor', $values);
-
-
-  // Set the form to rebuild and run submit handlers.
-  node_form_submit_build_node($form, $form_state);
-
-}
-
-
-/*
+ * Implementation of tripal_pub_delete().
  *
+ * This function takes a node and if the delete button has been chosen by the user, the publication
+ * and it's details will be removed.Following,given the node-ID, the instance will be deleted from
+ * the 'chado_pub' table.
  *
+ *  @parm $node
+ *    Then node which contains the information stored within the node-ID
  *
  */
-function tripal_pub_js($delta = 0) {
-
-    $form = tripal_pub_ajax_form_handler($delta);
-
-    // Render the new output.
-    $author_form = $form['author_wrapper']; //was ['author']
-
-    // Prevent duplicate wrappers.
-    unset($author_form['#prefix'], $author_form['#suffix']);
-
-    $output = theme('status_messages') . drupal_render($author_form);
-
-    // AHAH does not know about the "Remove" button.
-    // This causes it not to attach AHAH behaviours to it after modifying the form.
-    // So we need to tell it first.
-    $javascript = drupal_add_js(NULL, NULL);
-
-    if (isset($javascript['setting'])) {
-
-      $output .= '<script type="text/javascript">jQuery.extend(Drupal.settings, '. drupal_to_js(call_user_func_array('array_merge_recursive', $javascript['setting'])) .');</script>';
-
-    }
-
-    // Final rendering callback.
-    drupal_json(array('status' => TRUE, 'data' => $output));
-
-}
-
-
-/**
- * AJAX form handler.
- */
-function tripal_pub_ajax_form_handler($delta=0 ) {
-
-    // The form is generated in an include file which we need to include manually.
-    include_once 'modules/node/node.pages.inc';
-
-    $form_state = array('storage' => NULL, 'submitted' => FALSE);
-
-    $form_build_id = filter_xss($_POST['form_build_id']);
-
-    // Get the form from the cache.
-    $form = form_get_cache($form_build_id, $form_state);
-
-    $args = $form['#parameters'];
-
-    $form_id = array_shift($args);
-
-    // We need to process the form, prepare for that by setting a few internals.
-    $form_state['post'] = $form['#post'] = $_POST;
-
-    $form['#programmed'] = $form['#redirect'] = FALSE;
-
-    // Set up our form state variable, needed for removing authors.
-    $form_state['remove_delta'] = $delta;
-
-    // Build, validate and if possible, submit the form.
-    drupal_process_form($form_id, $form, $form_state);
-
-    // If validation fails, force form submission.
-    if (form_get_errors()) {
-
-      form_execute_handlers('submit', $form, $form_state);
+function chado_pub_delete(&$node) {
 
-    }
+  $pub_id = chado_get_id_for_node('pub', $node);
 
-    // This call recreates the form relying solely on the form_state that the
-    // drupal_process_form set up.
-    $form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
+  // if we don't have a pub id for this node then this isn't a node of
+  // type chado_pub or the entry in the chado_pub table was lost.
+  if (!$pub_id) {
+    return;
+  }
 
-    return $form;
+  // Remove data from {chado_pub}, {node} and {node_revisions} tables of
+  // drupal database
+  $sql_del = "DELETE FROM {chado_pub} ".
+             "WHERE nid = %d ".
+             "AND vid = %d";
+  db_query($sql_del, $node->nid, $node->vid);
+  $sql_del = "DELETE FROM {node_revisions} ".
+             "WHERE nid = %d ".
+             "AND vid = %d";
+  db_query($sql_del, $node->nid, $node->vid);
+  $sql_del = "DELETE FROM {node} ".
+             "WHERE nid = %d ".
+             "AND vid = %d";
+  db_query($sql_del, $node->nid, $node->vid);
+
+  // Remove data from pub and pubprop tables of chado database as well
+  chado_query("DELETE FROM {pubprop} WHERE pub_id = %d", $pub_id);
+  chado_query("DELETE FROM {pub} WHERE pub_id = %d", $pub_id);
 }
 
-
 /*
- *
- *
+ * 
  */
-function theme_tripal_pub_author_table($form) {
-
-  $rows = array();
-
-  $headers = array(
-    t('Givennames'),
-    t('Surname'),
-    t('Suffix'),
-    '',  // Blank header title for the remove link.
-  );
-
-  foreach (element_children($form) as $key) {
-
-    // No need to print the field title every time.
-    unset(
-      $form[$key]['author_name_text']['#title'],
-      $form[$key]['author_name_text-2']['#title'],
-      $form[$key]['author_name_text-3']['#title'],
-      $form[$key]['remove_author']['#title']
-    );
-
-    // Build the table row.
-    $row = array(
-      'data' => array(
-        array('data' => drupal_render($form[$key]['author_name']) . drupal_render($form[$key]['author_name_text']), 'class' => 'author-name'),
-        array('data' => drupal_render($form[$key]['author_name']) . drupal_render($form[$key]['author_name_text-2']), 'class' => 'author-name'),
-        array('data' => drupal_render($form[$key]['author_name']) . drupal_render($form[$key]['author_name_text-3']), 'class' => 'author-name'),
-        array('data' => drupal_render($form[$key]['edit_author']) . drupal_render($form[$key]['remove_author']), 'class' => 'remove-author'),
-      ),
-    );
-
-    // Add additional attributes to the row, such as a class for this row.
-    if (isset($form[$key]['#attributes'])) {
-
-      $row = array_merge($row, $form[$key]['#attributes']);
 
+function tripal_pub_form_alter(&$form, &$form_state, $form_id) {
+  if ($form_id == "tripal_pub_importer_setup_form") {    
+    // updating the form through the ahah callback sets the action of
+    // the form to the ahah callback URL. We need to set it back
+    // to the normal form URL
+    if ($form_state['values']['action'] == 'edit') {
+      $form['#action'] = url("admin/tripal/tripal_pub/import/edit/" . $form['pub_import_id']);
+    } 
+    if ($form_state['values']['action'] == 'add') {
+      $form['#action'] = url("admin/tripal/tripal_pub/import/add");
     }
-
-    $rows[] = $row;
-
   }
-
-  //$output = theme('table', $headers, $rows);
-
-  $output .= drupal_render($form);
-
-  return $output;
-
-}
+} 
 
 /**
- *
- * Helper function to define populated form field elements for publication node form.
- *
- */
-function tripal_pub_author_display_form($delta, $author) {
-
-  $form = array(
-    '#tree' => TRUE,
-  );
-
-  // Author Name
-  $form['author_name'] = array(
-    '#type' => 'hidden',
-    '#value' => $author,
-    '#parents' => array('authors', $delta),
-  );
-  $form['author_name_text'] = array(
-    '#type' => 'item',
-    '#title' => t('Givennames'),
-    '#parents' => array('authors', $delta),
-    '#value' => $author['author_name']['givennames'],
-  );
-
-  $form['author_name_text-2'] = array(
-    '#type' => 'item',
-    '#title' => t('Surname'),
-    '#parents' => array('authors', $delta),
-    '#value' => $author['author_name']['surname'],
-  );
-
-  $form['author_name_text-3'] = array(
-    '#type' => 'item',
-    '#title' => t('Suffix'),
-    '#parents' => array('authors', $delta),
-    '#value' => $author['author_name']['suffix'],
-  );
-
-    // Remove button.
-    $form['remove_author'] = array(
-        '#type' => 'submit',
-        '#name' => 'remove_author_' . $delta,
-        '#value' => t('Remove'),
-        '#submit' => array('tripal_pub_remove_row_submit'),
-        '#parents' => array('authors', $delta, 'remove_author'),
-        '#ahah' => array(
-          'path' => 'tripal_pub/js/0',
-          'wrapper' => 'author-wrapper',
-          'method' => 'replace',
-          'effect' => 'fade',
-        ),
-    );
-
-      // Edit Author button
-    $form['edit_author'] = array(
-        '#type' => 'submit',
-        '#name' => 'edit_author_' . $delta,
-        '#value' => t('Edit'),
-        '#submit' => array('tripal_pub_set_edit_author_submit'),
-        '#parents' => array('authors', $delta, 'edit_author'),
-        '#ahah' => array(
-          'path' => 'tripal_pub/js/0',
-          'wrapper' => 'author-wrapper',
-          'method' => 'replace',
-          'effect' => 'fade',
-        ),
-    );
-
-  return $form;
-}
-
-
-/*
- * This function executes commands periodically. This is called whenever a cron run occurs. This
- * function uses the time interval that the user has entered. This Publication module, requires
- * that the program is ran in pre-determined intervals, as desired by the user. By using a time stamp
- * and comparing the current time and the time that the last time a cron was ran, this program will
- *  be ran.
- *
- *
- * @TODO: The cron function is not working correctly, not sure why the cron is not working properly.
- *
- *
- *
- */
-/**
-function tripal_pub_cron(){
-
-      global $user;    //needed to make the current users details available so access of user id is available
-
-      //Aquiring the current time
-      $current_time = time();
-
-      //Aquiring the user entered time interval
-      $user_interval = variable_get('time_interval',NULL);
-
-      //converting the user entered interval into seconds for use with unix time stamp
-      $converted_interval = ($user_interval*60);
-
-      //Accessing database for time stamp from watchdog
-      $cron = db_result(db_query('select timestamp from {watchdog} where type="cron" order by timestamp desc limit 1'));
-
-      //debugging print statement
-      //print($cron);
-
-      //taking variable value & assigning for use
-      $cron_last = variable_get('cron', time());
-
-      $updated_interval = $cron_last - $converted_interval;
-
-      if($current_time >= $updated_interval ){
-
-        tripal_add_job('Search & Load PubMed Publications', 'tripal_pub', 'tripal_pub_search_load_pubmed_publications', $job_args, $user->uid);
-
-      }
-
-}
-  */
-
-
-
-
-//-----------------------------------------------------------------------------
-//  SECTION: Custom form Elements
-//-----------------------------------------------------------------------------
-
-
-/*
- * This fucnction tells the FAPI(Form-API) that this is a element that will carry a value, contains
- * arrays of callback function names. Will declare an element will create a reuseable element type.
- *
- *  @return
- *      An associative array with the name of each element type as a key and an
- *      array of attributes describingthe type as a value
- */
-function tripal_pub_elements() {
-
-      return array(
-          'publication_author' => array(
-               '#input' => TRUE,
-               '#process' => array('expand_publication_author'),
-               '#element_validate' => array('publication_author_validate'),
-              ),
-      );
-
-}
-
-
-/*
- *
  *
  *
+ * @ingroup tripal_pub
  */
-function expand_publication_author($element) {
-
-    if (empty($element['#value'])) {
-      $element['#value'] = array(
-              'givennames' => '',
-              'suffix' => '',
-              'surname' => '',
-            );
-
-    }
-
-    $element['#tree'] = TRUE;
-
-    $parents = $element['#parents'];
-
-    $parents[] = 'givennames';
-
-    $element['givennames'] = array(
-    '#type' => 'textfield',
-              '#size' => 10,
-              //'#maxlength' => TRUE,
-              //'#default_value'=> $element['#value']['#given'],
-              '#prefix' => 'Given Name',
-    );
-
-    if ($element['#default_value']) {
-
-      $element['givennames']['#default_value'] = $element['#default_value']['givennames'];
-
-    }
-
-    $parents = $element['#parents'];
-
-    $parents[]= 'surname';
-
-    $element['surname'] = array(
-    '#type' => 'textfield',
-              '#size' => 10,
-              //'#maxlength' => TRUE,
-              //'#default_value'=> $element['#value']['#surname'],
-              '#prefix' => 'Surname',
-    );
-
-    if ($element['#default_value']) {
-
-      $element['surname']['#default_value'] = $element['#default_value']['surname'];
-
-    }
-
-    $parents = $element['#parents'];
-
-    $parents[]= 'suffix';
-
-    $element['suffix'] = array(
-    '#type' => 'textfield',
-              '#size' => 5,
-              //'#maxlength' => TRUE,
-              //'#default_value'=> $element['#value']['#suffix'],
-              '#prefix' => 'suffix',
-    );
-
-    if ($element['#default_value']) {
-
-      $element['suffix']['#default_value'] = $element['#default_value']['suffix'];
-
-    }
-
-  return $element;
-
-}
+function tripal_pub_preprocess_tripal_pub_relationships(&$variables) {
+  // we want to provide a new variable that contains the matched pubs.
+  $pub = $variables['node']->pub;
+
+  // normally we would use tripal_core_expand_chado_vars to expand our
+  // organism object and add in the relationships, however whan a large
+  // number of relationships are present this significantly slows the
+  // query, therefore we will manually perform the query
+  $sql = "
+    SELECT P.title, P.pub_id, CP.nid, CVT.name as rel_type
+    FROM pub_relationship PR
+      INNER JOIN {pub} P            ON PR.object_id = P.pub_id
+      INNER JOIN {cvterm} CVT       ON PR.type_id   = CVT.cvterm_id
+      LEFT JOIN public.chado_pub CP ON P.pub_id     = CP.pub_id
+    WHERE PR.subject_id = %d
+  ";
+  $as_subject = chado_query($sql, $pub->pub_id);
+  $sql = "
+    SELECT P.title, P.pub_id, CP.nid, CVT.name as rel_type
+    FROM pub_relationship PR
+      INNER JOIN {pub} P            ON PR.subject_id = P.pub_id
+      INNER JOIN {cvterm} CVT       ON PR.type_id    = CVT.cvterm_id
+      LEFT JOIN public.chado_pub CP ON P.pub_id      = CP.pub_id
+    WHERE PR.object_id = %d
+  ";
+  $as_object = chado_query($sql, $pub->pub_id);
+
+  // combine both object and subject relationshisp into a single array
+  $relationships = array();
+  $relationships['object'] = array();
+  $relationships['subject'] = array();
+
+  // iterate through the object relationships
+  while ($relationship = db_fetch_object($as_object)) {
+
+     // get the relationship and child types
+     $rel_type = t(preg_replace('/_/', " ", $relationship->rel_type));
+     $sub_type = t(preg_replace('/_/', " ", $relationship->sub_type));
+
+     if (!array_key_exists($rel_type, $relationships['object'])) {
+       $relationships['object'][$rel_type] = array();
+     }
+     if (!array_key_exists($sub_type, $relationships['object'][$rel_type])) {
+       $relationships['object'][$rel_type][$sub_type] = array();
+     }
+     $relationships['object'][$rel_type][$sub_type][] = $relationship;
+  }
 
+  // now add in the subject relationships
+  while ($relationship = db_fetch_object($as_subject)) {
 
-/*
- *
- *
- *
- */
-function theme_publication_author($element) {
-  return theme('form_element', $element, '<div class="container-inline">' . $element['#children'] . '</div>');
-}
+     // get the relationship and child types
+     $rel_type = t(preg_replace('/_/', " ", $relationship->rel_type));
+     $obj_type = t(preg_replace('/_/', " ", $relationship->obj_type));
 
-/*
- *
- *
- *
- */
-function publication_author_validate($element) {
-  if ($element['#required']) {
-    if (trim($element['#value']['givennames']) == '' || trim($element['#value']['suffix']) == '' || trim($element['#value']['surname']) == '' ||
-      !is_string($element['#value']['givennames']) || !is_string($element['#value']['givennames']) || !is_string($element['#value']['surname'])) {
-      form_error($element, t('The Author name is required.'));
-    }
+     if (!array_key_exists($rel_type, $relationships['subject'])) {
+       $relationships['subject'][$rel_type] = array();
+     }
+     if (!array_key_exists($obj_type, $relationships['subject'][$rel_type])) {
+       $relationships['subject'][$rel_type][$obj_type] = array();
+     }
+     $relationships['subject'][$rel_type][$obj_type][] = $relationship;
   }
-}
 
-/*
- * 
- */
-
-function tripal_pub_form_alter(&$form, &$form_state, $form_id) {
-  if ($form_id == "tripal_pub_remote_search_form") {    
-    // updating the form through the ahah callback sets the action of
-    // the form to the ahah callback URL. We need to set it back
-    // to the normal form URL
-    $form['#action'] = url("admin/tripal/tripal_pub/import_setup");
-  }
+  $pub->all_relationships = $relationships;
 }