开发者

Hook called before to delete a node

I'm writing a custom module, and I would like to do some checks before the node is deleted. Is there a hook that gets trigerred before a node is deleted? And i开发者_Go百科s there a way to somehow prevent the deletion? BTW, I'm using drupal6


You can use hook_menu_alter to point the menu callback node/%node/delete to your own function. Your function can do whatever checks you want and then present the node_delete_confirm form if the checks pass.


This will remove the Delete button and add your own button and action. This will not prevent users from using the URL /node/[nid]/delete to delete the node, use the permission settings for that.

function my_module_form_alter(&$form, &$form_state, $form_id) {
  if($form_id == "allocation_node_form") {
    if (isset($form['#node']->nid))  {
            $form['buttons']['my_remove'] = array(
                                        '#type' => 'submit',
                                        '#value' => 'Remove',
                                        '#weight' => 15,
                                        '#submit' => array('allocation_remove_submit'),
                                        );

            if($user->uid != 1) {
              unset($form['buttons']['delete']);
              $form['buttons']['#suffix'] = "<br>".t("<b>Remove</b> will...");
            }else{
              $form['buttons']['#suffix'] = t("<b>Delete</b> only if ...");
            }
        }
  }

}


function allocation_remove_submit($form, &$form_state) {
    if (is_numeric($form_state['values']['field_a_team'][0]['nid'])) {
        //my actions

        //Clear forms cache
        $cid = 'content:'. $form_state['values']['nid'].':'. $form_state['values']['vid'];
        cache_clear_all($cid, 'cache_content', TRUE);

        //Redirect
        drupal_goto("node/".$form_state['values']['field_a_team'][0]['nid']);        
    }else{
        drupal_set_message(t("Need all values to be set"), "warning");
    }
}


You can use hook_nodeapi op delete.

It might be a bad idea trying to stop the deletion of a node, since you don't know what other modules have done, like deleting cck field values etc.

There is no hook you can use to do actions before a node is being deleted. The above is the closest you can come.


Use form_alter and remove the delete button if your conditions are met. Something like this.

function xxx_contact_form_alter(&$form, $form_state, $form_id) {
  global $user;

  if (strstr($form_id, 'xxx_node_form')) {
    // Stop deletion of xxx users unless you are an admin
    if (($form['#node']->uid) == 0 && ($user->uid != 1)) {
      unset($form['actions']['delete']);
    }
  }
}


This custom module code is for Drupal 7, but I'm sure a similar concept applies to Drupal 6. Plus, by now, you're most probably looking for a solution for Drupal 7.

This code will run "before" a node is deleted and hence you can run the checks you want and then optionally hide the delete button to prevent the node from being deleted. Check the function's comments for more info.

This is a screenshot showcasing the end result:

Hook called before to delete a node

And this is the custom code used:

<?php

/**
 * Implements hook_form_FORM_ID_alter() to conditionally prevent node deletion.
 * 
 * We check if the current node has child menu items and, if yes, we prevent
 * this node's deletion and also show a message explaining the situation and 
 * links to the child nodes so that the user can easily delete them first
 * or move them to another parent menu item.
 * 
 * This can be useful in many cases especially if you count on the paths of 
 * the child items being derived from their parent item path, for example.
 */
function sk_form_node_delete_confirm_alter(&$form, $form_state) {
    //Check if we have a node id and stop if not
    if(empty($form['nid']['#value'])) {
        return;
    }

    //Load the node from the form
    $node = node_load($form['nid']['#value']);

    //Check if node properly loaded and stop if not
    //Empty checks for both $node being not empty and also for its property nid
    if(empty($node->nid)) {
        return;
    }

    //Get child menu items array for this node
    $children_nids = sk_get_all_menu_node_children_ids('node/' . $node->nid);
    $children_count = count($children_nids);

    //If we have children, do set a warning and disable delete button and such
    //so that this node cannot be deleted by the user.
    //Note: we are not 100% that this prevents the user from deleting it through
    //views bulk operations for example or by faking a post request, but for our
    //needs, this is adequate as we trust the editors on our websites.
    if(!empty($children_nids)) {
        //Construct explanatory message
        $msg = '';

        $t1 = '';
        $t1 .= '%title is part of a menu and has %count child menu items. ';
        $t1 .= 'If you delete it, the URL paths of its children will no longer work.';
        $msg .= '<p>';
        $msg .= t($t1, array('%title' => $node->title, '%count' => $children_count));
        $msg .= '</p>';

        $t2 = 'Please check the %count child menu items below and delete them first.';
        $msg .= '<p>';
        $msg .= t($t2, array('%count' => $children_count));
        $msg .= '</p>';

        $msg .= '<ol>';        
        $children_nodes = node_load_multiple($children_nids);
        if(!empty($children_nodes)) {
            foreach($children_nodes as $child_node) {
                if(!empty($child_node->nid)) {
                    $msg .= '<li>';
                    $msg .= '<a href="' . url('node/' . $child_node->nid) . '">';
                    $msg .= $child_node->title;
                    $msg .= '</a>';
                    $msg .= '</li>';
                }
            }
        }
        $msg .= '</ol>';

        //Set explanatory message
        $form['sk_children_exist_warning'] = array(
            '#markup' => $msg,
            '#weight' => -10,
        );

        //Remove the 'This action cannot be undone' message
        unset($form['description']);

        //Remove the delete button
        unset($form['actions']['submit']);
    }
}

For more info, check this detailed blog post about conditionally preventing node deletion in Drupal 7. It has details about the whole process and also links to resources including how to easily create a custom module where you can copy/paste the above code into to get it working.

Good luck.


There isn't a hook that gets called before the node gets deleted, but Drupal does check with node_access to see if the user is allowed to delete the node before continuing with the deletion.

You could set the node access permissions to not allow the user to delete the node: it won't help if the user is user 1 or has the administer nodes permission, so don't give those permissions to untrusted users (i.e. people who would delete a node). This is also the Drupal Way to prevent unwarranted node deletions.


you can use hook_access and put conditions if op == delete. if you conditions fullfilled return True otherwise return false. in case of false your node will not be deleted.

Remember for admin this will not be triggered.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜