IDEAS | BLOG

Programmatically Restricting Access to Drupal Content

Have a requirement like "I want users to not be able to add, update, delete or view content if some condition is true?" If so, hook_node_access might be all you need.

This hook simply allows you to alter access to a node. Now let's learn how to use it. How this hook works Anytime a user accesses a node (to add, update, delete or view it) this hook is called and can be used to alter that access decision. It receives three parameters.

  • $node – Contains information about the node being accessed (or base information, if it is being created)
  • $op – What type of access it is (create, update, delete, view)
  • $account – Information about the user accessing the node

It expects a return value to alter the access, which is; NODE_ACCESS_DENY, NODE_ACCESS_IGNORE or NODE_ACCESS_ALLOW. Best practice is to not use allow and use either deny or ignore (ignore is the default, if no return is given). You get far less permissions headaches this way. I use this module often for customized workflow requirements. The most recent use case was "I want to deny update access to all users who try to update a node based on a user select field on the node selecting them or not." This is all done with one simple hook in a custom module (see below). NOTE: There are some instances this hook is not called/skipped. Refer to the hook's link for those cases.

/**
 * Implements hook_node_access().
 *
 * Enforces our access rules for custom workflow target content to force updates
 * only if the user is targeted in the user select field
 */
 function mymodule_node_access($node, $op, $account) {
   // If a node is being updated
   if ($op == 'update') {
     // If the user select field exists on this node
     if (isset($node->field_my_user_select)) {
       // If the user select field is not empty
       if (!empty($node->field_my_user_select)) {
         // If the user id in the user select field does not match the current user
         if ($node->field_my_user_select[LANGUAGE_NONE][0]['target_id'] !=
           $account->uid) {
           // The users are not the same. Deny access to update in this case
           return NODE_ACCESS_DENY;
         }
       }
     }
   }
   // Else ignore altering access
   return NODE_ACCESS_IGNORE;
}

 

More good ideas we think you'll enjoy