tripal_pub.module 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001
  1. <?php
  2. require_once "api/tripal_pub.api.inc";
  3. require_once "includes/tripal_pub.admin.inc";
  4. require_once "includes/pub_sync.inc";
  5. require_once "includes/pub_form.inc";
  6. require_once "includes/pub_importers.inc";
  7. require_once "includes/pub_search.inc";
  8. require_once "includes/pub_citation.inc";
  9. require_once "includes/importers/PMID.inc";
  10. require_once "includes/importers/AGL.inc";
  11. /**
  12. * @file
  13. *
  14. * The Tripal Publication module allows you to search the PubMed databse for academic articles,
  15. * that relate to user specified tpoic\s. As well, it allows management of publications so that
  16. * a user can enter specified details regarding a desired publication. This allows all of the important
  17. * information that is unique to a Academic Publication to be stored for access.
  18. */
  19. /**
  20. *
  21. * @ingroup tripal_pub
  22. */
  23. function tripal_pub_init() {
  24. drupal_add_css(drupal_get_path('module', 'tripal_pub') . '/theme/css/tripal_pub.css');
  25. drupal_add_js(drupal_get_path('module', 'tripal_pub') . '/theme/js/tripal_pub.js');
  26. }
  27. /**
  28. * Implementation of hook_tripal_pub_node_info().
  29. *
  30. * This node_info, is a simple node that describes the functionallity of the module.
  31. *
  32. */
  33. function tripal_pub_node_info() {
  34. return array(
  35. 'chado_pub' => array(
  36. 'name' => t('Publication'),
  37. 'base' => 'chado_pub',
  38. 'description' => t('A publication from the Chado database'),
  39. 'title_label' => t('Article Title'),
  40. 'body_label' => t('Abstract'),
  41. 'has_title' => TRUE,
  42. 'has_body' => FALSE,
  43. ),
  44. );
  45. }
  46. /**
  47. * Tripal-Publication-Menu
  48. *
  49. * Implemets hook_menu(): Adds menu items for the tripal_pub module menu. This section
  50. * gives the outline for the main menu of the Tripal-Publication module
  51. *
  52. * @return
  53. * An array of menu items that is visible within the Drupal Menu, returned as soon
  54. * as the program is ran
  55. */
  56. function tripal_pub_menu() {
  57. $items = array();
  58. $items['find/publications' ]= array(
  59. 'title' => 'Publication Search',
  60. 'description' => ('Search for publications'),
  61. 'page callback' => 'tripal_pub_search_page',
  62. 'access arguments' => array('access chado_pub content'),
  63. 'type' => MENU_CALLBACK
  64. );
  65. $items['find/publications/criteria/%/%'] = array(
  66. 'page callback' => 'tripal_pub_search_page_update_criteria',
  67. 'page arguments' => array(5, 6),
  68. 'access arguments' => array('access chado_pub content'),
  69. 'type ' => MENU_CALLBACK,
  70. );
  71. $items['admin/tripal/chado/tripal_pub']= array(
  72. 'title' => 'Publications',
  73. 'description' => ('A documented provenance artefact - publications, documents, personal communication.'),
  74. 'page callback' => 'tripal_pub_admin_pub_view',
  75. 'access arguments' => array('administer tripal pubs'),
  76. 'type' => MENU_NORMAL_ITEM
  77. );
  78. $items['admin/tripal/chado/tripal_pub/help']= array(
  79. 'title' => 'Help',
  80. 'description' => ('A module for interfacing the GMOD chado database with Drupal, providing viewing of publications'),
  81. 'page callback' => 'theme',
  82. 'page arguments' => array('tripal_pub_help'),
  83. 'access arguments' => array('administer tripal pubs'),
  84. 'type' => MENU_LOCAL_TASK,
  85. 'weight' => 10
  86. );
  87. $items['admin/tripal/chado/tripal_pub/configuration'] = array(
  88. 'title' => 'Settings',
  89. 'description' => 'Configure the Tripal publication module.',
  90. 'page callback' => 'drupal_get_form',
  91. 'page arguments' => array('tripal_pub_admin'),
  92. 'access arguments' => array('administer tripal pubs'),
  93. 'type' => MENU_LOCAL_TASK,
  94. 'weight' => 5
  95. );
  96. $items['admin/tripal/chado/tripal_pub/sync'] = array(
  97. 'title' => ' Sync',
  98. 'description' => 'Sync publications in Chado with Drupal',
  99. 'page callback' => 'drupal_get_form',
  100. 'page arguments' => array('tripal_pub_sync_form'),
  101. 'access arguments' => array('administer tripal pubs'),
  102. 'type' => MENU_LOCAL_TASK,
  103. 'weight' => 0
  104. );
  105. $items['admin/tripal/chado/tripal_pub/import_list'] = array(
  106. 'title' => t('Importers List'),
  107. 'description' => t('List all publication importers'),
  108. 'page callback' => 'tripal_pub_importers_list',
  109. 'access arguments' => array('administer tripal pubs'),
  110. 'type ' => MENU_CALLBACK,
  111. );
  112. $items['admin/tripal/chado/tripal_pub/import/new'] = array(
  113. 'title' => t('Add an Importer'),
  114. 'description' => t('Add a new publication importer.'),
  115. 'page callback' => 'tripal_pub_importer_setup',
  116. 'page arguments' => array(4, NULL),
  117. 'access arguments' => array('administer tripal pubs'),
  118. 'type ' => MENU_CALLBACK,
  119. );
  120. $items['admin/tripal/chado/tripal_pub/import/raw/%'] = array(
  121. 'page callback' => 'tripal_pub_get_raw_data',
  122. 'page arguments' => array(5),
  123. 'access arguments' => array('administer tripal pubs'),
  124. 'type ' => MENU_CALLBACK,
  125. );
  126. $items['admin/tripal/chado/tripal_pub/import/edit/%'] = array(
  127. 'page callback' => 'tripal_pub_importer_setup',
  128. 'page arguments' => array(4, 5),
  129. 'access arguments' => array('administer tripal pubs'),
  130. 'type ' => MENU_CALLBACK,
  131. );
  132. $items['admin/tripal/chado/tripal_pub/import/delete/%'] = array(
  133. 'page callback' => 'tripal_pub_importer_delete',
  134. 'page arguments' => array(5),
  135. 'access arguments' => array('administer tripal pubs'),
  136. 'type ' => MENU_CALLBACK,
  137. );
  138. $items['admin/tripal/chado/tripal_pub/import/changedb'] = array(
  139. 'page callback' => 'tripal_pub_importer_setup_page_update_remotedb',
  140. 'page arguments' => array(),
  141. 'access arguments' => array('administer tripal pubs'),
  142. 'type ' => MENU_CALLBACK,
  143. );
  144. $items['admin/tripal/chado/tripal_pub/import/criteria/%/%'] = array(
  145. 'page callback' => 'tripal_pub_importer_setup_page_update_criteria',
  146. 'page arguments' => array(5, 6),
  147. 'access arguments' => array('administer tripal pubs'),
  148. 'type ' => MENU_CALLBACK,
  149. );
  150. $items['tripal_pub/chado/properties/add'] = array(
  151. 'page callback' => 'tripal_pub_property_add',
  152. 'access arguments' => array('edit chado_pub content'),
  153. 'type ' => MENU_CALLBACK,
  154. );
  155. $items['tripal_pub/chado/properties/description'] = array(
  156. 'page callback' => 'tripal_pub_property_get_description',
  157. 'access arguments' => array('edit chado_pub content'),
  158. 'type ' => MENU_CALLBACK,
  159. );
  160. $items['tripal_pub/chado/properties/minus/%/%'] = array(
  161. 'page callback' => 'tripal_pub_property_delete',
  162. 'page arguments' => array(3, 4),
  163. 'access arguments' => array('edit chado_pub content'),
  164. 'type ' => MENU_CALLBACK,
  165. );
  166. $items['admin/tripal/chado/tripal_pub/citation'] = array(
  167. 'title' => ' Create Citations',
  168. 'description' => 'Create citations in Chado with Drupal',
  169. 'page callback' => 'drupal_get_form',
  170. 'page arguments' => array('tripal_pub_citation_form'),
  171. 'access arguments' => array('administer tripal pubs'),
  172. 'type' => MENU_CALLBACK,
  173. );
  174. return $items;
  175. }
  176. /**
  177. * Implements hook_theme(): Register themeing functions for this module
  178. *
  179. *
  180. * @return
  181. * An array of themeing functions to register
  182. *
  183. */
  184. function tripal_pub_theme() {
  185. $theme_path = drupal_get_path('module', 'tripal_pub') . '/theme';
  186. $items = array(
  187. // node templates
  188. 'tripal_pub_base' => array(
  189. 'arguments' => array('node' => NULL),
  190. 'template' => 'tripal_project_base',
  191. 'path' => "$theme_path/tripal_pub",
  192. ),
  193. 'tripal_pub_properties' => array(
  194. 'arguments' => array('node' => NULL),
  195. 'template' => 'tripal_project_base',
  196. 'path' => "$theme_path/tripal_pub",
  197. ),
  198. 'tripal_pub_authors' => array(
  199. 'arguments' => array('node' => NULL),
  200. 'template' => 'tripal_project_base',
  201. 'path' => "$theme_path/tripal_pub",
  202. ),
  203. 'tripal_pub_references' => array(
  204. 'arguments' => array('node' => NULL),
  205. 'template' => 'tripal_project_base',
  206. 'path' => "$theme_path/tripal_pub",
  207. ),
  208. 'tripal_pub_relationships' => array(
  209. 'arguments' => array('node' => NULL),
  210. 'template' => 'tripal_project_base',
  211. 'path' => "$theme_path/tripal_pub",
  212. ),
  213. 'tripal_pub_featuremaps' => array(
  214. 'arguments' => array('node' => NULL),
  215. 'template' => 'tripal_project_base',
  216. 'path' => "$theme_path/tripal_pub",
  217. ),
  218. 'tripal_pub_features' => array(
  219. 'arguments' => array('node' => NULL),
  220. 'template' => 'tripal_project_base',
  221. 'path' => "$theme_path/tripal_pub",
  222. ),
  223. 'tripal_pub_libraries' => array(
  224. 'arguments' => array('node' => NULL),
  225. 'template' => 'tripal_project_base',
  226. 'path' => "$theme_path/tripal_pub",
  227. ),
  228. 'tripal_pub_projects' => array(
  229. 'arguments' => array('node' => NULL),
  230. 'template' => 'tripal_project_base',
  231. 'path' => "$theme_path/tripal_pub",
  232. ),
  233. 'tripal_pub_stocks' => array(
  234. 'arguments' => array('node' => NULL),
  235. 'template' => 'tripal_project_base',
  236. 'path' => "$theme_path/tripal_pub",
  237. ),
  238. // instructions page for the pub module
  239. 'tripal_pub_help' => array(
  240. 'template' => 'tripal_pub_help',
  241. 'arguments' => array(NULL),
  242. 'path' => $theme_path,
  243. ),
  244. // themed forms
  245. 'tripal_pub_importer_setup_form' => array(
  246. 'arguments' => array('form'),
  247. ),
  248. 'tripal_pub_search_form' => array(
  249. 'arguments' => array('form'),
  250. ),
  251. 'chado_pub_node_form' => array(
  252. 'arguments' => array('form'),
  253. ),
  254. );
  255. return $items;
  256. }
  257. /**
  258. * Implements hook_help()
  259. * Purpose: Adds a help page to the module list
  260. */
  261. function tripal_pub_help ($path, $arg) {
  262. if ($path == 'admin/help#tripal_pub') {
  263. return theme('tripal_pub_help', array());
  264. }
  265. }
  266. /**
  267. * Implements hook_views_api()
  268. * Purpose: Essentially this hook tells drupal that there is views support for
  269. * for this module which then includes tripal_db.views.inc where all the
  270. * views integration code is
  271. *
  272. * @ingroup tripal_pub
  273. */
  274. function tripal_pub_views_api() {
  275. return array(
  276. 'api' => 3.0,
  277. );
  278. }
  279. /**
  280. * Implement hook_permissions().
  281. */
  282. function tripal_pub_permissions() {
  283. return array(
  284. 'access chado_pub content' => array(
  285. 'title' => t('View Publications'),
  286. 'description' => t('Allow users to view publication pages.'),
  287. ),
  288. 'create chado_pub content' => array(
  289. 'title' => t('Create Publication'),
  290. 'description' => t('Allow users to create new publication pages.'),
  291. ),
  292. 'delete chado_pub content' => array(
  293. 'title' => t('Delete Publication'),
  294. 'description' => t('Allow users to delete publication pages.'),
  295. ),
  296. 'edit chado_pub content' => array(
  297. 'title' => t('Edit Publications'),
  298. 'description' => t('Allow users to edit publication pages.'),
  299. ),
  300. 'adminster tripal pub' => array(
  301. 'title' => t('Administer Publications'),
  302. 'description' => t('Allow users to administer all publications.'),
  303. ),
  304. );
  305. }
  306. /**
  307. * Implement hook_access().
  308. *
  309. * This hook allows node modules to limit access to the node types they define.
  310. *
  311. * @param $node
  312. * The node on which the operation is to be performed, or, if it does not yet exist, the
  313. * type of node to be created
  314. *
  315. * @param $op
  316. * The operation to be performed
  317. *
  318. * @param $account
  319. * A user object representing the user for whom the operation is to be performed
  320. *
  321. * @return
  322. * If the permission for the specified operation is not set then return FALSE. If the
  323. * permission is set then return NULL as this allows other modules to disable
  324. * access. The only exception is when the $op == 'create'. We will always
  325. * return TRUE if the permission is set.
  326. *
  327. */
  328. function chado_pub_node_access($node, $op, $account ) {
  329. if ($op == 'create') {
  330. if (!user_access('create chado_pub content', $account)) {
  331. return FALSE;
  332. }
  333. return TRUE;
  334. }
  335. if ($op == 'update') {
  336. if (!user_access('edit chado_pub content', $account)) {
  337. return FALSE;
  338. }
  339. }
  340. if ($op == 'delete') {
  341. if (!user_access('delete chado_pub content', $account)) {
  342. return FALSE;
  343. }
  344. }
  345. if ($op == 'view') {
  346. if (!user_access('access chado_pub content', $account)) {
  347. return FALSE;
  348. }
  349. }
  350. return NULL;
  351. }
  352. /**
  353. * Implementation of tripal_pub_insert().
  354. *
  355. * This function inserts user entered information pertaining to the Publication instance into the
  356. * 'pubauthor', 'pubprop', 'chado_pub', 'pub' talble of the database.
  357. *
  358. * @parm $node
  359. * Then node which contains the information stored within the node-ID
  360. *
  361. *
  362. */
  363. function chado_pub_insert($node) {
  364. // we need an array suitable for the tripal_pub_create_citation() function
  365. // to automatically generate a citation if a uniquename doesn't already exist
  366. $pub_arr = array();
  367. // if a pub_id already exists for this node then it already exists in Chado and
  368. // we get here because we are syncing the node. Therefore, we can skip the insert
  369. // but we always want to set the URL path alias to be the Chado pub ID
  370. if ($node->pub_id) {
  371. $pub['pub_id'] = $node->pub_id;
  372. }
  373. else {
  374. $properties = array(); // stores all of the properties we need to add
  375. $cross_refs = array(); // stores any cross references for this publication
  376. // get the list of properties for easy lookup (without doing lots of database queries
  377. $properties_list = array();
  378. $sql = "
  379. SELECT CVTS.cvterm_id, CVTS.name, CVTS.definition
  380. FROM {cvtermpath} CVTP
  381. INNER JOIN {cvterm} CVTS ON CVTP.subject_id = CVTS.cvterm_id
  382. INNER JOIN {cvterm} CVTO ON CVTP.object_id = CVTO.cvterm_id
  383. INNER JOIN {cv} ON CVTO.cv_id = CV.cv_id
  384. WHERE CV.name = 'tripal_pub' and CVTO.name = 'Publication Details' and
  385. NOT CVTS.is_obsolete = 1
  386. ORDER BY CVTS.name ASC
  387. ";
  388. $prop_types = chado_query($sql);
  389. while ($prop = $prop_types->fetchObject()) {
  390. $properties_list[$prop->cvterm_id] = $prop->name;
  391. // The 'Citation' term is special because it serves
  392. // both as a property and as the uniquename for the
  393. // pub and we want it stored in both the pub table and the pubprop table
  394. if ($prop->name == 'Citation') {
  395. $properties[$prop->name][0] = $node->uniquename;
  396. }
  397. }
  398. // get the properties that should be added. Properties are in one of two forms:
  399. // 1) prop_value-[type id]-[index]
  400. // 2) new_value-[type id]-[index]
  401. // 3) new_id, new_value
  402. foreach ($node as $name => $value) {
  403. if (preg_match('/^new_value-(\d+)-(\d+)/', $name, $matches)) {
  404. $type_id = $matches[1];
  405. $index = $matches[2];
  406. $name = $properties_list[$type_id];
  407. $properties[$name][$index] = trim($value);
  408. }
  409. }
  410. if ($node->new_id and $node->new_value) {
  411. $type_id = $node->new_id;
  412. $index = count($properties[$name]);
  413. $name = $properties_list[$type_id];
  414. $properties[$name][$index] = trim($node->new_value);
  415. }
  416. // iterate through all of the properties and remove those that really are
  417. // part of the pub table fields
  418. foreach ($properties as $name => $element) {
  419. $value = trim($element[0]);
  420. // populate our $pub_array for building a citation
  421. $pub_arr[$name] = $value;
  422. // remove properties that are stored in the pub table
  423. if ($name == "Volume") {
  424. $volume = $value;
  425. unset($properties[$name]);
  426. }
  427. elseif ($name == "Volume Title") {
  428. $volumetitle = $value;
  429. unset($properties[$name]);
  430. }
  431. elseif ($name == "Issue") {
  432. $issue = $value;
  433. unset($properties[$name]);
  434. }
  435. elseif ($name == "Pages") {
  436. $pages = $value;
  437. unset($properties[$name]);
  438. }
  439. elseif ($name == "Publisher") {
  440. $publisher = $value;
  441. unset($properties[$name]);
  442. }
  443. elseif ($name == "Journal Name" or $name == "Conference Name") {
  444. $node->series_name = $value;
  445. unset($properties[$name]);
  446. }
  447. elseif ($name == "Journal Country" or $name == "Published Location") {
  448. $pubplace = $value;
  449. unset($properties[$name]);
  450. }
  451. elseif ($name == "Publication Dbxref") {
  452. // we will add the cross-references to the pub_dbxref table
  453. // but we also want to keep the property in the pubprop table so don't unset it
  454. $cross_refs[] = $value;
  455. }
  456. }
  457. // generate a citation for this pub if one doesn't already exist
  458. if (!$node->uniquename and array_key_exists('Citation', $properties)) {
  459. $pub_type = tripal_cv_get_cvterm_by_id($node->type_id);
  460. $pub_arr['Title'] = $node->pubtitle;
  461. $pub_arr['Publication Type'][0] = $pub_type->name;
  462. $pub_arr['Year'] = $node->pyear;
  463. $node->uniquename = tripal_pub_create_citation($pub_arr);
  464. $properties['Citation'][0] = $node->uniquename;
  465. }
  466. // insert the pub record
  467. $values = array(
  468. 'title' => trim($node->pubtitle),
  469. 'series_name' => substr(trim($node->series_name), 0, 255),
  470. 'type_id' => trim($node->type_id),
  471. 'pyear' => trim($node->pyear),
  472. 'is_obsolete' => $node->is_obsolete ? 'true' : 'false',
  473. 'uniquename' => trim($node->uniquename),
  474. 'volumetitle' => $volumetitle,
  475. 'volume' => $volume,
  476. 'issue' => $issue,
  477. 'pages' => $pages,
  478. 'miniref' => substr($miniref, 0, 255),
  479. 'publisher' => substr($publisher, 0, 255),
  480. 'pubplace' => substr($pubplace, 0, 255),
  481. );
  482. $pub = tripal_core_chado_insert('pub', $values);
  483. if (!$pub) {
  484. drupal_set_message("Error inserting publication", "error");
  485. watchdog('tripal_pub', "Error inserting publication", array(), WATCHDOG_ERROR);
  486. return;
  487. }
  488. // now add in the properties
  489. foreach ($properties as $property => $elements) {
  490. foreach ($elements as $rank => $value) {
  491. $status = tripal_pub_insert_property($pub['pub_id'], $property, $value, FALSE);
  492. if (!$status) {
  493. drupal_set_message("Error cannot add property: $property", "error");
  494. watchdog('tripal_pub', "Error cannot add property: %prop",
  495. array('%property' => $property), WATCHDOG_ERROR);
  496. }
  497. }
  498. }
  499. // add in any database cross-references
  500. foreach ($cross_refs as $index => $ref) {
  501. $pub_dbxref = tripal_pub_add_pub_dbxref($pub['pub_id'], trim($ref));
  502. if (!$pub_dbxref) {
  503. drupal_set_message("Error cannot add publication cross reference: $ref", "error");
  504. watchdog('tripal_pub', "Error cannot add publication cross reference: %ref",
  505. array('%ref' => $ref), WATCHDOG_ERROR);
  506. }
  507. }
  508. } // if ($node->pub_id) {} else
  509. if ($pub) {
  510. // make sure the entry for this feature doesn't already exist in the chado_pub table
  511. // if it doesn't exist then we want to add it.
  512. $pub_id = chado_get_id_for_node('pub', $node->nid) ;
  513. if (!$pub_id) {
  514. // next add the item to the drupal table
  515. $sql = "INSERT INTO {chado_pub} (nid, vid, pub_id) ".
  516. "VALUES (:nid, :vid, :pub_id)";
  517. db_query($sql, array(':nid' => $node->nid, ':vid' => $node->vid, ':pub_id' => $pub['pub_id']));
  518. }
  519. }
  520. else {
  521. drupal_set_message(t('Unable to add publication.', 'warning'));
  522. watchdog('tripal_pub', 'Insert publication: Unable to create pub where values: %values',
  523. array('%values' => print_r($values, TRUE)), WATCHDOG_WARNING);
  524. }
  525. }
  526. /*
  527. *
  528. * Implements hook_update
  529. *
  530. * The purpose of the function is to allow the module to take action when an edited node is being
  531. * updated. It updates any name changes to the database tables that werec reated upon registering a Publication.
  532. * As well, the database will be changed, so the user changed information will be saved to the database.
  533. *
  534. * @param $node
  535. * The node being updated
  536. *
  537. * @ingroup tripal_pub
  538. */
  539. function chado_pub_update($node) {
  540. if ($node->revision) {
  541. // there is no way to handle revisions in Chado but leave
  542. // this here just to make not we've addressed it.
  543. }
  544. // we need an array suitable for the tripal_pub_create_citation() function
  545. // to automatically generate a citation if a uniquename doesn't already exist
  546. $pub_arr = array();
  547. // get the publication ID for this publication
  548. $pub_id = chado_get_id_for_node('pub', $node->nid) ;
  549. $properties = array(); // stores all of the properties we need to add
  550. $cross_refs = array(); // stores any cross references for this publication
  551. // get the list of properties for easy lookup (without doing lots of database queries
  552. $properties_list = array();
  553. $sql = "
  554. SELECT DISTINCT CVTS.cvterm_id, CVTS.name, CVTS.definition
  555. FROM {cvtermpath} CVTP
  556. INNER JOIN {cvterm} CVTS ON CVTP.subject_id = CVTS.cvterm_id
  557. INNER JOIN {cvterm} CVTO ON CVTP.object_id = CVTO.cvterm_id
  558. INNER JOIN {cv} ON CVTO.cv_id = CV.cv_id
  559. WHERE CV.name = 'tripal_pub' and
  560. (CVTO.name = 'Publication Details' or CVTS.name = 'Publication Type') and
  561. NOT CVTS.is_obsolete = 1
  562. ORDER BY CVTS.name ASC
  563. ";
  564. $prop_types = chado_query($sql);
  565. while ($prop = $prop_types->fetchObject()) {
  566. $properties_list[$prop->cvterm_id] = $prop->name;
  567. // The 'Citation' term is special because it serves
  568. // both as a property and as the uniquename for the
  569. // pub and we want it stored in both the pub table and the pubprop table
  570. if ($prop->name == 'Citation') {
  571. $properties[$prop->name][0] = $node->uniquename;
  572. }
  573. }
  574. // get the properties that should be added. Properties are in one of three forms:
  575. // 1) prop_value-[type id]-[index]
  576. // 2) new_value-[type id]-[index]
  577. // 3) new_id, new_value
  578. // dpm($node);
  579. foreach ($node as $key => $value) {
  580. if (preg_match('/^prop_value-(\d+)-(\d+)/', $key, $matches)) {
  581. $type_id = $matches[1];
  582. $index = $matches[2];
  583. $name = $properties_list[$type_id];
  584. $properties[$name][$index] = trim($value);
  585. }
  586. if (preg_match('/^new_value-(\d+)-(\d+)/', $key, $matches)) {
  587. $type_id = $matches[1];
  588. $index = $matches[2];
  589. $name = $properties_list[$type_id];
  590. $properties[$name][$index] = trim($value);
  591. }
  592. }
  593. if ($node->new_id and $node->new_value) {
  594. $type_id = $node->new_id;
  595. $name = $properties_list[$type_id];
  596. $index = count($properties[$name]);
  597. $properties[$name][$index] = trim($node->new_value);
  598. }
  599. // iterate through all of the properties and remove those that really are
  600. // part of the pub table fields
  601. foreach ($properties as $name => $element) {
  602. foreach ($element as $index => $value) {
  603. // populate our $pub_array for building a citation
  604. $pub_arr[$name] = $value;
  605. // remove properties that are stored in the pub table
  606. if ($name == "Volume") {
  607. $volume = $value;
  608. unset($properties[$name]);
  609. }
  610. elseif ($name == "Volume Title") {
  611. $volumetitle = $value;
  612. unset($properties[$name]);
  613. }
  614. elseif ($name == "Issue") {
  615. $issue = $value;
  616. unset($properties[$name]);
  617. }
  618. elseif ($name == "Pages") {
  619. $pages = $value;
  620. unset($properties[$name]);
  621. }
  622. elseif ($name == "Publisher") {
  623. $publisher = $value;
  624. unset($properties[$name]);
  625. }
  626. elseif ($name == "Journal Name" or $name == "Conference Name") {
  627. $node->series_name = $value;
  628. unset($properties[$name]);
  629. }
  630. elseif ($name == "Journal Country" or $name == "Published Location") {
  631. $pubplace = $value;
  632. unset($properties[$name]);
  633. }
  634. elseif ($name == "Publication Dbxref") {
  635. // we will add the cross-references to the pub_dbxref table
  636. // but we also want to keep the property in the pubprop table so don't unset it
  637. $cross_refs[] = $value;
  638. }
  639. }
  640. }
  641. // generate a citation for this pub if one doesn't already exist
  642. if (!$node->uniquename) {
  643. $pub_type = tripal_cv_get_cvterm_by_id($node->type_id);
  644. $pub_arr['Title'] = $node->pubtitle;
  645. $pub_arr['Publication Type'][0] = $pub_type->name;
  646. $pub_arr['Year'] = $node->pyear;
  647. $node->uniquename = tripal_pub_create_citation($pub_arr);
  648. $properties['Citation'][0] = $node->uniquename;
  649. }
  650. // update the pub record
  651. $match = array(
  652. 'pub_id' => $pub_id,
  653. );
  654. $values = array(
  655. 'title' => trim($node->pubtitle),
  656. 'type_id' => trim($node->type_id),
  657. 'pyear' => trim($node->pyear),
  658. 'is_obsolete' => $node->is_obsolete ? 'true' : 'false',
  659. 'uniquename' => trim($node->uniquename),
  660. 'series_name' => trim($node->series_name),
  661. 'volumetitle' => $volumetitle,
  662. 'volume' => $volume,
  663. 'issue' => $issue,
  664. 'pages' => $pages,
  665. 'miniref' => $miniref,
  666. 'publisher' => $publisher,
  667. 'pubplace' => $pubplace,
  668. );
  669. $status = tripal_core_chado_update('pub', $match, $values);
  670. if (!$status) {
  671. drupal_set_message("Error updating publication", "error");
  672. watchdog('tripal_pub', "Error updating publication", array(), WATCHDOG_ERROR);
  673. return;
  674. }
  675. // now add in the properties by first removing any the publication
  676. // already has and adding the ones we have
  677. tripal_core_chado_delete('pubprop', array('pub_id' => $pub_id));
  678. foreach ($properties as $property => $elements) {
  679. foreach ($elements as $rank => $value) {
  680. $status = tripal_pub_insert_property($pub_id, $property, $value, FALSE);
  681. if (!$status) {
  682. drupal_set_message("Error cannot add property: '$property'", "error");
  683. watchdog('tripal_pub', "Error cannot add property: '%prop'",
  684. array('%prop' => $property), WATCHDOG_ERROR);
  685. }
  686. }
  687. }
  688. // add in any database cross-references after first removing
  689. tripal_core_chado_delete('pub_dbxref', array('pub_id' => $pub_id));
  690. foreach ($cross_refs as $index => $ref) {
  691. $pub_dbxref = tripal_pub_add_pub_dbxref($pub_id, trim($ref));
  692. if (!$pub_dbxref) {
  693. drupal_set_message("Error cannot add publication cross reference: $ref", "error");
  694. watchdog('tripal_pub', "Error cannot add publication cross reference: %ref",
  695. array('%ref' => $ref), WATCHDOG_ERROR);
  696. }
  697. }
  698. }
  699. /**
  700. * Implementation of tripal_pub_load().
  701. *
  702. *
  703. * @param $node
  704. * The node that is to be accessed from the database
  705. *
  706. * @return $node
  707. * The node with the information to be loaded into the database
  708. *
  709. */
  710. function chado_pub_load($node) {
  711. // get the feature details from chado
  712. $pub_id = chado_get_id_for_node('pub', $node->nid);
  713. $values = array('pub_id' => $pub_id);
  714. $pub = tripal_core_generate_chado_var('pub', $values);
  715. // expand the 'text' fields as those aren't included by default
  716. // and they really shouldn't be so large to cause problems
  717. if (is_array($pub) or is_object($pub)) {
  718. $pub = tripal_core_expand_chado_vars($pub, 'field', 'pub.title');
  719. $pub = tripal_core_expand_chado_vars($pub, 'field', 'pub.volumetitle');
  720. $pub = tripal_core_expand_chado_vars($pub, 'field', 'pub.uniquename');
  721. }
  722. // set the URL path
  723. $path = "pub/$pub_id";
  724. $additions = new stdClass();
  725. $additions->pub = $pub;
  726. return $additions;
  727. }
  728. /**
  729. * Implementation of tripal_pub_delete().
  730. *
  731. * This function takes a node and if the delete button has been chosen by the user, the publication
  732. * and it's details will be removed.Following,given the node-ID, the instance will be deleted from
  733. * the 'chado_pub' table.
  734. *
  735. * @parm $node
  736. * Then node which contains the information stored within the node-ID
  737. *
  738. */
  739. function chado_pub_delete(&$node) {
  740. $pub_id = chado_get_id_for_node('pub', $node->nid);
  741. // if we don't have a pub id for this node then this isn't a node of
  742. // type chado_pub or the entry in the chado_pub table was lost.
  743. if (!$pub_id) {
  744. return;
  745. }
  746. // Remove data from {chado_pub}, {node} and {node_revision} tables of
  747. // drupal database
  748. $sql_del = "DELETE FROM {chado_pub} WHERE nid = :nid AND vid = :vid";
  749. db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
  750. $sql_del = "DELETE FROM {node_revision} WHERE nid = :nid AND vid = :vid";
  751. db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
  752. $sql_del = "DELETE FROM {node} WHERE nid = :nid AND vid = :vid";
  753. db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
  754. // Remove data from pub and pubprop tables of chado database as well
  755. chado_query("DELETE FROM {pubprop} WHERE pub_id = :pub_id", array(':pub_id' => $pub_id));
  756. chado_query("DELETE FROM {pub} WHERE pub_id = :pub_id", array(':pub_id' => $pub_id));
  757. }
  758. /*
  759. *
  760. */
  761. function tripal_pub_form_alter(&$form, &$form_state, $form_id) {
  762. if ($form_id == "tripal_pub_importer_setup_form") {
  763. // updating the form through the ahah callback sets the action of
  764. // the form to the ahah callback URL. We need to set it back
  765. // to the normal form URL
  766. if ($form_state['values']['action'] == 'edit') {
  767. $form['#action'] = url("admin/tripal/tripal_pub/import/edit/" . $form_state['values']['pub_import_id']);
  768. }
  769. if ($form_state['values']['action'] == 'new') {
  770. $form['#action'] = url("admin/tripal/tripal_pub/import/new");
  771. }
  772. }
  773. if ($form_id == "tripal_pub_search_form") {
  774. $form['#action'] = url("find/publications");
  775. }
  776. if ($form_id == "chado_pub_node_form") {
  777. }
  778. }
  779. /**
  780. *
  781. *
  782. * @ingroup tripal_pub
  783. */
  784. function tripal_pub_preprocess_tripal_pub_relationships(&$variables) {
  785. // we want to provide a new variable that contains the matched pubs.
  786. $pub = $variables['node']->pub;
  787. // normally we would use tripal_core_expand_chado_vars to expand our
  788. // organism object and add in the relationships, however whan a large
  789. // number of relationships are present this significantly slows the
  790. // query, therefore we will manually perform the query
  791. $sql = "
  792. SELECT P.title, P.pub_id, CP.nid, CVT.name as rel_type
  793. FROM pub_relationship PR
  794. INNER JOIN {pub} P ON PR.object_id = P.pub_id
  795. INNER JOIN {cvterm} CVT ON PR.type_id = CVT.cvterm_id
  796. LEFT JOIN public.chado_pub CP ON P.pub_id = CP.pub_id
  797. WHERE PR.subject_id = :subject_id
  798. ";
  799. $as_subject = chado_query($sql, array(':subject_id' => $pub->pub_id));
  800. $sql = "
  801. SELECT P.title, P.pub_id, CP.nid, CVT.name as rel_type
  802. FROM pub_relationship PR
  803. INNER JOIN {pub} P ON PR.subject_id = P.pub_id
  804. INNER JOIN {cvterm} CVT ON PR.type_id = CVT.cvterm_id
  805. LEFT JOIN public.chado_pub CP ON P.pub_id = CP.pub_id
  806. WHERE PR.object_id = :object_id
  807. ";
  808. $as_object = chado_query($sql, array(':object_id' => $pub->pub_id));
  809. // combine both object and subject relationshisp into a single array
  810. $relationships = array();
  811. $relationships['object'] = array();
  812. $relationships['subject'] = array();
  813. // iterate through the object relationships
  814. while ($relationship = $as_object->fetchObject()) {
  815. // get the relationship and child types
  816. $rel_type = t(preg_replace('/_/', " ", $relationship->rel_type));
  817. $sub_type = t(preg_replace('/_/', " ", $relationship->sub_type));
  818. if (!array_key_exists($rel_type, $relationships['object'])) {
  819. $relationships['object'][$rel_type] = array();
  820. }
  821. if (!array_key_exists($sub_type, $relationships['object'][$rel_type])) {
  822. $relationships['object'][$rel_type][$sub_type] = array();
  823. }
  824. $relationships['object'][$rel_type][$sub_type][] = $relationship;
  825. }
  826. // now add in the subject relationships
  827. while ($relationship = $as_subject->fetchObject()) {
  828. // get the relationship and child types
  829. $rel_type = t(preg_replace('/_/', " ", $relationship->rel_type));
  830. $obj_type = t(preg_replace('/_/', " ", $relationship->obj_type));
  831. if (!array_key_exists($rel_type, $relationships['subject'])) {
  832. $relationships['subject'][$rel_type] = array();
  833. }
  834. if (!array_key_exists($obj_type, $relationships['subject'][$rel_type])) {
  835. $relationships['subject'][$rel_type][$obj_type] = array();
  836. }
  837. $relationships['subject'][$rel_type][$obj_type][] = $relationship;
  838. }
  839. $pub->all_relationships = $relationships;
  840. }
  841. /**
  842. *
  843. */
  844. function tripal_pub_mail($key, &$message, $params) {
  845. $language = $message['language'];
  846. $variables = user_mail_tokens($params['account'], $language);
  847. switch($key) {
  848. case 'import_report':
  849. $headers = array(
  850. 'MIME-Version' => '1.0',
  851. 'Content-Type' => 'text/html; charset=UTF-8; format=flowed',
  852. 'Content-Transfer-Encoding' => '8Bit',
  853. 'X-Mailer' => 'Drupal'
  854. );
  855. foreach ($headers as $key => $value) {
  856. $message['headers'][$key] = $value;
  857. }
  858. $message['subject'] = t('Publication import from !site', $variables, $language->language);
  859. $message['body'][] = $params['message'];
  860. break;
  861. }
  862. }
  863. /**
  864. *
  865. * @param $node
  866. */
  867. function tripal_pub_node_insert($node) {
  868. // we want the publications to always have a URL of http://[base url]/pub/[pub id]
  869. // where [pub id] is the Chado publication ID. This will allow for easy linking
  870. // into the publication without needing to know the node. Of course if you know the
  871. // node that will still work too (e.g. http://[base url]/node/[node id]
  872. // so the nodeapi function ensures that the URL path is set after insert or update
  873. // of the node and when the node is loaded if it hasn't yet been set.
  874. if ($node->type == 'chado_pub') {
  875. $pub_id = chado_get_id_for_node('pub', $node->nid);
  876. tripal_pub_set_pub_url($node, $pub_id);
  877. }
  878. }
  879. /**
  880. *
  881. * @param $node
  882. * @param $types
  883. */
  884. function tripal_pub_node_load($node, $types) {
  885. // we want the publications to always have a URL of http://[base url]/pub/[pub id]
  886. // where [pub id] is the Chado publication ID. This will allow for easy linking
  887. // into the publication without needing to know the node. Of course if you know the
  888. // node that will still work too (e.g. http://[base url]/node/[node id]
  889. // so the nodeapi function ensures that the URL path is set after insert or update
  890. // of the node and when the node is loaded if it hasn't yet been set.
  891. if ($node->type == 'chado_pub') {
  892. if (!$node->path) {
  893. $pub_id = chado_get_id_for_node('pub', $node->nid);
  894. $path = tripal_pub_set_pub_url($node, $pub_id);
  895. }
  896. }
  897. }
  898. /**
  899. *
  900. * @param $node
  901. */
  902. function tripal_pub_node_update($node) {
  903. // we want the publications to always have a URL of http://[base url]/pub/[pub id]
  904. // where [pub id] is the Chado publication ID. This will allow for easy linking
  905. // into the publication without needing to know the node. Of course if you know the
  906. // node that will still work too (e.g. http://[base url]/node/[node id]
  907. // so the nodeapi function ensures that the URL path is set after insert or update
  908. // of the node and when the node is loaded if it hasn't yet been set.
  909. if ($node->type == 'chado_pub') {
  910. $pub_id = chado_get_id_for_node('pub', $node->nid);
  911. tripal_pub_set_pub_url($node, $pub_id);
  912. }
  913. }