pub_search.inc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. <?php
  2. /*
  3. *
  4. */
  5. function tripal_pub_search_page() {
  6. global $pager_total, $pager_total_items;
  7. $pager_id = 0;
  8. $limit = 25;
  9. // generate the search form
  10. $form = drupal_get_form('tripal_pub_search_form');
  11. $output .= $form;
  12. // retrieve any results
  13. if ($_SESSION['tripal_pub_search_form']['perform_search']) {
  14. $num_criteria = $_SESSION['tripal_pub_search_form']['num_criteria'];
  15. $from_year = $_SESSION['tripal_pub_search_form']['from_year'];
  16. $to_year = $_SESSION['tripal_pub_search_form']['to_year'];
  17. $search_array = array();
  18. $search_array['num_criteria'] = $num_criteria;
  19. $search_array['from_year'] = $from_year;
  20. $search_array['to_year'] = $to_year;
  21. for ($i = 0; $i <= $num_criteria; $i++) {
  22. $search_array['criteria'][$i]['search_terms'] = $_SESSION['tripal_pub_search_form']['criteria'][$i]['search_terms'];
  23. $search_array['criteria'][$i]['scope'] = $_SESSION['tripal_pub_search_form']['criteria'][$i]['scope'];
  24. $search_array['criteria'][$i]['mode'] = $_SESSION['tripal_pub_search_form']['criteria'][$i]['mode'];
  25. $search_array['criteria'][$i]['operation'] = $_SESSION['tripal_pub_search_form']['criteria'][$i]['operation'];
  26. }
  27. // get the list of publications from the remote database using the search criteria.
  28. $pubs = tripal_pub_get_search_results($search_array, $limit, $pager_id);
  29. // generate the pager
  30. $total_pages = $pager_total[$pager_id];
  31. $total_items = $pager_total_items[$pager_id];
  32. $page = isset($_GET['page']) ? $_GET['page'] : '0';
  33. $pager = theme('pager');
  34. // iterate through the results and construct the table displaying the publications
  35. $rows = array();
  36. $i = $page * $limit + 1;
  37. while($pub = db_fetch_object($pubs)) {
  38. // get the citation for this publication
  39. $values = array(
  40. 'pub_id' => $pub->pub_id,
  41. 'type_id' => array(
  42. 'name' => 'Citation',
  43. ),
  44. );
  45. $citation_rec = tripal_core_generate_chado_var('pubprop', $values);
  46. $citation_rec = tripal_core_expand_chado_vars($citation_rec, 'field', 'pubprop.value');
  47. // if we have the citation then use it, otherwise, just use the title
  48. $title = htmlspecialchars($pub->title);
  49. $result = $title;
  50. if ($pub->nid) {
  51. $result = l($title ,'node/' . $pub->nid, array('attributes' => array('target' => '_blank')));
  52. }
  53. if ($citation_rec->value) {
  54. $citation = htmlspecialchars($citation_rec->value);
  55. $result .= '<br>' . $citation;
  56. }
  57. $rows[] = array(
  58. number_format($i) . ".",
  59. $pub->pyear,
  60. $result
  61. );
  62. $i++;
  63. }
  64. $headers = array('', 'Year', 'Publication');
  65. $table = theme('table', $headers, $rows);
  66. // join all to form the results
  67. $output .= "<br><p><b>Found " . number_format($total_items) .
  68. ". Page " . ($page + 1) . " of $total_pages. " .
  69. " Results</b></br>" . $table . '</p>' . $pager;
  70. }
  71. return $output;
  72. }
  73. /**
  74. * Purpose: Provides the form to search pubmed
  75. *
  76. * @ingroup tripal_pub
  77. */
  78. function tripal_pub_search_form(&$form_state = NULL) {
  79. tripal_core_ahah_init_form();
  80. // Set the default values. If the pub_import_id isn't already defined by the form values
  81. // and one is provided then look it up in the database
  82. $criteria = NULL;
  83. // if the session has variables then use those. This should only happen when
  84. // the 'Test Criteria' button is clicked.
  85. $num_criteria = $_SESSION['tripal_pub_search_form']['num_criteria'] ? $_SESSION['tripal_pub_search_form']['num_criteria'] : $num_criteria;
  86. $from_year = $_SESSION['tripal_pub_search_form']['from_year'] ? $_SESSION['tripal_pub_search_form']['from_year'] : '';
  87. $to_year = $_SESSION['tripal_pub_search_form']['to_year'] ? $_SESSION['tripal_pub_search_form']['to_year'] : '';
  88. // If the form_state has variables then use those. This happens when an error occurs on the form or the
  89. // form is resbumitted using AJAX
  90. $num_criteria = $form_state['values']['num_criteria'] ? $form_state['values']['num_criteria'] : $num_criteria;
  91. // change the number of criteria based on form_state post data.
  92. if (!$num_criteria) {
  93. $num_criteria = 2;
  94. }
  95. if($form_state['post']["add-$num_criteria"]) {
  96. $num_criteria++;
  97. }
  98. if($form_state['post']["remove-$num_criteria"]) {
  99. $num_criteria--;
  100. }
  101. $form['num_criteria']= array(
  102. '#type' => 'hidden',
  103. '#default_value' => $num_criteria,
  104. );
  105. $form['instructions'] = array(
  106. '#type' => 'item',
  107. '#value' => t('To search for publications enter keywords in the text boxes below. You can limit your search by selecting the field in the dropdown box. Click the plus and minus symbols to add additional fields for searching. '),
  108. );
  109. // get publication properties list
  110. $properties = array();
  111. $properties[] = 'Any Field';
  112. $sql = "
  113. SELECT DISTINCT CVTS.cvterm_id, CVTS.name, CVTS.definition
  114. FROM {cvtermpath} CVTP
  115. INNER JOIN {cvterm} CVTS ON CVTP.subject_id = CVTS.cvterm_id
  116. INNER JOIN {cvterm} CVTO ON CVTP.object_id = CVTO.cvterm_id
  117. INNER JOIN {cv} ON CVTO.cv_id = CV.cv_id
  118. WHERE CV.name = 'tripal_pub' and
  119. (CVTO.name = 'Publication Details' or CVTS.name = 'Publication Type') and
  120. NOT CVTS.is_obsolete = 1
  121. ORDER BY CVTS.name ASC
  122. ";
  123. $allowed_fields = variable_get('tripal_pub_allowed_search_fields', array());
  124. $prop_types = chado_query($sql);
  125. while ($prop = db_fetch_object($prop_types)) {
  126. if($allowed_fields[$prop->cvterm_id] > 0) {
  127. $properties[$prop->cvterm_id] = $prop->name;
  128. }
  129. }
  130. for($i = 1; $i <= $num_criteria; $i++) {
  131. $search_terms = '';
  132. $scope = '';
  133. $operation = '';
  134. $mode = '';
  135. // if we have criteria supplied from the database then use that, othrewise look from the form_state or the session
  136. if ($criteria) {
  137. $search_terms = $criteria['criteria'][$i]['search_terms'];
  138. $scope = $criteria['criteria'][$i]['scope'];
  139. $mode = $criteria['criteria'][$i]['mode'];
  140. $operation = $criteria['criteria'][$i]['operation'];
  141. }
  142. // first populate defaults using any values in the SESSION variable
  143. $search_terms = $_SESSION['tripal_pub_search_form']['criteria'][$i]['search_terms'] ? $_SESSION['tripal_pub_search_form']['criteria'][$i]['search_terms'] : $search_terms;
  144. $scope = $_SESSION['tripal_pub_search_form']['criteria'][$i]['scope'] ? $_SESSION['tripal_pub_search_form']['criteria'][$i]['scope'] : $scope;
  145. $mode = $_SESSION['tripal_pub_search_form']['criteria'][$i]['mode'] ? $_SESSION['tripal_pub_search_form']['criteria'][$i]['mode'] : $mode;
  146. $operation = $_SESSION['tripal_pub_search_form']['criteria'][$i]['operation'] ? $_SESSION['tripal_pub_search_form']['criteria'][$i]['operation'] : $operation;
  147. // next populate defaults using any form values
  148. $search_terms = $form_state['values']["search_terms-$i"] ? $form_state['values']["search_terms-$i"] : $search_terms;
  149. $scope = $form_state['values']["scope-$i"] ? $form_state['values']["scope-$i"] : $scope;
  150. $mode = $form_state['values']["mode-$i"] ? $form_state['values']["mode-$i"] : $mode;
  151. $operation = $form_state['values']["operation-$i"] ? $form_state['values']["operation-$i"] : $operation;
  152. // default to searching the title and abstract
  153. if (!$scope) {
  154. $scope = 'abstract';
  155. }
  156. $form['criteria'][$i]["search_terms-$i"] = array(
  157. '#type' => 'textfield',
  158. '#default_value' => $search_terms,
  159. '#required' => FALSE,
  160. );
  161. $form['criteria'][$i]["scope-$i"] = array(
  162. '#type' => 'select',
  163. '#options' => $properties,
  164. '#default_value' => $scope,
  165. '#attributes' => array('class' => 'tripal-pub-search-form-scope-select'),
  166. );
  167. /*
  168. $form['criteria'][$i]["mode-$i"] = array(
  169. '#type' => 'select',
  170. '#options' => array(
  171. 'Contains' => 'Contains',
  172. 'Starts With' => 'Starts With',
  173. 'Ends With' => 'Ends With',
  174. 'Exactly' => 'Exactly'),
  175. '#default_value' => $mode,
  176. );*/
  177. if ($i > 1) {
  178. $form['criteria'][$i]["operation-$i"] = array(
  179. '#type' => 'select',
  180. '#options' => array(
  181. 'AND' => 'AND',
  182. 'OR' => 'OR',
  183. 'NOT' => 'NOT'),
  184. '#default_value' => $operation,
  185. );
  186. }
  187. if ($i == $num_criteria) {
  188. if($i > 1) {
  189. $form['criteria'][$i]["remove-$i"] = array(
  190. '#type' => 'image_button',
  191. '#value' => t('Remove'),
  192. '#src' => drupal_get_path('theme', 'tripal') . '/images/minus.png',
  193. '#ahah' => array(
  194. 'path' => "find/publications/criteria/minus/$i",
  195. 'wrapper' => 'tripal-pub-search-form',
  196. 'event' => 'click',
  197. 'method' => 'replace',
  198. ),
  199. '#attributes' => array('onClick' => 'return false;'),
  200. );
  201. }
  202. $form['criteria'][$i]["add-$i"] = array(
  203. '#type' => 'image_button',
  204. '#value' => t('Add'),
  205. '#src' => drupal_get_path('theme', 'tripal') . '/images/add.png',
  206. '#ahah' => array(
  207. 'path' => "find/publications/criteria/add/$i",
  208. 'wrapper' => 'tripal-pub-search-form',
  209. 'event' => 'click',
  210. 'method' => 'replace',
  211. ),
  212. '#attributes' => array('onClick' => 'return false;'),
  213. );
  214. }
  215. }
  216. $form['criteria']["date"] = array(
  217. '#type' => 'select',
  218. '#options' => array('Years' => 'Years'),
  219. '#attributes' => array('class' => 'tripal-pub-search-form-scope-select'),
  220. );
  221. $form['criteria']["from_year"] = array(
  222. '#type' => 'textfield',
  223. '#default_value' => $from_year,
  224. '#required' => FALSE,
  225. '#title' => 'from',
  226. '#size' => 4,
  227. '#maxlength' => 4,
  228. );
  229. $form['criteria']["to_year"] = array(
  230. '#type' => 'textfield',
  231. '#default_value' => $to_year,
  232. '#required' => FALSE,
  233. '#title' => 'to',
  234. '#size' => 4,
  235. '#maxlength' => 4,
  236. );
  237. $form['search'] = array(
  238. '#type' => 'submit',
  239. '#value' => t('Search'),
  240. );
  241. $form['reset'] = array(
  242. '#type' => 'submit',
  243. '#value' => t('Reset'),
  244. );
  245. return $form;
  246. }
  247. /*
  248. *
  249. */
  250. function theme_tripal_pub_search_form($form) {
  251. $rows = array();
  252. foreach ($form['criteria'] as $i => $element) {
  253. if(is_numeric($i)) {
  254. $rows[] = array(
  255. drupal_render($element["operation-$i"]),
  256. drupal_render($element["scope-$i"]),
  257. //drupal_render($element["mode-$i"]) .
  258. drupal_render($element["search_terms-$i"]),
  259. drupal_render($element["add-$i"]) . drupal_render($element["remove-$i"]),
  260. );
  261. }
  262. }
  263. $rows[] = array(
  264. '&nbsp;',
  265. drupal_render($form['criteria']['date']),
  266. array(
  267. 'data' =>
  268. "<div id=\"pub-search-form-dates-row\">
  269. <div id=\"pub-search-form-dates\"> ".
  270. drupal_render($form['criteria']['from_year']) .
  271. drupal_render($form['criteria']['to_year']) . "
  272. </div>
  273. </div>",
  274. ),
  275. ''
  276. );
  277. $table = theme('table', $headers, $rows, array('id' => 'tripal-pub-search-form-table', 'border' => '0'));
  278. $headers = array();
  279. $markup = drupal_render($form['instructions']) . "
  280. <div id=\"pub-search-form-row1\">$table</div>
  281. <div style=\"clear: both;\"></div>
  282. ";
  283. $form['criteria'] = array(
  284. '#type' => 'markup',
  285. '#value' => $markup,
  286. '#weight' => -10,
  287. );
  288. return drupal_render($form);
  289. }
  290. /**
  291. *
  292. */
  293. function tripal_pub_search_form_validate($form, &$form_state) {
  294. $num_criteria = $form_state['values']['num_criteria'];
  295. $from_year = $form_state['values']['from_year'];
  296. $to_year = $form_state['values']['to_year'];
  297. $op = $form_state['values']['op'];
  298. // no need to vlaidate on a reset
  299. if ($op == 'Reset') {
  300. return;
  301. }
  302. if($from_year and !$to_year) {
  303. form_set_error('to_year', 'Please provide a 4-digit year.');
  304. }
  305. if(!$from_year and $to_year) {
  306. form_set_error('from_year', 'Please provide a 4-digit year.');
  307. }
  308. if($from_year and !preg_match('/\d\d\d\d/' , $from_year)) {
  309. form_set_error('from_year', 'Please provide a 4-digit year.');
  310. }
  311. if($to_year and !preg_match('/\d\d\d\d/' , $to_year)) {
  312. form_set_error('to_year', 'Please provide a 4-digit year.');
  313. }
  314. }
  315. /**
  316. *
  317. */
  318. function tripal_pub_search_form_submit($form, &$form_state) {
  319. $num_criteria = $form_state['values']['num_criteria'];
  320. $from_year = $form_state['values']['from_year'];
  321. $to_year = $form_state['values']['to_year'];
  322. $op = $form_state['values']['op'];
  323. // set the session variables
  324. if($op == 'Search') {
  325. $_SESSION['tripal_pub_search_form']['num_criteria'] = $num_criteria;
  326. unset($_SESSION['tripal_pub_search_form']['criteria']);
  327. for ($i = 0; $i <= $num_criteria; $i++) {
  328. $search_terms = trim($form_state['values']["search_terms-$i"]);
  329. $scope = $form_state['values']["scope-$i"];
  330. //$mode = $form_state['values']["mode-$i"];
  331. $mode = 'Contains';
  332. $operation = $form_state['values']["operation-$i"];
  333. $_SESSION['tripal_pub_search_form']['criteria'][$i] = array(
  334. 'search_terms' => $search_terms,
  335. 'scope' => $scope,
  336. 'mode' => $mode,
  337. 'operation' => $operation
  338. );
  339. }
  340. $_SESSION['tripal_pub_search_form']['from_year'] = $from_year;
  341. $_SESSION['tripal_pub_search_form']['to_year'] = $to_year;
  342. $_SESSION['tripal_pub_search_form']['perform_search'] = 1;
  343. }
  344. if($op == 'Reset') {
  345. unset($_SESSION['tripal_pub_search_form']);
  346. }
  347. }
  348. /*
  349. * AHAH callback
  350. */
  351. function tripal_pub_search_page_update_criteria($action, $i) {
  352. $status = TRUE;
  353. // prepare and render the form
  354. $form = tripal_core_ahah_prepare_form();
  355. $data = theme('tripal_pub_search_form', $form);
  356. // bind javascript events to the new objects that will be returned
  357. // so that AHAH enabled elements will work.
  358. $settings = tripal_core_ahah_bind_events();
  359. // return the updated JSON
  360. drupal_json(
  361. array(
  362. 'status' => $status,
  363. 'data' => $data,
  364. 'settings' => $settings,
  365. )
  366. );
  367. }
  368. /*
  369. *
  370. */
  371. function tripal_pub_get_search_results($search_array, $limit, $pager_id) {
  372. // build the SQL based on the criteria provided by the user
  373. $select = "SELECT DISTINCT P.*, CP.nid ";
  374. $from = "FROM {pub} P
  375. LEFT JOIN public.chado_pub CP on P.pub_id = CP.pub_id
  376. INNER JOIN {cvterm} CVT on CVT.cvterm_id = P.type_id
  377. ";
  378. $where = "WHERE (NOT P.title = 'null') "; // always exclude the dummy pub
  379. $order = "ORDER BY P.pyear DESC, P.title ASC";
  380. $fargs = array(); // arguments for from, inner join clause
  381. $wargs = array(); // arguments for where clause
  382. $join = 0;
  383. $num_criteria = $search_array['num_criteria'];
  384. $from_year = $search_array['from_year'];
  385. $to_year = $search_array['to_year'];
  386. for ($i = 1; $i <= $num_criteria; $i++) {
  387. $value = $search_array['criteria'][$i]['search_terms'];
  388. $type_id = $search_array['criteria'][$i]['scope'];
  389. $mode = $search_array['criteria'][$i]['mode'];
  390. $op = $search_array['criteria'][$i]['operation'];
  391. // skip criteria with no values
  392. if(!$value) {
  393. continue;
  394. }
  395. // to prevent SQL injection make sure our operator is
  396. // what we expect
  397. if ($op and $op != "AND" and $op != "OR" and $op != 'NOT') {
  398. $op = 'AND';
  399. }
  400. if ($op == 'NOT') {
  401. $op = 'AND NOT';
  402. }
  403. if (!$op) {
  404. $op = 'AND';
  405. }
  406. $action = "= lower('%s')";
  407. if($mode == 'Contains') {
  408. $action = 'LIKE lower(\'%%%s%%\')';
  409. }
  410. if($mode == 'Starts With') {
  411. $action = '= lower(\'%%%s\')';
  412. }
  413. if($mode == 'Ends With') {
  414. $action = '= lower(\'%s%%\')';
  415. }
  416. // get the scope type
  417. $values = array('cvterm_id' => $type_id);
  418. $cvterm = tripal_core_chado_select('cvterm', array('name'), $values);
  419. $type_name = $cvterm[0]->name;
  420. if ($type_name == 'Title') {
  421. $where .= " $op (lower(P.title) $action) ";
  422. $wargs[] = $value;
  423. }
  424. elseif ($type_name == 'Year') {
  425. $where .= " $op (lower(P.pyear) $action) ";
  426. $wargs[] = $value;
  427. }
  428. elseif ($type_name == 'Volume') {
  429. $where .= " $op (lower(P.volume) $action) ";
  430. $wargs[] = $value;
  431. }
  432. elseif ($type_name == 'Issue') {
  433. $where .= " $op (lower(P.issue) $action)";
  434. $wargs[] = $value;
  435. }
  436. elseif ($type_name == 'Journal Name') {
  437. $from .= " LEFT JOIN {pubprop} PP$i ON PP$i.pub_id = P.pub_id AND PP$i.type_id = %d ";
  438. $where .= " $op ((lower(P.series_name) $action and CVT.name = 'Journal Article') OR
  439. (lower(PP$i.value) $action)) ";
  440. $fargs[] = $type_id;
  441. $wargs[] = $value;
  442. $wargs[] = $value;
  443. }
  444. elseif ($type_name == 'Conference Name') {
  445. $from .= " LEFT JOIN {pubprop} PP$i ON PP$i.pub_id = P.pub_id AND PP$i.type_id = %d ";
  446. $where .= " $op ((lower(P.series_name) $action and CVT.name = 'Conference Proceedings') OR
  447. (lower(PP$i.value) $action)) ";
  448. $fargs[] = $type_id;
  449. $wargs[] = $value;
  450. $wargs[] = $value;
  451. }
  452. elseif ($type_name == 'Publication Type') {
  453. $where .= " $op (lower(CVT.name) $action)";
  454. $wargs[] = $value;
  455. }
  456. elseif ($type_id == 0) { //'Any Field'
  457. $from .= " LEFT JOIN {pubprop} PP$i ON PP$i.pub_id = P.pub_id ";
  458. $where .= " $op (lower(PP$i.value) $action OR
  459. lower(P.title) $action OR
  460. lower(P.volumetitle) $action OR
  461. lower(P.publisher) $action OR
  462. lower(P.uniquename) $action OR
  463. lower(P.pubplace) $action OR
  464. lower(P.miniref) $action OR
  465. lower(P.series_name) $action) ";
  466. $wargs[] = $value;
  467. $wargs[] = $value;
  468. $wargs[] = $value;
  469. $wargs[] = $value;
  470. $wargs[] = $value;
  471. $wargs[] = $value;
  472. $wargs[] = $value;
  473. $wargs[] = $value;
  474. }
  475. // for all other properties
  476. else {
  477. $from .= " LEFT JOIN {pubprop} PP$i ON PP$i.pub_id = P.pub_id AND PP$i.type_id = %d ";
  478. $where .= " $op (lower(PP$i.value) $action) ";
  479. $fargs[] = $type_id;
  480. $wargs[] = $value;
  481. }
  482. }
  483. if($from_year and $to_year) {
  484. $where .= " AND (P.pyear ~ '....' AND to_number(P.pyear,'9999') >= %d AND to_number(P.pyear,'9999') <= %d) ";
  485. $wargs[] = $from_year;
  486. $wargs[] = $to_year;
  487. }
  488. $sql = "$select $from $where $order";
  489. $count = "SELECT count(*) FROM ($select $from $where $order) as t1";
  490. $args = array_merge($fargs, $wargs);
  491. //dpm(array($mode, $sql, $args));
  492. return chado_pager_query($sql, $limit, $pager_id, $count, $args);
  493. }