3

I am calling node_delete($nid) from inside a function callback that is called when the DELETE button is pressed, but the node is not deleted. There is no error - it just doesn't work! What can be going wrong?

In bhl_form_alter() I put:

$form['actions']['delete']['#submit']['0'] = 'delete_mem';

Then delete_mem($node) calls node_delete($node->nid).

I have also tried to figure out a way to use the default callback hook_node_delete(), but if I put a redirect there with drupal_goto(), the redirect happens, but the node again does not get deleted. drupal_form_redirect() doesn't work in this function because $form_state is not passed.

3
  • 3
    Without seeing any code, it's not possible to understand why your code doesn't work. – kiamlaluno Feb 4 '12 at 2:22
  • 1
    hook_node_delete() is a hook function you add to your module if you want to respond to the deletion of nodes. api.drupal.org/api/drupal/modules--node--node.api.php/function/… – paul-m Feb 4 '12 at 19:08
  • It would also help to see the complete code of bhl_form_alter(), which is called for every form build from Drupal. Showing a single line doesn't help to understand what is wrong. – kiamlaluno Feb 5 '12 at 18:44
5

The first mistake in the code is how the additional submission handler is added. You should add it with the following code:

$form['actions']['delete']['#submit'][] = 'delete_mem';

If you want to be sure that submission handler is executed first, you should use the following code:

array_unshift($form['actions']['delete']['#submit'], 'delete_mem');

The second error is the argument declared for the form submission handler that, as shown in this documentation page, should be:

function delete_mem($form, &$form_state) {}

As consequence of this, if you defined your function as function delete_mem($node) and you call node_delete($node->nid) from that function, node_delete() doesn't work because what you are calling $node is really a form array, which doesn't contain the nid property; what you are passing to node_delete() is NULL, and the function doesn't delete any node. Eventually, NULL could be converted to 0, but there aren't nodes using 0 as node ID, and the function will not find any node to delete.
If you are using a Drupal development snapshot, you would get a warning about accessing a property of something that is not an object.

Supposing that you are altering the node edit form, the submission handler you are writing has access to the node object through $form_state['node']; the node ID can then retrieved with $form_state['node']->nid.

You can check the code executed from the default submission handler added from the Node module to the "Delete" button, which is the following one.

function node_form_delete_submit($form, &$form_state) {
  $destination = array();
  if (isset($_GET['destination'])) {
    $destination = drupal_get_destination();
    unset($_GET['destination']);
  }
  $node = $form['#node'];
  $form_state['redirect'] = array('node/' . $node->nid . '/delete', array('query' => $destination));
}

It uses $form['#node'] to get the node object, and $node->nid to get its node ID. Consider the note added in node_form() about $form['#node'].

  // @todo D8: Remove. Modules should access the node using $form_state['node'].
  $form['#node'] = $node;

This means that using $form['#node'] would not working anymore on Drupal 8 (or any future version), while $form_state['node'] would still work for Drupal 8 and any future Drupal version.

In this case, your submission handler doesn't need to call node_delete() as the function is already called from the submission handler added from the Node module to the "Delete" button. If you really need to delete information about a node that is being delete from a database table that your module uses, then you should implement hook_node_delete().

 

I have also tried to figure out a way to use the default callback hook_node_delete()

hook_node_delete() is a hook that needs to be implemented. If your module is bhl.module, the function that needs to be written has the following signature:

function bhl_node_delete($node)

That hook is implemented when you need to delete data saved from your module in its own database table, where you save some custom data and the node ID. It is not required to delete a node, which a task already done from node_delete_multiple(), which contains the following code.

try {
  foreach ($nodes as $nid => $node) {
    // Call the node-specific callback (if any):
    node_invoke($node, 'delete');
    module_invoke_all('node_delete', $node);
    module_invoke_all('entity_delete', $node, 'node');
    field_attach_delete('node', $node);

    // Remove this node from the search index if needed.
    // This code is implemented in node module rather than in search module,
    // because node module is implementing search module's API, not the other
    // way around.
    if (module_exists('search')) {
      search_reindex($nid, 'node');
    }
  }

  // Delete after calling hooks so that they can query node tables as needed.
  db_delete('node')
    ->condition('nid', $nids, 'IN')
    ->execute();
  db_delete('node_revision')
    ->condition('nid', $nids, 'IN')
    ->execute();
  db_delete('history')
    ->condition('nid', $nids, 'IN')
    ->execute();
  db_delete('node_access')
   ->condition('nid', $nids, 'IN')
   ->execute();
}

Inside the implementation of hook_node_delete(), you don't call node_delete(), or you cause an infinite loop. In fact, node_delete() calls node_delete_multiple(), which then invokes any implementation of hook_node_delete(), including yours that would call node_delete(), that would call node_delete_multiple(), which again would invoke any hook_node_delete() implementation, including yours.

 

As general suggestion, the functions defined from a module should always be prefixed from the short module name. In your case, if the hook function is bhl_form_alter(), the submission handler should be bhl_delete_mem().

9
  • I'm sorry to say you are incorrect. The signature for hook_node_delete is hook_node_delete($node). This is the problem. There is no access to $form or $form_state. Doc for this is here: api.drupal.org/api/drupal/modules--node--node.api.php/function/… – Jeff Davidson Feb 5 '12 at 17:03
  • this seems to be the same for the additional submission handler. Any thought on why node_delete does not work inside of the submission handler? – Jeff Davidson Feb 5 '12 at 17:05
  • The problem is that you are not implementing hook_node_delete(), but you are adding a form submission handler, for which the arguments are $form and $form_state. A form submission handler, which is what you are using, and hook_node_delete() are two unrelated, and completely different, things. – kiamlaluno Feb 5 '12 at 17:09
  • yes, your right. the problem I am having is that if I use a submission handler node_delete doesn't delete the node. Here is the code: function bhl_delete_mem($form, &$form_state){ node_delete($form['nid']['#value']); drupal_goto('memorabilia'); } – Jeff Davidson Feb 5 '12 at 17:33
  • and if I use bhl_node_delete, I can't figure out how to redirect after the delete. I tried drupal_goto and drupal_redirect_form. Both redirect but don't delete the node!? Thanks! – Jeff Davidson Feb 5 '12 at 17:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.