pubmed.inc 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. <?php
  2. /**
  3. * @file
  4. * Tripal Pub PubMed Interface
  5. *
  6. * @defgroup tripal_pub_pubmed PubMed Interface
  7. * @ingroup tripal_pub
  8. */
  9. /**
  10. *
  11. */
  12. function tripal_pub_remote_search_pubmed($terms_str, $num_to_retrieve, $pager_id) {
  13. // convert the terms list provicded by the caller into a string with words
  14. // separated by a '+' symbol.
  15. $search_terms = implode("+", preg_split('/\s+/', trim($terms_str)));
  16. // we want to get the list of pubs using the search terms but using a Drupal style pager
  17. $pubs = tripal_pager_callback('tripal_pub_remote_search_pubmed_range',
  18. 'tripal_pub_remote_search_pubmed_count', $num_to_retrieve, $pager_id, $search_terms);
  19. if ($pubs) {
  20. foreach ($pubs as $pub) {
  21. /*
  22. $pmid = $output[$i];
  23. //aquiring the pubmed id from the pub table based on the uniquename
  24. $values = array( 'uniquename' => $pmid);
  25. $pubmed_id = tripal_core_chado_select('pub', array('pub_id'), $values); */
  26. }
  27. }
  28. return $pubs;
  29. }
  30. /*
  31. * This function is used as the callback function when used with the
  32. * tripal_pager_callback function. This function returns a count of
  33. * the dataset to be paged.
  34. */
  35. function tripal_pub_remote_search_pubmed_count($terms) {
  36. // do a quick query using the provided terms, set the session variables
  37. // so we can reuse this query and then return the total number of records.
  38. $results = tripal_pub_remote_search_pubmed_query($terms);
  39. $_SESSION['tripal_pub_pubmed_query']['WebEnv'] = $results['WebEnv'];
  40. $_SESSION['tripal_pub_pubmed_query']['QueryKey'] = $results['QueryKey'];
  41. return $total_records;
  42. }
  43. /*
  44. * This function is used as the callback function when used with the
  45. * tripal_pager_callback function. This function returns the results
  46. * within the specified range
  47. */
  48. function tripal_pub_remote_search_pubmed_range($terms, $start = 0, $limit = 10) {
  49. // get the query_key and the web_env from the previous count query.
  50. $query_key = $_SESSION['tripal_pub_pubmed_query']['QueryKey'];
  51. $web_env = $_SESSION['tripal_pub_pubmed_query']['WebEnv'];
  52. // repeat the search performed previously (using WebEnv & QueryKey) to retrieve
  53. // the PMID's within the range specied. The PMIDs will be returned as a text list
  54. $pmids_txt = tripal_pub_remote_search_pubmed_fetch($terms, $query_key, $web_env, 'uilist', $start, $limit);
  55. // iterate through each PMID and get the publication record. This requires a new search and new fetch
  56. $pmids = explode("\n", trim($pmids_txt));
  57. $pubs = array();
  58. foreach ($pmids as $pmid) {
  59. // first intialize the search for a single PMID. This will give us a new query key and Web env
  60. $term = $pmid . "[uid]";
  61. $query = tripal_pub_remote_search_pubmed_query($terms);
  62. // second retrieve the individual record
  63. $pub_xml = tripal_pub_remote_search_pubmed_fetch($terms, $query['QueryKey'], $query['WebEnv'], 'xml', 0, 1);
  64. $pubs[] = $pub_xml;
  65. }
  66. return $pubs;
  67. }
  68. /*
  69. *
  70. */
  71. function tripal_pub_remote_search_pubmed_query($terms){
  72. // do a search for a single result so that we can establish a history, and get
  73. // the number of records. Once we have the number of records we can retrieve
  74. // those requested in the range.
  75. $query_url = "http://www.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=Pubmed&retmax=1&usehistory=y&term=$terms";
  76. $rfh = fopen($query_url, "r");
  77. if (!$rfh) {
  78. drupal_set_message('Could not perform Pubmed query. Cannot connect to Entrez.', 'error');
  79. return 0;
  80. }
  81. // retrieve the XML results
  82. $query_xml = '';
  83. while (!feof($rfh)) {
  84. $query_xml .= fread($rfh, 255);
  85. }
  86. fclose($rfh);
  87. $xml = new XMLReader();
  88. $xml->xml($query_xml);
  89. // iterate though the child nodes of the <eSearchResult> tag and get the count, history and query_id
  90. $result = array();
  91. while ($xml->read()) {
  92. if ($xml->nodeType == XMLReader::ELEMENT) {
  93. $element = $xml->name;
  94. $xml->read();
  95. $value = $xml->value;
  96. switch ($element) {
  97. case 'Count':
  98. $result['Count'] = $value;
  99. break;
  100. case 'WebEnv':
  101. $result['WebEnv'] = $value;
  102. break;
  103. case 'QueryKey':
  104. $result['QueryKey'] = $value;
  105. break;
  106. }
  107. }
  108. }
  109. return $result;
  110. }
  111. /*
  112. *
  113. */
  114. function tripal_pub_remote_search_pubmed_fetch($terms, $query_key, $web_env, $rettype = 'xml', $start = 0, $limit = 10){
  115. // repeat the search performed previously (using WebEnv & QueryKey) to retrieve
  116. // the PMID's within the range specied. The PMIDs will be returned as a text list
  117. $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";
  118. $rfh = fopen($fetch_url, "r");
  119. $results = '';
  120. while (!feof($rfh)) {
  121. $results .= fread($rfh, 255);
  122. }
  123. fclose($rfh);
  124. return $results;
  125. }
  126. /*
  127. * This function parses the XML containing details of a publication and
  128. * converts it into an associative array of where keys are Tripal Pub
  129. * ontology terms and the values are extracted from the XML. The
  130. * XML should contain only a single publication record.
  131. */
  132. function tripal_pub_remote_search_pubmed_parse_pubxml($pub_xml) {
  133. $pub = array();
  134. // read the XML and iterate through it.
  135. $xml = new XMLReader();
  136. $xml->xml($pub_xml);
  137. while ($xml->read()) {
  138. $element = $xml->name;
  139. if ($xml->nodeType == XMLReader::ELEMENT) {
  140. $xml->read();
  141. $value = $xml->value;
  142. switch ($element) {
  143. case 'PMID':
  144. $pub['pub_accession'] = $value;
  145. $pub['pub_database'] = 'PMID';
  146. break;
  147. case 'Article':
  148. tripal_pub_remote_search_pubmed_parse_article($xml, $pub);
  149. break;
  150. }
  151. }
  152. }
  153. return $pub;
  154. }
  155. /*
  156. *
  157. */
  158. function tripal_pub_remote_search_pubmed_parse_article($xml, &$pub) {
  159. while ($xml->read()) {
  160. $element = $xml->name;
  161. // if we're at the </Article> element then we're done with the article...
  162. if ($xml->nodeType == XMLReader::END_ELEMENT and $element = 'Article') {
  163. return;
  164. }
  165. if ($xml->nodeType == XMLReader::ELEMENT) {
  166. $element = $xml->name;
  167. $xml->read();
  168. $value = $xml->value;
  169. switch ($element) {
  170. case 'Journal':
  171. tripal_pub_remote_search_pubmed_parse_journal($xml, $pub);
  172. break;
  173. case 'ArticleTitle':
  174. break;
  175. case 'AbstractText':
  176. break;
  177. case 'Affiliation':
  178. break;
  179. case 'AuthorList':
  180. tripal_pub_remote_search_pubmed_parse_authorlist($xml, $pub);
  181. break;
  182. case 'Language':
  183. break;
  184. case 'ArticleDate':
  185. break;
  186. default:
  187. break;
  188. }
  189. }
  190. }
  191. }
  192. /*
  193. *
  194. */
  195. function tripal_pub_remote_search_pubmed_parse_journal($xml, &$pub) {
  196. while ($xml->read()) {
  197. $element = $xml->name;
  198. if ($xml->nodeType == XMLReader::END_ELEMENT){
  199. // if we're at the </AuthorList> element then we're done with the article...
  200. if($element = 'Journal') {
  201. return;
  202. }
  203. }
  204. if ($xml->nodeType == XMLReader::ELEMENT) {
  205. $xml->read();
  206. $value = $xml->value;
  207. switch ($element) {
  208. case 'ISSN':
  209. break;
  210. case 'Volume':
  211. break;
  212. case 'Year':
  213. break;
  214. case 'Title':
  215. break;
  216. case 'ISOAbbreviation':
  217. break;
  218. default:
  219. break;
  220. }
  221. }
  222. }
  223. }
  224. /*
  225. *
  226. */
  227. function tripal_pub_remote_search_pubmed_parse_authorlist($xml, &$pub) {
  228. $authors = array();
  229. $author = array();
  230. $author_list = '';
  231. while ($xml->read()) {
  232. $element = $xml->name;
  233. if ($xml->nodeType == XMLReader::END_ELEMENT){
  234. // if we're at the </AuthorList> element then we're done with the article...
  235. if($element = 'Article') {
  236. return;
  237. }
  238. // if we're at the end </Author> element then we're done with the author and we can
  239. // start a new one.
  240. if($element = 'Author') {
  241. return;
  242. }
  243. }
  244. if ($xml->nodeType == XMLReader::ELEMENT) {
  245. $xml->read();
  246. $value = $xml->value;
  247. switch ($element) {
  248. case 'Author':
  249. break;
  250. case 'LastName':
  251. break;
  252. case 'ForeName':
  253. break;
  254. case 'Initials':
  255. break;
  256. default:
  257. break;
  258. }
  259. }
  260. }
  261. }