search_api_page.pages.inc 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. <?php
  2. /**
  3. * Displays a search page.
  4. *
  5. * @param $id
  6. * The search page's machine name.
  7. * @param $keys
  8. * The keys to search for.
  9. */
  10. function search_api_page_view($id, $keys = NULL) {
  11. $page = search_api_page_load($id);
  12. if (!$page) {
  13. return MENU_NOT_FOUND;
  14. }
  15. // Override per_page setting with GET parameter.
  16. if (!empty($_GET['per_page']) && !empty($page->options['get_per_page']) && ((int) $_GET['per_page']) > 0) {
  17. // Remember and later restore the true setting value so we don't
  18. // accidentally permanently save the altered one.
  19. $page->options['original_per_page'] = $page->options['per_page'];
  20. $page->options['per_page'] = (int) $_GET['per_page'];
  21. }
  22. if (isset($page->options['result_page_search_form']) && $page->options['result_page_search_form']) {
  23. $ret['form'] = drupal_get_form('search_api_page_search_form', $page, $keys);
  24. }
  25. if ($keys) {
  26. try {
  27. $results = search_api_page_search_execute($page, $keys);
  28. }
  29. catch (SearchApiException $e) {
  30. $ret['message'] = t('An error occurred while executing the search. Please try again or contact the site administrator if the problem persists.');
  31. watchdog('search_api_page', 'An error occurred while executing a search: !msg.', array('!msg' => $e->getMessage()), WATCHDOG_ERROR, l(t('search page'), $_GET['q']));
  32. }
  33. // Load spellcheck.
  34. if (isset($results['search_api_spellcheck'])) {
  35. $ret['results']['#spellcheck'] = array(
  36. '#theme' => 'search_api_spellcheck',
  37. '#spellcheck' => $results['search_api_spellcheck'],
  38. // Let the theme function know where the key is stored by passing its arg
  39. // number. We can work this out from the number of args in the page path.
  40. '#options' => array(
  41. 'arg' => array(count(arg(NULL, $page->path))),
  42. ),
  43. '#prefix' => '<p class="search-api-spellcheck suggestion">',
  44. '#suffix' => '</p>',
  45. );
  46. }
  47. $ret['results']['#theme'] = 'search_api_page_results';
  48. $ret['results']['#index'] = search_api_index_load($page->index_id);
  49. $ret['results']['#results'] = $results;
  50. $ret['results']['#view_mode'] = isset($page->options['view_mode']) ? $page->options['view_mode'] : 'search_api_page_result';
  51. $ret['results']['#keys'] = $keys;
  52. $ret['results']['#page_machine_name'] = $page->machine_name;
  53. // Load pager.
  54. if ($results['result count'] > $page->options['per_page']) {
  55. pager_default_initialize($results['result count'], $page->options['per_page']);
  56. $ret['results']['#pager'] = theme('pager');
  57. }
  58. if (!empty($results['ignored'])) {
  59. drupal_set_message(t('The following search keys are too short or too common and were therefore ignored: "@list".', array('@list' => implode(t('", "'), $results['ignored']))), 'warning');
  60. }
  61. if (!empty($results['warnings'])) {
  62. foreach ($results['warnings'] as $warning) {
  63. drupal_set_message($warning, 'warning');
  64. }
  65. }
  66. }
  67. if (isset($page->options['original_per_page'])) {
  68. $page->options['per_page'] = $page->options['original_per_page'];
  69. unset($page->options['original_per_page']);
  70. }
  71. return $ret;
  72. }
  73. /**
  74. * Executes a search.
  75. *
  76. * @param Entity $page
  77. * The page for which a search should be executed.
  78. * @param $keys
  79. * The keywords to search for.
  80. *
  81. * @return array
  82. * The search results as returned by SearchApiQueryInterface::execute().
  83. */
  84. function search_api_page_search_execute(Entity $page, $keys) {
  85. $limit = $page->options['per_page'];
  86. $offset = pager_find_page() * $limit;
  87. $options = array(
  88. 'search id' => 'search_api_page:' . $page->path,
  89. 'parse mode' => $page->options['mode'],
  90. );
  91. if (!empty($page->options['search_api_spellcheck'])) {
  92. $options['search_api_spellcheck'] = TRUE;
  93. }
  94. $query = search_api_query($page->index_id, $options)
  95. ->keys($keys)
  96. ->range($offset, $limit);
  97. if (!empty($page->options['fields'])) {
  98. $query->fields($page->options['fields']);
  99. }
  100. return $query->execute();
  101. }
  102. /**
  103. * Function for preprocessing the variables for the search_api_page_results
  104. * template.
  105. *
  106. * @param array $variables
  107. * An associative array containing:
  108. * - $index: The index this search was executed on.
  109. * - $results: An array of search results, as returned by
  110. * SearchApiQueryInterface::execute().
  111. * - $keys: The keywords of the executed search.
  112. *
  113. * @see search_api_page-results.tpl.php
  114. */
  115. function template_preprocess_search_api_page_results(array &$variables) {
  116. $results = $variables['results'];
  117. $keys = $variables['keys'];
  118. $variables['items'] = $variables['index']->loadItems(array_keys($variables['results']['results']));
  119. $variables['result_count'] = $results['result count'];
  120. $variables['sec'] = round($results['performance']['complete'], 3);
  121. $variables['search_performance'] = array(
  122. '#theme' => 'search_performance',
  123. '#markup' => format_plural(
  124. $results['result count'],
  125. 'The search found 1 result in @sec seconds.',
  126. 'The search found @count results in @sec seconds.',
  127. array('@sec' => $variables['sec'])
  128. ),
  129. '#prefix' => '<p class="search-performance">',
  130. '#suffix' => '</p>',
  131. );
  132. $variables['search_results'] = array(
  133. '#theme' => 'search_results_list',
  134. 'results' => $variables['results']['results'],
  135. 'items' => $variables['items'],
  136. 'index' => $variables['index'],
  137. 'type' => 'ul',
  138. );
  139. }
  140. /**
  141. * Process variables for search-result.tpl.php.
  142. *
  143. * The $variables array contains the following arguments:
  144. * - $result
  145. *
  146. * @see search_api_page-result.tpl.php
  147. */
  148. function template_preprocess_search_api_page_result(&$variables) {
  149. $index = $variables['index'];
  150. $variables['id'] = $variables['result']['id'];
  151. $variables['excerpt'] = $variables['result']['excerpt'];
  152. $item = $variables['item'];
  153. $wrapper = $index->entityWrapper($item, FALSE);
  154. $variables['url'] = $index->datasource()->getItemUrl($item);
  155. $variables['title'] = $index->datasource()->getItemLabel($item);
  156. if (!empty($variables['excerpt'])) {
  157. $text = $variables['excerpt'];
  158. }
  159. else {
  160. $fields = $index->options['fields'];
  161. $fields = array_intersect_key($fields, drupal_map_assoc($index->getFulltextFields()));
  162. $fields = search_api_extract_fields($wrapper, $fields);
  163. $text = '';
  164. $length = 0;
  165. foreach ($fields as $field_name => $field) {
  166. if (search_api_is_list_type($field['type']) || !isset($field['value'])) {
  167. continue;
  168. }
  169. $val_length = drupal_strlen($field['value']);
  170. if ($val_length > $length) {
  171. $text = $field['value'];
  172. $length = $val_length;
  173. $format = NULL;
  174. if (($pos = strrpos($field_name, ':')) && substr($field_name, $pos + 1) == 'value') {
  175. $tmp = $wrapper;
  176. try {
  177. foreach (explode(':', substr($field_name, 0, $pos)) as $part) {
  178. if (!isset($tmp->$part)) {
  179. $tmp = NULL;
  180. }
  181. $tmp = $tmp->$part;
  182. }
  183. }
  184. catch (EntityMetadataWrapperException $e) {
  185. $tmp = NULL;
  186. }
  187. if ($tmp && $tmp->type() == 'text_formatted' && isset($tmp->format)) {
  188. $format = $tmp->format->value();
  189. }
  190. }
  191. }
  192. }
  193. if ($text && function_exists('text_summary')) {
  194. $text = text_summary($text, $format);
  195. }
  196. }
  197. // Check for existence. User search does not include snippets.
  198. $variables['snippet'] = isset($text) ? $text : '';
  199. // Meta information
  200. global $language;
  201. if (isset($item->language) && $item->language != $language->language && $item->language != LANGUAGE_NONE) {
  202. $variables['title_attributes_array']['xml:lang'] = $item->language;
  203. $variables['content_attributes_array']['xml:lang'] = $item->language;
  204. }
  205. $info = array();
  206. if (!empty($item->name)) {
  207. $info['user'] = $item->name;
  208. }
  209. if (!empty($item->created)) {
  210. $info['date'] = format_date($item->created, 'short');
  211. }
  212. // Provide separated and grouped meta information..
  213. $variables['info_split'] = $info;
  214. $variables['info'] = implode(' - ', $info);
  215. }