tripal_pub.pub_importers.inc 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. <?php
  2. /**
  3. * @file
  4. * Management of importers
  5. */
  6. /**
  7. * A function to generate a table containing the list of publication importers
  8. *
  9. * @ingroup tripal_pub
  10. */
  11. function tripal_pub_importers_list() {
  12. // clear out the session variable when we view the list.
  13. unset($_SESSION['tripal_pub_import']);
  14. $header = array('', 'Importer Name', 'Database', 'Search String', 'Disabled', 'Create Contact', '');
  15. $rows = array();
  16. $importers = db_query("SELECT * FROM {tripal_pub_import} ORDER BY name");
  17. while ($importer = $importers->fetchObject()) {
  18. $criteria = unserialize($importer->criteria);
  19. $num_criteria = $criteria['num_criteria'];
  20. $criteria_str = '';
  21. for ($i = 1; $i <= $num_criteria; $i++) {
  22. $search_terms = $criteria['criteria'][$i]['search_terms'];
  23. $scope = $criteria['criteria'][$i]['scope'];
  24. $is_phrase = $criteria['criteria'][$i]['is_phrase'];
  25. $operation = $criteria['criteria'][$i]['operation'];
  26. $criteria_str .= "$operation ($scope: $search_terms) ";
  27. }
  28. $rows[] = array(
  29. array(
  30. 'data' => l(t('Edit/Test'), "admin/tripal/chado/tripal_pub/import/edit/$importer->pub_import_id") . '<br>' .
  31. l(t('Import Pubs'), "admin/tripal/chado/tripal_pub/import/submit/$importer->pub_import_id"),
  32. 'nowrap' => 'nowrap'
  33. ),
  34. $importer->name,
  35. $criteria['remote_db'],
  36. $criteria_str,
  37. $importer->disabled ? 'Yes' : 'No',
  38. $importer->do_contact ? 'Yes' : 'No',
  39. l(t('Delete'), "admin/tripal/chado/tripal_pub/import/delete/$importer->pub_import_id"),
  40. );
  41. }
  42. $page = "<ul class='action-links'>";
  43. $page .= ' <li>' . l('New Importer', 'admin/tripal/chado/tripal_pub/import/new') . '</li>';
  44. $page .= '</ul>';
  45. $page .= '<p>' . t(
  46. "A publication importer is used to create a set of search criteria that can be used
  47. to query a remote database, find publications that match the specified criteria
  48. and then import those publications into the Chado database. An example use case would
  49. be to peridocially add new publications to this Tripal site that have appeared in PubMed
  50. in the last 30 days. You can import publications in one of two ways:
  51. <ol>
  52. <li>Create a new importer by clicking the 'New Importer' link above, and after saving it should appear in the list below. Click the
  53. link labeled 'Import Pubs' to schedule a job to import the publications</li>
  54. <li>The first method only performs the import once. However, you can schedule the
  55. importer to run peridically by adding a cron job. See the " .
  56. l("Pub Module help instructions", "admin/tripal/chado/tripal_pub/help") . " to learn how to
  57. set the importers to run automatically.") . '</li>
  58. </ol><br>';
  59. $page .= theme('table', array('header' => $header, 'rows' => $rows));
  60. return $page;
  61. }
  62. /**
  63. * @stephen
  64. *
  65. * @param $action
  66. * @param $pub_import_id
  67. *
  68. * @ingroup tripal_pub
  69. */
  70. function tripal_pub_importer_setup_page($action = 'new', $pub_import_id = NULL) {
  71. global $base_path;
  72. // make sure the tripal_pub and tripal_contact ontologies are loaded
  73. $values = array('name' => 'tripal_pub');
  74. $tpub_cv = chado_select_record('cv', array('cv_id'), $values);
  75. if (count($tpub_cv) == 0) {
  76. drupal_set_message(t('Before importing publications you must first ') . l(t('load the Tripal Pub Ontology'), 'admin/tripal/tripal_cv/obo_loader'), 'error');
  77. }
  78. $values = array('name' => 'tripal_contact');
  79. $tpub_cv = chado_select_record('cv', array('cv_id'), $values);
  80. if (count($tpub_cv) == 0) {
  81. drupal_set_message(t('If you want to create contact pages for authors, you must first ') . l(t('load the Tripal Contact Ontology'), 'admin/tripal/tripal_cv/obo_loader'), 'error');
  82. }
  83. if(!extension_loaded ('yaz')){
  84. drupal_set_message(t('<b>Note:</b> In order to create an importer using the USDA National Agricultural Library (AGL) you must install the yaz libraries. See the ') . l(t('Pub Module help page'), 'admin/tripal/chado/tripal_pub/help') . ' for assistance. If you do not want to use AGL you can ignore this warning.', 'warning');
  85. }
  86. // generate the search form
  87. $form = drupal_get_form('tripal_pub_importer_setup_form', $pub_import_id, $action);
  88. $output = l("Return to publication importers list", "admin/tripal/chado/tripal_pub/import_list");
  89. $output .= drupal_render($form);
  90. // retrieve any results
  91. if (array_key_exists('tripal_pub_import', $_SESSION)) {
  92. $remote_db = $_SESSION['tripal_pub_import']['remote_db'];
  93. $num_criteria = $_SESSION['tripal_pub_import']['num_criteria'];
  94. $days = $_SESSION['tripal_pub_import']['days'];
  95. $search_array = array();
  96. $search_array['remote_db'] = $remote_db;
  97. $search_array['num_criteria'] = $num_criteria;
  98. $search_array['days'] = $days;
  99. for ($i = 1; $i <= $num_criteria; $i++) {
  100. $search_array['criteria'][$i]['search_terms'] = $_SESSION['tripal_pub_import']['criteria'][$i]['search_terms'];
  101. $search_array['criteria'][$i]['scope'] = $_SESSION['tripal_pub_import']['criteria'][$i]['scope'];
  102. $search_array['criteria'][$i]['is_phrase'] = $_SESSION['tripal_pub_import']['criteria'][$i]['is_phrase'];
  103. $search_array['criteria'][$i]['operation'] = $_SESSION['tripal_pub_import']['criteria'][$i]['operation'];
  104. }
  105. // if the form has been submitted with the 'test' button then get the results
  106. if ($_SESSION['tripal_pub_import']['perform_search']) {
  107. $limit = 25;
  108. // get the list of publications from the remote database using the search criteria.
  109. $page = isset($_GET['page']) ? $_GET['page'] : '0';
  110. $results = tripal_pub_get_remote_search_results($remote_db, $search_array, $limit, $page);
  111. $total_records = $results['total_records'];
  112. $search_str = $results['search_str'];
  113. $pubs = $results['pubs'];
  114. // iterate through the results and construct the table displaying the publications
  115. $rows = array();
  116. $i = $page * $limit + 1;
  117. if (count($pubs) > 0) {
  118. foreach ($pubs as $pub) {
  119. $citation = htmlspecialchars($pub['Citation']);
  120. $raw_link = '';
  121. if($pub['Publication Dbxref']) {
  122. $raw_link = l('raw', 'admin/tripal/chado/tripal_pub/import/raw/' . $pub['Publication Dbxref'], array('attributes' => array('target' => '_blank')));
  123. }
  124. $rows[] = array(
  125. number_format($i),
  126. $citation,
  127. $raw_link,
  128. );
  129. $i++;
  130. }
  131. }
  132. if (count($rows) == 0) {
  133. $rows[] = array(
  134. array(
  135. 'data' => 'No results found',
  136. 'colspan' => 3,
  137. ),
  138. );
  139. }
  140. $headers = array('', 'Publication', 'Raw Results');
  141. $table = array(
  142. 'header' => $headers,
  143. 'rows' => $rows,
  144. 'attributes' => array(
  145. 'id' => 'tripal_pub-importer-test',
  146. ),
  147. 'sticky' => FALSE,
  148. 'caption' => '',
  149. 'colgroups' => array(),
  150. 'empty' => '',
  151. );
  152. // once we have our table array structure defined, we call Drupal's theme_table()
  153. // function to generate the table.
  154. $table = theme_table($table);
  155. // generate the pager
  156. pager_default_initialize($total_records, $limit);
  157. $pager = array(
  158. 'tags' => array(),
  159. 'element' => 0,
  160. 'parameters' => array(),
  161. 'quantity' => $limit,
  162. );
  163. $pager = theme_pager($pager);
  164. // because this is an ajax callback, the theme_pager will set the URL to be
  165. // "system/ajax", so we need to reset that
  166. $pager = str_replace($base_path . "system/ajax", "", $pager) ;
  167. // join all to form the results
  168. $total_pages = (int) ($total_records / $limit) + 1;
  169. $page = isset($_GET['page']) ? $_GET['page'] : '0';
  170. $output .= "$pager<br><b>Found " . number_format($total_records) . " publications. Page " . ($page + 1) . " of $total_pages.</b> " .
  171. "<br>$remote_db Search String: $search_str $table<br>$pager";
  172. }
  173. }
  174. return $output;
  175. }
  176. /**
  177. * Provides the form to search pubmed
  178. *
  179. * @stephen
  180. *
  181. * @param $form
  182. * @param $form_state
  183. * @param $pub_import_id
  184. * @param $action
  185. *
  186. * @ingroup tripal_pub
  187. */
  188. function tripal_pub_importer_setup_form($form, &$form_state = NULL, $pub_import_id = NULL, $action = 'new') {
  189. // Default values can come in the following ways:
  190. //
  191. // 1) as elements of the $pub_importer object. This occurs when editing an existing importer
  192. // 2) in the $form_state['values'] array which occurs on a failed validation or
  193. // ajax callbacks from non submit form elements
  194. // 3) in the $form_state['input'] array which occurs on ajax callbacks from submit
  195. // form elements and the form is being rebuilt
  196. //
  197. // set form field defaults
  198. // Set the default values. If the pub_import_id isn't already defined by the form values
  199. // and one is provided then look it up in the database
  200. $criteria = NULL;
  201. $remote_db = '';
  202. $days = '';
  203. $disabled = '';
  204. $do_contact = '';
  205. $num_criteria = 1;
  206. $loader_name = '';
  207. // if this is an edit the we are pulling an import object from the database
  208. if ($action == "edit") {
  209. $sql = "SELECT * FROM {tripal_pub_import} WHERE pub_import_id = :pub_import_id";
  210. $importer = db_query($sql, array(':pub_import_id' => $pub_import_id))->fetchObject();
  211. $criteria = unserialize($importer->criteria);
  212. $remote_db = $criteria['remote_db'];
  213. $days = $criteria['days'];
  214. $disabled = $criteria['disabled'];
  215. $do_contact = $criteria['do_contact'];
  216. $num_criteria = $criteria['num_criteria'];
  217. $loader_name = $criteria['loader_name'];
  218. }
  219. // if there are any session variables then use those
  220. if (array_key_exists('tripal_pub_import', $_SESSION)) {
  221. $remote_db = $_SESSION['tripal_pub_import']['remote_db'];
  222. $days = $_SESSION['tripal_pub_import']['days'];
  223. $disabled = $_SESSION['tripal_pub_import']['disabled'];
  224. $do_contact = $_SESSION['tripal_pub_import']['do_contact'];
  225. $num_criteria = $_SESSION['tripal_pub_import']['num_criteria'];
  226. $loader_name = $_SESSION['tripal_pub_import']['loader_name'];
  227. // check if the pub_import_id in the session variable is not the same as the one we've been provided
  228. // if so, then clear the session variable
  229. if ($pub_import_id and $pub_import_id != $_SESSION['tripal_pub_import']['pub_import_id']) {
  230. unset($_SESSION['tripal_pub_import']);
  231. }
  232. }
  233. // if we are re constructing the form from a failed validation or ajax callback
  234. // then use the $form_state['values'] values
  235. if (array_key_exists('values', $form_state)) {
  236. $remote_db = $form_state['values']['remote_db'];
  237. $days = $form_state['values']['days'];
  238. $disabled = $form_state['values']['disabled'];
  239. $do_contact = $form_state['values']['do_contact'];
  240. $num_criteria = $form_state['values']['num_criteria'];
  241. $loader_name = $form_state['values']['loader_name'];
  242. }
  243. // if we are re building the form from after submission (from ajax call) then
  244. // the values are in the $form_state['input'] array
  245. if (array_key_exists('input', $form_state) and !empty($form_state['input'])) {
  246. $remote_db = $form_state['input']['remote_db'];
  247. $days = $form_state['input']['days'];
  248. $disabled = $form_state['input']['disabled'];
  249. $do_contact = $form_state['input']['do_contact'];
  250. $loader_name = $form_state['input']['loader_name'];
  251. // because the num_criteria is a value and not a visible or hidden form
  252. // element it is not part of the ['input'] array, so we need to get it from the form
  253. $num_criteria = $form_state['complete form']['num_criteria']['#value'];
  254. }
  255. if (array_key_exists('triggering_element', $form_state) and
  256. $form_state['triggering_element']['#name'] == 'add') {
  257. $num_criteria++;
  258. }
  259. if (array_key_exists('triggering_element', $form_state) and
  260. $form_state['triggering_element']['#name'] == 'remove') {
  261. $num_criteria--;
  262. }
  263. // set the values we need for later but that should not be shown on the form
  264. $form['num_criteria']= array(
  265. '#type' => 'value',
  266. '#value' => $num_criteria,
  267. );
  268. $form['pub_import_id'] = array(
  269. '#type' => 'value',
  270. '#value' => $pub_import_id,
  271. );
  272. $form['action'] = array(
  273. '#type' => 'value',
  274. '#value' => $action,
  275. );
  276. // add in the elements that will be organized via a theme function
  277. $form['themed_element']['loader_name'] = array(
  278. '#type' => 'textfield',
  279. '#title' => t('Loader Name'),
  280. '#description' => t('Please provide a name for this loader setup.'),
  281. '#default_value' => $loader_name,
  282. '#required' => TRUE,
  283. );
  284. $supported_dbs = variable_get('tripal_pub_supported_dbs', array());
  285. $remote_dbs = array();
  286. $values = array(
  287. 'name' => $supported_dbs,
  288. );
  289. $dbs = chado_select_record('db', array('*'), $values);
  290. foreach ($dbs as $index => $db) {
  291. $remote_dbs[$db->name] = $db->description;
  292. };
  293. // use PubMed as the default
  294. if (!$remote_db) {
  295. $remote_db = 'PMID';
  296. }
  297. $form['themed_element']['remote_db'] = array(
  298. '#title' => t('Remote Database'),
  299. '#type' => 'select',
  300. '#options' => $remote_dbs,
  301. '#default_value' => $remote_db,
  302. '#ajax' => array(
  303. 'callback' => "tripal_pubs_setup_form_ajax_update",
  304. 'wrapper' => 'tripal-pubs-importer-setup',
  305. 'effect' => 'fade',
  306. 'method' => 'replace',
  307. ),
  308. );
  309. $form['themed_element']['days'] = array(
  310. '#type' => 'textfield',
  311. '#title' => t('Days since record modified'),
  312. '#description' => t('Limit the search to include pubs that have been added no more than this many days before today.'),
  313. '#default_value' => $days,
  314. '#size' => 5,
  315. );
  316. $form['themed_element']['disabled'] = array(
  317. '#type' => 'checkbox',
  318. '#title' => t('Disabled'),
  319. '#description' => t('Check to disable this importer.'),
  320. '#default_value' => $disabled,
  321. );
  322. $form['themed_element']['do_contact'] = array(
  323. '#type' => 'checkbox',
  324. '#title' => t('Create Contact'),
  325. '#description' => t('Check to create an entry in the contact table for each author of a matching publication during import. This allows storage of
  326. additional information such as affilation, etc. Otherwise, only authors names are retrieved.'),
  327. '#default_value' => $do_contact,
  328. );
  329. // add in the form for the criteria
  330. tripal_pub_importer_setup_add_criteria_fields($form, $form_state, $num_criteria, $criteria);
  331. // add in the buttons
  332. $form['save'] = array(
  333. '#type' => 'submit',
  334. '#value' => t('Save Importer'),
  335. );
  336. $form['test'] = array(
  337. '#type' => 'submit',
  338. '#value' => t('Test Importer'),
  339. );
  340. $form['delete'] = array(
  341. '#type' => 'submit',
  342. '#value' => t('Delete Importer'),
  343. '#attributes' => array('style' => 'float: right;')
  344. );
  345. // add in the section where the test results will appear
  346. $form['results'] = array(
  347. '#markup' => '<div id="tripal-pub-importer-test-section"></div>',
  348. );
  349. // allow the selected remote database to make changes to the form if needed
  350. $callback = "tripal_pub_remote_alter_form_$remote_db";
  351. $form = call_user_func($callback, $form, $form_state, $num_criteria);
  352. $form['themed_element']['#theme'] = 'tripal_pub_importer_setup_form_elements';
  353. return $form;
  354. }
  355. /**
  356. * @stephen
  357. *
  358. * @param $form
  359. * @param $form_state
  360. * @param $num_criteria
  361. * @param $criteria
  362. *
  363. * @ingroup tripal_pub
  364. */
  365. function tripal_pub_importer_setup_add_criteria_fields(&$form, &$form_state, $num_criteria, $criteria){
  366. // choices array
  367. $scope_choices = array(
  368. 'any' => 'Any Field',
  369. 'abstract' => 'Abstract',
  370. 'author' => 'Author',
  371. 'id' => 'Accession',
  372. 'title' => 'Title',
  373. 'journal' => 'Journal Name'
  374. );
  375. $first_op_choices = array(
  376. '' => '',
  377. 'NOT' => 'NOT'
  378. );
  379. $op_choices = array(
  380. 'AND' => 'AND',
  381. 'OR' => 'OR',
  382. 'NOT' => 'NOT'
  383. );
  384. for($i = 1; $i <= $num_criteria; $i++) {
  385. $is_phrase = 1;
  386. $search_terms = '';
  387. $scope = '';
  388. $is_phrase = '';
  389. $operation = '';
  390. // if we have criteria supplied from the database then use that as the initial defaults
  391. if ($criteria) {
  392. $search_terms = $criteria['criteria'][$i]['search_terms'];
  393. $scope = $criteria['criteria'][$i]['scope'];
  394. $is_phrase = $criteria['criteria'][$i]['is_phrase'];
  395. $operation = $criteria['criteria'][$i]['operation'];
  396. }
  397. // if the criteria comes the session
  398. if (array_key_exists('tripal_pub_import', $_SESSION)) {
  399. $search_terms = isset($_SESSION['tripal_pub_import']['criteria'][$i]['search_terms']) ? $_SESSION['tripal_pub_import']['criteria'][$i]['search_terms'] : $search_terms;
  400. $scope = isset($_SESSION['tripal_pub_import']['criteria'][$i]['scope']) ? $_SESSION['tripal_pub_import']['criteria'][$i]['scope'] : $scope;
  401. $is_phrase = isset($_SESSION['tripal_pub_import']['criteria'][$i]['is_phrase']) ? $_SESSION['tripal_pub_import']['criteria'][$i]['is_phrase'] : $is_phrase;
  402. $operation = isset($_SESSION['tripal_pub_import']['criteria'][$i]['operation']) ? $_SESSION['tripal_pub_import']['criteria'][$i]['operation'] : $operation;
  403. }
  404. // If the form_state has variables then use those. This happens when an error occurs on the form or the
  405. // form is resbumitted using AJAX
  406. if (array_key_exists('values', $form_state)) {
  407. $search_terms = $form_state['values']["search_terms-$i"];
  408. $scope = $form_state['values']["scope-$i"];
  409. $is_phrase = $form_state['values']["is_phrase-$i"];
  410. $operation = $form_state['values']["operation-$i"];
  411. }
  412. $form['themed_element']['criteria'][$i]["scope-$i"] = array(
  413. '#type' => 'select',
  414. '#description' => t('Please select the fields to search for this term.'),
  415. '#options' => $scope_choices,
  416. '#default_value' => $scope,
  417. );
  418. $form['themed_element']['criteria'][$i]["search_terms-$i"] = array(
  419. '#type' => 'textfield',
  420. '#description' => t('<span style="white-space: normal">Please provide a list of words for searching. You may use
  421. conjunctions such as "AND" or "OR" to separate words if they are expected in
  422. the same scope, but do not mix ANDs and ORs. Check the "Is Phrase" checkbox to use conjunctions as part of the text to search</span>'),
  423. '#default_value' => $search_terms,
  424. '#required' => TRUE,
  425. '#maxlength' => 2048,
  426. );
  427. $form['themed_element']['criteria'][$i]["is_phrase-$i"] = array(
  428. '#type' => 'checkbox',
  429. '#title' => t('Is Phrase?'),
  430. '#default_value' => $is_phrase,
  431. );
  432. if ($i == 1) {
  433. /*
  434. $form['criteria'][$i]["operation-$i"] = array(
  435. '#type' => 'select',
  436. '#options' => $first_op_choices,
  437. '#default_value' => $operation,
  438. );*/
  439. }
  440. if ($i > 1) {
  441. $form['themed_element']['criteria'][$i]["operation-$i"] = array(
  442. '#type' => 'select',
  443. '#options' => $op_choices,
  444. '#default_value' => $operation,
  445. );
  446. }
  447. if ($i == $num_criteria) {
  448. if($i > 1) {
  449. $form['themed_element']['criteria'][$i]["remove-$i"] = array(
  450. '#type' => 'button',
  451. '#name' => 'remove',
  452. '#value' => t('Remove'),
  453. '#ajax' => array(
  454. 'callback' => "tripal_pubs_setup_form_ajax_update",
  455. 'wrapper' => 'tripal-pubs-importer-setup',
  456. 'effect' => 'fade',
  457. 'method' => 'replace',
  458. 'prevent' => 'click'
  459. ),
  460. // When this button is clicked, the form will be validated and submitted.
  461. // Therefore, we set custom submit and validate functions to override the
  462. // default form submit. In the validate function we set the form_state
  463. // to rebuild the form so the submit function never actually gets called,
  464. // but we need it or Drupal will run the default validate anyway.
  465. // we also set #limit_validation_errors to empty so fields that
  466. // are required that don't have values won't generate warnings.
  467. '#submit' => array('tripal_pub_setup_form_ajax_button_submit'),
  468. '#validate' => array('tripal_pub_setup_form_ajax_button_validate'),
  469. '#limit_validation_errors' => array(),
  470. );
  471. }
  472. $form['themed_element']['criteria'][$i]["add-$i"] = array(
  473. '#type' => 'button',
  474. '#name' => 'add',
  475. '#value' => t('Add'),
  476. '#ajax' => array(
  477. 'callback' => "tripal_pubs_setup_form_ajax_update",
  478. 'wrapper' => 'tripal-pubs-importer-setup',
  479. 'effect' => 'fade',
  480. 'method' => 'replace',
  481. 'prevent' => 'click'
  482. ),
  483. // When this button is clicked, the form will be validated and submitted.
  484. // Therefore, we set custom submit and validate functions to override the
  485. // default form submit. In the validate function we set the form_state
  486. // to rebuild the form so the submit function never actually gets called,
  487. // but we need it or Drupal will run the default validate anyway.
  488. // we also set #limit_validation_errors to empty so fields that
  489. // are required that don't have values won't generate warnings.
  490. '#submit' => array('tripal_pub_setup_form_ajax_button_submit'),
  491. '#validate' => array('tripal_pub_setup_form_ajax_button_validate'),
  492. '#limit_validation_errors' => array(),
  493. );
  494. }
  495. }
  496. }
  497. /**
  498. * This function is used to rebuild the form if an ajax call is made vai a button.
  499. * The button causes the form to be submitted. We don't want this so we override
  500. * the validate and submit routines on the form button. Therefore, this function
  501. * only needs to tell Drupal to rebuild the form
  502. *
  503. * @ingroup tripal_pub
  504. */
  505. function tripal_pub_setup_form_ajax_button_validate($form, &$form_state){
  506. $form_state['rebuild'] = TRUE;
  507. }
  508. /**
  509. * This function is just a dummy to override the default form submit on ajax calls for buttons
  510. *
  511. * @ingroup tripal_pub
  512. */
  513. function tripal_pub_setup_form_ajax_button_submit($form, &$form_state){
  514. // do nothing
  515. }
  516. /**
  517. * Validate the tripal_pub_importer_setup_form form
  518. *
  519. * @ingroup tripal_pub
  520. */
  521. function tripal_pub_importer_setup_form_validate($form, &$form_state) {
  522. $num_criteria = $form_state['values']['num_criteria'];
  523. $remote_db = $form_state['values']["remote_db"];
  524. $days = trim($form_state['values']["days"]);
  525. $disabled = $form_state['values']["disabled"];
  526. $do_contact = $form_state['values']["do_contact"];
  527. $loader_name = trim($form_state['values']["loader_name"]);
  528. for ($i = 1; $i <= $num_criteria; $i++) {
  529. $search_terms = trim($form_state['values']["search_terms-$i"]);
  530. $scope = $form_state['values']["scope-$i"];
  531. $is_phrase = $form_state['values']["is_phrase-$i"];
  532. $operation = '';
  533. if($i > 1) {
  534. $operation = $form_state['values']["operation-$i"];
  535. }
  536. if (!$is_phrase) {
  537. if (preg_match('/and/i', $search_terms) and preg_match('/or/i', $search_terms)) {
  538. form_set_error("search_terms-$i", "You may use 'AND' or 'OR' but cannot use both. Add a new entry below with the same scope for the other conunction.");
  539. $_SESSION['tripal_pub_import']['perform_search'] = 0;
  540. }
  541. }
  542. }
  543. if ($days and !is_numeric($days) or preg_match('/\./', $days)) {
  544. form_set_error("days", "Please enter a numeric, non decimal value, for the number of days.");
  545. $_SESSION['tripal_pub_import']['perform_search'] = 0;
  546. }
  547. // allow the selected remote database to validate any changes to the form if needed
  548. $callback = "tripal_pub_remote_validate_form_$remote_db";
  549. $form = call_user_func($callback, $form, $form_state);
  550. }
  551. /**
  552. * Submit the tripal_pub_importer_setup_form form
  553. *
  554. * @ingroup tripal_pub
  555. */
  556. function tripal_pub_importer_setup_form_submit($form, &$form_state) {
  557. $pub_import_id = $form_state['values']['pub_import_id'];
  558. $num_criteria = $form_state['values']['num_criteria'];
  559. $remote_db = $form_state['values']["remote_db"];
  560. $days = trim($form_state['values']["days"]);
  561. $loader_name = trim($form_state['values']["loader_name"]);
  562. $disabled = $form_state['values']["disabled"];
  563. $do_contact = $form_state['values']["do_contact"];
  564. // set the session variables
  565. $_SESSION['tripal_pub_import']['remote_db'] = $remote_db;
  566. $_SESSION['tripal_pub_import']['days'] = $days;
  567. $_SESSION['tripal_pub_import']['num_criteria'] = $num_criteria;
  568. $_SESSION['tripal_pub_import']['loader_name'] = $loader_name;
  569. $_SESSION['tripal_pub_import']['disabled'] = $disabled;
  570. $_SESSION['tripal_pub_import']['do_contact'] = $do_contact;
  571. $_SESSION['tripal_pub_import']['pub_import_id'] = $pub_import_id;
  572. unset($_SESSION['tripal_pub_import']['criteria']);
  573. for ($i = 1; $i <= $num_criteria; $i++) {
  574. $search_terms = trim($form_state['values']["search_terms-$i"]);
  575. $scope = $form_state['values']["scope-$i"];
  576. $is_phrase = $form_state['values']["is_phrase-$i"];
  577. $operation = '';
  578. if ($i > 1) {
  579. $operation = $form_state['values']["operation-$i"];
  580. }
  581. $_SESSION['tripal_pub_import']['criteria'][$i] = array(
  582. 'search_terms' => $search_terms,
  583. 'scope' => $scope,
  584. 'is_phrase' => $is_phrase,
  585. 'operation' => $operation
  586. );
  587. }
  588. // now perform the appropriate action for the button clicked
  589. if ($form_state['values']['op'] == 'Test Importer') {
  590. $_SESSION['tripal_pub_import']['perform_search'] = 1;
  591. }
  592. if ($form_state['values']['op'] == 'Save Importer' or
  593. $form_state['values']['op'] == 'Save & Import Now') {
  594. $record = array(
  595. 'name' => $loader_name,
  596. 'criteria' => serialize($_SESSION['tripal_pub_import']),
  597. 'disabled' => $disabled,
  598. 'do_contact' => $do_contact
  599. );
  600. // first check to see if this pub_import_id is already present. If so,
  601. // do an update rather than an insert
  602. $sql = "SELECT * FROM {tripal_pub_import} WHERE pub_import_id = :pub_import_id";
  603. $importer = db_query($sql, array(':pub_import_id' => $pub_import_id))->fetchObject();
  604. if($importer) {
  605. // do the update
  606. $record['pub_import_id'] = $pub_import_id;
  607. if(drupal_write_record('tripal_pub_import', $record, 'pub_import_id')){
  608. unset($_SESSION['tripal_pub_import']);
  609. drupal_set_message('Publication import settings updated.');
  610. drupal_goto('admin/tripal/chado/tripal_pub/import_list');
  611. }
  612. else {
  613. drupal_set_message('Could not update publication import settings.', 'error');
  614. }
  615. }
  616. else {
  617. // do the insert
  618. if(drupal_write_record('tripal_pub_import', $record)){
  619. unset($_SESSION['tripal_pub_import']);
  620. drupal_set_message('Publication import settings saved.');
  621. // if the user wants to do the import now then do it (may time out
  622. // for long jobs)
  623. if ($form_state['values']['op'] == 'Save & Import Now') {
  624. tripal_pub_import_publications($record['pub_import_id']);
  625. }
  626. drupal_goto('admin/tripal/chado/tripal_pub/import_list');
  627. }
  628. else {
  629. drupal_set_message('Could not save publication import settings.', 'error');
  630. }
  631. }
  632. }
  633. if ($form_state['values']['op'] == 'Delete Importer') {
  634. $sql = "DELETE FROM {tripal_pub_import} WHERE pub_import_id = :pub_import_id";
  635. $success = db_query($sql, array(':pub_import_id' => $pub_import_id));
  636. if ($success) {
  637. drupal_set_message('Publication importer deleted.');
  638. drupal_goto('admin/tripal/chado/tripal_pub/import_list');
  639. }
  640. else {
  641. drupal_set_message('Could not delete publication importer.', 'error');
  642. }
  643. }
  644. }
  645. /**
  646. * AJAX callback for updating the form.
  647. *
  648. * @ingroup tripal_pub
  649. */
  650. function tripal_pubs_setup_form_ajax_update($form, $form_state) {
  651. return $form['themed_element'];
  652. }
  653. /**
  654. * Theme the tripal_pub_importer_setup_form form.
  655. *
  656. * @ingroup tripal_pub
  657. */
  658. function theme_tripal_pub_importer_setup_form_elements($variables) {
  659. $form = $variables['form'];
  660. // first render the fields at the top of the form
  661. $markup = '';
  662. $markup .= '<div id="pub-search-form-row0">';
  663. $markup .= ' <div id="pub-search-form-row0-col1" style="float: left">' . drupal_render($form['remote_db']) . '</div>';
  664. $markup .= ' <div id="pub-search-form-row0-col2" style="float: left; margin-left: 10px">' . drupal_render($form['loader_name']) . '</div>';
  665. $markup .= '</div>';
  666. $markup .= '<div id="pub-search-form-row1" style="clear:both">';
  667. $markup .= ' <div id="pub-search-form-row1-col1">' . drupal_render($form['days']) . '</div>';
  668. $markup .= '</div>';
  669. $markup .= '<div id="pub-search-form-row2">' . drupal_render($form['disabled']) . '</div>';
  670. $markup .= '<div id="pub-search-form-row3">' . drupal_render($form['do_contact']) . '</div>';
  671. // next render the criteria fields into a table format
  672. $rows = array();
  673. foreach ($form['criteria'] as $i => $element) {
  674. if(is_numeric($i)) {
  675. $rows[] = array(
  676. drupal_render($element["operation-$i"]),
  677. drupal_render($element["scope-$i"]),
  678. drupal_render($element["search_terms-$i"]),
  679. drupal_render($element["is_phrase-$i"]),
  680. drupal_render($element["add-$i"]) . drupal_render($element["remove-$i"]),
  681. );
  682. }
  683. }
  684. $headers = array('Operation','Scope', 'Search Terms', '','');
  685. $table = array(
  686. 'header' => $headers,
  687. 'rows' => $rows,
  688. 'attributes' => array(),
  689. 'sticky' => TRUE,
  690. 'caption' => '',
  691. 'colgroups' => array(),
  692. 'empty' => '',
  693. );
  694. $criteria_table = theme_table($table);
  695. $markup .= $criteria_table;
  696. // add the rendered form
  697. $form = array(
  698. '#markup' => $markup,
  699. '#prefix' => '<div id="tripal-pubs-importer-setup">',
  700. '#suffix' => '</div>',
  701. );
  702. return drupal_render($form);
  703. }
  704. /**
  705. * Add a job to import publications
  706. *
  707. * @param $pub_importer_id
  708. * The id of the importer to submit a job to update
  709. *
  710. * @ingroup tripal_pub
  711. */
  712. function tripal_pub_importer_submit_job($import_id) {
  713. global $user;
  714. // get all of the loaders
  715. $args = array(':import_id' => $import_id);
  716. $sql = "SELECT * FROM {tripal_pub_import} WHERE pub_import_id = :import_id ";
  717. $import = db_query($sql, $args)->fetchObject();
  718. $args = array($import_id);
  719. tripal_add_job("Import publications $import->name", 'tripal_pub',
  720. 'tripal_pub_import_publications_by_import_id', $args, $user->uid);
  721. drupal_goto('admin/tripal/chado/tripal_pub/import_list');
  722. }