context.core.inc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. <?php
  2. /**
  3. * Implementation of hook_help().
  4. */
  5. function context_help($path, $arg) {
  6. switch ($path) {
  7. case 'admin/help#context':
  8. $output = file_get_contents(drupal_get_path('module', 'context') . '/README.txt');
  9. return module_exists('markdown') ? filter_xss_admin(module_invoke('markdown', 'filter', 'process', 0, -1, $output)) : '<pre>' . check_plain($output) . '</pre>';
  10. }
  11. }
  12. /**
  13. * Implementation of hook_theme().
  14. */
  15. function context_theme() {
  16. $items = array();
  17. if (!module_exists('block')) {
  18. $items['block'] = array(
  19. 'render element' => 'elements',
  20. 'template' => 'block',
  21. 'path' => drupal_get_path('module', 'block'),
  22. 'file' => 'block.module',
  23. 'template' => 'block',
  24. );
  25. }
  26. $items['context_block_form'] = array(
  27. 'render element' => 'form',
  28. 'path' => drupal_get_path('module', 'context') . '/theme',
  29. 'file' => 'context_reaction_block.theme.inc',
  30. );
  31. $items['context_block_regions_form'] = array(
  32. 'render element' => 'form',
  33. 'path' => drupal_get_path('module', 'context') . '/theme',
  34. 'file' => 'context_reaction_block.theme.inc',
  35. );
  36. $items['context_block_editor'] = array(
  37. 'render element' => 'form',
  38. 'path' => drupal_get_path('module', 'context') . '/theme',
  39. 'file' => 'context_reaction_block.theme.inc',
  40. );
  41. $items['context_block_browser'] = array(
  42. 'variables' => array('blocks' => array(), 'context' => array()),
  43. 'path' => drupal_get_path('module', 'context') . '/theme',
  44. 'template' => 'context-block-browser',
  45. 'file' => 'context_reaction_block.theme.inc',
  46. );
  47. $items['context_block_browser_item'] = array(
  48. 'variables' => array('block' => array()),
  49. 'path' => drupal_get_path('module', 'context') . '/theme',
  50. 'template' => 'context-block-browser-item',
  51. 'file' => 'context_reaction_block.theme.inc',
  52. );
  53. $items['context_block_script_placeholder'] = array(
  54. 'variables' => array('text' => NULL),
  55. 'path' => drupal_get_path('module', 'context') . '/theme',
  56. 'file' => 'context_reaction_block.theme.inc',
  57. );
  58. return $items;
  59. }
  60. /**
  61. * Implementation of hook_theme_registry_alter().
  62. */
  63. function context_theme_registry_alter(&$theme_registry) {
  64. // Push theme_page() through a context_preprocess to provide
  65. // context-sensitive menus and variables. Ensure that
  66. // context_preprocess_page() comes immediately after
  67. // template_preprocess_page().
  68. $position = array_search('context_preprocess_page', $theme_registry['page']['preprocess functions']);
  69. if ($position !== FALSE) {
  70. unset($theme_registry['page']['preprocess functions'][$position]);
  71. }
  72. // Prevent conflict with i18n_menu.
  73. if (module_exists('i18n_menu')) {
  74. $position = array_search('i18n_menu_preprocess_page', $theme_registry['page']['preprocess functions']);
  75. }
  76. else {
  77. $position = array_search('template_preprocess_page', $theme_registry['page']['preprocess functions']);
  78. }
  79. $position = $position ? $position + 1 : 2;
  80. array_splice($theme_registry['page']['preprocess functions'], $position, 0, 'context_preprocess_page');
  81. }
  82. /**
  83. * Implementation of hook_ctools_render_alter().
  84. * Used to detect the presence of a page manager node view or node form.
  85. */
  86. function context_ctools_render_alter($info, $page, $data) {
  87. extract($data);
  88. if ($page && in_array($task['name'], array('node_view', 'node_edit'), TRUE)) {
  89. foreach ($contexts as $ctools_context) {
  90. if (in_array('node', $ctools_context->type) && !empty($ctools_context->data)) {
  91. context_node_condition($ctools_context->data, $task['name'] === 'node_view' ? 'view' : 'form');
  92. break;
  93. }
  94. }
  95. }
  96. }
  97. /**
  98. * Implementation of hook_entity_prepare_view().
  99. */
  100. function context_entity_prepare_view($prepare, $entity_type) {
  101. if ($entity_type === 'taxonomy_term' && count($prepare) === 1) {
  102. $term = reset($prepare);
  103. if ($term === menu_get_object('taxonomy_term', 2) && $plugin = context_get_plugin('condition', 'taxonomy_term')) {
  104. $plugin->execute($term, 'view');
  105. }
  106. }
  107. }
  108. /**
  109. * Implementation of hook_node_view().
  110. */
  111. function context_node_view($node, $view_mode) {
  112. if ($view_mode === 'full') {
  113. $object = menu_get_object();
  114. if (isset($object->nid) && $object->nid === $node->nid) {
  115. context_node_condition($node, 'view');
  116. }
  117. }
  118. }
  119. /**
  120. * Implementation of hook_form_alter().
  121. */
  122. function context_form_alter(&$form, $form_state, $form_id) {
  123. // If the form is an admin for, flag it so that we can force a rebuild if needed.
  124. if (path_is_admin($_GET['q'])) {
  125. $form['#submit'][] = 'context_admin_form_submit';
  126. }
  127. // Trigger the condition in an after_build function to avoid being skipped
  128. // when there are validation errors.
  129. $form['#after_build'][] = 'context_form_alter_node_after_build';
  130. }
  131. /**
  132. * Form #after_build callback for context_form_alter().
  133. */
  134. function context_form_alter_node_after_build($form, &$form_state) {
  135. // Prevent this from firing on admin pages... damn form driven apis...
  136. if (!empty($form['#node_edit_form']) && arg(0) != 'admin') {
  137. context_node_condition($form['#node'], 'form');
  138. }
  139. return $form;
  140. }
  141. /**
  142. * Clear out block info cache when an admin area form is submitted.
  143. */
  144. function context_admin_form_submit(&$form, $form_state) {
  145. if ($plugin = context_get_plugin('reaction', 'block')) {
  146. $plugin->rebuild_needed(TRUE);
  147. }
  148. }
  149. /**
  150. * Centralized node condition call function for the ever increasing number of
  151. * ways to get at a node view / node form.
  152. */
  153. function context_node_condition(&$node, $op) {
  154. if ($plugin = context_get_plugin('condition', 'node')) {
  155. $plugin->execute($node, $op);
  156. }
  157. if (module_exists('taxonomy')) {
  158. if ($plugin = context_get_plugin('condition', 'node_taxonomy')) {
  159. $plugin->execute($node, $op);
  160. }
  161. }
  162. if (module_exists('book')) {
  163. if ($plugin = context_get_plugin('condition', 'book')) {
  164. $plugin->execute($node, $op);
  165. }
  166. if ($plugin = context_get_plugin('condition', 'bookroot')) {
  167. $plugin->execute($node, $op);
  168. }
  169. }
  170. // Allow other plugins to easily be triggered on node-related events.
  171. drupal_alter('context_node_condition', $node, $op);
  172. }
  173. /**
  174. * Implementation of hook_form_alter() for system_modules_form.
  175. */
  176. function context_form_system_modules_form_alter(&$form, $form_state) {
  177. context_invalidate_cache();
  178. }
  179. /**
  180. * Implementation of hook_form_alter() for user_profile_form.
  181. */
  182. function context_form_user_profile_form_alter(&$form, $form_state) {
  183. if ($plugin = context_get_plugin('condition', 'user_page')) {
  184. $plugin->execute($form['#user'], 'form');
  185. }
  186. }
  187. /**
  188. * Implementation of hook_form_alter() for user_register_form.
  189. */
  190. function context_form_user_register_form_alter(&$form, $form_state) {
  191. if ($plugin = context_get_plugin('condition', 'user_page')) {
  192. $plugin->execute($form['#user'], 'register');
  193. }
  194. }
  195. /**
  196. * Implementation of hook_form_alter() for comment_form.
  197. */
  198. function context_form_comment_form_alter(&$form, $form_state) {
  199. if ($nid = $form['nid']['#value']) {
  200. $node = node_load($nid);
  201. context_node_condition($node, 'comment');
  202. }
  203. }
  204. /**
  205. * Implementation of hook_views_pre_view().
  206. */
  207. function context_views_pre_view($view, $display) {
  208. if ($plugin = context_get_plugin('condition', 'views')) {
  209. $plugin->execute($view);
  210. }
  211. // Support Views overrides of specific entity paths.
  212. if ($view->display_handler->has_path()) {
  213. switch ($view->display_handler->get_option('path')) {
  214. case 'taxonomy/term/%':
  215. if (($term = taxonomy_term_load(arg(2))) && ($plugin = context_get_plugin('condition', 'taxonomy_term'))) {
  216. $plugin->execute($term, 'view');
  217. }
  218. break;
  219. case 'node/%':
  220. if ($node = node_load(arg(1))) {
  221. context_node_condition($node, 'view');
  222. }
  223. break;
  224. case 'user/%':
  225. if (($account = user_load(arg(1))) && ($plugin = context_get_plugin('condition', 'user_page'))) {
  226. $plugin->execute($account, 'view');
  227. }
  228. break;
  229. }
  230. }
  231. }
  232. /**
  233. * Implementation of hook_user().
  234. */
  235. function context_user_view($account, $view_mode) {
  236. if ($view_mode === 'full' && $plugin = context_get_plugin('condition', 'user_page')) {
  237. $plugin->execute($account, 'view');
  238. }
  239. }
  240. /**
  241. * Implements hook_page_build().
  242. */
  243. function context_page_build(&$page) {
  244. module_invoke_all('context_page_condition');
  245. module_invoke_all('context_page_reaction');
  246. if ($plugin = context_get_plugin('reaction', 'block')) {
  247. $plugin->execute($page);
  248. }
  249. // See block_page_build. Clear static cache b/c in overlay form submissions
  250. // hook_page_build can get called more than once per page load.
  251. drupal_static_reset('context_reaction_block_list');
  252. }
  253. /**
  254. * THEME FUNCTIONS & RELATED ==========================================
  255. */
  256. /**
  257. * Generates an array of links (suitable for use with theme_links)
  258. * to the node forms of types associated with current active contexts.
  259. */
  260. function context_links($reset = FALSE) {
  261. static $links;
  262. if (!$links || $reset) {
  263. $contexts = context_active_contexts();
  264. $active_types = array();
  265. $conditions = array('node', 'bookroot');
  266. foreach ($conditions as $condition) {
  267. foreach ($contexts as $k => $v) {
  268. if (!empty($v->conditions[$condition]['values'])) {
  269. $active_types = array_merge($active_types, array_filter($v->conditions[$condition]['values']));
  270. }
  271. }
  272. }
  273. $links = array();
  274. if (!empty($active_types)) {
  275. // Iterate over active contexts
  276. foreach ($active_types as $type) {
  277. $add_url = 'node/add/' . str_replace('_', '-', $type);
  278. $item = menu_get_item($add_url);
  279. if ($item && $item['access'] && strpos($_GET['q'], $add_url) !== 0) {
  280. $links[$type] = array('title' => t('Add @type', array('@type' => node_type_get_name($type))), 'href' => $add_url);
  281. }
  282. }
  283. }
  284. drupal_alter('context_links', $links);
  285. uasort($links, 'element_sort');
  286. }
  287. return $links;
  288. }
  289. /**
  290. * Implementation of hook_context_page_condition().
  291. */
  292. function context_context_page_condition() {
  293. if ($plugin = context_get_plugin('condition', 'menu')) {
  294. $plugin->execute();
  295. }
  296. if ($plugin = context_get_plugin('condition', 'sitewide')) {
  297. $plugin->execute(1);
  298. }
  299. if ($plugin = context_get_plugin('condition', 'context')) {
  300. $plugin->execute();
  301. }
  302. }
  303. /**
  304. * Implementation of hook_context_page_reaction().
  305. */
  306. function context_context_page_reaction() {
  307. if ($plugin = context_get_plugin('reaction', 'breadcrumb')) {
  308. $plugin->execute();
  309. }
  310. if ($plugin = context_get_plugin('reaction', 'css_injector')) {
  311. $plugin->execute();
  312. }
  313. if ($plugin = context_get_plugin('reaction', 'debug')) {
  314. $plugin->execute();
  315. }
  316. }
  317. /**
  318. * Implementation of hook_page_alter().
  319. */
  320. function context_preprocess_page(&$vars) {
  321. if ($plugin = context_get_plugin('reaction', 'menu')) {
  322. $plugin->execute($vars);
  323. }
  324. if ($plugin = context_get_plugin('reaction', 'theme')) {
  325. $plugin->execute($vars);
  326. }
  327. /*
  328. if ($context_links = context_links()) {
  329. $vars['context_links'] = theme('links', $context_links);
  330. }
  331. else {
  332. $vars['context_links'] = '';
  333. }
  334. */
  335. }
  336. /**
  337. * Implementation of hook_preprocess_html().
  338. */
  339. function context_preprocess_html(&$vars) {
  340. if ($plugin = context_get_plugin('reaction', 'theme_html')) {
  341. $plugin->execute($vars);
  342. }
  343. }