2010-07-25 75 views
3

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

回答

1

您可以使用hook_nodeapi删除。

它可能是一个坏主意,试图阻止一个节点的缺失,因为你不知道什么是其他模块都做了,如删除CCK字段值等

没有钩子,你可以用它来在节点被删除之前执行操作。以上是最接近你可以来。

+0

重点在于我希望在节点上发生任何删除之前进行访问。我非常了解这个钩子,但并不能帮助我,因为我可以看到它 – 2010-07-25 11:31:29

0

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

您可以将节点访问权限设置为不允许用户删除节点:如果用户是用户1或具有管理节点权限,则不会有所帮助,因此不要将这些权限授予不受信任的用户即将删除节点的人)。这也是防止无端节点删除的Drupal方式。

3

您可以使用hook_menu_alter将菜单回调node/%node/delete指向您自己的功能。你的功能可以做任何你想要的检查,然后出示node_delete_confirm表格,如果检查通过。

+0

它适用于我的情况,因为它是一个封闭的系统,但它存在安全缺陷,但对我的情况无关紧要。 – 2010-07-26 09:45:03

+0

这不会保护使用视图批量操作删除节点。 – 2014-01-15 10:26:12

-1

你可以使用hook_access并且在op == delete的时候放置条件。如果满足条件fullfilled返回True否则返回false。如果错误,您的节点将不会被删除。

记住管理员这将不会被触发。

1

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

这将删除删除按钮并添加您自己的按钮和操作。这不会阻止用户使用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"); 
    } 
} 
1

该自定义模块的代码是为Drupal 7,但我敢肯定,类似的概念也适用于Drupal的6.加,现在,你最有可能寻找为Drupal 7

的解决方案

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

这是截图展示了最终结果:

Screenshot showing node deletion prevention using custom code hook

这是所使用的自定义代码:

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

欲了解更多信息,请在此详细的博客文章conditionally preventing node deletion in Drupal 7。它具有关于整个过程的详细信息,并链接到资源,包括如何轻松创建自定义模块,您可以在其中复制/粘贴上述代码以使其工作。

祝你好运。