tripal_pub.pub_search.inc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. <?php
  2. /**
  3. * @file
  4. *
  5. * Functions responsible for creating the publication search form that
  6. * allows a user of the site to search for publications that are currently
  7. * in Chado.
  8. */
  9. /**
  10. * The page that contains the publication search form and the results for the search
  11. *
  12. * @ingroup tripal_pub
  13. */
  14. function tripal_pub_search_page() {
  15. $limit = 25;
  16. // generate the search form
  17. $form = drupal_get_form('tripal_pub_search_form');
  18. $output = drupal_render($form);
  19. // retrieve any results
  20. if (array_key_exists('tripal_pub_search_form', $_SESSION) and
  21. $_SESSION['tripal_pub_search_form']['perform_search']) {
  22. $num_criteria = $_SESSION['tripal_pub_search_form']['num_criteria'];
  23. $from_year = $_SESSION['tripal_pub_search_form']['from_year'];
  24. $to_year = $_SESSION['tripal_pub_search_form']['to_year'];
  25. $search_array = array();
  26. $search_array['num_criteria'] = $num_criteria;
  27. $search_array['from_year'] = $from_year;
  28. $search_array['to_year'] = $to_year;
  29. for ($i = 0; $i <= $num_criteria; $i++) {
  30. $search_array['criteria'][$i]['search_terms'] = $_SESSION['tripal_pub_search_form']['criteria'][$i]['search_terms'];
  31. $search_array['criteria'][$i]['scope'] = $_SESSION['tripal_pub_search_form']['criteria'][$i]['scope'];
  32. $search_array['criteria'][$i]['mode'] = $_SESSION['tripal_pub_search_form']['criteria'][$i]['mode'];
  33. $search_array['criteria'][$i]['operation'] = $_SESSION['tripal_pub_search_form']['criteria'][$i]['operation'];
  34. }
  35. // get the list of publications from the remote database using the search criteria.
  36. $page = isset($_GET['page']) ? $_GET['page'] : '0';
  37. $offset = $page * $limit;
  38. $total_records = 0;
  39. $pubs = pub_search($search_array, $offset, $limit, $total_records);
  40. pager_default_initialize($total_records, $limit, 0);
  41. // iterate through the results and construct the table displaying the publications
  42. $rows = array();
  43. $i = $page * $limit + 1;
  44. foreach ($pubs as $pub) {
  45. // get the citation for this publication
  46. $values = array(
  47. 'pub_id' => $pub->pub_id,
  48. 'type_id' => array(
  49. 'name' => 'Citation',
  50. ),
  51. );
  52. $citation_rec = chado_generate_var('pubprop', $values);
  53. $citation_rec = chado_expand_var($citation_rec, 'field', 'pubprop.value');
  54. // if we have the citation then use it, otherwise, just use the title
  55. $title = htmlspecialchars($pub->title);
  56. $result = $title;
  57. if ($pub->nid) {
  58. $result = l($title ,'node/' . $pub->nid, array('attributes' => array('target' => '_blank')));
  59. }
  60. if ($citation_rec->value) {
  61. $citation = htmlspecialchars($citation_rec->value);
  62. $result .= '<br>' . $citation;
  63. }
  64. $rows[] = array(
  65. number_format($i) . ".",
  66. $pub->pyear,
  67. $result
  68. );
  69. $i++;
  70. }
  71. if (count($rows) == 0) {
  72. $rows[] = array(
  73. array(
  74. 'data' => 'No results found',
  75. 'colspan' => 3
  76. )
  77. );
  78. }
  79. $headers = array('', 'Year', 'Publication');
  80. $table = array(
  81. 'header' => $headers,
  82. 'rows' => $rows,
  83. 'attributes' => array('id' => 'tripal-pub-search-results-table', 'border' => '0'),
  84. 'sticky' => TRUE,
  85. 'caption' => '',
  86. 'colgroups' => array(),
  87. 'empty' => '',
  88. );
  89. $results = theme_table($table);
  90. // generate the pager
  91. $pager = array(
  92. 'tags' => array(),
  93. 'element' => 0,
  94. 'parameters' => array(),
  95. 'quantity' => $limit,
  96. );
  97. $pager = theme_pager($pager);
  98. // join all to form the results
  99. $output .= "<p><b>Found " . number_format($total_records) .
  100. " Results</b></br>" . $results . $pager;
  101. }
  102. return $output;
  103. }
  104. /**
  105. * Provides the form to search pubmed
  106. *
  107. * @ingroup tripal_pub
  108. */
  109. function tripal_pub_search_form($form, &$form_state) {
  110. // Default values can come in the following ways:
  111. //
  112. // 1) as elements of the $pub_importer object. This occurs when editing an existing importer
  113. // 2) in the $form_state['values'] array which occurs on a failed validation or
  114. // ajax callbacks from non submit form elements
  115. // 3) in the $form_state['input'] array which occurs on ajax callbacks from submit
  116. // form elements and the form is being rebuilt
  117. //
  118. // Set the default values. If the pub_import_id isn't already defined by the form values
  119. // and one is provided then look it up in the database
  120. $criteria = NULL;
  121. $num_criteria = 2;
  122. $from_year = '';
  123. $to_year = '';
  124. // if the session has variables then use those. This should only happen when
  125. // the 'Test Criteria' button is clicked.
  126. if (array_key_exists('tripal_pub_search_form', $_SESSION)) {
  127. $num_criteria = $_SESSION['tripal_pub_search_form']['num_criteria'] ? $_SESSION['tripal_pub_search_form']['num_criteria'] : $num_criteria;
  128. $from_year = $_SESSION['tripal_pub_search_form']['from_year'] ? $_SESSION['tripal_pub_search_form']['from_year'] : '';
  129. $to_year = $_SESSION['tripal_pub_search_form']['to_year'] ? $_SESSION['tripal_pub_search_form']['to_year'] : '';
  130. }
  131. if (array_key_exists('values', $form_state)) {
  132. $num_criteria = $form_state['values']['num_criteria'] ? $form_state['values']['num_criteria'] : $num_criteria;
  133. $from_year = $form_state['values']['from_year'] ? $form_state['values']['from_year'] : $from_year;
  134. $to_year = $form_state['values']['to_year'] ? $form_state['values']['to_year'] : $to_year;
  135. }
  136. if (array_key_exists('input', $form_state) and !empty($form_state['input'])) {
  137. $num_criteria = $form_state['input']['num_criteria'] ? $form_state['input']['num_criteria'] : $num_criteria;
  138. $from_year = $form_state['input']['from_year'] ? $form_state['input']['from_year'] : $from_year;
  139. $to_year = $form_state['input']['to_year'] ? $form_state['input']['to_year'] : $to_year;
  140. }
  141. if (array_key_exists('triggering_element', $form_state) and
  142. $form_state['triggering_element']['#name'] == 'add') {
  143. $num_criteria++;
  144. }
  145. if (array_key_exists('triggering_element', $form_state) and
  146. $form_state['triggering_element']['#name'] == 'remove') {
  147. $num_criteria--;
  148. }
  149. $form['num_criteria']= array(
  150. '#type' => 'hidden',
  151. '#default_value' => $num_criteria,
  152. );
  153. $form['admin-instructions'] = array(
  154. '#markup' => tripal_set_message(
  155. t('Administrators, you can select the fields with which a user can use to search, by checking the desired fields on the ' .
  156. l('Publication Module Settings Page', 'admin/tripal/chado/tripal_pub/configuration', array('attributes' => array('target' => '_blank'))) . '
  157. in the section titled "Search Options". The selected fields will appear in the dropdowns below.'),
  158. TRIPAL_INFO,
  159. array('return_html' => 1)),
  160. );
  161. $form['instructions'] = array(
  162. '#markup' => t('To search for publications enter keywords in the text boxes below.
  163. You can limit your search by selecting the field in the dropdown box. Click the
  164. add and remove buttons to add additional fields for searching. '),
  165. );
  166. // get publication properties list
  167. $properties = array();
  168. $properties[] = 'Any Field';
  169. $sql = "
  170. SELECT DISTINCT CVTS.cvterm_id, CVTS.name, CVTS.definition
  171. FROM {cvtermpath} CVTP
  172. INNER JOIN {cvterm} CVTS ON CVTP.subject_id = CVTS.cvterm_id
  173. INNER JOIN {cvterm} CVTO ON CVTP.object_id = CVTO.cvterm_id
  174. INNER JOIN {cv} ON CVTO.cv_id = CV.cv_id
  175. WHERE CV.name = 'tripal_pub' and
  176. (CVTO.name = 'Publication Details' or CVTS.name = 'Publication Type') and
  177. NOT CVTS.is_obsolete = 1
  178. ORDER BY CVTS.name ASC
  179. ";
  180. $allowed_fields = variable_get('tripal_pub_allowed_search_fields', array());
  181. $prop_types = chado_query($sql);
  182. foreach ($prop_types as $prop) {
  183. if(array_key_exists($prop->cvterm_id, $allowed_fields) and $allowed_fields[$prop->cvterm_id] > 0) {
  184. $properties[$prop->cvterm_id] = $prop->name;
  185. }
  186. }
  187. for($i = 1; $i <= $num_criteria; $i++) {
  188. $search_terms = '';
  189. $scope = '';
  190. $operation = '';
  191. $mode = '';
  192. // first populate defaults using any values in the SESSION variable
  193. if (array_key_exists('tripal_pub_search_form', $_SESSION)) {
  194. $search_terms = $_SESSION['tripal_pub_search_form']['criteria'][$i]['search_terms'] ? $_SESSION['tripal_pub_search_form']['criteria'][$i]['search_terms'] : $search_terms;
  195. $scope = $_SESSION['tripal_pub_search_form']['criteria'][$i]['scope'] ? $_SESSION['tripal_pub_search_form']['criteria'][$i]['scope'] : $scope;
  196. $mode = $_SESSION['tripal_pub_search_form']['criteria'][$i]['mode'] ? $_SESSION['tripal_pub_search_form']['criteria'][$i]['mode'] : $mode;
  197. $operation = $_SESSION['tripal_pub_search_form']['criteria'][$i]['operation'] ? $_SESSION['tripal_pub_search_form']['criteria'][$i]['operation'] : $operation;
  198. }
  199. if (array_key_exists('values', $form_state)) {
  200. $search_terms = array_key_exists("search_terms-$i", $form_state['values']) ? $form_state['values']["search_terms-$i"] : $search_terms;
  201. $scope = array_key_exists("scope-$i", $form_state['values']) ? $form_state['values']["scope-$i"] : $scope;
  202. $mode = array_key_exists("mode-$i", $form_state['values']) ? $form_state['values']["mode-$i"] : $mode;
  203. $operation = array_key_exists("operation-$i", $form_state['values']) ? $form_state['values']["operation-$i"] : $operation;
  204. }
  205. if (array_key_exists('input', $form_state)) {
  206. $search_terms = array_key_exists("search_terms-$i", $form_state['input']) ? $form_state['input']["search_terms-$i"] : $search_terms;
  207. $scope = array_key_exists("scope-$i", $form_state['input']) ? $form_state['input']["scope-$i"] : $scope;
  208. $mode = array_key_exists("mode-$i", $form_state['input']) ? $form_state['input']["mode-$i"] : $mode;
  209. $operation = array_key_exists("operation-$i", $form_state['input']) ? $form_state['input']["operation-$i"] : $operation;
  210. }
  211. // default to searching the title and abstract
  212. if (!$scope) {
  213. $scope = 'abstract';
  214. }
  215. $form['criteria'][$i]["search_terms-$i"] = array(
  216. '#type' => 'textfield',
  217. '#default_value' => $search_terms,
  218. '#required' => FALSE,
  219. );
  220. $form['criteria'][$i]["scope-$i"] = array(
  221. '#type' => 'select',
  222. '#options' => $properties,
  223. '#default_value' => $scope,
  224. '#attributes' => array('class' => array('tripal-pub-search-form-scope-select')),
  225. );
  226. /*
  227. $form['criteria'][$i]["mode-$i"] = array(
  228. '#type' => 'select',
  229. '#options' => array(
  230. 'Contains' => 'Contains',
  231. 'Starts With' => 'Starts With',
  232. 'Ends With' => 'Ends With',
  233. 'Exactly' => 'Exactly'),
  234. '#default_value' => $mode,
  235. );*/
  236. if ($i > 1) {
  237. $form['criteria'][$i]["operation-$i"] = array(
  238. '#type' => 'select',
  239. '#options' => array(
  240. 'AND' => 'AND',
  241. 'OR' => 'OR',
  242. 'NOT' => 'NOT'),
  243. '#default_value' => $operation,
  244. );
  245. }
  246. if ($i == $num_criteria) {
  247. if($i > 1) {
  248. $form['criteria'][$i]["remove-$i"] = array(
  249. '#type' => 'button',
  250. '#name' => 'remove',
  251. '#value' => t('Remove'),
  252. '#ajax' => array(
  253. 'callback' => "tripal_pubs_search_form_ajax_update",
  254. 'wrapper' => 'tripal-pub-search-form-criteria',
  255. 'effect' => 'fade',
  256. 'method' => 'replace',
  257. 'prevent' => 'click'
  258. ),
  259. // When this button is clicked, the form will be validated and submitted.
  260. // Therefore, we set custom submit and validate functions to override the
  261. // default form submit. In the validate function we set the form_state
  262. // to rebuild the form so the submit function never actually gets called,
  263. // but we need it or Drupal will run the default validate anyway.
  264. // we also set #limit_validation_errors to empty so fields that
  265. // are required that don't have values won't generate warnings.
  266. '#submit' => array('tripal_pub_search_form_ajax_button_submit'),
  267. '#validate' => array('tripal_pub_search_form_ajax_button_validate'),
  268. '#limit_validation_errors' => array(),
  269. );
  270. }
  271. $form['criteria'][$i]["add-$i"] = array(
  272. '#type' => 'button',
  273. '#name' => 'add',
  274. '#value' => t('Add'),
  275. '#ajax' => array(
  276. 'callback' => "tripal_pubs_search_form_ajax_update",
  277. 'wrapper' => 'tripal-pub-search-form-criteria',
  278. 'effect' => 'fade',
  279. 'method' => 'replace',
  280. 'prevent' => 'click'
  281. ),
  282. // When this button is clicked, the form will be validated and submitted.
  283. // Therefore, we set custom submit and validate functions to override the
  284. // default form submit. In the validate function we set the form_state
  285. // to rebuild the form so the submit function never actually gets called,
  286. // but we need it or Drupal will run the default validate anyway.
  287. // we also set #limit_validation_errors to empty so fields that
  288. // are required that don't have values won't generate warnings.
  289. '#submit' => array('tripal_pub_search_form_ajax_button_submit'),
  290. '#validate' => array('tripal_pub_search_form_ajax_button_validate'),
  291. '#limit_validation_errors' => array(),
  292. );
  293. }
  294. }
  295. $form['criteria']["date"] = array(
  296. '#type' => 'select',
  297. '#options' => array('Years' => 'Years'),
  298. '#attributes' => array('class' => array('tripal-pub-search-form-scope-select')),
  299. );
  300. $form['criteria']["from_year"] = array(
  301. '#type' => 'textfield',
  302. '#default_value' => $from_year,
  303. '#required' => FALSE,
  304. '#title' => 'from',
  305. '#size' => 4,
  306. '#maxlength' => 4,
  307. );
  308. $form['criteria']["to_year"] = array(
  309. '#type' => 'textfield',
  310. '#default_value' => $to_year,
  311. '#required' => FALSE,
  312. '#title' => 'to',
  313. '#size' => 4,
  314. '#maxlength' => 4,
  315. );
  316. $form['search'] = array(
  317. '#type' => 'submit',
  318. '#value' => t('Search'),
  319. );
  320. $form['reset'] = array(
  321. '#type' => 'submit',
  322. '#value' => t('Reset'),
  323. );
  324. $form['criteria']['#theme'] = 'tripal_pub_search_setup_form_elements';
  325. return $form;
  326. }
  327. /**
  328. * This function is used to rebuild the form if an ajax call is made vai a button.
  329. * The button causes the form to be submitted. We don't want this so we override
  330. * the validate and submit routines on the form button. Therefore, this function
  331. * only needs to tell Drupal to rebuild the form
  332. *
  333. * @ingroup tripal_pub
  334. */
  335. function tripal_pub_search_form_ajax_button_submit() {
  336. $form_state['rebuild'] = TRUE;
  337. }
  338. /**
  339. * This function is just a dummy to override the default form submit on ajax calls for buttons
  340. *
  341. * @ingroup tripal_pub
  342. */
  343. function tripal_pub_search_form_ajax_button_validate() {
  344. // do nothing
  345. }
  346. /**
  347. * Validate the tripal_pub_search_form form
  348. *
  349. * @ingroup tripal_pub
  350. */
  351. function tripal_pub_search_form_validate($form, &$form_state) {
  352. $num_criteria = $form_state['values']['num_criteria'];
  353. $from_year = $form_state['values']['from_year'];
  354. $to_year = $form_state['values']['to_year'];
  355. $op = $form_state['values']['op'];
  356. // no need to vlaidate on a reset
  357. if ($op == 'Reset') {
  358. return;
  359. }
  360. if($from_year and !$to_year) {
  361. form_set_error('to_year', 'Please provide a 4-digit year.');
  362. }
  363. if(!$from_year and $to_year) {
  364. form_set_error('from_year', 'Please provide a 4-digit year.');
  365. }
  366. if($from_year and !preg_match('/\d\d\d\d/' , $from_year)) {
  367. form_set_error('from_year', 'Please provide a 4-digit year.');
  368. }
  369. if($to_year and !preg_match('/\d\d\d\d/' , $to_year)) {
  370. form_set_error('to_year', 'Please provide a 4-digit year.');
  371. }
  372. }
  373. /**
  374. * Submit the tripal_pub_search_form form
  375. *
  376. * @ingroup tripal_pub
  377. */
  378. function tripal_pub_search_form_submit($form, &$form_state) {
  379. $num_criteria = $form_state['values']['num_criteria'];
  380. $from_year = $form_state['values']['from_year'];
  381. $to_year = $form_state['values']['to_year'];
  382. $op = $form_state['values']['op'];
  383. // set the session variables
  384. if($op == 'Search') {
  385. $_SESSION['tripal_pub_search_form']['num_criteria'] = $num_criteria;
  386. unset($_SESSION['tripal_pub_search_form']['criteria']);
  387. for ($i = 0; $i <= $num_criteria; $i++) {
  388. $search_terms = '';
  389. $scope = '';
  390. $mode = 'Contains';
  391. $operation = '';
  392. if (array_key_exists("search_terms-$i", $form_state['values'])) {
  393. $search_terms = trim($form_state['values']["search_terms-$i"]);
  394. }
  395. if (array_key_exists("scope-$i", $form_state['values'])) {
  396. $scope = $form_state['values']["scope-$i"];
  397. }
  398. if (array_key_exists("operation-$i", $form_state['values'])) {
  399. $operation = $form_state['values']["operation-$i"];
  400. }
  401. //$mode = $form_state['values']["mode-$i"];
  402. $_SESSION['tripal_pub_search_form']['criteria'][$i] = array(
  403. 'search_terms' => $search_terms,
  404. 'scope' => $scope,
  405. 'mode' => $mode,
  406. 'operation' => $operation
  407. );
  408. }
  409. $_SESSION['tripal_pub_search_form']['from_year'] = $from_year;
  410. $_SESSION['tripal_pub_search_form']['to_year'] = $to_year;
  411. $_SESSION['tripal_pub_search_form']['perform_search'] = 1;
  412. }
  413. if($op == 'Reset') {
  414. unset($_SESSION['tripal_pub_search_form']);
  415. }
  416. }
  417. /**
  418. * Ajax callback to update the form
  419. *
  420. * @param $form
  421. * The form array
  422. * @param $form_state
  423. * The form state array
  424. *
  425. * @ingroup tripal_pub
  426. */
  427. function tripal_pubs_search_form_ajax_update($form, $form_state) {
  428. return $form['criteria'];
  429. }
  430. /**
  431. * Theme the tripal_pub_search_setup_form form
  432. *
  433. * @ingroup tripal_pub
  434. */
  435. function theme_tripal_pub_search_setup_form_elements($variables) {
  436. $form = $variables['form'];
  437. $rows = array();
  438. // put each criteria element in a single table row
  439. foreach ($form as $i => $element) {
  440. if(is_numeric($i)) {
  441. $rows[] = array(
  442. drupal_render($element["operation-$i"]),
  443. drupal_render($element["scope-$i"]),
  444. //drupal_render($element["mode-$i"]) .
  445. drupal_render($element["search_terms-$i"]),
  446. array(
  447. 'data' => drupal_render($element["add-$i"]) . drupal_render($element["remove-$i"]),
  448. 'nowrap' => 'nowrap',
  449. ),
  450. );
  451. }
  452. }
  453. // add in the from_year and to_year elements as the final row of the table
  454. $rows[] = array(
  455. '&nbsp;',
  456. drupal_render($form['date']),
  457. array(
  458. 'data' =>
  459. "<div id=\"pub-search-form-dates-row\">
  460. <div id=\"pub-search-form-dates\"> ".
  461. drupal_render($form['from_year']) .
  462. drupal_render($form['to_year']) . "
  463. </div>
  464. </div>
  465. ",
  466. ),
  467. ''
  468. );
  469. $headers = array();
  470. $table = array(
  471. 'header' => $headers,
  472. 'rows' => $rows,
  473. 'attributes' => array('id' => 'tripal-pub-search-form-table', 'border' => '0'),
  474. 'sticky' => TRUE,
  475. 'caption' => '',
  476. 'colgroups' => array(),
  477. 'empty' => '',
  478. );
  479. $results = '<div id="tripal-pub-search-form-criteria">';
  480. $results .= theme_table($table);
  481. $results .= '</div>';
  482. return $results;
  483. }