Newer
Older
Earl Miles
committed
<?php
Earl Miles
committed
/**
* @file
*
* The delegator handles two plugins and provides a UI to link them together.
* The 'task' plugin defines a particular task, and it provides menu access
* to those tasks so that they can respond to page requests.
*
* 'task_handlers' are then chosen to handle these tasks, arranged in
* order of priority in the UI. Task handlers can choose whether or
* not to handle a task. The first one that does handles it.
*
* This system was initially designed to provide a nice way to override
* existing menu items and provide alternate paths based on the data,
* particularly for node views, but tasks are not limited to this
* kind of task. The UI is modular and can be embedded within another
* module's UI to allow specific tasks to have chosen handlers.
*/
/**
* Implementation of hook_perm().
*/
function delegator_perm() {
return array('administer delegator');
}
/**
* Implementation of hook_theme().
*/
Earl Miles
committed
function delegator_theme() {
Earl Miles
committed
$items = array(
Earl Miles
committed
'delegator_admin_list_form' => array(
'arguments' => array('form' => NULL),
'file' => 'delegator.admin.inc',
),
'delegator_admin_lock' => array(
'arguments' => array('lock' => array(), 'task_name' => NULL),
'file' => 'delegator.admin.inc',
),
'delegator_admin_changed' => array(
'arguments' => array(),
'file' => 'delegator.admin.inc',
),
Earl Miles
committed
);
Earl Miles
committed
// Allow task plugins to have theme registrations by passing through:
$tasks = delegator_get_tasks();
// Provide menu items for each task.
foreach ($tasks as $task_id => $task) {
if ($function = ctools_plugin_get_function($task, 'hook theme')) {
$function($items, $task);
}
}
return $items;
Earl Miles
committed
}
/**
* Implementation of hook_ctools_plugin_dierctory() to let the system know
* we implement task and task_handler plugins.
*/
function delegator_ctools_plugin_directory($module, $plugin) {
if ($module == 'delegator') {
return 'plugins/' . $plugin;
}
}
Earl Miles
committed
/**
* Implementation of hook_menu.
*
* Get a list of all tasks and delegate to them.
*/
function delegator_menu() {
$items = array();
// Task types get menu entries so they can set up their own administrative
// areas.
$task_types = delegator_get_task_types();
foreach ($task_types as $id => $task_type) {
if ($function = ctools_plugin_get_function($task_type, 'hook menu')) {
$function($items, $task_type);
}
}
Earl Miles
committed
$tasks = delegator_get_tasks();
// Provide menu items for each task.
foreach ($tasks as $task_id => $task) {
Earl Miles
committed
$handlers = delegator_get_task_handler_plugins($task);
delegator_menu_task_items($items, $task_id, $task, $handlers);
// And for those that provide subtasks, provide menu items for them, as well.
foreach (delegator_get_task_subtasks($task) as $subtask_id => $subtask) {
delegator_menu_task_items($items, $task_id, $subtask, $handlers, $subtask_id);
Earl Miles
committed
}
}
return $items;
}
/**
* Implementation of hook_menu_alter.
*
* Get a list of all tasks and delegate to them.
*/
function delegator_menu_alter(&$items) {
$tasks = delegator_get_tasks();
foreach ($tasks as $task) {
if ($function = ctools_plugin_get_function($task, 'hook menu alter')) {
Earl Miles
committed
$function($items, $task);
Earl Miles
committed
}
// let the subtasks alter the menu items too.
foreach (delegator_get_task_subtasks($task) as $subtask_id => $subtask) {
if ($function = ctools_plugin_get_function($subtask, 'hook menu alter')) {
$function($items, $subtask);
}
}
Earl Miles
committed
}
return $items;
}
/**
* Generate a menu item for a given task and subtask combination.
*/
function delegator_menu_task_items(&$items, $task_id, $task, $handlers, $subtask_id = NULL) {
// If using a subtask, attach the subtask id to the name we use.
$task_name = $task_id . ($subtask_id ? '-' . $subtask_id : '');
// Allow the task to add its own menu items.
if ($function = ctools_plugin_get_function($task, 'hook menu')) {
$function($items, $task);
}
// Set up access permissions.
$access_callback = isset($task['admin access callback']) ? $task['admin access callback'] : 'user_access';
$access_arguments = isset($task['admin access arguments']) ? $task['admin access arguments'] : array('administer delegator');
$base = array(
'access callback' => $access_callback,
'access arguments' => $access_arguments,
'file' => 'delegator.admin.inc',
);
if (isset($task['admin title'])) {
$items['admin/build/delegator/' . $task_name] = array(
'title' => $task['admin title'],
Earl Miles
committed
'description' => isset($task['admin description']) ? $task['admin description'] : '',
'page callback' => 'delegator_administer_task',
'page arguments' => array($task_name),
) + $base;
}
// Form to add new items to this task.
$items['admin/build/delegator/' . $task_name . '/add/%/%'] = array(
'page callback' => 'delegator_administer_task_handler_add',
'page arguments' => array($task_name, 5, 6),
) + $base;
// Form to add export a handler
$items['admin/build/delegator/' . $task_name . '/export/%'] = array(
'page callback' => 'delegator_administer_task_handler_export',
'page arguments' => array($task_name, 5),
) + $base;
// Form to break a lock on this task.
$items['admin/build/delegator/' . $task_name . '/break-lock'] = array(
'title' => 'Break lock',
'page callback' => 'drupal_get_form',
'page arguments' => array('delegator_administer_break_lock', $task_name),
'type' => MENU_CALLBACK,
) + $base;
// Form to import a task handler for this task.
$items['admin/build/delegator/' . $task_name . '/import'] = array(
'title' => 'Import',
'page callback' => 'drupal_get_form',
'page arguments' => array('delegator_admin_import_task_handler', $task_name),
'type' => MENU_CALLBACK,
) + $base;
foreach ($handlers as $handler_id => $handler) {
if (isset($handler['edit forms'])) {
$weight = 0;
Earl Miles
committed
$default_task = FALSE;
foreach ($handler['edit forms'] as $form_id => $form_title) {
if (!$default_task) {
$default_task = TRUE;
Earl Miles
committed
// The first edit form is the default for tabs, so it gets a bit
// of special treatment here. It gets the parent menu declaration
// which is just a callback, and it gets its main entry declared
// as the default local task.
$items["admin/build/delegator/$task_name/$handler_id/%"] = array(
'title' => t('Edit'),
'page callback' => 'delegator_administer_task_handler_edit',
'page arguments' => array($task_name, $handler_id, 5, $form_id),
Earl Miles
committed
'type' => MENU_CALLBACK,
Earl Miles
committed
$type = MENU_DEFAULT_LOCAL_TASK;
Earl Miles
committed
$type = $form_title ? MENU_LOCAL_TASK : MENU_CALLBACK;
Earl Miles
committed
// Handler to edit delegator task handlers. May exist in its own UI.
$items["admin/build/delegator/$task_name/$handler_id/%/$form_id"] = array(
'title' => $form_title,
'page callback' => 'delegator_administer_task_handler_edit',
'page arguments' => array($task_name, $handler_id, 5, $form_id),
// This allows an empty form title to provide a hidden form
// which is useful for doing more branch-like multi-step
// functionality.
'type' => $type,
'weight' => $weight++,
) + $base;
Earl Miles
committed
// --------------------------------------------------------------------------
// Database routines
/**
* Load a single task handler by name.
*
* Handlers can come from multiple sources; either the database or by normal
* export method, which is handled by the ctools library, but handlers can
* also be bundled with task/subtask. We have to check there and perform
* overrides as appropriate.
*
* Handlers bundled with the task are of a higher priority than default
* handlers provided by normal code, and are of a lower priority than
* the database, so we have to check the source of handlers when we have
* multiple to choose from.
Earl Miles
committed
*/
function delegator_load_task_handler($task, $subtask_id, $name) {
Earl Miles
committed
ctools_include('export');
$result = ctools_export_load_object('delegator_handlers', 'names', array($name));
$handlers = delegator_get_default_task_handlers($task, $subtask_id);
return delegator_compare_task_handlers($result, $handlers, $name);
Earl Miles
committed
}
/**
* Load all task handlers for a given task/subtask.
*/
function delegator_load_task_handlers($task, $subtask_id = NULL, $default_handlers = NULL) {
Earl Miles
committed
ctools_include('export');
$conditions = array(
'task' => $task['name'],
);
Earl Miles
committed
if (isset($subtask_id)) {
$conditions['subtask'] = $subtask_id;
}
$handlers = ctools_export_load_object('delegator_handlers', 'conditions', $conditions);
$defaults = isset($default_handlers) ? $default_handlers : delegator_get_default_task_handlers($task, $subtask_id);
foreach ($defaults as $name => $default) {
$result = delegator_compare_task_handlers($handlers, $defaults, $name);
if ($result) {
$handlers[$name] = $result;
// Ensure task and subtask are correct, because it's easy to change task
// names when editing a default and fail to do it on the associated handlers.
$result->task = $task['name'];
$result->subtask = $subtask_id;
}
}
// Override weights from the weight table.
if ($handlers) {
$names = array();
$placeholders = array();
foreach ($handlers as $handler) {
$names[] = $handler->name;
$placeholders[] = "'%s'";
}
$result = db_query("SELECT name, weight FROM {delegator_weights} WHERE name IN (" . implode(', ', $placeholders) . ")", $names);
while ($weight = db_fetch_object($result)) {
$handlers[$weight->name]->weight = $weight->weight;
}
}
return $handlers;
Earl Miles
committed
}
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
/**
* Get the default task handlers from a task, if they exist.
*
* Tasks can contain 'default' task handlers which are provided by the
* default task. Because these can come from either the task or the
* subtask, the logic is abstracted to reduce code duplication.
*/
function delegator_get_default_task_handlers($task, $subtask_id) {
// Load default handlers that are provied by the task/subtask itself.
$handlers = array();
if ($subtask_id) {
$subtask = delegator_get_task_subtask($task, $subtask_id);
if (isset($subtask['default handlers'])) {
$handlers = $subtask['default handlers'];
}
}
else if (isset($task['default handlers'])) {
$handlers = $task['default handlers'];
}
return $handlers;
}
/**
* Compare a single task handler from two lists and provide the correct one.
*
* Task handlers can be gotten from multiple sources. As exportable objects,
* they can be provided by default hooks and the database. But also, because
* they are tightly bound to tasks, they can also be provided by default
* tasks. This function reconciles where to pick up a task handler between
* the exportables list and the defaults provided by the task itself.
*
* @param $result
* A list of handlers provided by export.inc
* @param $handlers
* A list of handlers provided by the default task.
* @param $name
* Which handler to compare.
* @return
* Which handler to use, if any. May be NULL.
*/
function delegator_compare_task_handlers($result, $handlers, $name) {
// Compare our special default handler against the actual result, if
// any, and do the right thing.
if (!isset($result[$name]) && isset($handlers[$name])) {
$handlers[$name]->type = t('Default');
$handlers[$name]->export_type = EXPORT_IN_CODE;
return $handlers[$name];
}
else if (isset($result[$name]) && !isset($handlers[$name])) {
return $result[$name];
}
else if (isset($result[$name]) && isset($handlers[$name])) {
if ($result[$name]->export_type & EXPORT_IN_DATABASE) {
$result[$name]->type = t('Overridden');
$result[$name]->export_type = $result[$name]->export_type | EXPORT_IN_CODE;
return $result[$name];
}
else {
// In this case, our default is a higher priority than the standard default.
$handlers[$name]->type = t('Default');
$handlers[$name]->export_type = EXPORT_IN_CODE;
return $handlers[$name];
}
}
}
Earl Miles
committed
/**
* Load all task handlers for a given task and subtask and sort them.
*/
function delegator_load_sorted_handlers($task, $subtask_id = NULL, $enabled = FALSE) {
Earl Miles
committed
$handlers = delegator_load_task_handlers($task, $subtask_id);
if ($enabled) {
foreach ($handlers as $id => $handler) {
if (!empty($handler->disabled)) {
unset($handlers[$id]);
}
}
}
Earl Miles
committed
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
uasort($handlers, '_delegator_sort_task_handlers');
return $handlers;
}
/**
* Callback for uasort to sort task handlers.
*
* Task handlers are sorted by weight then by name.
*/
function _delegator_sort_task_handlers($a, $b) {
if ($a->weight < $b->weight) {
return -1;
}
elseif ($a->weight > $b->weight) {
return 1;
}
elseif ($a->name < $b->name) {
return -1;
}
elseif ($a->name > $b->name) {
return 1;
}
return 0;
}
Earl Miles
committed
/**
* Write a task handler to the database.
*/
Earl Miles
committed
function delegator_save_task_handler(&$handler) {
Earl Miles
committed
$update = (isset($handler->did)) ? array('did') : array();
Earl Miles
committed
// Let the task handler respond to saves:
if ($function = ctools_plugin_load_function('delegator', 'task_handlers', $handler->handler, 'save')) {
$function($handler, $update);
}
Earl Miles
committed
drupal_write_record('delegator_handlers', $handler, $update);
db_query("DELETE FROM {delegator_weights} WHERE name = '%s'", $handler->name);
// If this was previously a default handler, we may have to write task handlers.
if (!$update) {
// @todo wtf was I going to do here?
}
Earl Miles
committed
return $handler;
}
/**
* Remove a task handler.
*/
function delegator_delete_task_handler($handler) {
// Let the task handler respond to saves:
if ($function = ctools_plugin_load_function('delegator', 'task_handlers', $handler->handler, 'delete')) {
$function($handler);
}
Earl Miles
committed
db_query("DELETE FROM {delegator_handlers} WHERE name = '%s'", $handler->name);
db_query("DELETE FROM {delegator_weights} WHERE name = '%s'", $handler->name);
Earl Miles
committed
}
Earl Miles
committed
/**
* Export a task handler into code suitable for import or use as a default
* task handler.
*/
function delegator_export_task_handler($handler, $indent = '') {
ctools_include('export');
ctools_include('plugins');
$handler = drupal_clone($handler);
$append = '';
if ($function = ctools_plugin_load_function('delegator', 'task_handlers', $handler->handler, 'export')) {
$append = $function($handler, $indent);
}
Earl Miles
committed
$output = ctools_export_object('delegator_handlers', $handler, $indent);
$output .= $append;
return $output;
}
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
/**
* Create a new task handler object.
*
* @param $task
* The task this task handler is for.
* @param $subtask_id
* The subtask this task handler is for.
* @param $plugin
* The plugin this task handler is created from.
* @param $weight
* The weight to give this new task handler.
* @param $cache
* The task cache if the task is currently being edited. This must be used
* if task handlers already exist as it is used to determine a unique name
* and without this naming collisions could occur.
*/
function delegator_new_task_handler($task, $subtask_id, $plugin, $weight = 0, $cache = NULL) {
// Generate a unique name. Unlike most named objects, we don't let people choose
// names for task handlers because they mostly don't make sense.
$base = $task['name'];
if ($subtask_id) {
$base .= '_' . $subtask_id;
}
$base .= '_' . $plugin['name'];
// Once we have a base, check to see if it is used. If it is, start counting up.
$name = $base;
$count = 1;
// If taken
while (isset($cache->handlers[$name])) {
$name = $base . '_' . ++$count;
}
// Create a new, empty handler object.
$handler = new stdClass;
$handler->title = '';
$handler->task = $task['name'];
$handler->subtask = $subtask_id;
$handler->handler = $plugin['name'];
$handler->weight = $weight;
$handler->conf = array();
// These are provided by the core export API provided by ctools and we
// set defaults here so that we don't cause notices. Perhaps ctools should
// provide a way to do this for us so we don't have to muck with it.
$handler->export_type = EXPORT_IN_DATABASE;
$handler->type = t('Local');
if (isset($plugin['default conf'])) {
if (is_array($plugin['default conf'])) {
$handler->conf = $plugin['default conf'];
}
else if (function_exists($plugin['default conf'])) {
$handler->conf = $plugin['default conf']($handler, $task, $subtask_id);
}
}
return $handler;
}
/**
* Set an overidden weight for a task handler.
*
* We do this so that in-code task handlers don't need to get written
* to the database just because they have their weight changed.
*/
function delegator_update_task_handler_weight($handler, $weight) {
db_query("DELETE FROM {delegator_weights} WHERE name = '%s'", $handler->name);
db_query("INSERT INTO {delegator_weights} (name, weight) VALUES ('%s', %d)", $handler->name, $weight);
}
Earl Miles
committed
/**
* Shortcut function to get task type plugins.
*/
function delegator_get_task_types() {
ctools_include('plugins');
return ctools_get_plugins('delegator', 'task_types');
}
/**
* Shortcut function to get a task type plugin.
*/
function delegator_get_task_type($id) {
ctools_include('plugins');
return ctools_get_plugins('delegator', 'task_types', $id);
}
Earl Miles
committed
/**
* Shortcut function to get task plugins.
*/
function delegator_get_tasks() {
ctools_include('plugins');
Earl Miles
committed
return ctools_get_plugins('delegator', 'tasks');
}
/**
* Shortcut function to get a task plugin.
*/
function delegator_get_task($id) {
ctools_include('plugins');
Earl Miles
committed
return ctools_get_plugins('delegator', 'tasks', $id);
}
/**
* Get all tasks for a given type.
*/
function delegator_get_tasks_by_type($type) {
ctools_include('plugins');
$all_tasks = ctools_get_plugins('delegator', 'tasks');
$tasks = array();
foreach ($all_tasks as $id => $task) {
if (isset($task['task type']) && $task['task type'] == $type) {
$tasks[$id] = $task;
}
}
return $tasks;
}
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
/**
* Fetch all subtasks for a delegator task.
*
* @param $task
* A loaded $task plugin object.
*/
function delegator_get_task_subtasks($task) {
if (empty($task['subtasks'])) {
return array();
}
if ($function = ctools_plugin_get_function($task, 'subtasks callback')) {
return $function($task);
}
}
/**
* Fetch all subtasks for a delegator task.
*
* @param $task
* A loaded $task plugin object.
* @param $subtask_id
* The subtask ID to load.
*/
function delegator_get_task_subtask($task, $subtask_id) {
if (empty($task['subtasks'])) {
return;
}
if ($function = ctools_plugin_get_function($task, 'subtask callback')) {
return $function($task, $subtask_id);
}
}
Earl Miles
committed
/**
* Shortcut function to get task handler plugins.
*/
function delegator_get_task_handlers() {
ctools_include('plugins');
Earl Miles
committed
return ctools_get_plugins('delegator', 'task_handlers');
}
/**
* Shortcut function to get a task handler plugin.
*/
function delegator_get_task_handler($id) {
ctools_include('plugins');
Earl Miles
committed
return ctools_get_plugins('delegator', 'task_handlers', $id);
}
/**
* Retrieve a list of all applicable task handlers for a given task.
*
Earl Miles
committed
* This looks at the $task['handler type'] and compares that to $task_handler['handler type'].
Earl Miles
committed
* If the task has no type, the id of the task is used instead.
*/
function delegator_get_task_handler_plugins($task) {
Earl Miles
committed
$type = isset($task['handler type']) ? $task['handler type'] : $task['name'];
$name = $task['name'];
Earl Miles
committed
$handlers = array();
$task_handlers = delegator_get_task_handlers();
foreach ($task_handlers as $id => $handler) {
Earl Miles
committed
$task_type = is_array($handler['handler type']) ? $handler['handler type'] : array($handler['handler type']);
if (in_array($type, $task_type) || in_array($name, $task_type)) {
Earl Miles
committed
$handlers[$id] = $handler;
}
}
return $handlers;
}
/**
* Get the title for a given handler.
*
* If the plugin has no 'admin title' function, the generic title of the
* plugin is used instead.
Earl Miles
committed
*/
function delegator_get_handler_title($plugin, $handler, $task, $subtask_id) {
$function = ctools_plugin_get_function($plugin, 'admin title');
if ($function) {
return $function($handler, $task, $subtask_id);
}
else {
return $plugin['title'];
}
}
Earl Miles
committed
/**
* Get the admin summary (additional info) for a given handler.
*/
function delegator_get_handler_summary($plugin, $handler, $task, $subtask_id) {
if ($function = ctools_plugin_get_function($plugin, 'admin summary')) {
return $function($handler, $task, $subtask_id);
}
}
Earl Miles
committed
/**
* Split a task name into a task id and subtask id, if applicable.
Earl Miles
committed
*/
function delegator_get_task_id($task_name) {
if (strpos($task_name, '-') !== FALSE) {
return explode('-', $task_name, 2);
}
else {
return array($task_name, NULL);
}
}
/**
* Turn a task id + subtask_id into a task name.
*/
function delegator_make_task_name($task_id, $subtask_id) {
if ($subtask_id) {
return $task_id . '-' . $subtask_id;
}
else {
return $task_id;
Earl Miles
committed
}
}
/**
* Delegator for arg load function because menu system will not load extra
* files for these; they must be in a .module.
*/
function dp_arg_load($value, $subtask, $argument) {
require_once './' . drupal_get_path('module', 'delegator') . '/plugins/tasks/page.inc';
return _dp_arg_load($value, $subtask, $argument);
}
/**
* Possibly provide a default value so that variable items can appear in visible menus.
*/
function dp_arg_to_arg($bit, $map, $index) {
/*
Reference code.
$start = microtime();
$introspect = debug_backtrace();
dsm(microtime() - $start);
foreach ($introspect as $call) {
if ($call['function'] == '_menu_link_translate') {
dsm(array($map, $call['args']['0']));
}
}
*/
}
/**
* Get the render function for a handler.
*/
function delegator_get_renderer($handler) {
return ctools_plugin_load_function('delegator', 'task_handlers', $handler->handler, 'render');
Earl Miles
committed
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
}
/**
* Callback for access control ajax form on behalf of page.inc task.
*
* Returns the cached access config and contexts used.
*/
function delegator_page_ctools_access_get($argument) {
ctools_include('context');
$task = delegator_get_task('page');
require_once './' . drupal_get_path('module', 'delegator') . '/plugins/tasks/page.admin.inc';
$page = delegator_page_get_page_cache($argument);
$contexts = array();
// Load contexts based on argument data:
if ($arguments = _delegator_page_get_arguments($page)) {
$contexts = ctools_context_get_placeholders_from_argument($arguments);
}
return array($page->access, $contexts);
}
/**
* Callback for access control ajax form on behalf of page.inc task.
*
* Writes the changed access to the cache.
*/
function delegator_page_ctools_access_set($argument, $access) {
$page = delegator_page_get_page_cache($argument);
$page->access = $access;
delegator_page_set_page_cache($page);
}
/**
* Callback for access control ajax form on behalf of context task handler.
*
* Returns the cached access config and contexts used.
*/
function delegator_task_handler_ctools_access_get($argument) {
ctools_include('context');
require_once './' . drupal_get_path('module', 'delegator') . '/delegator.admin.inc';
list($task_name, $name) = explode('*', $argument);
list($task_id, $subtask_id) = delegator_get_task_id($task_name);
$task = delegator_get_task($task_id);
$cache = delegator_admin_get_task_cache($task, $subtask_id);
$handler = delegator_admin_find_handler($name, $cache, $task_name);
if (!isset($handler->conf['access'])) {
$handler->conf['access'] = array();
}
ctools_include('context-task-handler');
$contexts = ctools_context_handler_get_all_contexts($task, $subtask_id, $handler);
return array($handler->conf['access'], $contexts);
}
/**
* Callback for access control ajax form on behalf of context task handler.
*
* Writes the changed access to the cache.
*/
function delegator_task_handler_ctools_access_set($argument, $access) {
list($task_name, $name) = explode('*', $argument);
list($task_id, $subtask_id) = delegator_get_task_id($task_name);
$task = delegator_get_task($task_id);
$cache = delegator_admin_get_task_cache($task, $subtask_id);
$handler = delegator_admin_find_handler($name, $cache, $task_name);
$handler->conf['access'] = $access;
delegator_admin_set_task_handler_cache($handler, TRUE);
// Make sure the cache is aware that we're editing this item:
if (!isset($cache->working) || $cache->working != $handler->name) {
$cache->working = $handler->name;
delegator_admin_set_task_cache($task, $subtask_id, $cache);
}
}
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
/**
* Load a context from an argument for a given page task.
*
* This is used as a menu callback to translate arguments and that is why it is
* here in the .module file.
*
* @param $value
* The incoming argument value.
* @param $subtask
* The subtask id.
* @param $argument
* The numeric position of the argument in the path, counting from 0.
*
* @return
* A context item if one is configured, the argument if one is not, or
* FALSE if restricted or invalid.
*/
function _dp_arg_load($value, $subtask, $argument) {
$page = delegator_page_load($subtask);
if (!$page) {
return FALSE;
}
$path = explode('/', $page->path);
if (empty($path[$argument])) {
return FALSE;
}
$keyword = substr($path[$argument], 1);
if (empty($page->arguments[$keyword])) {
return $value;
}
$page->arguments[$keyword]['keyword'] = $keyword;
ctools_include('context');
$context = ctools_context_get_context_from_argument($page->arguments[$keyword], $value);
// convert false equivalents to false.
return $context ? $context : FALSE;
}
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
/**
* Reset the active menu trail to the trail specified by the task type.
*
* The task type can specify an 'admin path'. If it does,
* 'admin/build/delegator' will be removed from the active trail and replaced
* with whatever is in the admin path; that way task types can provide
* their own administration.
*/
function delegator_set_trail($task, $task_name = NULL) {
$task_type = delegator_get_task_type($task['task type']);
if (empty($task_type['admin path'])) {
return;
}
ctools_include('menu');
$trail = menu_get_active_trail();
$remove = ctools_get_menu_trail('admin/build/delegator');
foreach ($remove as $info) {
foreach ($trail as $id => $crumb) {
if ($crumb['href'] == $info['href']) {
unset($trail[$id]);
}
}
}
if ($task_name) {
// Clean up broken 'Edit' link that Drupal leaves behind.
$trail = array_values($trail);
if (isset($trail[0]) && $trail[0]['title'] == t('Edit')) {
unset($trail[0]);
}
array_unshift($trail, menu_get_item('admin/build/delegator/' . $task_name));
}
$trail = array_merge(ctools_get_menu_trail($task_type['admin path']), $trail);
menu_set_active_trail($trail);
}