search.inc 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <?php
  2. /**
  3. * @file
  4. * Handle the 'node view' override task.
  5. *
  6. * This plugin overrides node/%node and reroutes it to the page manager, where
  7. * a list of tasks can be used to service this request based upon criteria
  8. * supplied by access plugins.
  9. */
  10. /**
  11. * Specialized implementation of hook_page_manager_task_tasks(). See api-task.html for
  12. * more information.
  13. */
  14. function page_manager_search_page_manager_tasks() {
  15. if (!module_exists('search')) {
  16. return;
  17. }
  18. return array(
  19. // This is a 'page' task and will fall under the page admin UI
  20. 'task type' => 'page',
  21. 'title' => t('Search'),
  22. // There are multiple search pages, let's override each of them
  23. // separately.
  24. 'subtasks' => TRUE,
  25. 'subtask callback' => 'page_manager_search_subtask',
  26. 'subtasks callback' => 'page_manager_search_subtasks',
  27. // Menu hooks so that we can alter the node/%node menu entry to point to us.
  28. 'hook menu alter' => 'page_manager_search_menu_alter',
  29. // This is task uses 'context' handlers and must implement these to give the
  30. // handler data it needs.
  31. 'handler type' => 'context',
  32. 'get arguments' => 'page_manager_search_get_arguments',
  33. 'get context placeholders' => 'page_manager_search_get_contexts',
  34. 'access callback' => 'page_manager_search_access_check',
  35. );
  36. }
  37. /**
  38. * Callback defined by page_manager_search_page_manager_tasks().
  39. *
  40. * Alter the search tabs to work with page manager. The search flow is
  41. * quite odd, and tracing through the code takes hours to realize
  42. * that the tab you click on does not normally actually handle
  43. * the search. This tries to account for that.
  44. *
  45. * Note to module authors: This tends to work a lot better with modules
  46. * that override their own search pages if their _alter runs *before*
  47. * this one.
  48. */
  49. function page_manager_search_menu_alter(&$items, $task) {
  50. // We are creating two sets of tabs. One set is for searching without
  51. // keywords. A second set is for searching *with* keywords. This
  52. // is necessary because search/node/% and search/node need to be
  53. // different due to the way the search menu items function.
  54. $default_info = search_get_default_module_info();
  55. if (empty($default_info)) {
  56. // Nothing to do.
  57. return;
  58. }
  59. // Go through each search module item.
  60. foreach (search_get_info() as $module => $info) {
  61. if (variable_get('page_manager_search_disabled_' . $module, TRUE)) {
  62. continue;
  63. }
  64. $path = 'search/' . $info['path'];
  65. $callback = $items["$path/%menu_tail"]['page callback'];
  66. if ($callback == 'search_view' || variable_get('page_manager_override_anyway', FALSE)) {
  67. $items["$path"]['page callback'] = 'page_manager_search_page';
  68. $items["$path"]['file path'] = $task['path'];
  69. $items["$path"]['file'] = $task['file'];
  70. $items["$path/%menu_tail"]['page callback'] = 'page_manager_search_page';
  71. $items["$path/%menu_tail"]['file path'] = $task['path'];
  72. $items["$path/%menu_tail"]['file'] = $task['file'];
  73. }
  74. else {
  75. // automatically disable this task if it cannot be enabled.
  76. variable_set('page_manager_search_disabled_' . $module, TRUE);
  77. if (!empty($GLOBALS['page_manager_enabling_search'])) {
  78. drupal_set_message(t('Page manager module is unable to enable @path because some other module already has overridden with %callback.', array('%callback' => $callback, '@path' => $path)), 'error');
  79. }
  80. }
  81. }
  82. }
  83. /**
  84. * Entry point for our overridden search page.
  85. *
  86. */
  87. function page_manager_search_page($type) {
  88. ctools_include('menu');
  89. // menu_set_active_trail(ctools_get_menu_trail('search/' . $type));
  90. // Get the arguments and construct a keys string out of them.
  91. $args = func_get_args();
  92. // We have to remove the $type.
  93. array_shift($args);
  94. // And implode() it all back together.
  95. $keys = $args ? implode('/', $args) : '';
  96. // Allow other modules to alter the search keys
  97. drupal_alter(array('search_keys', 'search_'. $type .'_keys'), $keys);
  98. // Load my task plugin
  99. $task = page_manager_get_task('search');
  100. $subtask = page_manager_get_task_subtask($task, $type);
  101. // Load the node into a context.
  102. ctools_include('context');
  103. ctools_include('context-task-handler');
  104. $contexts = ctools_context_handler_get_task_contexts($task, $subtask, array($keys));
  105. $output = ctools_context_handler_render($task, $subtask, $contexts, array($keys));
  106. if ($output !== FALSE) {
  107. return $output;
  108. }
  109. $function = 'search_view';
  110. foreach (module_implements('page_manager_override') as $module) {
  111. $call = $module . '_page_manager_override';
  112. if (($rc = $call('search')) && function_exists($rc)) {
  113. $function = $rc;
  114. break;
  115. }
  116. }
  117. // Otherwise, fall back.
  118. // Put the $type back on the arguments.
  119. module_load_include('inc', 'search', 'search.pages');
  120. array_unshift($args, $type);
  121. return call_user_func_array($function, $args);
  122. }
  123. /**
  124. * Callback to get arguments provided by this task handler.
  125. *
  126. * Since this is the node view and there is no UI on the arguments, we
  127. * create dummy arguments that contain the needed data.
  128. */
  129. function page_manager_search_get_arguments($task, $subtask_id) {
  130. return array(
  131. array(
  132. 'keyword' => 'keywords',
  133. 'identifier' => t('Keywords'),
  134. 'id' => 1,
  135. 'name' => 'string',
  136. 'settings' => array('use_tail' => TRUE),
  137. ),
  138. );
  139. }
  140. /**
  141. * Callback to get context placeholders provided by this handler.
  142. */
  143. function page_manager_search_get_contexts($task, $subtask_id) {
  144. return ctools_context_get_placeholders_from_argument(page_manager_search_get_arguments($task, $subtask_id));
  145. }
  146. /**
  147. * Callback to enable/disable the page from the UI.
  148. */
  149. function page_manager_search_enable($cache, $status) {
  150. variable_set('page_manager_search_disabled_' . $cache->subtask_id, $status);
  151. // Set a global flag so that the menu routine knows it needs
  152. // to set a message if enabling cannot be done.
  153. if (!$status) {
  154. $GLOBALS['page_manager_enabling_search'] = TRUE;
  155. }
  156. }
  157. /**
  158. * Task callback to get all subtasks.
  159. *
  160. * Return a list of all subtasks.
  161. */
  162. function page_manager_search_subtasks($task) {
  163. $return = array();
  164. foreach (search_get_info() as $module => $info) {
  165. if ($info['path']) {
  166. // We don't pass the $info because the subtask build could be called
  167. // singly without the $info when just the subtask needs to be built.
  168. $return[$module] = page_manager_search_build_subtask($task, $module);
  169. }
  170. }
  171. return $return;
  172. }
  173. /**
  174. * Callback to return a single subtask.
  175. */
  176. function page_manager_search_subtask($task, $subtask_id) {
  177. return page_manager_search_build_subtask($task, $subtask_id);
  178. }
  179. /**
  180. * Build a subtask array for a given page.
  181. */
  182. function page_manager_search_build_subtask($task, $module) {
  183. $search_info = search_get_info();
  184. $info = $search_info[$module];
  185. $path = 'search/' . $info['path'];
  186. $subtask = array(
  187. 'name' => $module,
  188. 'admin title' => $info['title'],
  189. 'admin path' => "$path/!keywords",
  190. 'admin description' => t('Search @type', array('@type' => $info['title'])),
  191. 'admin type' => t('System'),
  192. 'row class' => empty($page->disabled) ? 'page-manager-enabled' : 'page-manager-disabled',
  193. 'storage' => t('In code'),
  194. 'disabled' => variable_get('page_manager_search_disabled_' . $module, TRUE),
  195. // This works for both enable AND disable
  196. 'enable callback' => 'page_manager_search_enable',
  197. );
  198. return $subtask;
  199. }
  200. /**
  201. * Callback to determine if a page is accessible.
  202. *
  203. * @param $task
  204. * The task plugin.
  205. * @param $subtask_id
  206. * The subtask id
  207. * @param $contexts
  208. * The contexts loaded for the task.
  209. * @return
  210. * TRUE if the current user can access the page.
  211. */
  212. function page_manager_search_access_check($task, $subtask_id, $contexts) {
  213. $context = reset($contexts);
  214. return _search_menu_access($context->data);
  215. }