search_api_page.admin.inc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. <?php
  2. /**
  3. * @file
  4. * Admin page callbacks for the Search pages module.
  5. */
  6. /**
  7. * Displays an overview of all defined search pages.
  8. */
  9. function search_api_page_admin_overview() {
  10. $base_path = drupal_get_path('module', 'search_api') . '/';
  11. drupal_add_css($base_path . 'search_api.admin.css');
  12. $header = array(t('Status'), t('Configuration'), t('Name'), t('Path'), t('Index'), t('Operations'));
  13. $rows = array();
  14. $t_enabled['data'] = array(
  15. '#theme' => 'image',
  16. '#path' => $base_path . 'enabled.png',
  17. '#alt' => t('enabled'),
  18. '#title' => t('enabled'),
  19. );
  20. $t_enabled['class'] = array('search-api-status');
  21. $t_disabled['data'] = array(
  22. '#theme' => 'image',
  23. '#path' => $base_path . 'disabled.png',
  24. '#alt' => t('disabled'),
  25. '#title' => t('disabled'),
  26. );
  27. $t_disabled['class'] = array('search-api-status');
  28. $t_enable = t('enable');
  29. $t_disable = t('disable');
  30. $t_edit = t('edit');
  31. $t_delete = t('delete');
  32. $pre = 'admin/config/search/search_api/page/';
  33. $pre_index = 'admin/config/search/search_api/index/';
  34. $enable = '/enable';
  35. $disable = '/disable';
  36. $edit = '/edit';
  37. $delete = '/delete';
  38. foreach (search_api_page_load_multiple() as $page) {
  39. $url = $pre . $page->machine_name;
  40. $index = search_api_index_load($page->index_id);
  41. $rows[] = array(
  42. $page->enabled ? $t_enabled : $t_disabled,
  43. theme('entity_status', array('status' => $page->status)),
  44. l($page->name, $page->path),
  45. l($page->path, $page->path),
  46. l($index->name, $pre_index . $index->machine_name),
  47. l($t_edit, $url . $edit),
  48. );
  49. }
  50. return array(
  51. '#theme' => 'table',
  52. '#header' => $header,
  53. '#rows' => $rows,
  54. '#empty' => t('There are no search pages defined yet.'),
  55. );
  56. }
  57. /**
  58. * Displays a form for adding a search page.
  59. */
  60. function search_api_page_admin_add(array $form, array &$form_state) {
  61. $form = array();
  62. if (empty($form_state['step_one'])) {
  63. $indexes = search_api_index_load_multiple(FALSE);
  64. if (!$indexes) {
  65. drupal_set_message(t('There are no searches indexes which can be searched. Please <a href="@url">create an index</a> first.', array('@url' => url('admin/config/search/search_api/add_index'))), 'warning');
  66. return array();
  67. }
  68. $index_options = array();
  69. foreach ($indexes as $index) {
  70. if ($index->enabled) {
  71. $index_options[$index->machine_name] = $index->name;
  72. }
  73. }
  74. foreach ($indexes as $index) {
  75. if (!$index->enabled) {
  76. $index_options[$index->machine_name] = $index->name . ' (' . t('disabled') . ')';
  77. }
  78. }
  79. $form['name'] = array(
  80. '#type' => 'textfield',
  81. '#title' => t('Search name'),
  82. '#maxlength' => 50,
  83. '#required' => TRUE,
  84. );
  85. $form['machine_name'] = array(
  86. '#type' => 'machine_name',
  87. '#maxlength' => 51,
  88. '#machine_name' => array(
  89. 'exists' => 'search_api_index_load',
  90. ),
  91. );
  92. $form['index_id'] = array(
  93. '#type' => 'select',
  94. '#title' => t('Index'),
  95. '#description' => t('Select the index this page should search. This cannot be changed later.'),
  96. '#options' => $index_options,
  97. '#required' => TRUE,
  98. );
  99. $form['enabled'] = array(
  100. '#type' => 'checkbox',
  101. '#title' => t('Enabled'),
  102. '#description' => t('This will only take effect if the selected index is also enabled.'),
  103. '#default_value' => TRUE,
  104. );
  105. $form['description'] = array(
  106. '#type' => 'textarea',
  107. '#title' => t('Search description'),
  108. );
  109. $form['path'] = array(
  110. '#type' => 'textfield',
  111. '#title' => t('Path'),
  112. '#description' => t('Set the path under which the search page will be accessible, when enabled.'),
  113. '#maxlength' => 50,
  114. '#required' => TRUE,
  115. );
  116. $form['submit'] = array(
  117. '#type' => 'submit',
  118. '#value' => t('Create page'),
  119. );
  120. return $form;
  121. }
  122. $index = search_api_index_load($form_state['step_one']['index_id']);
  123. if ($index->enabled) {
  124. $modes = array();
  125. foreach ($index->query()->parseModes() as $mode => $info) {
  126. $modes[$mode] = $info['name'];
  127. }
  128. }
  129. else {
  130. $modes = array();
  131. $modes['direct'] = t('Direct query');
  132. $modes['single'] = t('Single term');
  133. $modes['terms'] = t('Multiple terms');
  134. }
  135. $form['mode'] = array(
  136. '#type' => 'select',
  137. '#title' => t('Query type'),
  138. '#description' => t('Select how the query will be parsed.'),
  139. '#options' => $modes,
  140. '#default_value' => 'terms',
  141. );
  142. $fields = array();
  143. $index_fields = $index->getFields();
  144. foreach ($index->getFulltextFields() as $name) {
  145. $fields[$name] = $index_fields[$name]['name'];
  146. }
  147. if (count($fields) > 1) {
  148. $form['fields'] = array(
  149. '#type' => 'select',
  150. '#title' => t('Searched fields'),
  151. '#description' => t('Select the fields that will be searched. If no fields are selected, all available fulltext fields will be searched.'),
  152. '#options' => $fields,
  153. '#size' => min(4, count($fields)),
  154. '#multiple' => TRUE,
  155. );
  156. }
  157. else {
  158. $form['fields'] = array(
  159. '#type' => 'value',
  160. '#value' => array(),
  161. );
  162. }
  163. $form['per_page'] = array(
  164. '#type' => 'select',
  165. '#title' => t('Results per page'),
  166. '#description' => t('Select how many items will be displayed on one page of the search result.'),
  167. '#options' => drupal_map_assoc(array(5, 10, 20, 30, 40, 50, 60, 80, 100)),
  168. '#default_value' => 10,
  169. );
  170. $form['get_per_page'] = array(
  171. '#type' => 'checkbox',
  172. '#title' => t('Allow GET override'),
  173. '#description' => t('Allow the „Results per page“ setting to be overridden from the URL, using the "per_page" GET parameter.<br />' .
  174. 'Example: http://example.com/search_results?per_page=7'),
  175. '#default_value' => TRUE,
  176. );
  177. $form['result_page_search_form'] = array(
  178. '#type' => 'checkbox',
  179. '#title' => t('Show search form on result page'),
  180. '#description' => t('Enable or disable the search form on the result page'),
  181. '#default_value' => TRUE,
  182. );
  183. $view_modes = array(
  184. 'search_api_page_result' => t('Themed as search results'),
  185. );
  186. // For entities, we also add all entity view modes.
  187. if ($entity_info = entity_get_info($index->item_type)) {
  188. foreach ($entity_info['view modes'] as $mode => $mode_info) {
  189. $view_modes[$mode] = $mode_info['label'];
  190. }
  191. }
  192. if (count($view_modes) > 1) {
  193. $form['view_mode'] = array(
  194. '#type' => 'select',
  195. '#title' => t('View mode'),
  196. '#options' => $view_modes,
  197. '#description' => t('Select how search results will be displayed.'),
  198. '#size' => 1,
  199. '#default_value' => 'search_api_page_result',
  200. );
  201. }
  202. else {
  203. $form['view_mode'] = array(
  204. '#type' => 'value',
  205. '#value' => key($view_modes),
  206. );
  207. }
  208. if (module_exists('search_api_spellcheck') && ($server = $index->server()) && $server->supportsFeature('search_api_spellcheck')) {
  209. $form['search_api_spellcheck'] = array(
  210. '#type' => 'checkbox',
  211. '#title' => t('Enable spell check'),
  212. '#description' => t('Display "Did you mean … ?" above search results.'),
  213. '#default_value' => TRUE,
  214. );
  215. }
  216. $form['submit'] = array(
  217. '#type' => 'submit',
  218. '#value' => t('Create page'),
  219. );
  220. return $form;
  221. }
  222. /**
  223. * Validation callback for search_api_page_admin_add().
  224. */
  225. function search_api_page_admin_add_validate(array $form, array &$form_state) {
  226. if (empty($form_state['step_one'])) {
  227. $form_state['values']['path'] = drupal_strtolower(trim($form_state['values']['path']));
  228. if (search_api_page_load_multiple(FALSE, array('path' => $form_state['values']['path']))) {
  229. form_set_error('path', t('The entered path is already in use. Please enter a unique path.'));
  230. }
  231. }
  232. }
  233. /**
  234. * Submit callback for search_api_page_admin_add().
  235. */
  236. function search_api_page_admin_add_submit(array $form, array &$form_state) {
  237. form_state_values_clean($form_state);
  238. if (empty($form_state['step_one'])) {
  239. $form_state['step_one'] = $form_state['values'];
  240. $form_state['rebuild'] = TRUE;
  241. return;
  242. }
  243. $values = $form_state['step_one'];
  244. $values['options'] = $form_state['values'];
  245. search_api_page_insert($values);
  246. drupal_set_message(t('The search page was successfully created.'));
  247. $form_state['redirect'] = 'admin/config/search/search_api/page';
  248. }
  249. /**
  250. * Displays a form for editing or deleting a search page.
  251. */
  252. function search_api_page_admin_edit(array $form, array &$form_state, Entity $page) {
  253. $index = search_api_index_load($page->index_id);
  254. $form_state['page'] = $page;
  255. $form['name'] = array(
  256. '#type' => 'textfield',
  257. '#title' => t('Search name'),
  258. '#maxlength' => 50,
  259. '#required' => TRUE,
  260. '#default_value' => $page->name,
  261. );
  262. $form['enabled'] = array(
  263. '#type' => 'checkbox',
  264. '#title' => t('Enabled'),
  265. '#description' => t('This will only take effect if the selected index is also enabled.'),
  266. '#default_value' => $page->enabled,
  267. '#disabled' => !$index->enabled,
  268. );
  269. $form['description'] = array(
  270. '#type' => 'textarea',
  271. '#title' => t('Search description'),
  272. '#default_value' => $page->description,
  273. );
  274. $form['index'] = array(
  275. '#type' => 'item',
  276. '#title' => t('Index'),
  277. '#description' => l($index->name, 'admin/config/search/search_api/index/' . $index->machine_name),
  278. );
  279. $form['path'] = array(
  280. '#type' => 'textfield',
  281. '#title' => t('Path'),
  282. '#description' => t('Set the path under which the search page will be accessible, when enabled.'),
  283. '#maxlength' => 50,
  284. '#default_value' => $page->path,
  285. );
  286. if ($index->enabled) {
  287. $modes = array();
  288. foreach ($index->query()->parseModes() as $mode => $info) {
  289. $modes[$mode] = $info['name'];
  290. }
  291. }
  292. else {
  293. $modes = array();
  294. $modes['direct'] = array(
  295. 'name' => t('Direct query'),
  296. 'description' => t("Don't parse the query, just hand it to the search server unaltered. " .
  297. "Might fail if the query contains syntax errors in regard to the specific server's query syntax."),
  298. );
  299. $modes['single'] = array(
  300. 'name' => t('Single term'),
  301. 'description' => t('The query is interpreted as a single keyword, maybe containing spaces or special characters.'),
  302. );
  303. $modes['terms'] = array(
  304. 'name' => t('Multiple terms'),
  305. 'description' => t('The query is interpreted as multiple keywords seperated by spaces. ' .
  306. 'Keywords containing spaces may be "quoted". Quoted keywords must still be seperated by spaces.'),
  307. );
  308. }
  309. $form['options']['#tree'] = TRUE;
  310. $form['options']['mode'] = array(
  311. '#type' => 'select',
  312. '#title' => t('Query type'),
  313. '#description' => t('Select how the query will be parsed.'),
  314. '#options' => $modes,
  315. '#default_value' => $page->options['mode'],
  316. );
  317. $fields = array();
  318. $index_fields = $index->getFields();
  319. foreach ($index->getFulltextFields() as $name) {
  320. $fields[$name] = $index_fields[$name]['name'];
  321. }
  322. if (count($fields) > 1) {
  323. $form['options']['fields'] = array(
  324. '#type' => 'select',
  325. '#title' => t('Searched fields'),
  326. '#description' => t('Select the fields that will be searched. If no fields are selected, all available fulltext fields will be searched.'),
  327. '#options' => $fields,
  328. '#size' => min(4, count($fields)),
  329. '#multiple' => TRUE,
  330. '#default_value' => $page->options['fields'],
  331. );
  332. }
  333. else {
  334. $form['options']['fields'] = array(
  335. '#type' => 'value',
  336. '#value' => array(),
  337. );
  338. }
  339. $form['options']['per_page'] = array(
  340. '#type' => 'select',
  341. '#title' => t('Results per page'),
  342. '#description' => t('Select how many items will be displayed on one page of the search result.'),
  343. '#options' => drupal_map_assoc(array(5, 10, 20, 30, 40, 50, 60, 80, 100)),
  344. '#default_value' => $page->options['per_page'],
  345. );
  346. $form['options']['result_page_search_form'] = array(
  347. '#type' => 'checkbox',
  348. '#title' => t('Show search form on result page'),
  349. '#description' => t('Enable or disable the search form on the result page'),
  350. '#default_value' => isset($page->options['result_page_search_form']) ? $page->options['result_page_search_form'] : TRUE,
  351. );
  352. $form['options']['get_per_page'] = array(
  353. '#type' => 'checkbox',
  354. '#title' => t('Allow GET override'),
  355. '#description' => t('Allow the „Results per page“ setting to be overridden from the URL, using the "per_page" GET parameter.<br />' .
  356. 'Example: <code>http://example.com/search_results?per_page=7</code>'),
  357. '#default_value' => !empty($page->options['get_per_page']),
  358. );
  359. $view_modes = array(
  360. 'search_api_page_result' => t('Themed as search results'),
  361. );
  362. // For entities, we also add all entity view modes.
  363. if ($entity_info = entity_get_info($index->item_type)) {
  364. foreach ($entity_info['view modes'] as $mode => $mode_info) {
  365. $view_modes[$mode] = $mode_info['label'];
  366. }
  367. }
  368. if (count($view_modes) > 1) {
  369. $form['options']['view_mode'] = array(
  370. '#type' => 'select',
  371. '#title' => t('View mode'),
  372. '#options' => $view_modes,
  373. '#description' => t('Select how search results will be displayed.'),
  374. '#size' => 1,
  375. '#default_value' => isset($page->options['view_mode']) ? $page->options['view_mode'] : 'search_api_page_result',
  376. );
  377. }
  378. else {
  379. $form['options']['view_mode'] = array(
  380. '#type' => 'value',
  381. '#value' => key($view_modes),
  382. );
  383. }
  384. if (module_exists('search_api_spellcheck') && ($server = $index->server()) && $server->supportsFeature('search_api_spellcheck')) {
  385. $form['options']['search_api_spellcheck'] = array(
  386. '#type' => 'checkbox',
  387. '#title' => t('Enable spell check'),
  388. '#description' => t('Display "Did you mean … ?" above search results.'),
  389. '#default_value' => !empty($page->options['search_api_spellcheck']),
  390. );
  391. }
  392. $form['actions']['#type'] = 'actions';
  393. $form['actions']['submit'] = array(
  394. '#type' => 'submit',
  395. '#value' => t('Save changes'),
  396. );
  397. if ($page->hasStatus(ENTITY_OVERRIDDEN)) {
  398. $form['actions']['revert'] = array(
  399. '#type' => 'fieldset',
  400. '#title' => t('Revert search page'),
  401. '#description' => t('This will revert all settings on this search page back to the defaults. This action cannot be undone.'),
  402. '#collapsible' => TRUE,
  403. '#collapsed' => TRUE,
  404. 'revert' => array(
  405. '#type' => 'submit',
  406. '#value' => t('Revert search page'),
  407. ),
  408. );
  409. }
  410. elseif ($page->hasStatus(ENTITY_CUSTOM)) {
  411. $form['actions']['delete'] = array(
  412. '#type' => 'fieldset',
  413. '#title' => t('Delete search page'),
  414. '#description' => t('This will delete the search page along with all of its settings.'),
  415. '#collapsible' => TRUE,
  416. '#collapsed' => TRUE,
  417. 'delete' => array(
  418. '#type' => 'submit',
  419. '#value' => t('Delete search page'),
  420. ),
  421. );
  422. }
  423. return $form;
  424. }
  425. /**
  426. * Validation callback for search_api_page_admin_edit().
  427. */
  428. function search_api_page_admin_edit_validate(array $form, array &$form_state) {
  429. if ($form_state['values']['op'] == t('Save changes')) {
  430. $form_state['values']['path'] = drupal_strtolower(trim($form_state['values']['path']));
  431. $pages = search_api_page_load_multiple(FALSE, array('path' => $form_state['values']['path']));
  432. if (count($pages) > 1 || (($page = array_shift($pages)) && $page->machine_name != $form_state['page']->machine_name)) {
  433. form_set_error('path', t('The entered path is already in use. Please enter a unique path.'));
  434. }
  435. }
  436. }
  437. /**
  438. * Submit callback for search_api_page_admin_edit().
  439. */
  440. function search_api_page_admin_edit_submit(array $form, array &$form_state) {
  441. $op = $form_state['values']['op'];
  442. form_state_values_clean($form_state);
  443. $form_state['redirect'] = 'admin/config/search/search_api/page';
  444. if ($op == t('Delete search page') || $op == t('Revert search page')) {
  445. $form_state['page']->delete();
  446. if ($op == t('Revert search page')) {
  447. drupal_set_message(t('The search page was successfully reverted.'));
  448. }
  449. else {
  450. drupal_set_message(t('The search page was successfully deleted.'));
  451. }
  452. return;
  453. }
  454. search_api_page_edit($form_state['page']->machine_name, $form_state['values']);
  455. drupal_set_message(t('The changes were successfully saved.'));
  456. }