2010-09-16 45 views
4

如何为某些节点发出403?我尝试使用drupal_access_denied。虽然我得到了一个访问被拒绝的消息,看门狗充满:为某些节点发出403

不能更改头信息 - 头已经发出已

是正常吗?我没有使用drupal_access_denied的权利?

+2

你在哪里发出拒绝?在主题中,为时已晚。但是,您可以在没有问题的hook_nodeapi中执行该操作。 – berkes 2010-09-16 20:46:41

+0

加载操作中的hook_nodeapi是我拥有它的地方。是否可能登录平底雪橇干扰? – Kevin 2010-09-16 23:34:03

回答

5

使用建议的hook_nodeapi()还为时过晚。

如果你使用$op = load,你可能会耗尽你的内存,因为Drupal已经承诺它加载一个节点(包括多次加载它)时所做的所有正常事情。

如果使用$op = view,你可以“假”,如果你做到以下几点:

function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) { 
    switch ($op) { 
    case 'view': 
     drupal_access_denied(); 
     exit(); 
     break; 
    } 
} 

但它不是一个真正的403,它不会被报告为这样除了看门狗,所有的正常的东西仍然会加载和渲染,就像节点在那里一样。

对于一个简单的黑客,你可以使用hook_init()

function mymodule_init() { 
    $nodes_403 = array(42, 69, 187); 
    if (arg(0) == 'node' && in_array(arg(1), $nodes_403)) 
    drupal_access_denied(); 
    exit(); 
    } 
} 

但是,这不必要的绕过Drupal的内置的权限系统。相反,您希望利用Drupal的node access rights系统拒绝对节点的访问。

如果你定义的模块在自己的内容类型,你可以使用hook_access()

function mymodule_access($op, $node, $account) { 
    $nodes_403 = array(42, 69, 187); 

    if (in_array($node->nid, $nodes_403)) { 
    return FALSE; 
    } 
} 

但是,如果你没有定义自己的自定义内容类型,则永远不会调用hook_access()。因此,相反,你需要重写节点路径的access callback用自己:

function mymodule_menu_alter(&$items) { 
    $items['node/%node']['access callback'] = 'mymodule_access'; 
} 

function mymodule_access($op, $node, $account = NULL) { 
    $nodes_403 = array(42, 69, 187); 

    if ($op == 'view' && in_array($node->nid, $nodes_403)) { 
    return FALSE; 
    } 

    return node_access($op, $node, $account); 
} 

因为hook_menu_alter()落实,确保实现上述后重建你的菜单系统。

+0

我能够通过执行drupal_access_denied()获得'headers'错误。打破;在每次检查 - 但我也会看你的方法。希望这种解释是在API中。 http://api.drupal.org/api/function/drupal_access_denied/6 – Kevin 2010-09-17 12:49:47

+0

@Kevin:节点访问API的记录非常糟糕,当它开始时设计得不好的时候没有帮助(为什么我只能使用'hook_access ()'当我定义我自己的自定义内容类型时,而不是在所有节点上?或者就此而言,在任何*页上)。 Drupal 7清理了API,希望文档能够得到一些爱。 – 2010-09-17 16:32:42

+0

是的 - 我注意到这是为用户0打破某些cron函数。我重构了您的方法。另外,我疯了,还是nodeapi视图案不能像你期望的那样工作? – Kevin 2010-09-17 17:20:07