Using the suggested hook_nodeapi()
is still too late.
If you use the $op = load
, you'll likely exhaust your memory because Drupal has already committed to all the normal things it does when it loads a node (including loading it multiple times).
If you use $op = view
, you can "fake" it if you do the following:
function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
switch ($op) {
case 'view':
drupal_access_denied();
exit();
break;
}
}
But it's not a real 403: it won't be reported as such except in Watchdog, and all the normal stuff will still load and render as if the node was there.
For an easy hack, you could use 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();
}
}
But that's bypassing Drupal's built-in permissions system unnecessarily. Instead, you want to take advantage of Drupal's node access rights system to deny access to the node.
If you defined your own content type in the module, you could use hook_access()
:
function mymodule_access($op, $node, $account) {
$nodes_403 = array(42, 69, 187);
if (in_array($node->nid, $nodes_403)) {
return FALSE;
}
}
But if you don't define your own custom content types, hook_access()
is never invoked. So instead, you need to override the node path's access callback
with your own:
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);
}
Because of the hook_menu_alter()
implementation, make sure to rebuild your menu system after implementing the above.