[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

/sites/all/modules/ctools/includes/ -> context-task-handler.inc (source)

   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  


Generated: Mon Jul 9 18:01:44 2012 Cross-referenced by PHPXref 0.7