tripal_pub.api.inc 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486
  1. <?php
  2. /**
  3. * @file
  4. * Provides an application programming interface (API) to manage chado publications
  5. */
  6. /**
  7. * @defgroup tripal_pub_api Publication Module API
  8. * @ingroup tripal_api
  9. * @{
  10. * Provides an application programming interface (API) to manage chado publications
  11. * @}
  12. */
  13. /**
  14. * Retrieves a list of publications as an associated array where
  15. * keys correspond directly with Tripal Pub CV terms.
  16. *
  17. * @param remote_db
  18. * The name of the remote publication database to query. These names should
  19. * match the name of the databases in the Chado 'db' table. Currently
  20. * supported databass include
  21. * 'PMID': PubMed
  22. *
  23. * @param search_array
  24. * An associate array containing the search criteria. The following key
  25. * are expected
  26. * 'remote_db': Specifies the name of the remote publication database
  27. * 'num_criteria': Specifies the number of criteria present in the search array
  28. * 'days': The number of days to include in the search starting from today
  29. * 'criteria': An associate array containing the search critiera. There should
  30. * be no less than 'num_criteria' elements in this array.
  31. *
  32. * The following keys are expected in the 'criteria' array
  33. * 'search_terms': A list of terms to search on, separated by spaces.
  34. * 'scope': The fields to search in the remote database. Valid values
  35. * include: 'title', 'abstract', 'author' and 'any'
  36. * 'operation': The logical operation to use for this criteria. Valid
  37. * values include: 'AND', 'OR' and 'NOT'.
  38. * @param $num_to_retrieve
  39. * The number of records to retrieve. In cases with large numbers of
  40. * records to retrieve, the remote database may limit the size of each
  41. * retrieval.
  42. * @param $page
  43. * Optional. If this function is called where the
  44. * page for the pager cannot be set using the $_GET variable, use this
  45. * argument to specify the page to retrieve.
  46. *
  47. * @return
  48. * Returns an array of pubs where each element is
  49. * an associative array where the keys are Tripal Pub CV terms.
  50. *
  51. * @ingroup tripal_pub_api
  52. */
  53. function tripal_pub_get_remote_search_results($remote_db, $search_array, $num_to_retrieve, $page = 0) {
  54. // now call the callback function to get the results
  55. $callback = "tripal_pub_remote_search_$remote_db";
  56. $pubs = array(
  57. 'total_records' => 0,
  58. 'search_str' => '',
  59. 'pubs' => array(),
  60. );
  61. if (function_exists($callback)) {
  62. $pubs = call_user_func($callback, $search_array, $num_to_retrieve, $page);
  63. }
  64. return $pubs;
  65. }
  66. /**
  67. * @stephen
  68. *
  69. * @param $dbxref
  70. *
  71. * @return
  72. *
  73. *
  74. * @ingroup tripal_pub_api
  75. */
  76. function tripal_pub_get_raw_data($dbxref) {
  77. if(preg_match('/^(.*?):(.*?)$/', $dbxref, $matches)) {
  78. $remote_db = $matches[1];
  79. $accession = $matches[2];
  80. // check that the database is supported
  81. $supported_dbs = variable_get('tripal_pub_supported_dbs', array());
  82. if(!in_array($remote_db, $supported_dbs)) {
  83. return "Unsupported database: $dbxref";
  84. }
  85. $search = array(
  86. 'num_criteria' => 1,
  87. 'remote_db' => $remote_db,
  88. 'criteria' => array(
  89. '1' => array(
  90. 'search_terms' => "$remote_db:$accession",
  91. 'scope' => 'id',
  92. 'operation' => '',
  93. 'is_phrase' => 0,
  94. ),
  95. ),
  96. );
  97. $pubs = tripal_pub_get_remote_search_results($remote_db, $search, 1, 0);
  98. return '<textarea cols=80 rows=20>' . $pubs[0]['raw'] . '</textarea>';
  99. }
  100. return 'Invalid DB xref';
  101. }
  102. /**
  103. * @stephen
  104. *
  105. * @param $do_contact
  106. * @param $dbxref
  107. * @param $db
  108. *
  109. * @ingroup tripal_pub_api
  110. */
  111. function tripal_pub_update_publications($do_contact = FALSE, $dbxref = NULL, $db = NULL) {
  112. print "\nNOTE: Loading of publications is performed using a database transaction. \n" .
  113. "If the load fails or is terminated prematurely then the entire set of \n" .
  114. "insertions/updates is rolled back and will not be found in the database\n\n";
  115. $transaction = db_transaction();
  116. try {
  117. // get a list of all publications by their Dbxrefs that have supported databases
  118. $sql = "
  119. SELECT DB.name as db_name, DBX.accession
  120. FROM pub P
  121. INNER JOIN pub_dbxref PDBX ON P.pub_id = PDBX.pub_id
  122. INNER JOIN dbxref DBX ON DBX.dbxref_id = PDBX.dbxref_id
  123. INNER JOIN db DB ON DB.db_id = DBX.db_id
  124. ";
  125. $args = array();
  126. if ($dbxref and preg_match('/^(.*?):(.*?)$/', $dbxref, $matches)) {
  127. $dbname = $matches[1];
  128. $accession = $matches[2];
  129. $sql .= "WHERE DBX.accession = :accession and DB.name = :dbname ";
  130. $args[':accession'] = $accession;
  131. $args[':dbname'] = $dbname;
  132. }
  133. elseif ($db) {
  134. $sql .= " WHERE DB.name = :dbname ";
  135. $args[':dbname'] = $db;
  136. }
  137. $sql .= "ORDER BY DB.name, P.pub_id";
  138. $results = chado_query($sql, $args);
  139. $num_to_retrieve = 100;
  140. $i = 0; // count the number of IDs. When we hit $num_to_retrieve we'll do the query
  141. $curr_db = ''; // keeps track of the current current database
  142. $ids = array(); // the list of IDs for the database
  143. $search = array(); // the search array passed to the search function
  144. // iterate through the pub IDs
  145. while ($pub = $results->fetchObject()) {
  146. $accession = $pub->accession;
  147. $remote_db = $pub->db_name;
  148. // here we need to only update publications for databases we support
  149. $supported_dbs = variable_get('tripal_pub_supported_dbs', array());
  150. if(!in_array($remote_db, $supported_dbs)) {
  151. continue;
  152. }
  153. $search = array(
  154. 'num_criteria' => 1,
  155. 'remote_db' => $remote_db,
  156. 'criteria' => array(
  157. '1' => array(
  158. 'search_terms' => "$remote_db:$accession",
  159. 'scope' => 'id',
  160. 'operation' => '',
  161. 'is_phrase' => 0,
  162. ),
  163. ),
  164. );
  165. $pubs = tripal_pub_get_remote_search_results($remote_db, $search, 1, 0);
  166. tripal_pub_add_publications($pubs, $do_contact, TRUE);
  167. $i++;
  168. }
  169. // sync the newly added publications with Drupal
  170. print "Syncing publications with Drupal...\n";
  171. tripal_pub_sync_pubs();
  172. // if the caller wants to create contacts then we should sync them
  173. if ($do_contact) {
  174. print "Syncing contacts with Drupal...\n";
  175. tripal_contact_sync_contacts();
  176. }
  177. }
  178. catch (Exception $e) {
  179. print "\n"; // make sure we start errors on new line
  180. watchdog_exception('T_pub_import', $e);
  181. $transaction->rollback();
  182. print "FAILED: Rolling back database changes...\n";
  183. return;
  184. }
  185. print "Done.\n";
  186. }
  187. /**
  188. * @stephen
  189. *
  190. * @param $import_id
  191. * @param $job_id
  192. *
  193. * @ingroup tripal_pub_api
  194. */
  195. function tripal_pub_import_publications_by_import_id($import_id, $job_id = NULL) {
  196. print "\nNOTE: Loading of publications is performed using a database transaction. \n" .
  197. "If the load fails or is terminated prematurely then the entire set of \n" .
  198. "insertions/updates is rolled back and will not be found in the database\n\n";
  199. // start the transaction
  200. $transaction = db_transaction();
  201. try {
  202. $page = 0;
  203. $do_contact = FALSE;
  204. $num_to_retrieve = 100;
  205. // get all of the loaders
  206. $args = array(':import_id' => $import_id);
  207. $sql = "SELECT * FROM {tripal_pub_import} WHERE pub_import_id = :import_id ";
  208. $import = db_query($sql, $args)->fetchObject();
  209. print "Importing: " . $import->name . "\n";
  210. $criteria = unserialize($import->criteria);
  211. $remote_db = $criteria['remote_db'];
  212. $total_pubs = 0;
  213. do {
  214. // retrieve the pubs for this page. We'll retreive 100 at a time
  215. $results = tripal_pub_get_remote_search_results($remote_db, $criteria, $num_to_retrieve, $page);
  216. $pubs = $results['pubs'];
  217. $num_pubs = $rseults['total_records'];
  218. $total_pubs += $num_pubs;
  219. tripal_pub_add_publications($pubs, $import->do_contact);
  220. $page++;
  221. }
  222. // continue looping until we have a $pubs array that does not have
  223. // our requested numer of records. This means we've hit the end
  224. while (count($pubs) == $num_to_retrieve);
  225. // sync the newly added publications with Drupal. If the user
  226. // requested a report then we don't want to print any syncing information
  227. // so pass 'FALSE' to the sync call
  228. print "Syncing publications with Drupal...\n";
  229. tripal_pub_sync_pubs();
  230. // if any of the importers wanted to create contacts from the authors then sync them
  231. if($import->do_contact) {
  232. print "Syncing contacts with Drupal...\n";
  233. tripal_contact_sync_contacts();
  234. }
  235. tripal_set_job_progress($job_id, '100');
  236. }
  237. catch (Exception $e) {
  238. print "\n"; // make sure we start errors on new line
  239. watchdog_exception('T_pub_import', $e);
  240. $transaction->rollback();
  241. print "FAILED: Rolling back database changes...\n";
  242. return;
  243. }
  244. print "Done.\n";
  245. }
  246. /**
  247. * @stephen
  248. *
  249. * @param $report_email
  250. * @param $do_update
  251. *
  252. * @ingroup tripal_pub_api
  253. */
  254. function tripal_pub_import_publications($report_email = FALSE, $do_update = FALSE) {
  255. $num_to_retrieve = 100;
  256. $page = 0;
  257. print "\nNOTE: Loading of publications is performed using a database transaction. \n" .
  258. "If the load fails or is terminated prematurely then the entire set of \n" .
  259. "insertions/updates is rolled back and will not be found in the database\n\n";
  260. // start the transaction
  261. $transaction = db_transaction();
  262. try {
  263. // get all of the loaders
  264. $args = array();
  265. $sql = "SELECT * FROM {tripal_pub_import} WHERE disabled = 0 ";
  266. $results = db_query($sql, $args);
  267. $do_contact = FALSE;
  268. $reports = array();
  269. foreach ($results as $import) {
  270. $page = 0;
  271. print "Importing: " . $import->name . "\n";
  272. // keep track if any of the importers want to create contacts from authors
  273. if ($import->do_contact == 1) {
  274. $do_contact = TRUE;
  275. }
  276. $criteria = unserialize($import->criteria);
  277. $remote_db = $criteria['remote_db'];
  278. do {
  279. // retrieve the pubs for this page. We'll retreive 100 at a time
  280. $results = tripal_pub_get_remote_search_results($remote_db, $criteria, $num_to_retrieve, $page);
  281. $pubs = $results['pubs'];
  282. $reports[$import->name] = tripal_pub_add_publications($pubs, $import->do_contact, $do_update);
  283. $page++;
  284. }
  285. // continue looping until we have a $pubs array that does not have
  286. // our requested numer of records. This means we've hit the end
  287. while (count($pubs) == $num_to_retrieve);
  288. }
  289. // sync the newly added publications with Drupal. If the user
  290. // requested a report then we don't want to print any syncing information
  291. // so pass 'FALSE' to the sync call
  292. print "Syncing publications with Drupal...\n";
  293. tripal_pub_sync_pubs();
  294. // iterate through each of the reports and generate a final report with HTML links
  295. $HTML_report = '';
  296. if ($report_email) {
  297. $HTML_report .= "<html>";
  298. global $base_url;
  299. foreach ($reports as $importer => $report) {
  300. $total = count($report['inserted']);
  301. $HTML_report .= "<b>$total new publications from importer: $importer</b><br><ol>\n";
  302. foreach ($report['inserted'] as $pub) {
  303. $item = $pub['Title'];
  304. if (array_key_exists('pub_id', $pub)) {
  305. $item = l($pub['Title'], "$base_url/pub/" . $pub['pub_id']);
  306. }
  307. $HTML_report .= "<li>$item</li>\n";
  308. }
  309. $HTML_report .= "</ol>\n";
  310. }
  311. $HTML_report .= "</html>";
  312. $site_email = variable_get('site_mail', '');
  313. $params = array(
  314. 'message' => $HTML_report
  315. );
  316. drupal_mail('tripal_pub', 'import_report', $report_email, language_default(), $params, $site_email, TRUE);
  317. }
  318. // if any of the importers wanted to create contacts from the authors then sync them
  319. if($do_contact) {
  320. print "Syncing contacts with Drupal...\n";
  321. tripal_contact_sync_contacts();
  322. }
  323. }
  324. catch (Exception $e) {
  325. print "\n"; // make sure we start errors on new line
  326. watchdog_exception('T_pub_import', $e);
  327. $transaction->rollback();
  328. print "FAILED: Rolling back database changes...\n";
  329. return;
  330. }
  331. print "Done.\n";
  332. }
  333. /**
  334. * @stephen
  335. *
  336. * @param $pub_dbxref
  337. * @param $do_contact
  338. * @param $do_update
  339. *
  340. * @ingroup tripal_pub_api
  341. */
  342. function tripal_pub_import_by_dbxref($pub_dbxref, $do_contact = FALSE, $do_update) {
  343. $num_to_retrieve = 1;
  344. $pager_id = 0;
  345. $page = 0;
  346. $num_pubs = 0;
  347. print "\nNOTE: Loading of publications is performed using a database transaction. \n" .
  348. "If the load fails or is terminated prematurely then the entire set of \n" .
  349. "insertions/updates is rolled back and will not be found in the database\n\n";
  350. $transaction = db_transaction();
  351. try {
  352. if(preg_match('/^(.*?):(.*?)$/', $pub_dbxref, $matches)) {
  353. $dbname = $matches[1];
  354. $accession = $matches[2];
  355. $criteria = array(
  356. 'num_criteria' => 1,
  357. 'remote_db' => $dbname,
  358. 'criteria' => array(
  359. '1' => array(
  360. 'search_terms' => "$dbname:$accession",
  361. 'scope' => 'id',
  362. 'operation' => '',
  363. 'is_phrase' => 0,
  364. ),
  365. ),
  366. );
  367. $remote_db = $criteria['remote_db'];
  368. $results = tripal_pub_get_remote_search_results($remote_db, $criteria, $num_to_retrieve, $page);
  369. $pubs = $results['pubs'];
  370. $search_str = $results['search_str'];
  371. $total_records = $results['total_records'];
  372. $pub_id = tripal_pub_add_publications($pubs, $do_contact, $do_update);
  373. }
  374. // sync the newly added publications with Drupal
  375. print "Syncing publications with Drupal...\n";
  376. tripal_pub_sync_pubs();
  377. // if any of the importers wanted to create contacts from the authors then sync them
  378. if($do_contact) {
  379. print "Syncing contacts with Drupal...\n";
  380. tripal_contact_sync_contacts();
  381. }
  382. }
  383. catch (Exception $e) {
  384. print "\n"; // make sure we start errors on new line
  385. watchdog_exception('T_pub_import', $e);
  386. $transaction->rollback();
  387. print "FAILED: Rolling back database changes...\n";
  388. return;
  389. }
  390. print "Done.\n";
  391. }
  392. /**
  393. * @stephen
  394. *
  395. * @param $pubs
  396. * @param $do_contact
  397. * @param $update
  398. *
  399. * @return
  400. *
  401. * @ingroup tripal_pub_api
  402. */
  403. function tripal_pub_add_publications($pubs, $do_contact, $update = FALSE) {
  404. $report = array();
  405. $report['error'] = 0;
  406. $report['inserted'] = array();
  407. $report['skipped'] = array();
  408. $total_pubs = count($pubs);
  409. // iterate through the publications and add each one
  410. $i = 1;
  411. foreach ($pubs as $pub) {
  412. $memory = number_format(memory_get_usage()) . " bytes";
  413. print "Processing $i of $total_pubs. Memory usage: $memory.\r";
  414. // add the publication to Chado
  415. $action = '';
  416. $pub_id = tripal_pub_add_publication($pub, $action, $do_contact, $update);
  417. if ($pub_id){
  418. // add the publication cross reference (e.g. to PubMed)
  419. if ($pub_id and $pub['Publication Dbxref']) {
  420. $pub_dbxref = tripal_pub_add_pub_dbxref($pub_id, $pub['Publication Dbxref']);
  421. }
  422. $pub['pub_id'] = $pub_id;
  423. }
  424. switch ($action) {
  425. case 'error':
  426. $report['error']++;
  427. break;
  428. case 'inserted':
  429. $report['inserted'][] = $pub;
  430. break;
  431. case 'updated':
  432. $report['updated'][] = $pub;
  433. break;
  434. case 'skipped':
  435. $report['skipped'][] = $pub;
  436. break;
  437. }
  438. $i++;
  439. }
  440. print "\n";
  441. return $report;
  442. }
  443. /**
  444. * Adds a dbxref record to a publication
  445. *
  446. * @stephen
  447. *
  448. * @param $pub_id
  449. * @param $pub_dbxref
  450. *
  451. * @return
  452. *
  453. * @ingroup tripal_pub_api
  454. */
  455. function tripal_pub_add_pub_dbxref($pub_id, $pub_dbxref) {
  456. // break apart the dbxref
  457. $dbname = '';
  458. $accession = '';
  459. if(preg_match('/^(.*?):(.*?)$/', $pub_dbxref, $matches)) {
  460. $dbname = $matches[1];
  461. $accession = $matches[2];
  462. }
  463. else {
  464. return FALSE;
  465. }
  466. // check to see if the pub_dbxref record already exist
  467. $values = array(
  468. 'dbxref_id' => array(
  469. 'accession' => $accession,
  470. 'db_id' => array(
  471. 'name' => $dbname,
  472. ),
  473. ),
  474. 'pub_id' => $pub_id,
  475. );
  476. $options = array('statement_name' => 'sel_pubdbxref_dbpu');
  477. $results = chado_select_record('pub_dbxref', array('*'), $values, $options);
  478. // if the pub_dbxref record exist then we don't need to re-add it.
  479. if(count($results) > 0) {
  480. return $results[0];
  481. }
  482. // make sure our database already exists
  483. $db = tripal_db_add_db($dbname);
  484. // get the database cross-reference
  485. $dbxvalues = array(
  486. 'accession' => $accession,
  487. 'db_id' => $db->db_id,
  488. );
  489. $dbxoptions = array('statement_name' => 'sel_dbxref_acdb');
  490. $results = chado_select_record('dbxref', array('dbxref_id'), $dbxvalues, $dbxoptions);
  491. // if the accession doesn't exist then add it
  492. if(count($results) == 0){
  493. $dbxref = tripal_db_add_dbxref($db->db_id, $accession);
  494. }
  495. else {
  496. $dbxref = $results[0];
  497. }
  498. // now add the record
  499. $options = array('statement_name' => 'ins_pubdbxref_dbpu');
  500. $results = chado_insert_record('pub_dbxref', $values, $options);
  501. if (!$results) {
  502. tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot add publication dbxref: %db:%accession.",
  503. array('%db' => $dbname, '%accession' => $accession));
  504. return FALSE;
  505. }
  506. return $results;
  507. }
  508. /**
  509. * Returns the list of publications that are assigned the database
  510. * cross-reference provided
  511. *
  512. * @param $pub_dbxref
  513. * The database cross reference accession. It should be in the form
  514. * DB:ACCESSION, where DB is the database name and ACCESSION is the
  515. * unique publication identifier (e.g. PMID:4382934)
  516. *
  517. * @return
  518. * Returns an array of all the publications that have the provided
  519. * cross reference. If no publications match, then an empty array
  520. * is returned.
  521. *
  522. * @ingroup tripal_pub_api
  523. */
  524. function tripal_pub_get_pubs_by_dbxref($pub_dbxref) {
  525. $return = array();
  526. if(preg_match('/^(.*?):(.*?)$/', $pub_dbxref, $matches)) {
  527. $dbname = $matches[1];
  528. $accession = $matches[2];
  529. $values = array(
  530. 'dbxref_id' => array (
  531. 'accession' => $accession,
  532. 'db_id' => array(
  533. 'name' => $dbname
  534. ),
  535. ),
  536. );
  537. $options = array('statement_name' => 'sel_pubdbxref_db');
  538. $results = chado_select_record('pub_dbxref', array('pub_id'), $values, $options);
  539. foreach ($results as $index => $pub) {
  540. $return[] = $pub->pub_id;
  541. }
  542. }
  543. return $return;
  544. }
  545. /**
  546. * Returns the list of publications that match a given title, type and year
  547. *
  548. * @param title
  549. * The title of the publication to look for
  550. * @param type
  551. * Optional. The publication type. The value of this field should come from
  552. * the Tripal Pub vocabulary. This should be the type name (e.g. cvterm.name)
  553. * @param pyear
  554. * Optional. The year the publication was published.
  555. * @param series_name
  556. * Optional. The name of the series (e.g. Journal name)
  557. *
  558. * @return
  559. * Returns an array of all the publications that have the provided
  560. * cross reference. If no publications match, then an empty array
  561. * is returned.
  562. *
  563. * @ingroup tripal_pub_api
  564. */
  565. function tripal_pub_get_pubs_by_title_type_pyear_series($title, $type = NULL, $pyear = NULL, $series_name = NULL) {
  566. $return = array();
  567. // build the values array for the query.
  568. $values = array(
  569. 'title' => $title,
  570. );
  571. $stmnt_suffix = 'ti';
  572. if ($type) {
  573. $values['type_id'] = array(
  574. 'name' => $type,
  575. 'cv_id' => array(
  576. 'name' => 'tripal_pub'
  577. )
  578. );
  579. $stmnt_suffix .= 'ty';
  580. }
  581. if ($pyear) {
  582. $values['pyear'] = $pyear;
  583. $stmnt_suffix .= 'py';
  584. }
  585. if ($series_name) {
  586. $values['series_name'] = strtolower($series_name);
  587. $stmnt_suffix .= 'se';
  588. }
  589. $options = array(
  590. 'statement_name' => 'sel_pub_' . $stmnt_suffix,
  591. 'case_insensitive_columns' => array('title', 'series_name'),
  592. );
  593. $results = chado_select_record('pub', array('pub_id'), $values, $options);
  594. // iterate through any matches and pull out the pub_id
  595. foreach ($results as $index => $pub) {
  596. $return[] = $pub->pub_id;
  597. }
  598. return $return;
  599. }
  600. /**
  601. * Returns the list of publications that match a given title, type and year
  602. *
  603. * @param title
  604. * The title of the publication to look for
  605. * @param type
  606. * Optional. The publication type. The value of this field should come from
  607. * the Tripal Pub vocabulary. This should be the type name (e.g. cvterm.name)
  608. * @param year
  609. * Optional. The year the publication was published.
  610. * @param series_name
  611. * Optional. The name of the series (e.g. Journal name)
  612. *
  613. * @return
  614. * Returns an array of all the publications that have the provided
  615. * cross reference. If no publications match, then an empty array
  616. * is returned.
  617. *
  618. * @ingroup tripal_pub_api
  619. */
  620. function tripal_pub_get_pub_by_uniquename($name) {
  621. $return = array();
  622. // build the values array for the query.
  623. $values = array(
  624. 'uniquename' => $name,
  625. );
  626. $options = array(
  627. 'statement_name' => 'sel_pub_un',
  628. 'case_insensitive_columns' => array('uniquename'),
  629. );
  630. $results = chado_select_record('pub', array('pub_id'), $values, $options);
  631. // iterate through any matches and pull out the pub_id
  632. foreach ($results as $index => $pub) {
  633. $return[] = $pub->pub_id;
  634. }
  635. return $return;
  636. }
  637. /**
  638. * Adds a new publication to the Chado, along with all properties and
  639. * database cross-references. If the publication does not already exist
  640. * in Chado then it is added. If it does exist nothing is done. If
  641. * the $update parameter is TRUE then the publication is updated if it exists.
  642. *
  643. * @param $pub_details
  644. * An associative array containing all of the details about the publication.
  645. * @param $action
  646. * This variable will get set to a text value indicating the action that was
  647. * performed. The values include 'skipped', 'inserted', 'updated' or 'error'.
  648. * @param $do_contact
  649. * Optional. Set to TRUE if a contact entry should be added to the Chado contact table
  650. * for authors of the publication.
  651. * @param $update_if_exists
  652. * Optional. If the publication already exists then this function will return
  653. * without adding a new publication. However, set this value to TRUE to force
  654. * the function to pudate the publication using the $pub_details that are provided.
  655. *
  656. * @return
  657. * If the publication already exists, is inserted or updated then the publication
  658. * ID is returned, otherwise FALSE is returned. If the publication already exists
  659. * and $update_if_exists is not TRUE then the $action variable is set to 'skipped'.
  660. * If the publication already exists and $update_if_exists is TRUE and if the update
  661. * was successful then $action is set to 'updated'. Otherwise on successful insert
  662. * the $action variable is set to 'inserted'. If the function failes then the
  663. * $action variable is set to 'error'
  664. *
  665. * @ingroup tripal_pub_api
  666. */
  667. function tripal_pub_add_publication($pub_details, &$action, $do_contact = FALSE, $update_if_exists = FALSE) {
  668. $pub_id = 0;
  669. if (!is_array($pub_details)) {
  670. return FALSE;
  671. }
  672. // first try to find the publication using the accession number. It will have
  673. // one if the pub has already been loaded for the publication database
  674. if (array_key_exists('Publication Dbxref', $pub_details)) {
  675. $results = tripal_pub_get_pubs_by_dbxref($pub_details['Publication Dbxref']);
  676. if(count($results) == 1) {
  677. $pub_id = $results[0];
  678. if ($pub_id and !$update_if_exists) {
  679. //tripal_core_report_error('tripal_pub', TRIPAL_WARNING, "A publication with this Dbxref already exists... Skipping: %dbxref",
  680. //array('%dbxref' => $pub_details['Publication Dbxref']));
  681. $action = 'skipped';
  682. return $pub_id;
  683. }
  684. }
  685. elseif (count($results) > 1) {
  686. tripal_report_error('tripal_pub', TRIPAL_ERROR, "There are two publications with this accession: %db:%accession. Cannot determine which to update.",
  687. array('%db' => $dbname, '%accession' => $accession));
  688. $action = 'error';
  689. return FALSE;
  690. }
  691. }
  692. // if we couldn't find a publication by the accession (which means it doesn't
  693. // yet exist or it has been added using a different publication database) then
  694. // try to find it using the title and publication year.
  695. if (!$pub_id and array_key_exists('Title', $pub_details)) {
  696. $results = tripal_pub_get_pubs_by_title_type_pyear_series($pub_details['Title'], NULL, $pub_details['Year']);
  697. if (count($results) == 1) {
  698. $pub_id = $results[0];
  699. if ($pub_id and !$update_if_exists) {
  700. tripal_report_error('tripal_pub', TRIPAL_WARNING, "The publication with the same title, type and year already exists. Skipping. ".
  701. " Title: '%title'. Type: '%type'. Year: '%year'",
  702. array('%title' => $pub_details['Title'], '%type' => $pub_details['Publication Type'], '%year' => $pub_details['Year']));
  703. $action = 'skipped';
  704. return $pub_id;
  705. }
  706. }
  707. elseif (count($results) > 1) {
  708. tripal_report_error('tripal_pub', TRIPAL_ERROR, "The publication with the same title, type and year is present multiple times. Cannot ".
  709. "determine which to use. Title: '%title'. Type: '%type'. Year: '%year'",
  710. array('%title' => $pub_details['Title'], '%type' => $pub_details['Publication Type'], '%year' => $pub_details['Year']));
  711. $action = 'error';
  712. return FALSE;
  713. }
  714. }
  715. // get the publication type (use the first publication type, any others will get stored as properties)
  716. if (array_key_exists('Publication Type', $pub_details)) {
  717. if(is_array($pub_details['Publication Type'])) {
  718. $pub_type = tripal_cv_get_cvterm_by_name($pub_details['Publication Type'][0], NULL, 'tripal_pub');
  719. }
  720. else {
  721. $pub_type = tripal_cv_get_cvterm_by_name($pub_details['Publication Type'], NULL, 'tripal_pub');
  722. }
  723. }
  724. else {
  725. tripal_report_error('tripal_pub', TRIPAL_ERROR, "The Publication Type is a required property but is missing", array());
  726. $action = 'error';
  727. return FALSE;
  728. }
  729. if (!$pub_type) {
  730. tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot find publication type: '%type'",
  731. array('%type' => $pub_details['Publication Type'][0]));
  732. $action = 'error';
  733. return FALSE;
  734. }
  735. // build the values array for inserting or updating
  736. $values = array(
  737. 'title' => $pub_details['Title'],
  738. 'volume' => $pub_details['Volume'],
  739. 'series_name' => substr($pub_details['Journal Name'], 0, 255),
  740. 'issue' => $pub_details['Issue'],
  741. 'pyear' => $pub_details['Year'],
  742. 'pages' => $pub_details['Pages'],
  743. 'uniquename' => $pub_details['Citation'],
  744. 'type_id' => $pub_type->cvterm_id,
  745. );
  746. // if there is no pub_id then we need to do an insert.
  747. if (!$pub_id) {
  748. $options = array('statement_name' => 'ins_pub_tivoseispypaunty');
  749. $pub = chado_insert_record('pub', $values, $options);
  750. if (!$pub) {
  751. tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot insert the publication with title: %title",
  752. array('%title' => $pub_details['Title']));
  753. $action = 'error';
  754. return FALSE;
  755. }
  756. $pub_id = $pub['pub_id'];
  757. $action = 'inserted';
  758. }
  759. // if there is a pub_id and we've been told to update, then do the update
  760. if ($pub_id and $update_if_exists) {
  761. $match = array('pub_id' => $pub_id);
  762. $options = array('statement_name' => 'up_pub_tivoseispypaunty');
  763. $success = chado_update_record('pub', $match, $values, $options);
  764. if (!$success) {
  765. tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot update the publication with title: %title",
  766. array('%title' => $pub_details['Title']));
  767. $action = 'error';
  768. return FALSE;
  769. }
  770. $action = 'updated';
  771. }
  772. // before we add any new properties we need to remove those that are there if this
  773. // is an update. The only thing we don't want to remove are the 'Publication Dbxref'
  774. if ($update_if_exists) {
  775. $sql = "
  776. DELETE FROM {pubprop}
  777. WHERE
  778. pub_id = :pub_id AND
  779. NOT type_id in (
  780. SELECT cvterm_id
  781. FROM {cvterm}
  782. WHERE name = 'Publication Dbxref'
  783. )
  784. ";
  785. chado_query($sql, array(':pub_id' => $pub_id));
  786. }
  787. // iterate through the properties and add them
  788. foreach ($pub_details as $key => $value) {
  789. // the pub_details may have the raw search data (e.g. in XML from PubMed. We'll irgnore this for now
  790. if($key == 'raw') {
  791. continue;
  792. }
  793. // get the cvterm by name or synonym
  794. $cvterm = tripal_cv_get_cvterm_by_name($key, NULL, 'tripal_pub');
  795. if (!$cvterm) {
  796. $cvterm = tripal_cv_get_cvterm_by_synonym($key, NULL, 'tripal_pub');
  797. }
  798. if (!$cvterm) {
  799. tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot find term: '%prop'. Skipping.", array('%prop' => $key));
  800. continue;
  801. }
  802. // skip details that won't be stored as properties
  803. if ($key == 'Author List') {
  804. tripal_pub_add_authors($pub_id, $value, $do_contact);
  805. continue;
  806. }
  807. if ($key == 'Title' or $key == 'Volume' or $key == 'Journal Name' or $key == 'Issue' or
  808. $key == 'Year' or $key == 'Pages') {
  809. continue;
  810. }
  811. $success = 0;
  812. if (is_array($value)) {
  813. foreach ($value as $subkey => $subvalue) {
  814. // if the key is an integer then this array is a simple list and
  815. // we will insert using the primary key. Otheriwse, use the new key
  816. if(is_int($subkey)) {
  817. $success = chado_insert_property('pub', $pub_id, $key, 'tripal_pub', $subvalue, FALSE);
  818. }
  819. else {
  820. $success = chado_insert_property('pub', $pub_id, $subkey, 'tripal_pub', $subvalue, FALSE);
  821. }
  822. }
  823. }
  824. else {
  825. $success = chado_insert_property('pub', $pub_id, $key, 'tripal_pub', $value, TRUE);
  826. }
  827. if (!$success) {
  828. tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot add property '%prop' to publication. Skipping.",
  829. array('%prop' => $key));
  830. continue;
  831. }
  832. }
  833. return $pub_id;
  834. }
  835. /**
  836. * @stephen
  837. *
  838. * @param $pub_id
  839. * @param $authors
  840. * @param $do_contact
  841. *
  842. * @ingroup tripal_pub_api
  843. */
  844. function tripal_pub_add_authors($pub_id, $authors, $do_contact) {
  845. $rank = 0;
  846. // first remove any of the existing pubauthor entires
  847. $sql = "DELETE FROM {pubauthor} WHERE pub_id = :pub_id";
  848. chado_query($sql, array(':pub_id' => $pub_id));
  849. // iterate through the authors and add them to the pubauthors and contact
  850. // tables of chado, then link them through the custom pubauthors_contact table
  851. foreach ($authors as $author) {
  852. // skip invalid author entires
  853. if ($author['valid'] == 'N') {
  854. continue;
  855. }
  856. // remove the 'valid' property as we don't have a CV term for it
  857. unset($author['valid']);
  858. // construct the contact.name field using the author information
  859. $name = '';
  860. $type = 'Person';
  861. if ($author['Given Name']) {
  862. $name .= $author['Given Name'];
  863. }
  864. if ($author['Surname']) {
  865. $name .= ' ' . $author['Surname'];
  866. }
  867. if ($author['Suffix']) {
  868. $name .= ' ' . $author['Suffix'];
  869. }
  870. if ($author['Collective']) {
  871. $name = $author['Collective'];
  872. $type = 'Collective';
  873. }
  874. $name = trim($name);
  875. // add an entry to the pubauthors table
  876. $values = array(
  877. 'pub_id' => $pub_id,
  878. 'rank' => $rank,
  879. 'surname' => $author['Surname'] ? substr($author['Surname'], 0, 100) : substr($author['Collective'], 0, 100),
  880. 'givennames' => $author['Given Name'],
  881. 'suffix' => $author['Suffix'],
  882. );
  883. $options = array('statement_name' => 'ins_pubauthor_idrasugisu');
  884. $pubauthor = chado_insert_record('pubauthor', $values, $options);
  885. // if the user wants us to create a contact for each author then do it.
  886. if ($do_contact) {
  887. // Add the contact
  888. $contact = tripal_contact_add_contact($name, '', $type, $author);
  889. // if we have succesfully added the contact and the pubauthor entries then we want to
  890. // link them together
  891. if ($contact and $pubauthor) {
  892. // link the pubauthor entry to the contact
  893. $values = array(
  894. 'pubauthor_id' => $pubauthor['pubauthor_id'],
  895. 'contact_id' => $contact['contact_id'],
  896. );
  897. $options = array('statement_name' => 'ins_pubauthorcontact_puco');
  898. $pubauthor_contact = chado_insert_record('pubauthor_contact', $values, $options);
  899. if (!$pubauthor_contact) {
  900. tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot link pub authro and contact.", array());
  901. }
  902. }
  903. }
  904. $rank++;
  905. }
  906. }
  907. /**
  908. * Retrieve properties of a given type for a given pub
  909. *
  910. * @param $pub_id
  911. * The pub_id of the properties you would like to retrieve
  912. * @param $property
  913. * The cvterm name of the properties to retrieve
  914. *
  915. * @return
  916. * An pub chado variable with the specified properties expanded
  917. *
  918. * @ingroup tripal_pub_api
  919. */
  920. function tripal_pub_get_property($pub_id, $property) {
  921. return chado_get_property('pub', $pub_id, $property, 'tripal_pub');
  922. }
  923. /**
  924. * Insert a given property
  925. *
  926. * @param $pub_id
  927. * The pub_id of the property to insert
  928. * @param $property
  929. * The cvterm name of the property to insert
  930. * @param $value
  931. * The value of the property to insert
  932. * @param $update_if_present
  933. * A boolean indicated whether to update the record if it's already present
  934. *
  935. * @return
  936. * True of success, False otherwise
  937. *
  938. * @ingroup tripal_pub_api
  939. */
  940. function tripal_pub_insert_property($pub_id, $property, $value, $update_if_present = 0) {
  941. return chado_insert_property('pub', $pub_id, $property, 'tripal_pub', $value, $update_if_present);
  942. }
  943. /**
  944. * Update a given property
  945. *
  946. * @param $pub_id
  947. * The pub_id of the property to update
  948. * @param $property
  949. * The cvterm name of the property to update
  950. * @param $value
  951. * The value of the property to update
  952. * @param $insert_if_missing
  953. * A boolean indicated whether to insert the record if it's absent
  954. *
  955. * Note: The property will be identified using the unique combination of the $pub_id and $property
  956. * and then it will be updated with the supplied value
  957. *
  958. * @return
  959. * True of success, False otherwise
  960. *
  961. * @ingroup tripal_pub_api
  962. */
  963. function tripal_pub_update_property($pub_id, $property, $value, $insert_if_missing = 0) {
  964. return chado_update_property('pub', $pub_id, $property, 'tripal_pub', $value, $insert_if_missing);
  965. }
  966. /**
  967. * Delete a given property
  968. *
  969. * @param $pub_id
  970. * The pub_id of the property to delete
  971. * @param $property
  972. * The cvterm name of the property to delete
  973. *
  974. * Note: The property will be identified using the unique combination of the $pub_id and $property
  975. * and then it will be deleted
  976. *
  977. * @return
  978. * True of success, False otherwise
  979. *
  980. * @ingroup tripal_pub_api
  981. */
  982. function tripal_pub_delete_property($pub_id, $property) {
  983. return chado_delete_property('pub', $pub_id, $property, 'tripal_pub');
  984. }
  985. /**
  986. * This function generates an array suitable for use with the
  987. * tripal_pub_create_citation function for any publication
  988. * already stored in the Chado tables.
  989. *
  990. * @param $pub_id
  991. * The publication ID
  992. * @param $skip_existing
  993. * Set to TRUE to skip publications that already have a citation
  994. * in the pubprop table. Set to FALSE to generate a citation
  995. * regardless if the citation already exists.
  996. *
  997. * @return
  998. * An array suitable for the trpial_pub_create_citation function. On
  999. * failure returns FALSE.
  1000. *
  1001. * @ingroup tripal_pub_api
  1002. */
  1003. function tripal_pub_get_publication_array($pub_id, $skip_existing = TRUE) {
  1004. $options = array('return_array' => 1);
  1005. // ---------------------------------
  1006. // get the publication
  1007. // ---------------------------------
  1008. $values = array('pub_id' => $pub_id);
  1009. $pub = chado_generate_var('pub', $values);
  1010. // expand the title
  1011. $pub = chado_expand_var($pub, 'field', 'pub.title');
  1012. $pub = chado_expand_var($pub, 'field', 'pub.volumetitle');
  1013. $pub = chado_expand_var($pub, 'field', 'pub.uniquename');
  1014. $pub_array = array();
  1015. if (trim($pub->title)) {
  1016. $pub_array['Title'] = $pub->title;
  1017. }
  1018. if (trim($pub->volumetitle)) {
  1019. $pub_array['Volume Title'] = $pub->volumetitle;
  1020. }
  1021. if (trim($pub->volume)) {
  1022. $pub_array['Volume'] = $pub->volume;
  1023. }
  1024. if (trim($pub->series_name)) {
  1025. $pub_array['Series Name'] = $pub->series_name;
  1026. }
  1027. if (trim($pub->issue)) {
  1028. $pub_array['Issue'] = $pub->issue;
  1029. }
  1030. if (trim($pub->pyear)) {
  1031. $pub_array['Year'] = $pub->pyear;
  1032. }
  1033. if (trim($pub->pages)) {
  1034. $pub_array['Pages'] = $pub->pages;
  1035. }
  1036. if (trim($pub->miniref)) {
  1037. $pub_array['Mini Ref'] = $pub->miniref;
  1038. }
  1039. if (trim($pub->uniquename)) {
  1040. $pub_array['Uniquename'] = $pub->uniquename;
  1041. }
  1042. $pub_array['Publication Type'][] = $pub->type_id->name;
  1043. // ---------------------------------
  1044. // get the citation
  1045. // ---------------------------------
  1046. $values = array(
  1047. 'pub_id' => $pub->pub_id,
  1048. 'type_id' => array(
  1049. 'name' => 'Citation',
  1050. ),
  1051. );
  1052. $citation = chado_generate_var('pubprop', $values);
  1053. if ($citation) {
  1054. $citation = chado_expand_var($citation, 'field', 'pubprop.value', $options);
  1055. if (count($citation) > 1) {
  1056. tripal_report_error('tripal_pub', TRIPAL_ERROR, "Publication has multiple citations already: %pub_id",
  1057. array('%pub_id' => $pubid));
  1058. return FALSE;
  1059. }
  1060. elseif (count($citation) == 1 and $skip_existing == TRUE) {
  1061. // skip this publication, it already has a citation
  1062. return FALSE;
  1063. }
  1064. }
  1065. // ---------------------------------
  1066. // get the publication types
  1067. // ---------------------------------
  1068. $values = array(
  1069. 'pub_id' => $pub->pub_id,
  1070. 'type_id' => array(
  1071. 'name' => 'Publication Type',
  1072. ),
  1073. );
  1074. $ptypes = chado_generate_var('pubprop', $values, $options);
  1075. if ($ptypes) {
  1076. $ptypes = chado_expand_var($ptypes, 'field', 'pubprop.value', $options);
  1077. foreach ($ptypes as $ptype) {
  1078. $pub_array['Publication Type'][] = $ptype->value;
  1079. }
  1080. }
  1081. // ---------------------------------
  1082. // get the authors list
  1083. // ---------------------------------
  1084. $values = array(
  1085. 'pub_id' => $pub->pub_id,
  1086. 'type_id' => array(
  1087. 'name' => 'Authors',
  1088. ),
  1089. );
  1090. $authors = chado_generate_var('pubprop', $values);
  1091. $authors = chado_expand_var($authors, 'field', 'pubprop.value', $options);
  1092. if (count($authors) > 1) {
  1093. tripal_report_error('tripal_pub', TRIPAL_ERROR, "Publication has multiple author lists. It should have only one list: %pub_id",
  1094. array('%pub_id' => $pubid));
  1095. return FALSE;
  1096. }
  1097. else if (trim($authors->value)) {
  1098. $pub_array['Authors'] = $authors->value;
  1099. }
  1100. // if there is no 'Author's property then try to retreive authors from the pubauthor table
  1101. else {
  1102. $sql = "
  1103. SELECT string_agg(surname || ' ' || givennames, ', ')
  1104. FROM {pubauthor}
  1105. WHERE pub_id = :pub_id
  1106. GROUP BY pub_id
  1107. ";
  1108. $au = chado_query($sql, array(':pub_id' => $pub_id))->fetchField();
  1109. if ($au) {
  1110. $pub_array['Authors'] = $au;
  1111. }
  1112. }
  1113. //Get other props
  1114. $props = array(
  1115. 'Journal Abbreviation',
  1116. 'Elocation',
  1117. 'Media Code',
  1118. 'Conference Name',
  1119. 'Keywords',
  1120. 'Series Name',
  1121. 'pISSN',
  1122. 'Publication Date',
  1123. 'Journal Code',
  1124. 'Journal Alias',
  1125. 'Journal Country',
  1126. 'Published Location',
  1127. 'Publication Model',
  1128. 'Language Abbr',
  1129. 'Alias',
  1130. 'Publication Dbxref',
  1131. 'Copyright',
  1132. 'Abstract',
  1133. 'Notes',
  1134. 'Citation',
  1135. 'Language',
  1136. 'URL',
  1137. 'eISSN',
  1138. 'DOI',
  1139. 'ISSN',
  1140. 'Publication Code',
  1141. 'Comments',
  1142. 'Publisher',
  1143. 'Media Alias',
  1144. 'Original Title');
  1145. foreach ($props AS $prop) {
  1146. $sql =
  1147. "SELECT value FROM {pubprop}
  1148. WHERE type_id =
  1149. (SELECT cvterm_id
  1150. FROM {cvterm}
  1151. WHERE name = :cvtname AND cv_id =
  1152. (SELECT cv_id
  1153. FROM {cv}
  1154. WHERE name = 'tripal_pub'
  1155. )
  1156. )
  1157. AND pub_id = :pub_id
  1158. ";
  1159. $val = trim(chado_query($sql, array(':cvtname' => $prop, ':pub_id' => $pub->pub_id))->fetchField());
  1160. if ($val) {
  1161. $pub_array[$prop] =$val;
  1162. }
  1163. }
  1164. return $pub_array;
  1165. }
  1166. /**
  1167. * This function generates citations for publications. It requires
  1168. * an array structure with keys being the terms in the Tripal
  1169. * publication ontology. This function is intended to be used
  1170. * for any function that needs to generate a citation.
  1171. *
  1172. * @param $pub
  1173. * An array structure containing publication details where the keys
  1174. * are the publication ontology term names and values are the
  1175. * corresponding details. The pub array can contain the following
  1176. * keys with corresponding values:
  1177. * - Publication Type: an array of publication types. a publication can have more than one type
  1178. * - Authors: a string containing all of the authors of a publication
  1179. * - Journal Name: a string containing the journal name
  1180. * - Journal Abbreviation: a string containing the journal name abbreviation
  1181. * - Series Name: a string containing the series (e.g. conference proceedings) name
  1182. * - Series Abbreviation: a string containing the series name abbreviation
  1183. * - Volume: the serives volume number
  1184. * - Issue: the series issue number
  1185. * - Pages: the page numbers for the publication
  1186. * - Publication Date: A date in the format "Year Month Day"
  1187. *
  1188. * @return
  1189. * A text string containing the citation
  1190. *
  1191. * @ingroup tripal_pub_api
  1192. */
  1193. function tripal_pub_create_citation($pub) {
  1194. $citation = '';
  1195. $pub_type = '';
  1196. // An article may have more than one publication type. For example,
  1197. // a publication type can be 'Journal Article' but also a 'Clinical Trial'.
  1198. // Therefore, we need to select the type that makes most sense for
  1199. // construction of the citation. Here we'll iterate through them all
  1200. // and select the one that matches best.
  1201. if(is_array($pub['Publication Type'])) {
  1202. foreach ($pub['Publication Type'] as $ptype) {
  1203. if ($ptype == 'Journal Article' ) {
  1204. $pub_type = $ptype;
  1205. break;
  1206. }
  1207. else if ($ptype == 'Conference Proceedings'){
  1208. $pub_type = $ptype;
  1209. break;
  1210. }
  1211. else if ($ptype == 'Book') {
  1212. $pub_type = $ptype;
  1213. break;
  1214. }
  1215. else if ($ptype == 'Letter') {
  1216. $pub_type = $ptype;
  1217. break;
  1218. }
  1219. else if ($ptype == 'Book Chapter') {
  1220. $pub_type = $ptype;
  1221. break;
  1222. }
  1223. else if ($ptype == "Research Support, Non-U.S. Gov't") {
  1224. $pub_type = $ptype;
  1225. // we don't break because if the article is also a Journal Article
  1226. // we prefer that type
  1227. }
  1228. }
  1229. if (!$pub_type) {
  1230. tripal_report_error('tripal_pub', TRIPAL_ERROR, "Cannot generate citation for publication type: %types",
  1231. array('%types' => print_r($pub['Publication Type'], TRUE)));
  1232. return FALSE;
  1233. }
  1234. }
  1235. else {
  1236. $pub_type = $pub['Publication Type'];
  1237. }
  1238. //----------------------
  1239. // Journal Article
  1240. //----------------------
  1241. if ($pub_type == 'Journal Article') {
  1242. $citation = $pub['Authors'] . '. ' . $pub['Title'] . '. ';
  1243. if (array_key_exists('Journal Name', $pub)) {
  1244. $citation .= $pub['Journal Name'] . '. ';
  1245. }
  1246. elseif (array_key_exists('Journal Abbreviation', $pub)) {
  1247. $citation .= $pub['Journal Abbreviation'] . '. ';
  1248. }
  1249. elseif (array_key_exists('Series Name', $pub)) {
  1250. $citation .= $pub['Series Name'] . '. ';
  1251. }
  1252. elseif (array_key_exists('Series Abbreviation', $pub)) {
  1253. $citation .= $pub['Series Abbreviation'] . '. ';
  1254. }
  1255. if (array_key_exists('Publication Date', $pub)) {
  1256. $citation .= $pub['Publication Date'];
  1257. }
  1258. elseif (array_key_exists('Year', $pub)) {
  1259. $citation .= $pub['Year'];
  1260. }
  1261. if (array_key_exists('Volume', $pub) or array_key_exists('Issue', $pub) or array_key_exists('Pages',$pub)) {
  1262. $citation .= '; ';
  1263. }
  1264. if (array_key_exists('Volume', $pub)) {
  1265. $citation .= $pub['Volume'];
  1266. }
  1267. if (array_key_exists('Issue', $pub)) {
  1268. $citation .= '(' . $pub['Issue'] . ')';
  1269. }
  1270. if (array_key_exists('Pages', $pub)) {
  1271. if (array_key_exists('Volume', $pub)) {
  1272. $citation .= ':';
  1273. }
  1274. $citation .= $pub['Pages'];
  1275. }
  1276. $citation .= '.';
  1277. }
  1278. //----------------------
  1279. // Research Support, Non-U.S. Gov't
  1280. //----------------------
  1281. elseif ($pub_type == "Research Support, Non-U.S. Gov't") {
  1282. $citation = $pub['Authors'] . '. ' . $pub['Title'] . '. ';
  1283. if (array_key_exists('Journal Name', $pub)) {
  1284. $citation .= $pub['Journal Name'] . '. ';
  1285. }
  1286. if (array_key_exists('Publication Date', $pub)) {
  1287. $citation .= $pub['Publication Date'];
  1288. }
  1289. elseif (array_key_exists('Year', $pub)) {
  1290. $citation .= $pub['Year'];
  1291. }
  1292. $citation .= '.';
  1293. }
  1294. //----------------------
  1295. // Letter
  1296. //----------------------
  1297. elseif ($pub_type == 'Letter') {
  1298. $citation = $pub['Authors'] . '. ' . $pub['Title'] . '. ';
  1299. if (array_key_exists('Journal Name', $pub)) {
  1300. $citation .= $pub['Journal Name'] . '. ';
  1301. }
  1302. elseif (array_key_exists('Journal Abbreviation', $pub)) {
  1303. $citation .= $pub['Journal Abbreviation'] . '. ';
  1304. }
  1305. elseif (array_key_exists('Series Name', $pub)) {
  1306. $citation .= $pub['Series Name'] . '. ';
  1307. }
  1308. elseif (array_key_exists('Series Abbreviation', $pub)) {
  1309. $citation .= $pub['Series Abbreviation'] . '. ';
  1310. }
  1311. if (array_key_exists('Publication Date', $pub)) {
  1312. $citation .= $pub['Publication Date'];
  1313. }
  1314. elseif (array_key_exists('Year', $pub)) {
  1315. $citation .= $pub['Year'];
  1316. }
  1317. if (array_key_exists('Volume', $pub) or array_key_exists('Issue', $pub) or array_key_exists('Pages',$pub)) {
  1318. $citation .= '; ';
  1319. }
  1320. if (array_key_exists('Volume', $pub)) {
  1321. $citation .= $pub['Volume'];
  1322. }
  1323. if (array_key_exists('Issue', $pub)) {
  1324. $citation .= '(' . $pub['Issue'] . ')';
  1325. }
  1326. if (array_key_exists('Pages', $pub)) {
  1327. if (array_key_exists('Volume', $pub)) {
  1328. $citation .= ':';
  1329. }
  1330. $citation .= $pub['Pages'];
  1331. }
  1332. $citation .= '.';
  1333. }
  1334. //----------------------
  1335. // Book
  1336. //----------------------
  1337. elseif ($pub_type == 'Book') {
  1338. }
  1339. //----------------------
  1340. // Book Chapter
  1341. //----------------------
  1342. elseif ($pub_type == 'Book Chapter') {
  1343. }
  1344. //----------------------
  1345. // Conference Proceedings
  1346. //----------------------
  1347. elseif ($pub_type == 'Conference Proceedings') {
  1348. $citation = $pub['Authors'] . '. ' . $pub['Title'] . '. ';
  1349. if (array_key_exists('Conference Name', $pub)) {
  1350. $citation .= $pub['Conference Name'] . '. ';
  1351. }
  1352. elseif (array_key_exists('Series Name', $pub)) {
  1353. $citation .= $pub['Series Name'] . '. ';
  1354. }
  1355. elseif (array_key_exists('Series Abbreviation', $pub)) {
  1356. $citation .= $pub['Series Abbreviation'] . '. ';
  1357. }
  1358. if (array_key_exists('Publication Date', $pub)) {
  1359. $citation .= $pub['Publication Date'];
  1360. }
  1361. elseif (array_key_exists('Year', $pub)) {
  1362. $citation .= $pub['Year'];
  1363. }
  1364. if (array_key_exists('Volume', $pub) or array_key_exists('Issue', $pub) or array_key_exists('Pages',$pub)) {
  1365. $citation .= '; ';
  1366. }
  1367. if (array_key_exists('Volume', $pub)) {
  1368. $citation .= $pub['Volume'];
  1369. }
  1370. if (array_key_exists('Issue', $pub)) {
  1371. $citation .= '(' . $pub['Issue'] . ')';
  1372. }
  1373. if (array_key_exists('Pages', $pub)) {
  1374. if (array_key_exists('Volume', $pub)) {
  1375. $citation .= ':';
  1376. }
  1377. $citation .= $pub['Pages'];
  1378. }
  1379. $citation .= '.';
  1380. }
  1381. return $citation;
  1382. }