| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
1 <?php 2 // $Id: context-task-handler.inc,v 1.23.2.9 2010/09/10 18:25:13 merlinofchaos Exp $ 3 4 /** 5 * @file 6 * Support for creating 'context' type task handlers. 7 * 8 * Context task handlers expect the task to provide 0 or more contexts. The 9 * task handler should use those contexts as selection rules, as well as 10 * rendering with them. 11 * 12 * The functions and forms in this file should be common to every context type 13 * task handler made. 14 * 15 * Forms: 16 * - ... 17 */ 18 19 /** 20 * Render a context type task handler given a list of handlers 21 * attached to a type. 22 * 23 * @param $task 24 * The $task object in use. 25 * @param $subtask 26 * The id of the subtask in use. 27 * @param $contexts 28 * The context objects in use. 29 * @param $args 30 * The raw arguments behind the contexts. 31 * @param $page 32 * If TRUE then this renderer owns the page and can use theme('page') 33 * for no blocks; if false, output is returned regardless of any no 34 * blocks settings. 35 * @return 36 * Either the output or NULL if there was output, FALSE if no handler 37 * accepted the task. If $page is FALSE then the $info block is returned instead. 38 */ 39 function ctools_context_handler_render($task, $subtask, $contexts, $args, $page = TRUE) { 40 // Load the landlers, choosing only enabled handlers. 41 $handlers = page_manager_load_sorted_handlers($task, $subtask ? $subtask['name'] : '', TRUE); 42 43 // Try each handler. 44 foreach ($handlers as $handler) { 45 if ($function = page_manager_get_renderer($handler)) { 46 if ($info = $function($handler, $contexts, $args)) { 47 drupal_alter('ctools_render', $info, $page, $args, $contexts, $task, $subtask, $handler); 48 // If we don't own the page, let the caller deal with rendering. 49 if (!$page) { 50 return $info; 51 } 52 53 if ($subtask) { 54 $task_name = page_manager_make_task_name($task['name'], $subtask['name']); 55 } 56 else { 57 $task_name = $task['name']; 58 } 59 60 page_manager_get_current_page(array( 61 'name' => $task_name, 62 'task' => $task, 63 'subtask' => $subtask, 64 'contexts' => $contexts, 65 'arguments' => $args, 66 'handler' => $handler, 67 )); 68 69 if (!empty($info['response code']) && $info['response code'] != 200) { 70 switch ($info['response code']) { 71 case 403: 72 return MENU_ACCESS_DENIED; 73 case 404: 74 return MENU_NOT_FOUND; 75 case 301: 76 case 302: 77 case 303: 78 case 304: 79 case 305: 80 case 307: 81 $info += array( 82 'query' => '', 83 'fragment' => '', 84 ); 85 return drupal_goto($info['destination'], $info['query'], $info['fragment'], $info['response code']); 86 // @todo -- should other response codes be supported here? 87 } 88 } 89 90 /* 91 // Only do this if something hasn't already changed the active menu, 92 // such as a book. 93 if (menu_get_active_menu_name() == 'navigation') { 94 $item = menu_get_item(); 95 $mlink = db_fetch_object(db_query("SELECT * FROM {menu_links} WHERE link_path = '%s'", $item['href'])); 96 97 if ($mlink && isset($mlink->menu_name)) { 98 menu_set_active_menu_name($mlink->menu_name); 99 } 100 } 101 */ 102 foreach (ctools_context_handler_get_task_arguments($task, $subtask) as $id => $argument) { 103 $plugin = ctools_get_argument($argument['name']); 104 $cid = ctools_context_id($argument, 'argument'); 105 if (!empty($contexts[$cid]) && ($function = ctools_plugin_get_function($plugin, 'breadcrumb'))) { 106 $function($argument['settings'], $contexts[$cid]); 107 } 108 } 109 110 if (isset($info['title'])) { 111 drupal_set_title($info['title']); 112 } 113 114 // Only directly output if $page was set to true. 115 if (!empty($info['no_blocks'])) { 116 print theme('page', $info['content'], FALSE); 117 return; 118 } 119 else { 120 return $info['content']; 121 } 122 } 123 } 124 } 125 126 return FALSE; 127 } 128 129 /** 130 * Called to execute actions that should happen before a handler is rendered. 131 */ 132 function ctools_context_handler_pre_render($handler, $contexts, $args) { 133 $plugin = page_manager_get_task_handler($handler->handler); 134 135 if (user_access('administer page manager') && isset($handler->task)) { 136 // Provide a tab to edit this context: 137 ctools_include('menu'); 138 $task = page_manager_get_task($handler->task); 139 140 $title = !empty($task['tab title']) ? $task['tab title'] : t('Edit @type', array('@type' => $plugin['title'])); 141 $trail = array(); 142 if (!empty($plugin['tab operation'])) { 143 if (is_array($plugin['tab operation'])) { 144 $trail = $plugin['tab operation']; 145 } 146 else if (function_exists($plugin['tab operation'])) { 147 $trail = $plugin['tab operation']($handler, $contexts, $args); 148 } 149 } 150 151 ctools_menu_add_tab(array( 152 'title' => $title, 153 'href' => page_manager_edit_url(page_manager_make_task_name($handler->task, $handler->subtask), $trail), 154 )); 155 } 156 } 157 158 /** 159 * Compare arguments to contexts for selection purposes. 160 * 161 * @param $handler 162 * The handler in question. 163 * @param $contexts 164 * The context objects provided by the task. 165 * 166 * @return 167 * TRUE if these contexts match the selection rules. NULL or FALSE 168 * otherwise. 169 */ 170 function ctools_context_handler_select($handler, $contexts) { 171 if (empty($handler->conf['access'])) { 172 return TRUE; 173 } 174 175 ctools_include('context'); 176 return ctools_access($handler->conf['access'], $contexts); 177 } 178 179 /** 180 * Get the array of summary strings for the arguments. 181 * 182 * These summary strings are used to communicate to the user what 183 * arguments the task handlers are selecting. 184 * 185 * @param $task 186 * The loaded task plugin. 187 * @param $subtask 188 * The subtask id. 189 * @param $handler 190 * The handler to be checked. 191 */ 192 function ctools_context_handler_summary($task, $subtask, $handler) { 193 if (empty($handler->conf['access']['plugins'])) { 194 return array(); 195 } 196 197 ctools_include('context'); 198 $strings = array(); 199 $contexts = ctools_context_handler_get_all_contexts($task, $subtask, $handler); 200 201 foreach ($handler->conf['access']['plugins'] as $test) { 202 $plugin = ctools_get_access_plugin($test['name']); 203 if ($string = ctools_access_summary($plugin, $contexts, $test)) { 204 $strings[] = $string; 205 } 206 } 207 208 return $strings; 209 } 210 211 // -------------------------------------------------------------------------- 212 // Tasks and Task handlers can both have their own sources of contexts. 213 // Sometimes we need all of these contexts at once (when editing 214 // the task handler, for example) but sometimes we need them separately 215 // (when a task has contexts loaded and is trying out the task handlers, 216 // for example). Therefore there are two paths we can take to getting contexts. 217 218 /** 219 * Load the contexts for a task, using arguments. 220 * 221 * This creates the base array of contexts, loaded from arguments, suitable 222 * for use in rendering. 223 */ 224 function ctools_context_handler_get_task_contexts($task, $subtask, $args) { 225 $contexts = ctools_context_handler_get_base_contexts($task, $subtask); 226 $arguments = ctools_context_handler_get_task_arguments($task, $subtask); 227 ctools_context_get_context_from_arguments($arguments, $contexts, $args); 228 229 return $contexts; 230 } 231 232 /** 233 * Load the contexts for a task handler. 234 * 235 * This expands a base set of contexts passed in from a task with the 236 * contexts defined on the task handler. The contexts from the task 237 * must already have been loaded. 238 */ 239 function ctools_context_handler_get_handler_contexts($contexts, $handler) { 240 $object = ctools_context_handler_get_handler_object($handler); 241 return ctools_context_load_contexts($object, FALSE, $contexts); 242 } 243 244 /** 245 * Load the contexts for a task and task handler together. 246 * 247 * This pulls the arguments from a task and everything else from a task 248 * handler and loads them as a group. Since there is no data, this loads 249 * the contexts as placeholders. 250 */ 251 function ctools_context_handler_get_all_contexts($task, $subtask, $handler) { 252 $contexts = array(); 253 254 $object = ctools_context_handler_get_task_object($task, $subtask, $handler); 255 $contexts = ctools_context_load_contexts($object, TRUE, $contexts); 256 ctools_context_handler_set_access_restrictions($task, $subtask, $handler, $contexts); 257 return $contexts; 258 } 259 260 /** 261 * Create an object suitable for use with the context system that kind of 262 * expects things in a certain, kind of clunky format. 263 */ 264 function ctools_context_handler_get_handler_object($handler) { 265 $object = new stdClass; 266 $object->name = $handler->name; 267 $object->contexts = isset($handler->conf['contexts']) ? $handler->conf['contexts'] : array(); 268 $object->relationships = isset($handler->conf['relationships']) ? $handler->conf['relationships'] : array(); 269 270 return $object; 271 } 272 273 /** 274 * Create an object suitable for use with the context system that kind of 275 * expects things in a certain, kind of clunky format. This one adds in 276 * arguments from the task. 277 */ 278 function ctools_context_handler_get_task_object($task, $subtask, $handler) { 279 $object = new stdClass; 280 $object->name = !empty($handler->name) ? $handler->name : 'temp'; 281 $object->base_contexts = ctools_context_handler_get_base_contexts($task, $subtask, TRUE); 282 $object->arguments = ctools_context_handler_get_task_arguments($task, $subtask); 283 $object->contexts = isset($handler->conf['contexts']) ? $handler->conf['contexts'] : array(); 284 $object->relationships = isset($handler->conf['relationships']) ? $handler->conf['relationships'] : array(); 285 286 return $object; 287 } 288 289 /** 290 * Get base contexts from a task, if it has any. 291 * 292 * Tasks can get their contexts either from base contexts or arguments; base 293 * contexts extract their information from the environment. 294 */ 295 function ctools_context_handler_get_base_contexts($task, $subtask, $placeholders = FALSE) { 296 if ($function = ctools_plugin_get_function($task, 'get base contexts')) { 297 return $function($task, $subtask, $placeholders); 298 } 299 300 return array(); 301 } 302 303 /** 304 * Get the arguments from a task that are used to load contexts. 305 */ 306 function ctools_context_handler_get_task_arguments($task, $subtask) { 307 if ($function = ctools_plugin_get_function($task, 'get arguments')) { 308 return $function($task, $subtask); 309 } 310 311 return array(); 312 } 313 314 /** 315 * Set any access restrictions on the contexts for a handler. 316 * 317 * Both the task and the handler could add restrictions to the contexts 318 * based upon the access control. These restrictions might be useful 319 * to limit what kind of content appears in the add content dialog; 320 * for example, if we have an access item that limits a node context 321 * to only 'story' and 'page' types, there is no need for content that 322 * only applies to the 'poll' type to appear. 323 */ 324 function ctools_context_handler_set_access_restrictions($task, $subtask, $handler, &$contexts) { 325 // First, for the task: 326 if ($function = ctools_plugin_get_function($task, 'access restrictions')) { 327 $function($task, $subtask, $contexts); 328 } 329 330 // Then for the handler: 331 if (isset($handler->conf['access'])) { 332 ctools_access_add_restrictions($handler->conf['access'], $contexts); 333 } 334 } 335 336 /** 337 * Form to choose context based selection rules for a task handler. 338 * 339 * The configuration will be assumed to go simply in $handler->conf and 340 * will be keyed by the argument ID. 341 */ 342 function ctools_context_handler_edit_criteria(&$form, &$form_state) { 343 if (!isset($form_state['handler']->conf['access'])) { 344 $form_state['handler']->conf['access'] = array(); 345 } 346 347 ctools_include('context'); 348 ctools_include('modal'); 349 ctools_include('ajax'); 350 ctools_modal_add_plugin_js(ctools_get_access_plugins()); 351 ctools_include('context-access-admin'); 352 $form_state['module'] = 'page_manager_task_handler'; 353 // Encode a bunch of info into the argument so we can get our cache later 354 $form_state['callback argument'] = $form_state['task_name'] . '*' . $form_state['handler']->name; 355 $form_state['access'] = $form_state['handler']->conf['access']; 356 $form_state['no buttons'] = TRUE; 357 $form_state['contexts'] = ctools_context_handler_get_all_contexts($form_state['task'], $form_state['subtask'], $form_state['handler']); 358 359 $form['markup'] = array( 360 '#value' => '<div class="description">' . 361 t('If there is more than one variant on a page, when the page is visited each variant is given an opportunity to be displayed. Starting from the first variant and working to the last, each one tests to see if its selection rules will pass. The first variant that its criteria (as specified below) will be used.') . 362 '</div>', 363 ); 364 $form = array_merge($form, ctools_access_admin_form($form_state)); 365 } 366 367 /** 368 * Submit handler for rules selection 369 */ 370 function ctools_context_handler_edit_criteria_submit(&$form, &$form_state) { 371 $form_state['handler']->conf['access']['logic'] = $form_state['values']['logic']; 372 } 373 374 /** 375 * Edit contexts that go with this panel. 376 */ 377 function ctools_context_handler_edit_context(&$form, &$form_state) { 378 ctools_include('context-admin'); 379 ctools_context_admin_includes(); 380 381 $handler = $form_state['handler']; 382 $page = $form_state['page']; 383 $cache_name = $handler->name ? $handler->name : 'temp'; 384 if (isset($page->context_cache[$cache_name])) { 385 $cache = $page->context_cache[$cache_name]; 386 } 387 else { 388 $cache = ctools_context_handler_get_task_object($form_state['task'], $form_state['subtask'], $form_state['handler']); 389 $form_state['page']->context_cache[$cache_name] = $cache; 390 } 391 392 $form['right'] = array( 393 '#prefix' => '<div class="clear-block"><div class="right-container">', 394 '#suffix' => '</div>', 395 ); 396 397 $form['left'] = array( 398 '#prefix' => '<div class="left-container">', 399 '#suffix' => '</div></div>', 400 ); 401 402 $module = 'page_manager-' . $page->task_name; 403 ctools_context_add_context_form($module, $form, $form_state, $form['right']['contexts_table'], $cache); 404 ctools_context_add_relationship_form($module, $form, $form_state, $form['right']['relationships_table'], $cache); 405 406 // Set an additional description if CCK and Token are enabled, to notify of unlisted keywords 407 if (module_exists('content') && module_exists('token')) { 408 $description = t('Note that CCK fields may be used as keywords using patterns like <em>%node:field_name-formatted</em>.'); 409 } elseif (!module_exists('token')) { 410 $description = t('More keywords will be available if you install the Token module, see http://drupal.org/project/token.'); 411 } 412 413 $form['left']['summary'] = array( 414 '#prefix' => '<div class="page-manager-contexts">', 415 '#suffix' => '</div>', 416 '#value' => theme('ctools_context_list', $cache, t('Summary of contexts'), $description), 417 ); 418 419 $form_state['context_object'] = &$cache; 420 } 421 422 /** 423 * Process submission of the context edit form. 424 */ 425 function ctools_context_handler_edit_context_submit(&$form, &$form_state) { 426 $handler = &$form_state['handler']; 427 428 $cache_name = $handler->name ? $handler->name : 'temp'; 429 430 $handler->conf['contexts'] = $form_state['context_object']->contexts; 431 $handler->conf['relationships'] = $form_state['context_object']->relationships; 432 if (isset($form_state['page']->context_cache[$cache_name])) { 433 unset($form_state['page']->context_cache[$cache_name]); 434 } 435 } 436
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |