I want to redirect after deleting a node to /admin/content/list when I delete a node using the delete button on the edit node form. Right now if I delete a node it redirects to the home page. I tried using drupal_got('admin/content/list') but this exits regular code execution and doesn't finish deleting the node that triggered the action. How can I redirect to another url instead of drupal_get_destination() without using drupal_goto()?

function _project_action_nodeapi(&$node, $op) 
{
	if ($op == 'delete')
	{
		// Get project nid
		$project_nid = $node->nid;
		
		// Delete project gallery images
		$result = db_query('SELECT nid FROM content_type_image WHERE field_gallery_nid = %d', $project_nid); 
		while ($row = db_fetch_object($result)) 
		{
			// delete project child image node
     		        node_delete($row->nid);
		}
		
		$destination = str_replace('destination=', '', drupal_get_destination());
		$destination = urldecode($destination);
		
		if($destination != 'admin/content/list')
		{ 
                        // somehow set the destination without using drupal_goto()
		}
	}
}

Comments

roper.’s picture

You'll probably have to use hook_form_alter() instead:


function mymodule_form_alter(&$form, &$form_state, $form_id) {
  if (strpos($form_id, '_node_form')) {
    $form['#submit'][] = 'mymodule_node_form_submit';
  }
}

function mymodule_node_form_submit($form, &$form_state) {
  if ($form_state['values']['op'] == t('Delete')) {
    $form_state['redirect'] = 'admin/content/list';
  }
}

edit: Ah yes, the post below me is more correct, i forgot about the confirm form. Don't use this, it will redirect you to admin/content/list without actually deleting your node... Code below looks good except I don't know that you need the check for node type (and therefore the node_load() call)...

NaX’s picture

I would alter the confirm form to add a custom submit handler that runs after node_delete_confirm_submit()

Something like this.


/**
 * Implementation of hook_form_alter
 */
function mymodule_form_alter(&$form, $form_state, $form_id) {
  // Alter node delete form
  if ($form_id == 'node_delete_confirm') {
    // Get the node to check the type.
    // We could also use $form['#parameters'][2]    
    if ($node = node_load($form['nid']['#value'])) {
      if ($node->type == 'page') {
        // Add custom Delete submit handler
        // node_delete_confirm_submit() needs to be first.
        $form['#submit'][] = 'mymodule_node_delete_confirm';
      }
    }
  } 
}

function mymodule_node_delete_confirm($form, &$form_state) {
  // Check user permissions first to prevent redirecting to an access denied page.
  if (user_access('administer nodes')) {
    // Alter the redirect path
    $form_state['redirect'] = 'admin/content/node';
  }
}

You should also have a look at the comments on the API docs page for node_delete_confirm_submit().

I hope that helps.

mtpultz’s picture

I looked at the comment on http://api.drupal.org/api/drupal/modules--node--node.pages.inc/function/... and copy and pasted it into my code to run after confirmation of deletion, which it does. I've stepped through it and it executes as it should but it doesn't redirect to "admin/content/list" it redirects back to the confirmation page "node/nid/delete" after the node is deleted. Do you know what I've done wrong? Or why this happens?

/**
 * Implementation of hook_form_node_delete_confirm_alter()
 */
function project_form_node_delete_confirm_alter(&$form, &$form_state)
{
	$form['#redirect'] = FALSE;
	$form['#submit'][] = '_project_delete_redirect';
}

/**
 * An additional submit handler to respect hook_form_node_delete_confirm_alter()
 */ 
function _project_delete_redirect($form, &$form_state)
{
	if($form["#redirect"] === FALSE)
	{
		$form_state['redirect'] = "admin/content/list";
	}
}
mtpultz’s picture

Got it to work but not quite how they explained it... Do you know why this works and adding another submit handler does not? Or at least why it doesn't redirect where you want it?

/**
 * Implementation of hook_form_node_delete_confirm_alter()
 */
function project_form_node_delete_confirm_alter(&$form, &$form_state)
{
	//$form['#submit'][] = '_project_delete_redirect'; // doesn't work
	$form['#redirect'] = "admin/content/list"; // works by itself???
}

/**
 * An additional submit handler to respect hook_form_node_delete_confirm_alter()
 */ 
function _project_delete_redirect($form, &$form_state)
{
	if($form["#redirect"] === "admin/content/list")
	{
		$form_state['redirect'] = "admin/content/list"; // would make it here but doesn't redirect properly
	}
}
roper.’s picture

In your second-to-last post, you explicitly set #redirect to FALSE on the form. That will take precedence over the $form_state['redirect']. By setting it to FALSE you're forcing the form to NOT redirect no matter what.

In your last example you can probably JUST set the #redirect on the form without dealing with $form_state. Keep in mind too, it's always possible another module is running after yours and changing your values...

@see: http://api.drupal.org/api/drupal/includes--form.inc/function/drupal_redi..., which receives the $form array and $form_state['redirect'] (or NULL if there isn't one) from drupal_process_form().

NaX’s picture

Try this. Please note that "admin/content/list" does not exist for me, I assume it might be a view you created, so in my example I used "admin/content/node" and because that path requires "administer nodes" permission I wrapped it in a if statement.

Please note I tested this on one of my dev sites and it worked fine for me.


/**
 * Implementation of hook_form_node_delete_confirm_alter()
 */
function project_form_node_delete_confirm_alter(&$form, &$form_state) {
  // Add custom Delete submit handler
  // node_delete_confirm_submit() needs to be first.
  $form['#submit'][] = '_project_delete_redirect';	
}

/**
 * An additional submit handler to respect hook_form_node_delete_confirm_alter()
 */ 
function _project_delete_redirect($form, &$form_state) {
  // Check user permissions first to prevent redirecting to an access denied page.
  if (user_access('administer nodes')) {
    // Alter the redirect path
    $form_state['redirect'] = 'admin/content/node';
  }
}

Hope it helps.