diff --git a/delegator/plugins/tasks/node_edit.inc b/delegator/plugins/tasks/node_edit.inc new file mode 100644 index 0000000000000000000000000000000000000000..320bfb8b252f1a723c29912ed2ca514e6ca26f0b --- /dev/null +++ b/delegator/plugins/tasks/node_edit.inc @@ -0,0 +1,114 @@ +<?php +// $Id$ + +/** + * Specialized implementation of hook_delegator_tasks(). See api-task.html for + * more information. + */ +function delegator_node_edit_delegator_tasks() { + return array( + 'node_edit' => array( + // This is a 'page' task and will fall under the page admin UI + 'task type' => 'page', + + 'title' => t('Node view'), + 'description' => t('The node edit task allows you to control what handler will handle the job of editing a node at the path <em>node/%node/edit</em>. If no handler is set or matches the criteria, the default Drupal node renderer will be used.'), + + 'admin title' => 'Node edit', // translated by menu system + 'admin description' => 'Overrides for the built in node edit handler at <em>node/%node/edit</em>.', + 'admin path' => 'node/%node/edit', + + // Menu hooks so that we can alter the node/%node menu entry to point to us. + 'hook menu' => 'delegator_node_edit_menu', + 'hook menu alter' => 'delegator_node_edit_menu_alter', + + // This is task uses 'context' handlers and must implement these to give the + // handler data it needs. + 'handler type' => 'context', // handler type -- misnamed + 'get arguments' => 'delegator_node_edit_get_arguments', + 'get context placeholders' => 'delegator_node_edit_get_contexts', + ), + ); +} + +/** + * Callback defined by delegator_node_edit_delegator_tasks(). + * + * Alter the node view input so that node view comes to us rather than the + * normal node view process. + */ +function delegator_node_edit_menu_alter(&$items, $task) { + // Override the node view handler for our purpose. + $items['node/%node/edit']['page callback'] = 'delegator_node_edit'; + $items['node/%node/edit']['file path'] = $task['path']; + $items['node/%node/edit']['file'] = $task['file']; +} + +/** + * Entry point for our overridden node view. + * + * This function asks its assigned handlers who, if anyone, would like + * to run with it. If no one does, it passes through to Drupal core's + * node view, which is node_page_view(). + */ +function delegator_node_edit($node) { + // Load my task plugin + $task = delegator_get_task('node_edit'); + + // Load the node into a context. + ctools_include('context'); + ctools_include('context-task-handler'); + $contexts = ctools_context_handler_get_task_contexts($task, '', array($node)); + + // Load the landlers. + $handlers = delegator_load_sorted_handlers($task, '', TRUE); + + // Try each handler. + foreach ($handlers as $handler) { + if ($function = delegator_get_renderer($handler)) { + $output = $function($handler, $contexts); + if ($output) { + // Since we're not using node_show() we need to emulate what it used to do. + // Update the history table, stating that this user viewed this node. + node_tag_new($node->nid); + + // TRUE is a special return used to let us know that it handled the + // task but does not wish us to render anything, as it already did. + // This is needed for the 'no blocks' functionality. + if ($output === TRUE) { + return; + } + return $output; + } + } + } + + // Fall back! + module_load_include('inc', 'node', 'node.pages'); + return node_page_edit($node); +} + +/** + * Callback to get arguments provided by this task handler. + * + * Since this is the node view and there is no UI on the arguments, we + * create dummy arguments that contain the needed data. + */ +function delegator_node_edit_get_arguments($task, $subtask_id) { + return array( + array( + 'keyword' => 'node', + 'identifier' => t('Node being edited'), + 'id' => 0, + 'name' => 'node_edit', + 'settings' => array(), + ), + ); +} + +/** + * Callback to get context placeholders provided by this handler. + */ +function delegator_node_edit_get_contexts($task, $subtask_id) { + return ctools_context_get_placeholders_from_argument(delegator_node_edit_get_arguments($task, $subtask_id)); +} diff --git a/includes/form.inc b/includes/form.inc index 4ac55576b140bda0090ec2e324e71f8d476c5d9d..22d12d6952bd5a0563284be9002cf5903a3a4a7d 100644 --- a/includes/form.inc +++ b/includes/form.inc @@ -69,7 +69,8 @@ function ctools_build_form($form_id, &$form_state) { else { // Use a copy of the function's arguments for manipulation $args_temp = $args; - $args_temp[0] = &$form_state; + array_unshift($args_temp, 'placeholder'); + $args_temp[0] = &$form_state; // replaces the placeholder. array_unshift($args_temp, $form_id); $form = call_user_func_array('drupal_retrieve_form', $args_temp); @@ -131,6 +132,11 @@ function ctools_build_form($form_id, &$form_state) { $form = ctools_rebuild_form($form_id, $form_state, $args); } + // If whoever is calling this wants the $form array (so that it can render it + // another way, for example) then return it. + if (!empty($form_state['want form'])) { + return $form; + } // If we haven't redirected to a new location by now, we want to // render whatever form array is currently in hand. return drupal_render_form($form_id, $form); @@ -145,7 +151,8 @@ function ctools_rebuild_form($form_id, &$form_state, $args, $form_build_id = NUL // Remove the first argument. This is $form_id.when called from // drupal_get_form and the original $form_state when called from some AHAH // callback. Neither is needed. After that, put in the current state. - $args[0] = &$form_state; + array_unshift($args, 'placeholder'); + $args[0] = &$form_state; // Replaces placeholder. // And the form_id. array_unshift($args, $form_id); $form = call_user_func_array('drupal_retrieve_form', $args); diff --git a/plugins/arguments/node_edit.inc b/plugins/arguments/node_edit.inc index dff82b321a7add1e03e0601e8c61104f2f14670d..ece6c26c0437d9b9d75838828a7549a87b601fbe 100644 --- a/plugins/arguments/node_edit.inc +++ b/plugins/arguments/node_edit.inc @@ -30,8 +30,13 @@ function ctools_node_edit_context($arg = NULL, $conf = NULL, $empty = FALSE) { return ctools_context_create_empty('node_edit_form'); } + // We can accept either a node object or a pure nid. + if (is_object($arg)) { + return ctools_context_create('node_edit_form', $arg); + } + if (!is_numeric($arg)) { - return NULL; + return FALSE; } $node = node_load($arg); @@ -39,10 +44,6 @@ function ctools_node_edit_context($arg = NULL, $conf = NULL, $empty = FALSE) { return NULL; } - if (array_filter($conf['types']) && empty($conf['types'][$node->type])) { - return NULL; - } - // This will perform a node_access check, so we don't have to. return ctools_context_create('node_edit_form', $node); } diff --git a/plugins/contexts/node_edit_form.inc b/plugins/contexts/node_edit_form.inc index 37ec931770a52deb6d074cf05906de91bcd58d2c..995d2f330b8334cf5a6c374582b0da5c4bb9a27f 100644 --- a/plugins/contexts/node_edit_form.inc +++ b/plugins/contexts/node_edit_form.inc @@ -41,25 +41,21 @@ function ctools_context_create_node_edit_form($empty, $node = NULL, $conf = FALS } if (!empty($node) && node_access('update', $node)) { - // This is from node_edit_page cause Drupal still doesn't use fapi right. - if ($_POST['op'] == t('Delete')) { - // Note: we redirect from node/nid/edit to node/nid/delete to make the tabs disappear. - if ($_REQUEST['destination']) { - $destination = drupal_get_destination(); - unset($_REQUEST['destination']); - } - drupal_goto('node/'. $node->nid .'/delete', $destination); - } + module_load_include('inc', 'node', 'node.pages'); + ctools_include('form'); + $form_id = $node->type . '_node_form'; + + $form_state = array('want form' => TRUE, 'args' => array($node)); + $form = ctools_build_form($form_id, $form_state); - $form = drupal_retrieve_form($node->type . '_node_form', $node); - drupal_process_form($node->type . '_node_form', $form); // Fill in the 'node' portion of the context $context->data = $node; $context->title = $node->title; $context->argument = $node->nid; $context->form = $form; - $context->form_id = $node->type . '_node_form'; + $context->form_state = &$form_state; + $context->form_id = $form_id; $context->form_title = $node->title; $context->node_type = $node->type; return $context;