tripal_pub.api.inc 50 KB

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