[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/ctools/page_manager/ -> page_manager.module (source)

   1  <?php
   2  // $Id: page_manager.module,v 1.17.2.8 2010/07/23 21:47:20 merlinofchaos Exp $
   3  
   4  /**
   5   * @file
   6   * The page manager module provides a UI and API to manage pages.
   7   *
   8   * It defines pages, both for system pages, overrides of system pages, and
   9   * custom pages using Drupal's normal menu system. It allows complex
  10   * manipulations of these pages, their content, and their hierarchy within
  11   * the site. These pages can be exported to code for superior revision
  12   * control.
  13   */
  14  
  15  /**
  16   * Bit flag on the 'changed' value to tell us if an item was moved.
  17   */
  18  define('PAGE_MANAGER_CHANGED_MOVED', 0x01);
  19  
  20  /**
  21   * Bit flag on the 'changed' value to tell us if an item edited or added.
  22   */
  23  define('PAGE_MANAGER_CHANGED_CACHED', 0x02);
  24  
  25  /**
  26   * Bit flag on the 'changed' value to tell us if an item deleted.
  27   */
  28  define('PAGE_MANAGER_CHANGED_DELETED', 0x04);
  29  
  30  /**
  31   * Bit flag on the 'changed' value to tell us if an item has had its disabled status changed.
  32   */
  33  define('PAGE_MANAGER_CHANGED_STATUS', 0x08);
  34  
  35  // --------------------------------------------------------------------------
  36  // Drupal hooks
  37  
  38  /**
  39   * Implementation of hook_perm().
  40   */
  41  function page_manager_perm() {
  42    return array('use page manager', 'administer page manager');
  43  }
  44  
  45  /**
  46   * Implementation of hook_ctools_plugin_directory() to let the system know
  47   * where our task and task_handler plugins are.
  48   */
  49  function page_manager_ctools_plugin_directory($owner, $plugin_type) {
  50    if ($owner == 'page_manager') {
  51      return 'plugins/' . $plugin_type;
  52    }
  53  }
  54  
  55  /**
  56   * Delegated implementation of hook_menu().
  57   */
  58  function page_manager_menu() {
  59    // For some reason, some things can activate modules without satisfying
  60    // dependencies. I don't know how, but this helps prevent things from
  61    // whitescreening when this happens.
  62    if (!module_exists('ctools')) {
  63      return;
  64    }
  65  
  66    $items = array();
  67    $base = array(
  68      'access arguments' => array('use page manager'),
  69      'file' => 'page_manager.admin.inc',
  70    );
  71  
  72    $items['admin/build/pages'] = array(
  73      'title' => 'Pages',
  74      'description' => 'Add, edit and remove overridden system pages and user defined pages from the system.',
  75      'page callback' => 'page_manager_list_page',
  76    ) + $base;
  77  
  78    $items['admin/build/pages/list'] = array(
  79      'title' => 'List',
  80      'page callback' => 'page_manager_list_page',
  81      'type' => MENU_DEFAULT_LOCAL_TASK,
  82      'weight' => -10,
  83    ) + $base;
  84  
  85    $items['admin/build/pages/edit/%page_manager_cache'] = array(
  86      'title' => 'Edit',
  87      'page callback' => 'page_manager_edit_page',
  88      'page arguments' => array(4),
  89      'type' => MENU_CALLBACK,
  90    ) + $base;
  91  
  92    $items['admin/build/pages/%ctools_js/operation/%page_manager_cache'] = array(
  93      'page callback' => 'page_manager_edit_page_operation',
  94      'page arguments' => array(3, 5),
  95      'type' => MENU_CALLBACK,
  96    ) + $base;
  97  
  98    $items['admin/build/pages/%ctools_js/enable/%page_manager_cache'] = array(
  99      'page callback' => 'page_manager_enable_page',
 100      'page arguments' => array(FALSE, 3, 5),
 101      'type' => MENU_CALLBACK,
 102    ) + $base;
 103  
 104    $items['admin/build/pages/%ctools_js/disable/%page_manager_cache'] = array(
 105      'page callback' => 'page_manager_enable_page',
 106      'page arguments' => array(TRUE, 3, 5),
 107      'type' => MENU_CALLBACK,
 108    ) + $base;
 109  
 110    $tasks = page_manager_get_tasks();
 111  
 112    // Provide menu items for each task.
 113    foreach ($tasks as $task_id => $task) {
 114      $handlers = page_manager_get_task_handler_plugins($task);
 115      // Allow the task to add its own menu items.
 116      if ($function = ctools_plugin_get_function($task, 'hook menu')) {
 117        $function($items, $task);
 118      }
 119  
 120      // And for those that provide subtasks, provide menu items for them, as well.
 121      foreach (page_manager_get_task_subtasks($task) as $subtask_id => $subtask) {
 122        // Allow the task to add its own menu items.
 123        if ($function = ctools_plugin_get_function($task, 'hook menu')) {
 124          $function($items, $subtask);
 125        }
 126      }
 127    }
 128  
 129    return $items;
 130  }
 131  
 132  /**
 133   * Implementation of hook_menu_alter.
 134   *
 135   * Get a list of all tasks and delegate to them.
 136   */
 137  function page_manager_menu_alter(&$items) {
 138    // For some reason, some things can activate modules without satisfying
 139    // dependencies. I don't know how, but this helps prevent things from
 140    // whitescreening when this happens.
 141    if (!module_exists('ctools')) {
 142      return;
 143    }
 144  
 145    $tasks = page_manager_get_tasks();
 146  
 147    foreach ($tasks as $task) {
 148      if ($function = ctools_plugin_get_function($task, 'hook menu alter')) {
 149        $function($items, $task);
 150      }
 151      // let the subtasks alter the menu items too.
 152      foreach (page_manager_get_task_subtasks($task) as $subtask_id => $subtask) {
 153        if ($function = ctools_plugin_get_function($subtask, 'hook menu alter')) {
 154          $function($items, $subtask);
 155        }
 156      }
 157    }
 158  
 159    return $items;
 160  }
 161  
 162  /*
 163   * Implementation of hook_theme()
 164   */
 165  function page_manager_theme() {
 166    // For some reason, some things can activate modules without satisfying
 167    // dependencies. I don't know how, but this helps prevent things from
 168    // whitescreening when this happens.
 169    if (!module_exists('ctools')) {
 170      return;
 171    }
 172  
 173    $base = array(
 174      'path' => drupal_get_path('module', 'page_manager') . '/theme',
 175      'file' => 'page_manager.theme.inc',
 176    );
 177  
 178    $items = array(
 179      'page_manager_list_pages_form' => array(
 180        'arguments' => array('form' => NULL),
 181      ) + $base,
 182      'page_manager_handler_rearrange' => array(
 183        'arguments' => array('form' => NULL),
 184      ) + $base,
 185      'page_manager_edit_page' => array(
 186        'template' => 'page-manager-edit-page',
 187        'arguments' => array('page' => NULL, 'save' => NULL, 'operations' => array(), 'content' => array()),
 188      ) + $base,
 189      'page_manager_lock' => array(
 190        'arguments' => array('page' => array()),
 191      ) + $base,
 192      'page_manager_changed' => array(
 193        'arguments' => array('text' => NULL, 'description' => NULL),
 194      ) + $base,
 195    );
 196  
 197    // Allow task plugins to have theme registrations by passing through:
 198    $tasks = page_manager_get_tasks();
 199  
 200    // Provide menu items for each task.
 201    foreach ($tasks as $task_id => $task) {
 202      if ($function = ctools_plugin_get_function($task, 'hook theme')) {
 203        $function($items, $task);
 204      }
 205    }
 206  
 207    return $items;
 208  }
 209  
 210  // --------------------------------------------------------------------------
 211  // Page caching
 212  //
 213  // The page cache is used to store a page temporarily, using the ctools object
 214  // cache. When loading from the page cache, it will either load the cached
 215  // version, or if there is not one, load the real thing and create a cache
 216  // object which can then be easily stored.
 217  
 218  /**
 219   * Get the cached changes to a given task handler.
 220   */
 221  function page_manager_get_page_cache($task_name) {
 222    ctools_include('object-cache');
 223    $cache = ctools_object_cache_get('page_manager_page', $task_name);
 224    if (!$cache) {
 225      $cache = new stdClass();
 226      $cache->task_name = $task_name;
 227      list($cache->task_id, $cache->subtask_id) = page_manager_get_task_id($cache->task_name);
 228  
 229      $cache->task = page_manager_get_task($cache->task_id);
 230      if (empty($cache->task)) {
 231        return FALSE;
 232      }
 233  
 234      if ($cache->subtask_id) {
 235        $cache->subtask = page_manager_get_task_subtask($cache->task, $cache->subtask_id);
 236        if (empty($cache->subtask)) {
 237          return FALSE;
 238        }
 239      }
 240      else {
 241        $cache->subtask = $cache->task;
 242        $cache->subtask['name'] = '';
 243      }
 244  
 245      $cache->handlers = page_manager_load_sorted_handlers($cache->task, $cache->subtask_id);
 246      $cache->handler_info = array();
 247      foreach ($cache->handlers as $id => $handler) {
 248        $cache->handler_info[$id] = array(
 249          'weight' => $handler->weight,
 250          'changed' => FALSE,
 251          'name' => $id,
 252        );
 253      }
 254    }
 255    else {
 256      // ensure the task is loaded.
 257      page_manager_get_task($cache->task_id);
 258    }
 259  
 260    if ($task_name != '::new') {
 261      $cache->locked = ctools_object_cache_test('page_manager_page', $task_name);
 262    }
 263    else {
 264      $cache->locked = FALSE;
 265    }
 266  
 267    return $cache;
 268  }
 269  
 270  /**
 271   * Store changes to a task handler in the object cache.
 272   */
 273  function page_manager_set_page_cache($page) {
 274    if (!empty($page->locked)) {
 275      return;
 276    }
 277  
 278    if (empty($page->task_name)) {
 279      return;
 280    }
 281  
 282    ctools_include('object-cache');
 283    $page->changed = TRUE;
 284    $cache = ctools_object_cache_set('page_manager_page', $page->task_name, $page);
 285  }
 286  
 287  /**
 288   * Remove an item from the object cache.
 289   */
 290  function page_manager_clear_page_cache($name) {
 291    ctools_include('object-cache');
 292    ctools_object_cache_clear('page_manager_page', $name);
 293  }
 294  
 295  /**
 296   * Write all changes from the page cache and clear it out.
 297   */
 298  function page_manager_save_page_cache($cache) {
 299    // Save the subtask:
 300    if ($function = ctools_plugin_get_function($cache->task, 'save subtask callback')) {
 301      $function($cache->subtask, $cache);
 302    }
 303  
 304    // Iterate through handlers and save/delete/update as necessary.
 305    // Go through each of the task handlers, check to see if it needs updating,
 306    // and update it if so.
 307    foreach ($cache->handler_info as $id => $info) {
 308      $handler = &$cache->handlers[$id];
 309      // If it has been marked for deletion, delete it.
 310  
 311      if ($info['changed'] & PAGE_MANAGER_CHANGED_DELETED) {
 312        page_manager_delete_task_handler($handler);
 313      }
 314      // If it has been somehow edited (or added), write the cached version
 315      elseif ($info['changed'] & PAGE_MANAGER_CHANGED_CACHED) {
 316        // Make sure we get updated weight from the form for this.
 317        $handler->weight = $info['weight'];
 318        page_manager_save_task_handler($handler);
 319      }
 320      // Otherwise, check to see if it has moved and, if so, update the weight.
 321      elseif ($info['weight'] != $handler->weight) {
 322        // Theoretically we could only do this for in code objects, but since our
 323        // load mechanism checks for all, this is less database work.
 324        page_manager_update_task_handler_weight($handler, $info['weight']);
 325      }
 326  
 327      // Set enable/disabled status.
 328      if ($info['changed'] & PAGE_MANAGER_CHANGED_STATUS) {
 329        ctools_include('export');
 330        ctools_export_set_object_status($cache->handlers[$id], $info['disabled']);
 331      }
 332    }
 333  
 334    page_manager_clear_page_cache($cache->task_name);
 335  
 336    if (!empty($cache->path_changed) || !empty($cache->new)) {
 337      // Force a menu rebuild to make sure the menu entries are set.
 338      menu_rebuild();
 339    }
 340    cache_clear_all();
 341  }
 342  
 343  /**
 344   * Menu callback to load a page manager cache object for menu callbacks.
 345   */
 346  function page_manager_cache_load($task_name) {
 347    // load context plugin as there may be contexts cached here.
 348    ctools_include('context');
 349    return page_manager_get_page_cache($task_name);
 350  }
 351  
 352  /**
 353   * Generate a unique name for a task handler.
 354   *
 355   * Task handlers need to be named but they aren't allowed to set their own
 356   * names. Instead, they are named based upon their parent task and type.
 357   */
 358  function page_manager_handler_get_name($task_name, $handlers, $handler) {
 359    $base = str_replace('-', '_', $task_name);
 360    // Generate a unique name. Unlike most named objects, we don't let people choose
 361    // names for task handlers because they mostly don't make sense.
 362    $base .= '_' . $handler->handler;
 363  
 364    // Once we have a base, check to see if it is used. If it is, start counting up.
 365    $name = $base;
 366    $count = 1;
 367    // If taken
 368    while (isset($handlers[$name])) {
 369      $name = $base . '_' . ++$count;
 370    }
 371  
 372    return $name;
 373  }
 374  
 375  /**
 376   * Import a handler into a page.
 377   *
 378   * This is used by both import and clone, since clone just exports the
 379   * handler and immediately imports it.
 380   */
 381  function page_manager_handler_add_to_page(&$page, &$handler, $title = NULL) {
 382    $last = end($page->handler_info);
 383    $handler->weight = $last ? $last['weight'] + 1 : 0;
 384    $handler->task = $page->task_id;
 385    $handler->subtask = $page->subtask_id;
 386    $handler->export_type = EXPORT_IN_DATABASE;
 387    $handler->type = t('Normal');
 388  
 389    if ($title) {
 390      $handler->conf['title'] = $title;
 391    }
 392  
 393    $name = page_manager_handler_get_name($page->task_name, $page->handlers, $handler);
 394  
 395    $handler->name = $name;
 396  
 397    $page->handlers[$name] = $handler;
 398    $page->handler_info[$name] = array(
 399      'weight' => $handler->weight,
 400      'name' => $handler->name,
 401      'changed' => PAGE_MANAGER_CHANGED_CACHED,
 402    );
 403  }
 404  
 405  // --------------------------------------------------------------------------
 406  // Database routines
 407  //
 408  // This includes fetching plugins and plugin info as well as specialized
 409  // fetch methods to get groups of task handlers per task.
 410  
 411  /**
 412   * Load a single task handler by name.
 413   *
 414   * Handlers can come from multiple sources; either the database or by normal
 415   * export method, which is handled by the ctools library, but handlers can
 416   * also be bundled with task/subtask. We have to check there and perform
 417   * overrides as appropriate.
 418   *
 419   * Handlers bundled with the task are of a higher priority than default
 420   * handlers provided by normal code, and are of a lower priority than
 421   * the database, so we have to check the source of handlers when we have
 422   * multiple to choose from.
 423   */
 424  function page_manager_load_task_handler($task, $subtask_id, $name) {
 425    ctools_include('export');
 426    $result = ctools_export_load_object('page_manager_handlers', 'names', array($name));
 427    $handlers = page_manager_get_default_task_handlers($task, $subtask_id);
 428    return page_manager_compare_task_handlers($result, $handlers, $name);
 429  }
 430  
 431  /**
 432   * Load all task handlers for a given task/subtask.
 433   */
 434  function page_manager_load_task_handlers($task, $subtask_id = NULL, $default_handlers = NULL) {
 435    ctools_include('export');
 436    $conditions = array(
 437      'task' => $task['name'],
 438    );
 439  
 440    if (isset($subtask_id)) {
 441      $conditions['subtask'] = $subtask_id;
 442    }
 443  
 444    $handlers = ctools_export_load_object('page_manager_handlers', 'conditions', $conditions);
 445    $defaults = isset($default_handlers) ? $default_handlers : page_manager_get_default_task_handlers($task, $subtask_id);
 446    foreach ($defaults as $name => $default) {
 447      $result = page_manager_compare_task_handlers($handlers, $defaults, $name);
 448  
 449      if ($result) {
 450        $handlers[$name] = $result;
 451        // Ensure task and subtask are correct, because it's easy to change task
 452        // names when editing a default and fail to do it on the associated handlers.
 453        $result->task = $task['name'];
 454        $result->subtask = $subtask_id;
 455      }
 456    }
 457  
 458    // Override weights from the weight table.
 459    if ($handlers) {
 460      $names = array();
 461      $placeholders = array();
 462      foreach ($handlers as $handler) {
 463        $names[] = $handler->name;
 464        $placeholders[] = "'%s'";
 465      }
 466  
 467      $result = db_query("SELECT name, weight FROM {page_manager_weights} WHERE name IN (" . implode(', ', $placeholders) . ")", $names);
 468      while ($weight = db_fetch_object($result)) {
 469        $handlers[$weight->name]->weight = $weight->weight;
 470      }
 471    }
 472  
 473    return $handlers;
 474  }
 475  
 476  /**
 477   * Get the default task handlers from a task, if they exist.
 478   *
 479   * Tasks can contain 'default' task handlers which are provided by the
 480   * default task. Because these can come from either the task or the
 481   * subtask, the logic is abstracted to reduce code duplication.
 482   */
 483  function page_manager_get_default_task_handlers($task, $subtask_id) {
 484    // Load default handlers that are provied by the task/subtask itself.
 485    $handlers = array();
 486    if ($subtask_id) {
 487      $subtask = page_manager_get_task_subtask($task, $subtask_id);
 488      if (isset($subtask['default handlers'])) {
 489        $handlers = $subtask['default handlers'];
 490      }
 491    }
 492    else if (isset($task['default handlers'])) {
 493      $handlers = $task['default handlers'];
 494    }
 495  
 496    return $handlers;
 497  }
 498  
 499  /**
 500   * Compare a single task handler from two lists and provide the correct one.
 501   *
 502   * Task handlers can be gotten from multiple sources. As exportable objects,
 503   * they can be provided by default hooks and the database. But also, because
 504   * they are tightly bound to tasks, they can also be provided by default
 505   * tasks. This function reconciles where to pick up a task handler between
 506   * the exportables list and the defaults provided by the task itself.
 507   *
 508   * @param $result
 509   *   A list of handlers provided by export.inc
 510   * @param $handlers
 511   *   A list of handlers provided by the default task.
 512   * @param $name
 513   *   Which handler to compare.
 514   * @return
 515   *   Which handler to use, if any. May be NULL.
 516   */
 517  function page_manager_compare_task_handlers($result, $handlers, $name) {
 518    // Compare our special default handler against the actual result, if
 519    // any, and do the right thing.
 520    if (!isset($result[$name]) && isset($handlers[$name])) {
 521      $handlers[$name]->type = t('Default');
 522      $handlers[$name]->export_type = EXPORT_IN_CODE;
 523      return $handlers[$name];
 524    }
 525    else if (isset($result[$name]) && !isset($handlers[$name])) {
 526      return $result[$name];
 527    }
 528    else if (isset($result[$name]) && isset($handlers[$name])) {
 529      if ($result[$name]->export_type & EXPORT_IN_DATABASE) {
 530        $result[$name]->type = t('Overridden');
 531        $result[$name]->export_type = $result[$name]->export_type | EXPORT_IN_CODE;
 532        return $result[$name];
 533      }
 534      else {
 535        // In this case, our default is a higher priority than the standard default.
 536        $handlers[$name]->type = t('Default');
 537        $handlers[$name]->export_type = EXPORT_IN_CODE;
 538        return $handlers[$name];
 539      }
 540    }
 541  }
 542  
 543  /**
 544   * Load all task handlers for a given task and subtask and sort them.
 545   */
 546  function page_manager_load_sorted_handlers($task, $subtask_id = NULL, $enabled = FALSE) {
 547    $handlers = page_manager_load_task_handlers($task, $subtask_id);
 548    if ($enabled) {
 549      foreach ($handlers as $id => $handler) {
 550        if (!empty($handler->disabled)) {
 551          unset($handlers[$id]);
 552        }
 553      }
 554    }
 555    uasort($handlers, 'page_manager_sort_task_handlers');
 556    return $handlers;
 557  }
 558  
 559  /**
 560   * Callback for uasort to sort task handlers.
 561   *
 562   * Task handlers are sorted by weight then by name.
 563   */
 564  function page_manager_sort_task_handlers($a, $b) {
 565    if ($a->weight < $b->weight) {
 566      return -1;
 567    }
 568    elseif ($a->weight > $b->weight) {
 569      return 1;
 570    }
 571    elseif ($a->name < $b->name) {
 572      return -1;
 573    }
 574    elseif ($a->name > $b->name) {
 575      return 1;
 576    }
 577  
 578    return 0;
 579  }
 580  
 581  /**
 582   * Write a task handler to the database.
 583   */
 584  function page_manager_save_task_handler(&$handler) {
 585    $update = (isset($handler->did)) ? array('did') : array();
 586    // Let the task handler respond to saves:
 587    if ($function = ctools_plugin_load_function('page_manager', 'task_handlers', $handler->handler, 'save')) {
 588      $function($handler, $update);
 589    }
 590  
 591    drupal_write_record('page_manager_handlers', $handler, $update);
 592    db_query("DELETE FROM {page_manager_weights} WHERE name = '%s'", $handler->name);
 593  
 594    // If this was previously a default handler, we may have to write task handlers.
 595    if (!$update) {
 596      // @todo wtf was I going to do here?
 597    }
 598    return $handler;
 599  }
 600  
 601  /**
 602   * Remove a task handler.
 603   */
 604  function page_manager_delete_task_handler($handler) {
 605    // Let the task handler respond to saves:
 606    if ($function = ctools_plugin_load_function('page_manager', 'task_handlers', $handler->handler, 'delete')) {
 607      $function($handler);
 608    }
 609    db_query("DELETE FROM {page_manager_handlers} WHERE name = '%s'", $handler->name);
 610    db_query("DELETE FROM {page_manager_weights} WHERE name = '%s'", $handler->name);
 611  }
 612  
 613  /**
 614   * Export a task handler into code suitable for import or use as a default
 615   * task handler.
 616   */
 617  function page_manager_export_task_handler($handler, $indent = '') {
 618    ctools_include('export');
 619    ctools_include('plugins');
 620    $handler = drupal_clone($handler);
 621  
 622    $append = '';
 623    if ($function = ctools_plugin_load_function('page_manager', 'task_handlers', $handler->handler, 'export')) {
 624      $append = $function($handler, $indent);
 625    }
 626  
 627    $output = ctools_export_object('page_manager_handlers', $handler, $indent);
 628    $output .= $append;
 629  
 630    return $output;
 631  }
 632  
 633  /**
 634   * Create a new task handler object.
 635   *
 636   * @param $plugin
 637   *   The plugin this task handler is created from.
 638   */
 639  function page_manager_new_task_handler($plugin) {
 640    // Generate a unique name. Unlike most named objects, we don't let people choose
 641    // names for task handlers because they mostly don't make sense.
 642  
 643    // Create a new, empty handler object.
 644    $handler          = new stdClass;
 645    $handler->title   = $plugin['title'];
 646    $handler->task    = NULL;
 647    $handler->subtask = NULL;
 648    $handler->name    = NULL;
 649    $handler->handler = $plugin['name'];
 650    $handler->weight  = 0;
 651    $handler->conf    = array();
 652  
 653    // These are provided by the core export API provided by ctools and we
 654    // set defaults here so that we don't cause notices. Perhaps ctools should
 655    // provide a way to do this for us so we don't have to muck with it.
 656    $handler->export_type = EXPORT_IN_DATABASE;
 657    $handler->type = t('Local');
 658  
 659    if (isset($plugin['default conf'])) {
 660      if (is_array($plugin['default conf'])) {
 661        $handler->conf = $plugin['default conf'];
 662      }
 663      else if (function_exists($plugin['default conf'])) {
 664        $handler->conf = $plugin['default conf']($handler);
 665      }
 666    }
 667  
 668    return $handler;
 669  }
 670  
 671  /**
 672   * Set an overidden weight for a task handler.
 673   *
 674   * We do this so that in-code task handlers don't need to get written
 675   * to the database just because they have their weight changed.
 676   */
 677  function page_manager_update_task_handler_weight($handler, $weight) {
 678    db_query("DELETE FROM {page_manager_weights} WHERE name = '%s'", $handler->name);
 679    db_query("INSERT INTO {page_manager_weights} (name, weight) VALUES ('%s', %d)", $handler->name, $weight);
 680  }
 681  
 682  
 683  /**
 684   * Shortcut function to get task plugins.
 685   */
 686  function page_manager_get_tasks() {
 687    ctools_include('plugins');
 688    return ctools_get_plugins('page_manager', 'tasks');
 689  }
 690  
 691  /**
 692   * Shortcut function to get a task plugin.
 693   */
 694  function page_manager_get_task($id) {
 695    ctools_include('plugins');
 696    return ctools_get_plugins('page_manager', 'tasks', $id);
 697  }
 698  
 699  /**
 700   * Get all tasks for a given type.
 701   */
 702  function page_manager_get_tasks_by_type($type) {
 703    ctools_include('plugins');
 704    $all_tasks = ctools_get_plugins('page_manager', 'tasks');
 705    $tasks = array();
 706    foreach ($all_tasks as $id => $task) {
 707      if (isset($task['task type']) && $task['task type'] == $type) {
 708        $tasks[$id] = $task;
 709      }
 710    }
 711  
 712    return $tasks;
 713  }
 714  
 715  /**
 716   * Fetch all subtasks for a page managertask.
 717   *
 718   * @param $task
 719   *   A loaded $task plugin object.
 720   */
 721  function page_manager_get_task_subtasks($task) {
 722    if (empty($task['subtasks'])) {
 723      return array();
 724    }
 725  
 726    if ($function = ctools_plugin_get_function($task, 'subtasks callback')) {
 727      return $function($task);
 728    }
 729  
 730    return array();
 731  }
 732  
 733  /**
 734   * Fetch all subtasks for a page managertask.
 735   *
 736   * @param $task
 737   *   A loaded $task plugin object.
 738   * @param $subtask_id
 739   *   The subtask ID to load.
 740   */
 741  function page_manager_get_task_subtask($task, $subtask_id) {
 742    if (empty($task['subtasks'])) {
 743      return;
 744    }
 745  
 746    if ($function = ctools_plugin_get_function($task, 'subtask callback')) {
 747      return $function($task, $subtask_id);
 748    }
 749  }
 750  
 751  /**
 752   * Shortcut function to get task handler plugins.
 753   */
 754  function page_manager_get_task_handlers() {
 755    ctools_include('plugins');
 756    return ctools_get_plugins('page_manager', 'task_handlers');
 757  }
 758  
 759  /**
 760   * Shortcut function to get a task handler plugin.
 761   */
 762  function page_manager_get_task_handler($id) {
 763    ctools_include('plugins');
 764    return ctools_get_plugins('page_manager', 'task_handlers', $id);
 765  }
 766  
 767  /**
 768   * Retrieve a list of all applicable task handlers for a given task.
 769   *
 770   * This looks at the $task['handler type'] and compares that to $task_handler['handler type'].
 771   * If the task has no type, the id of the task is used instead.
 772   */
 773  function page_manager_get_task_handler_plugins($task, $all = FALSE) {
 774    $type = isset($task['handler type']) ? $task['handler type'] : $task['name'];
 775    $name = $task['name'];
 776  
 777    $handlers = array();
 778    $task_handlers = page_manager_get_task_handlers();
 779    foreach ($task_handlers as $id => $handler) {
 780      $task_type = is_array($handler['handler type']) ? $handler['handler type'] : array($handler['handler type']);
 781      if (in_array($type, $task_type) || in_array($name, $task_type)) {
 782        if ($all || !empty($handler['visible'])) {
 783          $handlers[$id] = $handler;
 784        }
 785      }
 786    }
 787  
 788    return $handlers;
 789  }
 790  
 791  /**
 792   * Get the title for a given handler.
 793   *
 794   * If the plugin has no 'admin title' function, the generic title of the
 795   * plugin is used instead.
 796   */
 797  function page_manager_get_handler_title($plugin, $handler, $task, $subtask_id) {
 798    $function = ctools_plugin_get_function($plugin, 'admin title');
 799    if ($function) {
 800      return $function($handler, $task, $subtask_id);
 801    }
 802    else {
 803      return $plugin['title'];
 804    }
 805  }
 806  
 807  /**
 808   * Get the admin summary (additional info) for a given handler.
 809   */
 810  function page_manager_get_handler_summary($plugin, $handler, $page, $title = TRUE) {
 811    if ($function = ctools_plugin_get_function($plugin, 'admin summary')) {
 812      return $function($handler, $page->task, $page->subtask, $page, $title);
 813    }
 814  }
 815  
 816  /**
 817   * Get the admin summary (additional info) for a given page.
 818   */
 819  function page_manager_get_page_summary($task, $subtask) {
 820    if ($function = ctools_plugin_get_function($subtask, 'admin summary')) {
 821      return $function($task, $subtask);
 822    }
 823  }
 824  
 825  /**
 826   * Split a task name into a task id and subtask id, if applicable.
 827   */
 828  function page_manager_get_task_id($task_name) {
 829    if (strpos($task_name, '-') !== FALSE) {
 830      return explode('-', $task_name, 2);
 831    }
 832    else {
 833      return array($task_name, NULL);
 834    }
 835  }
 836  
 837  /**
 838   * Turn a task id + subtask_id into a task name.
 839   */
 840  function page_manager_make_task_name($task_id, $subtask_id) {
 841    if ($subtask_id) {
 842      return $task_id . '-' . $subtask_id;
 843    }
 844    else {
 845      return $task_id;
 846    }
 847  }
 848  
 849  /**
 850   * Get the render function for a handler.
 851   */
 852  function page_manager_get_renderer($handler) {
 853    return ctools_plugin_load_function('page_manager', 'task_handlers', $handler->handler, 'render');
 854  }
 855  
 856  // --------------------------------------------------------------------------
 857  // Functions existing on behalf of tasks and task handlers
 858  
 859  
 860  /**
 861   * Page manager arg load function because menu system will not load extra
 862   * files for these; they must be in a .module.
 863   */
 864  function pm_arg_load($value, $subtask, $argument) {
 865    page_manager_get_task('page');
 866    return _pm_arg_load($value, $subtask, $argument);
 867  }
 868  
 869  /**
 870   * Special arg_load function to use %menu_tail like functionality to
 871   * get everything after the arg together as a single value.
 872   */
 873  function pm_arg_tail_load($value, $subtask, $argument, $map) {
 874    $value = implode('/', array_slice($map, $argument));
 875    page_manager_get_task('page');
 876    return _pm_arg_load($value, $subtask, $argument);
 877  }
 878  
 879  /**
 880   * Special menu _load() function for the user:uid argument.
 881   *
 882   * This is just the normal page manager argument. It only exists so that
 883   * the to_arg can exist.
 884   */
 885  function pm_uid_arg_load($value, $subtask, $argument) {
 886    page_manager_get_task('page');
 887    return _pm_arg_load($value, $subtask, $argument);
 888  }
 889  
 890  /**
 891   * to_arg function for the user:uid argument to provide the arg for the
 892   * current global user.
 893   */
 894  function pm_uid_arg_to_arg($arg) {
 895    return user_uid_optional_to_arg($arg);
 896  }
 897  
 898  /**
 899   * Callback for access control ajax form on behalf of page.inc task.
 900   *
 901   * Returns the cached access config and contexts used.
 902   */
 903  function page_manager_page_ctools_access_get($argument) {
 904    $page = page_manager_get_page_cache($argument);
 905  
 906    $contexts = array();
 907  
 908    // Load contexts based on argument data:
 909    if ($arguments = _page_manager_page_get_arguments($page->subtask['subtask'])) {
 910      $contexts = ctools_context_get_placeholders_from_argument($arguments);
 911    }
 912  
 913    return array($page->subtask['subtask']->access, $contexts);
 914  }
 915  
 916  /**
 917   * Callback for access control ajax form on behalf of page.inc task.
 918   *
 919   * Writes the changed access to the cache.
 920   */
 921  function page_manager_page_ctools_access_set($argument, $access) {
 922    $page = page_manager_get_page_cache($argument);
 923    $page->subtask['subtask']->access = $access;
 924    page_manager_set_page_cache($page);
 925  }
 926  
 927  /**
 928   * Callback for access control ajax form on behalf of context task handler.
 929   *
 930   * Returns the cached access config and contexts used.
 931   */
 932  function page_manager_task_handler_ctools_access_get($argument) {
 933    list($task_name, $name) = explode('*', $argument);
 934    $page = page_manager_get_page_cache($task_name);
 935    if (empty($name)) {
 936      $handler = &$page->new_handler;
 937    }
 938    else {
 939      $handler = &$page->handlers[$name];
 940    }
 941  
 942    if (!isset($handler->conf['access'])) {
 943      $handler->conf['access'] = array();
 944    }
 945  
 946    ctools_include('context-task-handler');
 947  
 948    $contexts = ctools_context_handler_get_all_contexts($page->task, $page->subtask, $handler);
 949  
 950    return array($handler->conf['access'], $contexts);
 951  }
 952  
 953  function page_manager_context_cache_get($task_name, $key) {
 954    $page = page_manager_get_page_cache($task_name);
 955    if ($page) {
 956      if (!empty($page->context_cache[$key])) {
 957        return $page->context_cache[$key];
 958      }
 959      else {
 960        ctools_include('context-task-handler');
 961        if ($key == 'temp') {
 962          $handler = $page->new_handler;
 963        }
 964        else {
 965          $handler = $page->handlers[$key];
 966        }
 967        return ctools_context_handler_get_task_object($page->task, $page->subtask, $handler);
 968      }
 969    }
 970  }
 971  
 972  function page_manager_context_cache_set($task_name, $key, $object) {
 973    $page = page_manager_get_page_cache($task_name);
 974    if ($page) {
 975      $page->context_cache[$key] = $object;
 976      page_manager_set_page_cache($page);
 977    }
 978  }
 979  
 980  /**
 981   * Callback for access control ajax form on behalf of context task handler.
 982   *
 983   * Writes the changed access to the cache.
 984   */
 985  function page_manager_task_handler_ctools_access_set($argument, $access) {
 986    list($task_name, $name) = explode('*', $argument);
 987    $page = page_manager_get_page_cache($task_name);
 988    if (empty($name)) {
 989      $handler = &$page->new_handler;
 990    }
 991    else {
 992      $handler = &$page->handlers[$name];
 993    }
 994  
 995    $handler->conf['access'] = $access;
 996    page_manager_set_page_cache($page);
 997  }
 998  
 999  /**
1000   * Form a URL to edit a given page given the trail.
1001   */
1002  function page_manager_edit_url($task_name, $trail = array()) {
1003    if (!is_array($trail)) {
1004      $trail = array($trail);
1005    }
1006  
1007    if (empty($trail) || $trail == array('summary')) {
1008      return "admin/build/pages/edit/$task_name";
1009    }
1010  
1011    return 'admin/build/pages/nojs/operation/' . $task_name . '/' . implode('/', $trail);
1012  }
1013  
1014  /**
1015   * Watch menu links during the menu rebuild, and re-parent things if we need to.
1016   */
1017  function page_manager_menu_link_alter(&$item, $menu) {
1018    return;
1019  /** -- disabled, concept code --
1020    static $mlids = array();
1021    // Keep an array of mlids as links are saved that we can use later.
1022    if (isset($item['mlid'])) {
1023      $mlids[$item['path']] = $item['mlid'];
1024    }
1025  
1026    if (isset($item['parent_path'])) {
1027      if (isset($mlids[$item['parent_path']])) {
1028        $item['plid'] = $mlids[$item['parent_path']];
1029      }
1030      else {
1031        // Since we didn't already see an mlid, let's check the database for one.
1032        $mlid = db_result(db_query("SELECT mlid FROM {menu_links} WHERE router_path = '%s'", $item['parent_path']));
1033        if ($mlid) {
1034          $item['plid'] = $mlid;
1035        }
1036      }
1037    }
1038   */
1039  }
1040  
1041  /**
1042   * Callback to list handlers available for export.
1043   */
1044  function page_manager_page_manager_handlers_list() {
1045    $list = $types = array();
1046    $tasks = page_manager_get_tasks();
1047    foreach ($tasks as $type => $info) {
1048      if (empty($info['non-exportable'])) {
1049        $types[] = $type;
1050      }
1051    }
1052  
1053    $handlers = ctools_export_load_object('page_manager_handlers');
1054    foreach ($handlers as $handler) {
1055      if (in_array($handler->task, $types)) {
1056        $list[$handler->name] = check_plain("$handler->task: " . $handler->conf['title'] . " ($handler->name)");
1057      }
1058    }
1059    return $list;
1060  }
1061  
1062  /**
1063   * Callback to bulk export page manager pages.
1064   */
1065  function page_manager_page_manager_pages_to_hook_code($names = array(), $name = 'foo') {
1066    $schema = ctools_export_get_schema('page_manager_pages');
1067    $export = $schema['export'];
1068    $objects = ctools_export_load_object('page_manager_pages', 'names', array_values($names));
1069    if ($objects) {
1070      $code = "/**\n";
1071      $code .= " * Implementation of hook_{$export['default hook']}()\n";
1072      $code .= " */\n";
1073      $code .= "function " . $name . "_{$export['default hook']}() {\n";
1074      foreach ($objects as $object) {
1075        // Have to implement our own because this export func sig requires it
1076        $code .= $export['export callback']($object, TRUE, '  ');
1077        $code .= "  \${$export['identifier']}s['" . check_plain($object->$export['key']) . "'] = \${$export['identifier']};\n\n";
1078      }
1079      $code .= " return \${$export['identifier']}s;\n";
1080      $code .= "}\n";
1081      return $code;
1082    }
1083  }
1084  
1085  /**
1086   * Get the current page information.
1087   *
1088   * @return $page
1089   *   An array containing the following information.
1090   *
1091   * - 'name': The name of the page as used in the page manager admin UI.
1092   * - 'task': The plugin for the task in use. If this is a system page it
1093   *   will contain information about that page, such as what functions
1094   *   it uses.
1095   * - 'subtask': The plugin for the subtask. If this is a custom page, this
1096   *   will contain information about that custom page. See 'subtask' in this
1097   *   array to get the actual page object.
1098   * - 'handler': The actual handler object used. If using panels, see
1099   *   $page['handler']->conf['display'] for the actual panels display
1100   *   used to render.
1101   * - 'contexts': The context objects used to render this page.
1102   * - 'arguments': The raw arguments from the URL used on this page.
1103   */
1104  function page_manager_get_current_page($page = NULL) {
1105    static $current = array();
1106    if (isset($page)) {
1107      $current = $page;
1108    }
1109  
1110    return $current;
1111  }
1112  
1113  /**
1114   * Implementation of hook_panels_dashboard_blocks().
1115   *
1116   * Adds page information to the Panels dashboard.
1117   */
1118  function page_manager_panels_dashboard_blocks(&$vars) {
1119    $vars['links']['page_manager'] = array(
1120      'weight' => -100,
1121      'title' => l(t('Panel page'), 'admin/build/pages/add'),
1122      'description' => t('Panel pages can be used as landing pages. They have a URL path, accept arguments and can have menu entries.'),
1123    );
1124  
1125    module_load_include('inc', 'page_manager', 'page_manager.admin');
1126    $tasks = page_manager_get_tasks_by_type('page');
1127    $pages = array('operations' => array());
1128  
1129    page_manager_get_pages($tasks, $pages);
1130    $count = 0;
1131    $rows = array();
1132    foreach ($pages['rows'] as $id => $info) {
1133      $rows[] = array(
1134        'data' => array(
1135          $info['data']['title'],
1136          $info['data']['operations'],
1137        ),
1138        'class' => $info['class'],
1139      );
1140  
1141      // Only show 10.
1142      if (++$count >= 10) {
1143        break;
1144      }
1145    }
1146  
1147    $vars['blocks']['page_manager'] = array(
1148      'weight' => -100,
1149      'title' => t('Manage pages'),
1150      'link' => l(t('Go to list'), 'admin/build/pages'),
1151      'content' => theme('table', array(), $rows, array('class' => 'panels-manage')),
1152      'class' => 'dashboard-pages',
1153      'section' => 'right',
1154    );
1155  }
1156  


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7