search_api_saved_searches.pages.inc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. <?php
  2. /**
  3. * @file
  4. * User UI functions and form callbacks for saved searches.
  5. */
  6. /**
  7. * Page callback for listing all saved searches of a user.
  8. *
  9. * @param $account
  10. * The user of which to list saved searches.
  11. */
  12. function search_api_saved_searches_user_listing($account) {
  13. $base_path = 'search-api/saved-search/';
  14. $header = array(
  15. t('Name'),
  16. t('Created'),
  17. t('Last executed'),
  18. t('Interval'),
  19. t('Operations'),
  20. );
  21. $searches = search_api_saved_search_load_multiple(FALSE, array('uid' => $account->uid));
  22. $rows = array();
  23. foreach ($searches as $search) {
  24. $settings = $search->settings();
  25. if (empty($search->options['page'])) {
  26. $name = check_plain($search->name);
  27. }
  28. else {
  29. $name = $search->l($search->name);
  30. }
  31. $created = format_date($search->created, 'short');
  32. $last_execute = t('@time ago', array('@time' => format_interval(REQUEST_TIME - $search->last_execute)));
  33. // Get the translated label for the interval.
  34. $available_intervals = $settings->getTranslatedOption('interval_options');
  35. if (isset($available_intervals[$search->notify_interval])) {
  36. $interval = $available_intervals[$search->notify_interval];
  37. }
  38. elseif ($search->notify_interval < 0) {
  39. $interval = t('Never');
  40. }
  41. else {
  42. $interval = format_interval($search->notify_interval, 1);
  43. }
  44. $enable_options['attributes']['class'][] = 'saved-search-enable';
  45. $edit_options['attributes']['class'][] = 'saved-search-edit';
  46. $delete_options['attributes']['class'][] = 'saved-search-delete';
  47. if ($search->enabled) {
  48. $enable_action = '/disable';
  49. $enable_label = t('disable');
  50. }
  51. else {
  52. $enable_action = '/enable';
  53. $enable_label = t('enable');
  54. $enable_options['query']['token'] = drupal_get_token($search->id);
  55. }
  56. $path = $base_path . $search->id;
  57. $enable_link = l($enable_label, $path . $enable_action, $enable_options);
  58. $edit_link = l(t('edit'), $path . '/edit', $edit_options);
  59. $delete_link = l(t('delete'), $path . '/delete', $delete_options);
  60. $rows[] = array(
  61. $name,
  62. $created,
  63. $last_execute,
  64. $interval,
  65. $enable_link . ' | ' . $edit_link . ' | ' . $delete_link,
  66. );
  67. }
  68. $render = array(
  69. '#theme' => 'table',
  70. '#header' => $header,
  71. '#rows' => $rows,
  72. '#empty' => t('No searches were saved yet.'),
  73. '#sticky' => TRUE,
  74. );
  75. return $render;
  76. }
  77. /**
  78. * Page callback for manually creating a new saved search.
  79. *
  80. * @param SearchApiSavedSearchesSettings $settings
  81. * (optional) The settings to use. If not present, either the only available
  82. * settings will be used, or a form for selecting one will be displayed.
  83. */
  84. function search_api_saved_searches_create_manual(SearchApiSavedSearchesSettings $settings = NULL) {
  85. if (!isset($settings)) {
  86. foreach (search_api_saved_searches_settings_load_multiple(FALSE, array('enabled' => TRUE)) as $settings) {
  87. if (!empty($settings->options['manual']['allow'])) {
  88. $available_settings[$settings->delta] = $settings;
  89. }
  90. }
  91. if (empty($available_settings)) {
  92. return t('There are no searches for which saved searches can be created manually.');
  93. }
  94. if (count($available_settings) == 1) {
  95. $settings = reset($available_settings);
  96. }
  97. else {
  98. $render = array();
  99. $render['question']['#markup'] = t('For which search do you want to create a saved search?');
  100. $render['list']['#theme'] = 'list';
  101. $render['list']['#items'] = array();
  102. $base = 'search-api/saved-searches/add/';
  103. foreach ($available_settings as $id => $settings) {
  104. $name = $settings->index()->name;
  105. if (!empty($settings->options['manual']['page']['path'])) {
  106. $item = menu_get_item($settings->options['manual']['page']['path']);
  107. if (!empty($item['title'])) {
  108. $name = $item['title'];
  109. }
  110. }
  111. $render['list']['#items'][]['#markup'] = l($name, $base . $id);
  112. }
  113. return $render;
  114. }
  115. }
  116. return drupal_get_form('search_api_saved_searches_save_form', $settings);
  117. }
  118. /**
  119. * Page callback that activates a saved search.
  120. *
  121. * This is mostly necessary for anonymous users, but also when a user enters a
  122. * different mail address than the one he registered with.
  123. *
  124. * @param SearchApiSavedSearch $search
  125. * The search to activate.
  126. * @param string $key
  127. * The secret access key for this search, used to authenticate the user.
  128. */
  129. function search_api_saved_searches_activate_page(SearchApiSavedSearch $search, $key) {
  130. $ret = array(
  131. 'message' => array(
  132. '#markup' => '',
  133. ),
  134. 'link' => array(
  135. '#markup' => '<p>' . $search->l(t('View this saved search')) . '</p>',
  136. ),
  137. );
  138. if ($search->enabled) {
  139. $msg = t('This saved search has already been activated.');
  140. }
  141. else {
  142. $search->enabled = TRUE;
  143. $success = $search->save();
  144. if (!$success) {
  145. drupal_set_message(t('An error occurred while trying to activate the search. Please contact the site administrator.'), 'error');
  146. return $ret;
  147. }
  148. $msg = t('Your saved search was successfully activated.');
  149. }
  150. if ($search->notify_interval >= 0) {
  151. $msg .= ' ' . t('You will receive e-mail notifications for new results in the future.');
  152. }
  153. $ret['message']['#markup'] = '<p>' . $msg . '</p>';
  154. return $ret;
  155. }
  156. /**
  157. * Form builder for editing a saved search.
  158. *
  159. * @param SearchApiSavedSearch $search
  160. * The search to edit.
  161. *
  162. * @see search_api_saved_searches_search_edit_form_submit()
  163. * @ingroup forms
  164. */
  165. function search_api_saved_searches_search_edit_form(array $form, array &$form_state, SearchApiSavedSearch $search) {
  166. $form_state['search'] = $search;
  167. $settings = $search->settings();
  168. if ($search->uid) {
  169. $form_state['destination']['path'] = 'user/' . $search->uid . '/saved-searches';
  170. }
  171. elseif (!empty($search->options['page'])) {
  172. $form_state['destination'] = array($search->options['page']['path'], $search->options['page']);
  173. }
  174. $form['enabled'] = array(
  175. '#type' => 'checkbox',
  176. '#title' => t('Enabled'),
  177. '#description' => t('Disable to stop receiving notifications from this saved search.'),
  178. '#default_value' => $search->enabled,
  179. );
  180. $form['name'] = array(
  181. '#type' => 'textfield',
  182. '#title' => t('Name'),
  183. '#description' => t('The name that will be displayed for this saved search.'),
  184. '#maxlength' => 50,
  185. '#required' => TRUE,
  186. '#default_value' => $search->name,
  187. );
  188. if ($settings->options['user_select_interval'] && count($settings->options['interval_options']) > 1) {
  189. $form['notify_interval'] = array(
  190. '#type' => 'select',
  191. '#title' => t('Notification interval'),
  192. '#options' => $settings->getTranslatedOption('interval_options'),
  193. '#required' => TRUE,
  194. '#default_value' => $search->notify_interval,
  195. );
  196. }
  197. $form['actions']['#type'] = 'actions';
  198. $form['actions']['submit'] = array(
  199. '#type' => 'submit',
  200. '#value' => t('Save changes'),
  201. );
  202. if (!empty($form_state['destination'])) {
  203. $form['actions']['cancel'] = array(
  204. '#type' => 'link',
  205. '#title' => t('Cancel'),
  206. '#href' => $form_state['destination']['path'],
  207. '#options' => $form_state['destination'],
  208. );
  209. }
  210. return $form;
  211. }
  212. /**
  213. * Submission handler for search_api_saved_searches_search_edit_form().
  214. *
  215. * @see search_api_saved_searches_search_edit_form()
  216. */
  217. function search_api_saved_searches_search_edit_form_submit(array $form, array &$form_state) {
  218. $values = $form_state['values'];
  219. $search = $form_state['search'];
  220. $search->name = $values['name'];
  221. $search->enabled = $values['enabled'];
  222. if (isset($values['notify_interval'])) {
  223. $search->notify_interval = $values['notify_interval'];
  224. }
  225. if ($search->save()) {
  226. drupal_set_message(t('Successfully saved your changes.'));
  227. if (!empty($form_state['destination'])) {
  228. $form_state['redirect'] = $form_state['destination'];
  229. }
  230. }
  231. else {
  232. drupal_set_message(t('An error occurred while trying to save the changes.'), 'error');
  233. }
  234. }
  235. /**
  236. * Page callback: Enables a saved search.
  237. *
  238. * @param SearchApiSavedSearch $search
  239. * The search to enable.
  240. */
  241. function search_api_saved_searches_search_enable(SearchApiSavedSearch $search = NULL) {
  242. if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], $search->id)) {
  243. return MENU_ACCESS_DENIED;
  244. }
  245. $search->enabled = TRUE;
  246. if ($search->save()) {
  247. drupal_set_message(t('The saved search was successfully enabled.'));
  248. }
  249. else {
  250. drupal_set_message(t('The saved search could not be enabled.'), 'error');
  251. }
  252. drupal_goto(_search_api_saved_searches_admin_redirect_url($search));
  253. return NULL;
  254. }
  255. /**
  256. * Page callback: Constructs a form for disabling a saved search.
  257. *
  258. * @param SearchApiSavedSearch $search
  259. * The search to disable.
  260. *
  261. * @see search_api_saved_searches_search_disable_form_submit()
  262. *
  263. * @ingroup forms
  264. */
  265. function search_api_saved_searches_search_disable_form(array $form, array &$form_state, SearchApiSavedSearch $search) {
  266. $form_state['search'] = $search;
  267. $url = _search_api_saved_searches_admin_redirect_url($search);
  268. return confirm_form($form, t('Do you really want to disable this saved search?'), $url, t('You will not receive any updates for this saved search until it is re-enabled.'));
  269. }
  270. /**
  271. * Form submission handler for search_api_saved_searches_search_disable_form().
  272. */
  273. function search_api_saved_searches_search_disable_form_submit(array $form, array &$form_state) {
  274. $search = $form_state['search'];
  275. $search->enabled = FALSE;
  276. $search->save();
  277. drupal_set_message(t('The saved search was successfully disabled.'));
  278. $form_state['redirect'] = _search_api_saved_searches_admin_redirect_url($search);
  279. }
  280. /**
  281. * Form builder for confirming the deletion of a saved search.
  282. *
  283. * @param SearchApiSavedSearch $search
  284. * The search to delete.
  285. *
  286. * @see search_api_saved_searches_search_delete_form_submit()
  287. * @ingroup forms
  288. */
  289. function search_api_saved_searches_search_delete_form(array $form, array &$form_state, SearchApiSavedSearch $search) {
  290. $form_state['search'] = $search;
  291. $url = _search_api_saved_searches_admin_redirect_url($search);
  292. return confirm_form($form, t('Do you really want to delete this saved search?'), $url);
  293. }
  294. /**
  295. * Submission handler for search_api_saved_searches_search_delete_form().
  296. *
  297. * @see search_api_saved_searches_search_delete_form()
  298. */
  299. function search_api_saved_searches_search_delete_form_submit(array $form, array &$form_state) {
  300. $search = $form_state['search'];
  301. $search->delete();
  302. drupal_set_message(t('The saved search was successfully deleted.'));
  303. $form_state['redirect'] = _search_api_saved_searches_admin_redirect_url($search);
  304. }
  305. /**
  306. * Returns the correct redirect URL after changing a saved search.
  307. *
  308. * This will be the user's "Saved searches" overview tab, if it is accessible;
  309. * otherwise, if the search has a page associated with it, that page; and if
  310. * none of the two are the case, the front page.
  311. *
  312. * @param SearchApiSavedSearch $search
  313. * The saved search that was edited, deleted or otherwise changed.
  314. *
  315. * @return string
  316. * The URL to redirect to.
  317. */
  318. function _search_api_saved_searches_admin_redirect_url(SearchApiSavedSearch $search) {
  319. if ($search->uid && search_api_saved_search_edit_access(user_load($search->uid))) {
  320. return 'user/' . $search->uid . '/saved-searches';
  321. }
  322. elseif (!empty($search->options['page'])) {
  323. return $search->options['page'];
  324. }
  325. return '<front>';
  326. }