在删除节点之前调用的钩子

发布于 2024-09-11 15:43:45 字数 104 浏览 4 评论 0 原文

我正在编写一个自定义模块,我想在删除节点之前进行一些检查。是否有一个钩子在删除节点之前触发?有没有办法以某种方式防止删除?顺便说一句,我正在使用 drupal6

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 is there a way to somehow prevent the deletion? BTW, I'm using drupal6

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

一身骄傲 2024-09-18 15:43:45

您可以使用 hook_menu_alter 将菜单回调 node/%node/delete 指向您自己的函数。您的函数可以执行您想要的任何检查,然后在检查通过时显示 node_delete_confirm 表单。

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.

怕倦 2024-09-18 15:43:45

这将删除“删除”按钮并添加您自己的按钮和操作。这不会阻止用户使用 URL /node/[nid]/delete 删除节点,请使用相应的权限设置。

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");
    }
}

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");
    }
}
‖放下 2024-09-18 15:43:45

您可以使用 hook_nodeapi 进行删除。

尝试停止删除节点可能是一个坏主意,因为您不知道其他模块做了什么,例如删除 cck 字段值等。

在删除节点之前没有可以用来执行操作的钩子。以上是您可以得到的最接近的结果。

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.

爱你不解释 2024-09-18 15:43:45

如果满足您的条件,请使用 form_alter 并删除删除按钮。
像这样的东西。

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']);
    }
  }
}

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']);
    }
  }
}
坦然微笑 2024-09-18 15:43:45

此自定义模块代码适用于 Drupal 7,但我确信类似的概念也适用于 Drupal 6。另外,到目前为止,您很可能正在寻找适用于 Drupal 7 的解决方案。

此代码将在节点“之前”运行已删除,因此您可以运行所需的检查,然后可以选择隐藏删除按钮以防止节点被删除。检查函数的注释以获取更多信息。

这是显示最终结果的屏幕截图:

这是使用的自定义代码:

<?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']);
    }
}

有关更多信息,请查看这篇关于在 Drupal 7 中有条件地防止节点删除的详细博客文章< /a>.它包含有关整个过程的详细信息,还链接到资源,包括如何轻松创建自定义模块,您可以在其中复制/粘贴上述代码以使其正常工作。

祝你好运。

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:

Screenshot showing node deletion prevention using custom code hook

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.

幸福%小乖 2024-09-18 15:43:45

在删除节点之前没有调用钩子,但 Drupal 会检查 node_access 以查看是否允许用户在继续删除之前删除节点。

您可以将节点访问权限设置为不允许用户删除节点:如果用户是用户 1 或具有管理节点权限,这将无济于事,因此不要将这些权限授予不受信任的用户(即那些会删除节点)。这也是 Drupal 防止不必要的节点删除的方法。

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.

慕巷 2024-09-18 15:43:45

您可以使用 hook_access 并放置条件 if op == delete。如果条件满足则返回 True,否则返回 false。如果为 false,您的节点将不会被删除。

请记住,对于管理员来说,这不会被触发。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文