Selaa lähdekoodia

Provided some code clenup for the analysis module, added new API functions to the tripal_feature module, and added new case checking to some of the API calls in the Tripal core

spficklin 12 vuotta sitten
vanhempi
commit
ed0dad3cf7

+ 25 - 8
tripal_analysis/tripal_analysis.install

@@ -15,9 +15,18 @@ function tripal_analysis_install() {
   // Use schema API to create database table.
   drupal_install_schema('tripal_analysis');
 
-  // Create analysisfeatureprop table in chado. This cannot be accomplished
-  // by calling drupal_install_schema because it's not in the drupal db. This
-  // table is used to store Blast xml and Interpro html/goterms
+  // we may need the analysisfeatureprop table if it doesn't already exist
+  tripal_analysis_create_analysisfeatureprop();
+  
+  // add cvterms
+  tripal_analysis_add_cvterms();
+}
+/*
+ * 
+ */
+function tripal_analysis_create_analysisfeatureprop(){
+  // Create analysisfeatureprop table in chado.  This is needed for Chado 
+  // version 1.11, the table exists in Chado 1.2. 
   if (!db_table_exists('analysisfeatureprop')) {
     $sql = "CREATE TABLE analysisfeatureprop (".
             "  analysisfeatureprop_id SERIAL PRIMARY KEY, ".
@@ -30,9 +39,14 @@ function tripal_analysis_install() {
             "  CONSTRAINT analysisfeature_id_type_id_rank UNIQUE(analysisfeature_id, type_id, rank)".
             ")";
     chado_query($sql);
-  }
-
-  // add some cvterms
+  } 
+}
+/*
+ * 
+ */
+function tripal_analysis_add_cvterms(){
+  
+  // add analysis_type
   $term = array(
     'name' => 'analysis_type', 
     'def' => 'The type of analysis was performed. This value is automatically set by '.
@@ -40,18 +54,21 @@ function tripal_analysis_install() {
              '(e.g. tripal_analysis_blast, tripal_analysis_go).'
   );
   tripal_cv_add_cvterm($term, 'tripal', 0, 1, 'tripal');
+  
+  // add analysis_date
   $term = array(
     'name' => 'analysis_date', 
     'def' => 'The date that an analysis was performed.'
   );
   tripal_cv_add_cvterm($term, 'tripal', 0, 1, 'tripal');
+  
+  // add analysis_short_name
   $term = array(
     'name' => 'analysis_short_name', 
     'def' => 'A computer legible (no spaces or special characters) abbreviation for the analysis.'
   );     
-  tripal_cv_add_cvterm($term, 'tripal', 0, 1 , 'tripal');
+  tripal_cv_add_cvterm($term, 'tripal', 0, 1 , 'tripal'); 
 }
-
 /**
  * Implementation of hook_uninstall().
  */

+ 2 - 0
tripal_analysis/tripal_analysis.module

@@ -16,6 +16,8 @@
 
 require('api/tripal_analysis.api.inc');
 require('includes/tripal_analysis_privacy.inc');
+require('includes/tripal_analysis.admin.inc');
+
 
 
 /**

+ 25 - 9
tripal_core/api/tripal_core_chado.api.inc

@@ -2083,7 +2083,7 @@ function tripal_core_expand_chado_vars($object, $type, $to_expand, $table_option
 
   // make sure we have a value
   if (!$object) {
-    watchdog('tripal_core', 'Cannot pass non array as $object.', array(),WATCHDOG_ERROR);
+    watchdog('tripal_core', 'Cannot pass non array as $object.', array(), WATCHDOG_ERROR);
     return $object;  
   }
   
@@ -2602,7 +2602,7 @@ function tripal_core_get_property($basetable, $record_id, $property, $cv_name) {
 
   // construct the array of values to be selected
   $values = array(
-  $fkcol => $record_id,
+    $fkcol => $record_id,
     'type_id' => array(
       'cv_id' => array(
         'name' => $cv_name,
@@ -2612,7 +2612,9 @@ function tripal_core_get_property($basetable, $record_id, $property, $cv_name) {
     ),
   );
   $results = tripal_core_generate_chado_var($basetable . 'prop', $values);
-  $results = tripal_core_expand_chado_vars($results, 'field', $basetable . 'prop.value');
+  if ($results) {
+    $results = tripal_core_expand_chado_vars($results, 'field', $basetable . 'prop.value');
+  }
 
   return $results;
 }
@@ -2680,26 +2682,40 @@ $cv_name, $value, $update_if_present = 0) {
     array('!prop_name' => $property), WATCHDOG_ERROR);
   }
 
-
+  // make sure the cvterm exists.  Otherwise we'll get an error with
+  // prepared statements not matching
+  $values = array(
+    'cv_id' => array(
+      'name' => $cv_name,
+    ),
+    '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) {
+    return FALSE;
+  }
+  
   // get the foreign key for this property table
   $table_desc = tripal_core_get_chado_table_schema($basetable . 'prop');
   $fkcol = key($table_desc['foreign keys'][$basetable]['columns']);
 
   // construct the array of values to be inserted
   $values = array(
-  $fkcol => $record_id,
+    $fkcol => $record_id,
     'type_id' => array(
       'cv_id' => array(
         'name' => $cv_name,
-  ),
+      ),
       'name' => $property,
-      'is_obsolete' => 0
-  ),
+    ),
     'value' => $value,
     'rank' => $rank,
   );
 
-  return tripal_core_chado_insert($basetable . 'prop', $values);
+  $options = array('statement_name' => 'ins_' . $basetable . 'prop_' . substr($fkcol, 0, 2) . 'tyvara');
+  $result = tripal_core_chado_insert($basetable . 'prop', $values, $options);
+  return $result;
 }
 
 /**

+ 53 - 0
tripal_core/api/tripal_core_misc.api.inc

@@ -0,0 +1,53 @@
+<?php 
+/**
+ * This function implements a pager, similar to a pager for a database query
+ * using a non query.  Rather than pass a query as in pager_query function, a 
+ * callback function should recieve as it's first argument an array of the 
+ * argumetns passed to this function. The second argument should be the 
+ * number of results to retreive, and the third argument should be the the
+ * element index (same as with pager_query) function.  The callback function
+ * should always return an array. If no values are available then an empty 
+ * array should be returned.
+ * 
+ * @param $func
+ *  The name of the callback function used to retrieve the results. The
+ *  callback function should have three arguments: first, an array of values
+ *  passed into the tripal_pager_callback; second, the start index of
+ *  the paged values; third, the number of records to include.
+ * @param cfunc
+ *  The name of the callback function used to specify the total results. The
+ *  callback f unction should receive one argument: an array of values that
+ *  are passed into the tripal_pager_callbck function. 
+ * @param limit
+ *  The number of records to include in the paged results
+ * @param element
+ *  A unique integer ID if more than one pager exists on a page.  if multiple
+ *  types of pagers (e.g. pager_query, chado_pager_query) are on the same
+ *  page then this parameter should be unique amongst them all.
+ */
+function tripal_pager_callback($func, $cfunc, $limit = 9, $element = 0) {
+  
+  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, 3);
+  // Alternative syntax for '...'
+  if (isset($args[0]) && is_array($args[0])) {
+    $args = $args[0];
+  }
+
+  $count = $cfunc($args);  
+  
+  // Convert comma-separated $page to an array, used by other functions.
+  $pager_page_array = explode(',', $page);
+
+  // We calculate the total of pages as ceil(items / limit).
+  $pager_total_items[$element] = $count;
+  $pager_total[$element] = ceil($pager_total_items[$element] / $limit);
+  $pager_page_array[$element] = max(0, min((int)$pager_page_array[$element], ((int)$pager_total[$element]) - 1));
+  
+  // retrieve the results using the specified callback.
+  return $func($args, $pager_page_array[$element] * $limit, $limit);
+}

+ 1 - 0
tripal_core/tripal_core.module

@@ -44,6 +44,7 @@ require_once "api/tripal_core_ahah.api.inc";
 require_once "api/tripal_core_custom_tables.api.inc";
 require_once "api/tripal_core_jobs.api.inc";
 require_once "api/tripal_core_mviews.api.inc";
+require_once "api/tripal_core_misc.api.inc";
 require_once "includes/jobs.php";
 require_once "includes/mviews.php";
 require_once "includes/custom_tables.php";

+ 126 - 4
tripal_feature/api/tripal_feature.api.inc

@@ -87,8 +87,7 @@ function tripal_feature_analysis_get_property($analysis_id = NULL, $feature_id =
  * @ingroup tripal_feature_api
  */
 function tripal_feature_analysis_insert_property($analysis_id = NULL, $feature_id = NUll,
-  $analysisfeature_id = NULL, $property, $value, $update_if_present = 0,
-  $cv_name = 'tripal') {
+  $analysisfeature_id = NULL, $property, $value, $update_if_present = 0, $cv_name = 'tripal') {
 
   // check that the incoming arguments are correct
   if (($analysis_id and !$feature_id) or
@@ -107,8 +106,15 @@ function tripal_feature_analysis_insert_property($analysis_id = NULL, $feature_i
   }
 
   // insert the property.
-  return tripal_core_insert_property('analysisfeature', $analysisfeature_id,
+  $success = tripal_core_insert_property('analysisfeature', $analysisfeature_id,
     $property, $cv_name, $value, $update_if_present);
+  if (!$success) {
+     watchdog('tripal_feature',
+      'tripal_feature_analysis_insert_property: Failed to insert analysis feature property',
+       array(), WATCHDOG_WARNING);  
+     return FALSE;
+  }
+  return $success;
 }
 
 /**
@@ -928,4 +934,120 @@ function tripal_feature_get_feature_relationships($feature) {
     }
   }
   return $relationships;
-} 
+} 
+
+/*
+ * This function adds an entry to the feature_dbxref table.
+  *
+ * @param $feature_id
+ *   The numeric feature_if of the feature 
+ * @param $dbname
+ *   The name of the database to which the term belongs
+ * @param accession
+ *   The accession of the term   
+ *    
+ * @return
+ *   TRUE on success. FALSE on failure.
+ *
+ * @ingroup tripal_feature_api
+ */
+function tripal_feature_add_dbxref($feature_id, $dbname, $accession) {
+   
+  // make sure the db exists. If it doesn't, then add it
+  $values = array('name' => $dbname);
+  $options = array('statement_name' => 'sel_db_na');
+  $db = tripal_core_chado_select('db', array('db_id'), $values, $options);
+  if (!$db or count($db) == 0) {    
+    $options = array('statement_name' => 'ins_db_na');
+    $success = tripal_core_chado_insert('db', $values, $options);
+      if (!$success) {
+      watchdog('tripal_feature', 'tripal_feature_add_dbxref: The feature dbxref entry for feature, %feature_id, ". 
+        "could not be added because the database, %dbname, does not exist and cannot be added.', 
+        array('%feature_id' => $feature_id, '%dbname' => $dbname), WATCHDOG_WARNING);
+      return FALSE;
+    }
+  }
+  
+  // first make sure that the record doesn't already exist
+  $values = array(
+    'dbxref_id' => array(
+      'accession' => $accession,
+      'db_id' => array(
+        'name' => $dbname
+      ),
+    ),
+    'feature_id' => $feature_id,
+  );
+  $options = array('statement_name' => 'sel_featuredbxref_dbfe');
+  $xref = tripal_core_chado_select('feature_dbxref', array('feature_dbxref_id'), $values, $options);
+  if (count($xref) == 0) {    
+    // if the record doesn't exist then add it.
+    $options = array('statement_name' => 'ins_featuredbxref_dbfe');
+    $success = tripal_core_chado_insert('feature_dbxref', $values, $options);
+    if (!$success) {
+      watchdog('tripal_feature', 'tripal_feature_add_dbxref: The feature dbxref entry for feature, %feature_id, '. 
+        'could not be added: %db:%accession.', array('%feature_id' => $feature_id, '%db' => $dbname, 
+        '%accession' => $accession), WATCHDOG_WARNING);
+      return FALSE;
+    }
+  }
+  return TRUE;
+}
+
+/*
+ * This function adds an entry to the feature_cvterm table.
+  *
+ * @param $feature_id
+ *   The numeric feature_if of the feature 
+ * @param $cvname
+ *   The name of the controlled vocabulary to which the term belongs
+ * @param cvterm
+ *   The name of the cvterm  
+ *    
+ * @return
+ *   TRUE on success. FALSE on failure.
+ *
+ * @ingroup tripal_feature_api
+ */
+function tripal_feature_add_cvterm($feature_id, $cvname, $cvterm) {
+   
+  // make sure the cv exists. If it doesn't, then add it
+  $values = array('name' => $cvname);
+  $options = array('statement_name' => 'sel_cv_na');
+  $cv = tripal_core_chado_select('cv', array('cv_id'), $values, $options);
+  if (!$cv or count($cv) == 0) {    
+    $options = array('statement_name' => 'ins_cv_na');
+    $success = tripal_core_chado_insert('cv', $values, $options);
+      if (!$success) {
+      watchdog('tripal_feature', 'tripal_feature_add_cvterm: The feature cvterm entry for feature, %feature_id, ". 
+        "could not be added because the CV, %cvname, does not exist and cannot be added.', 
+        array('%feature_id' => $feature_id, '%cvname' => $cvname), WATCHDOG_WARNING);
+      return FALSE;
+    }
+  }
+  
+  // first make sure that the record doesn't already exist
+  $values = array(
+    'cvterm_id' => array(
+      'name' => $cvterm,
+      'cv_id' => array(
+        'name' => $cvname
+      ),
+    ),
+    'feature_id' => $feature_id,
+    'pub_id' => 1,
+  );
+  $options = array('statement_name' => 'sel_featuredcvterm_cvfepu');
+  $xref = tripal_core_chado_select('feature_cvterm', array('feature_cvterm_id'), $values, $options);
+  if (count($xref) == 0) {    
+    // if the record doesn't exist then add it.
+    $options = array('statement_name' => 'ins_featurecvterm_cvfepu');
+    $success = tripal_core_chado_insert('feature_cvterm', $values, $options);
+    if (!$success) {
+      watchdog('tripal_feature', 'tripal_feature_add_cvterm: The feature cvterm entry for feature, %feature_id, '. 
+        'could not be added: %cvterm.', array('%feature_id' => $feature_id, '%cvterm' => $cvterm), WATCHDOG_WARNING);
+      return FALSE;
+    }
+  }
+  return TRUE;
+}

+ 292 - 0
tripal_pub/includes/pubmed.inc

@@ -0,0 +1,292 @@
+<?php 
+/**
+ * @file
+ * Tripal Pub PubMed Interface
+ *
+ * @defgroup tripal_pub_pubmed PubMed Interface
+ * @ingroup tripal_pub
+ */
+
+/**
+ *
+ */
+function tripal_pub_remote_search_pubmed($terms_str, $num_to_retrieve, $pager_id) {
+
+  // convert the terms list provicded by the caller into a string with words
+  // separated by a '+' symbol.
+  $search_terms = implode("+", preg_split('/\s+/', trim($terms_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',
+    'tripal_pub_remote_search_pubmed_count', $num_to_retrieve, $pager_id, $search_terms);
+  
+  if ($pubs) {
+    foreach ($pubs as $pub) {
+      /*
+      $pmid = $output[$i];
+  
+      //aquiring the pubmed id from the pub table based on the uniquename
+      $values = array( 'uniquename' => $pmid);
+      $pubmed_id = tripal_core_chado_select('pub', array('pub_id'), $values); */
+    }
+  }
+  return $pubs;
+}
+
+/*
+ * This function is used as the callback function when used with the
+ * tripal_pager_callback function.  This function returns a count of
+ * the dataset to be paged.
+ */
+function tripal_pub_remote_search_pubmed_count($terms) {
+
+  // do a quick query using the provided terms, set the session variables
+  // so we can reuse this query and then return the total number of records.
+  $results = tripal_pub_remote_search_pubmed_query($terms);
+  $_SESSION['tripal_pub_pubmed_query']['WebEnv'] = $results['WebEnv'];
+  $_SESSION['tripal_pub_pubmed_query']['QueryKey'] = $results['QueryKey'];
+    
+  return $total_records;
+}
+
+/*
+ * This function is used as the callback function when used with the
+ * tripal_pager_callback function.  This function returns the results
+ * within the specified range
+ */
+function tripal_pub_remote_search_pubmed_range($terms, $start = 0, $limit = 10) {
+
+  // get the query_key and the web_env from the previous count query.
+  $query_key = $_SESSION['tripal_pub_pubmed_query']['QueryKey'];
+  $web_env = $_SESSION['tripal_pub_pubmed_query']['WebEnv'];
+     
+  // repeat the search performed previously (using WebEnv & QueryKey) to retrieve
+  // the PMID's within the range specied.  The PMIDs will be returned as a text list
+  $pmids_txt = tripal_pub_remote_search_pubmed_fetch($terms, $query_key, $web_env, 'uilist', $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) {
+    
+    // first intialize the search for a single PMID. This will give us a new query key and Web env 
+    $term = $pmid . "[uid]";    
+    $query = tripal_pub_remote_search_pubmed_query($terms); 
+    
+    // second retrieve the individual record
+    $pub_xml = tripal_pub_remote_search_pubmed_fetch($terms, $query['QueryKey'], $query['WebEnv'], 'xml', 0, 1); 
+    $pubs[] = $pub_xml;
+    
+  } 
+  return $pubs;
+}
+
+/*
+ * 
+ */
+function tripal_pub_remote_search_pubmed_query($terms){
+   
+  // 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
+  // those requested in the range.
+  $query_url = "http://www.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=Pubmed&retmax=1&usehistory=y&term=$terms";
+  $rfh = fopen($query_url, "r");
+  if (!$rfh) {
+    drupal_set_message('Could not perform Pubmed query. Cannot connect to Entrez.', 'error');
+    return 0;    
+  }
+  
+  // retrieve the XML results
+  $query_xml = '';
+  while (!feof($rfh)) {
+    $query_xml .= fread($rfh, 255);
+  }
+  fclose($rfh);
+  $xml = new XMLReader();
+  $xml->xml($query_xml);
+  
+  // iterate though the child nodes of the <eSearchResult> tag and get the count, history and query_id
+  $result = array();
+  while ($xml->read()) {
+    if ($xml->nodeType == XMLReader::ELEMENT) {
+      $element = $xml->name;
+      $xml->read();
+      $value = $xml->value;
+      switch ($element) {
+        case 'Count':
+          $result['Count'] = $value;
+          break;        
+        case 'WebEnv':
+          $result['WebEnv'] = $value;
+          break;
+        case 'QueryKey':
+          $result['QueryKey'] = $value;
+          break;
+      }
+    }
+  }  
+  return $result;
+}
+
+/*
+ * 
+ */
+function tripal_pub_remote_search_pubmed_fetch($terms, $query_key, $web_env, $rettype = 'xml', $start = 0, $limit = 10){
+  
+  // repeat the search performed previously (using WebEnv & QueryKey) to retrieve
+  // the PMID's within the range specied.  The PMIDs will be returned as a text list
+  $fetch_url = "http://www.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?rettype=$rettype&retmode=text&retstart=$start&retmax=$limit&db=Pubmed&query_key=$query_key&WebEnv=$web_env";
+  $rfh = fopen($fetch_url, "r");
+  $results = '';
+  while (!feof($rfh)) {
+    $results .= fread($rfh, 255);
+  }  
+  fclose($rfh);
+  
+  return $results;
+}
+
+/*
+ * This function parses the XML containing details of a publication and
+ * converts it into an associative array of where keys are Tripal Pub 
+ * ontology terms and the values are extracted from the XML. The
+ * XML should contain only a single publication record.
+ */
+function tripal_pub_remote_search_pubmed_parse_pubxml($pub_xml) {
+  $pub = array();
+  
+  // read the XML and iterate through it.
+  $xml = new XMLReader();
+  $xml->xml($pub_xml);
+  while ($xml->read()) {    
+    $element = $xml->name;    
+    if ($xml->nodeType == XMLReader::ELEMENT) {
+      $xml->read();
+      $value = $xml->value;
+      switch ($element) {
+        case 'PMID':
+          $pub['pub_accession'] = $value;
+          $pub['pub_database'] = 'PMID';
+          break;        
+        case 'Article':
+          tripal_pub_remote_search_pubmed_parse_article($xml, $pub);
+          break;
+      }
+    }
+  }
+  
+  return $pub;
+}
+
+/*
+ * 
+ */
+function tripal_pub_remote_search_pubmed_parse_article($xml, &$pub) {
+    
+  while ($xml->read()) {
+    $element = $xml->name;  
+    // if we're at the </Article> element then we're done with the article...
+    if ($xml->nodeType == XMLReader::END_ELEMENT and $element = 'Article') {
+      return;  
+    }
+    if ($xml->nodeType == XMLReader::ELEMENT) {
+      $element = $xml->name;
+      $xml->read();
+      $value = $xml->value;
+      switch ($element) {
+        case 'Journal':
+          tripal_pub_remote_search_pubmed_parse_journal($xml, $pub);
+          break;
+        case 'ArticleTitle':
+          break;
+        case 'AbstractText':
+          break;
+        case 'Affiliation':
+          break;
+        case 'AuthorList':
+          tripal_pub_remote_search_pubmed_parse_authorlist($xml, $pub);
+          break;
+        case 'Language':
+          break;
+        case 'ArticleDate':
+          break; 
+        default:
+          break;     
+      }
+    }
+  }
+}
+/*
+ * 
+ */
+function tripal_pub_remote_search_pubmed_parse_journal($xml, &$pub) {
+  
+  while ($xml->read()) {
+    $element = $xml->name;
+      
+    if ($xml->nodeType == XMLReader::END_ELEMENT){
+      // if we're at the </AuthorList> element then we're done with the article...
+      if($element = 'Journal') {
+        return;
+      }
+    }
+    if ($xml->nodeType == XMLReader::ELEMENT) {
+      $xml->read();
+      $value = $xml->value;
+      switch ($element) {
+        case 'ISSN':          
+          break;
+        case 'Volume':          
+          break;
+        case 'Year':          
+          break;
+        case 'Title':          
+          break;
+        case 'ISOAbbreviation':          
+          break;
+        default:
+          break;
+      }
+    }
+  }
+}
+/*
+ * 
+ */
+function tripal_pub_remote_search_pubmed_parse_authorlist($xml, &$pub) {
+  $authors = array();
+  $author = array();
+  $author_list = '';
+  
+  while ($xml->read()) {
+    $element = $xml->name;
+      
+    if ($xml->nodeType == XMLReader::END_ELEMENT){
+      // if we're at the </AuthorList> element then we're done with the article...
+      if($element = 'Article') {
+        return;
+      }
+      // if we're at the end </Author> element then we're done with the author and we can
+      // start a new one.
+      if($element = 'Author') {
+        return;
+      }  
+    }
+    if ($xml->nodeType == XMLReader::ELEMENT) {
+      $xml->read();
+      $value = $xml->value;
+      switch ($element) {
+        case 'Author':          
+          break;
+        case 'LastName':          
+          break;
+        case 'ForeName':          
+          break;
+        case 'Initials':          
+          break;
+        default:
+          break;
+      }
+    }
+  }
+}

+ 105 - 0
tripal_pub/includes/remote_search.inc

@@ -0,0 +1,105 @@
+<?php
+/*
+ * 
+ */
+function tripal_pub_remote_search_page() {
+  global $pager_total;
+  
+  // generate the search form 
+  $form = drupal_get_form('tripal_pub_remote_search_form');
+
+  // retrieve any results
+  $remote_db = $_SESSION['tripal_pub_search_criteria']['remote_db'];
+  $search_terms = $_SESSION['tripal_pub_search_criteria']['search_terms'];  
+  $results = tripal_pub_get_remote_search_results($remote_db, $search_terms, 10, 0);
+  
+  // iterate through the results and construct the table displaying the publications
+  if (count($results) > 0) {
+  
+  }
+  
+  // generate the pager
+  $total_items = $pager_total[0];
+  $pager = theme('pager');
+  
+  // join all to form the final page
+  $output = $form . "<p><b>Found " . number_format($total_items) . " Results</b></br>" . $table . '</p>' . $pager;
+    dpm($results);
+  
+  return $output;
+}
+/*
+ * 
+ */
+function tripal_pub_get_remote_search_results($remote_db, $search_terms, $num_to_retrieve, $pager_id) {
+ 
+  $results = array();
+  $callback = 'tripal_pub_remote_search_' . strtolower($remote_db);
+  if (function_exists($callback) and $search_terms) {
+    $results = call_user_func($callback, $search_terms, $num_to_retrieve, $pager_id);
+  }    
+  
+  return $results;  
+}
+/**
+ * Purpose: Provides the form to search pubmed
+ *
+  * @ingroup tripal_pub
+ */
+function tripal_pub_remote_search_form(&$form_state = NULL) {
+  $remote_db = $_SESSION['tripal_pub_search_criteria']['remote_db'];
+  $search_terms = $_SESSION['tripal_pub_search_criteria']['search_terms'];
+  
+  $remote_dbs = array('Pubmed' => 'Pubmed');
+  $form['remote_db'] = array(
+    '#title' => t('Remote Publication Database'),
+    '#type' => 'select',
+    '#options' => $remote_dbs,
+    '#default_value' => $remote_db,
+  );
+
+  $form['search_terms']= array(
+    '#type'          => 'textfield',
+    '#title'         => t('Search Terms'),
+    '#description'   => t('Please provide a list of words, separated by spaces for searching'),
+    '#default_value' => $search_terms,
+  );
+
+  $form['submit'] = array(
+    '#type'         => 'submit',
+    '#value'        => t('Submit'),
+    '#executes_submit_callback' => TRUE,
+  );
+
+  return $form;
+}
+
+/**
+ *
+ */
+function tripal_pub_remote_search_form_validate($form, &$form_state) {
+  $remote_db =  $form_state['values']['remote_db'];
+  $search_terms =  $form_state['values']['search_terms'];
+}
+
+/**
+ *
+ */
+function tripal_pub_remote_search_form_submit($form, &$form_state) {
+  $remote_db =  $form_state['values']['remote_db'];
+  $search_terms =  $form_state['values']['search_terms'];
+  
+  // store the search settings in a session variable. Then when the page
+  // is refreshed these values will be available for the page to 
+  // generate results. 
+  if ($op == 'Reset') {   
+    unset($_SESSION['tripal_pub_search_criteria']); 
+    unset($form_state['values']);
+  }
+  else {
+    $_SESSION['tripal_pub_search_criteria'] = array(
+      'remote_db' => $remote_db,
+      'search_terms' => $search_terms,
+    );
+  }  
+}

+ 119 - 0
tripal_pub/includes/tripal_pub.admin.inc

@@ -0,0 +1,119 @@
+<?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'
+ *
+ */
+function tripal_pub_configuration_form() {
+
+  $cv_options = tripal_cv_get_cv_options();
+
+  //Creating Fieldset for multiple fields in form
+  $form['node_form'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Create/Edit Publication Settings'),
+  );
+
+  $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.',
+  );
+
+  $form['pubmed'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Create Nodes via PubMed Search'),
+  );
+
+  $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.'
+  );
+
+  //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)
+  );
+
+  //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)
+  );
+  */
+
+  $form['pubmed']['sync_info'] = array(
+      '#type' => 'submit',
+      '#title' => t('Sync Publications Jobs'),
+      '#value' => t('Sync'),
+  );
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#weight' => 10,
+    '#value' => t('Save Configuration')
+  );
+
+  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) {
+
+    global $user;    //needed to make the current users details available so access of user id is available
+
+    if ($form_state['values']['op'] == t('Save Configuration')) {
+
+        variable_set('tripal_pub_types_cv', $form_state['values']['tripal_pub_types_cv']);
+        variable_set('unique_name', $form_state['values']['unique_name'] );
+
+    }
+
+    //adding a tripal job if the user selects to Sync the Publications
+    if ($form_state['values']['op'] == t('Sync')) {
+
+        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);
+
+    }
+
+}

+ 64 - 0
tripal_pub/theme/tripal_pub_admin.tpl.php

@@ -0,0 +1,64 @@
+<br /><h3>Tripal Publication Administrative Tools Quick Links</h3>
+<ul>
+<li><?php print l('Configuration', 'admin/tripal/tripal_pub/configuration') ?></li>
+</ul>
+
+<h3>Module Description:</h3>
+<p>The Tripal Publication Module provides the functionality for adding, editing, deleting and
+accessing academic publications, entered by the user.This module also allows a time limited search,
+specified by the user, which searches the PubMed extracts and saves acedemic puplications.
+ </p>
+<h3>Setup Instructions:</h3>
+<ol>
+<li><p><b>Set Permissions</b>: The publication module supports the Drupal user permissions interface for
+               controlling access to publlication content and functions. These permissions include viewing,
+               creating, editing or administering of
+               publication content. The default is that only the original site administrator has these
+               permissions.  You can <a href="<?php print url('admin/user/roles') ?>">add roles</a> for classifying users,
+               <a href="<?php print url('admin/user/user') ?>">assign users to roles</a> and
+               <a href="<?php print url('admin/user/permissions') ?>">assign permissions</a> for the publication content to
+               those roles.  For a simple setup, allow anonymous users access to view publication content and
+               allow the site administrator all other permissions.</p></li>
+<li><p><b>Set Publication Type Controlled Vocabulary</b>: The select list for setting the publication 
+                type is controlled be a controlled vocabulary (cv)
+                <ul><li>Before you can add any publications you need 
+                to create/load this cv. There is a limited cv included in this module. To use it, you need to 
+                load it using the <a href="<?php print url('admin/tripal/tripal_cv/obo_loader') ?>">OBO Loader included with Tripal</a>.</li>
+                <li>After the controlled vocabulary is loaded you need to set it to be used for the publication 
+                module. To do this, go to <a href="<?php print url('admin/tripal/tripal_pub/configuration') ?>">Publication->Configuration</a>, select it in the controlled vocabulary '
+                select list and click save configuration.</p></li></ul>
+
+</ol>
+<h3>Features of this Module:</h3>
+<ul>
+<li><p><b>Configuration (Search For Academic Publications):</b>  The search capability implemented in
+  this module allows a user to search, by remote connection , the PubMEd database for articles
+  that relate to key search words, chosen by the user.The "search keys" are used to search through
+  Publication titles and when one of the key words is matched in a title, the recognized article will
+  be saved to the database.
+
+      <ul>
+
+      <li><b>Choose a Controlled Vocabulary:</b>The controlled vocabulary list is a set of terms
+
+      <li><b>Set Search Key Words:</b>The search keywords, are the user entered key terms, in which
+      the publications in the PubMed database can be recognized by. The user may enter any number
+      of search terms, as by adding more search terms, the search will limit the results to those
+      in which all of the search terms appear in the publication title.
+
+      <li><b>Set a time search interval:</b>The search term interval represents a pre-set ammount
+      of time for the search. The time search interval must be entered in minutes. This allows
+      the module to automatically search the PubMed database in a predetermined time interval.
+    </ul>
+  </p></li>
+
+<li><b>Creating a Publication:</b>
+
+<p>To <b>Create,update/delete a given property of a publication</b>:When Creating a Publication
+  it is neccessary to enter the requried fields in the form. These are marked with an astrix and
+  if they are not entered upon completion a warning will be issued and the user is forced to fill
+  in these entries. The author field, requires a given/surname/suffix to be entered. To add the
+  author to the publication, the add author button is to be pushed. The user is able to add as
+  many authors to the publication as needed.
+  </p>
+

+ 9 - 0
tripal_pub/tripal_pub.module

@@ -3,6 +3,7 @@
 //require_once('cron.php');
 require_once "includes/tripal_pub.admin.inc";
 require_once "includes/pubmed.inc";
+require_once "includes/remote_search.inc";
 
 /**
  * @file
@@ -87,6 +88,14 @@ function tripal_pub_menu() {
     'access arguments' => array('access content'),
     'type ' => MENU_CALLBACK,
   );
+  
+  $items['pub_finder'] = array(
+    'title' => t('Publication Finder'),
+    'description' => t('Finds publications using remote publication databases (e.g. PubMed).'),
+    'page callback' => 'tripal_pub_remote_search_page',
+    'access arguments' => array('access content'),
+    'type ' => MENU_CALLBACK,
+  );
 
   return $items;
 }