node_access_example.module

<?php
// $Id: node_access_example.module,v 1.4.4.3 2006/11/17 21:14:17 drewish Exp $

/**
 * @file
 * This is an example illustrating how to restrict access to nodes based on some
 * criterion associated with the user.
 *
 * Database definition:
 * @code
 *   DELETE FROM node_access;
 *   INSERT INTO node_access (nid, gid, realm, grant_view, grant_update,
 *      grant_delete) VALUES (0, 1, 'example', 1, 0, 0)
 * @endcode
 *
 * This SQL needs to be run before the module will work properly. The installer
 * system will probably perform this work in the future. The first line removes
 * any existing grants, including (most importantly) the universal grant
 * installed by default that gives read access to every node for everyone. The
 * second line grants read access to every node for users with the "access
 * private content" permission; in the scheme we're defining here, each node
 * will either be private (in which case it can always be read by anyone with
 * that permission) or public (in which case it can be read by everyone). We'll
 * take care of public nodes in node_access_example_nodeapi().
 */

/**
 * Implementation of hook_help().
 */
function node_access_example_help($section) {
  switch ($section) {
    case 'admin/modules#description':
      return t('An example illustrating how to restrict access to nodes based on some criterion associated with the user.');
  }
}

/**
 * Implementation of hook_perm().
 *
 * In this example, we will use a simple permission to determine whether a user
 * has access to "private" content. This permission is defined here.
 */
function node_access_example_perm() {
  return array('access private content');
}

/**
 * Implementation of hook_node_grants().
 *
 * Since we are restricting access based on a permission, we need to check that
 * permission and return the appropriate result.
 *
 */
function node_access_example_node_grants($account, $op) {
  $grants = array();
  if (user_access('access content', $account)) {
    $grants[] = 0;
  }
  if (user_access('access private content', $account)) {
    $grants[] = 1;
  }
  return array('example' => $grants);
}

/**
 * Implementation of hook_form_alter().
 *
 * We use this to alter the node editing form and insert a check box so the
 * admins can manage the node's access rights.
 *
 * Modules may wish to provide default grants per node type using this hook.
 */
function node_access_example_form_alter($form_id, &$form) {
  // This hook is called for all forms. We only want to work with node settings
  // and edit forms.
  if (isset($form['type'])) {
    // Node settings form.
    if ($form['type']['#value'] .'_node_settings' == $form_id) {
      // If the module needed it, this would be where you would insert controls
      // for the node's settings form.
    }

    // Node edit form for users with "administer nodes" permission.
    if ($form['type']['#value'] .'_node_form' == $form_id && user_access('administer nodes')) {
      $node = $form['#node'];
       if (!isset($node->access_example)) {
        // Load the grants from the database.
        $result = db_query('SELECT na.gid FROM {node_access} na WHERE na.nid = %d AND na.realm = \'example\' AND na.grant_view = 1', $node->nid);
        $grant = db_fetch_object($result);
        if ($grant && $grant->gid == 0) {
          // The "public" grant was set.
          $node->access_example = 0;
        }
        else {
          $node->access_example = 1;
        }
      }
      $form['access_example'] = array(
        '#type' => 'checkbox',
        '#title' => t('Private Node Access'),
        '#default_value' => $node->access_example,
        '#weight' => -10,
        '#description' => t('Make this node private.'),
      );
    }
  }
}

/**
 * Implementation of hook_nodeapi().
 *
 * Most of a node access module's work will be done via this hook. Several
 * values of $op will require responses:
 *
 * - "delete", "insert", and "update":
 *   The module must take care of updating the node_access table appropriately
 *   when nodes are modified, probably using the form element mentioned above.
 *   Only the realm(s) handled by the module should be affected, so that multiple
 *   node access modules can peacefully coexist.
 * - "validate":
 *   Depending on the user interface provided in the node form, the selection
 *   may need to be verified and validated here.
 */
function node_access_example_nodeapi(&$node, $op, $arg = 0) {
  switch ($op) {
    case 'delete':
      // When a node is deleted, delete any relevant grants.
      db_query('DELETE FROM {node_access} WHERE nid = %d AND realm = \'example\'', $node->nid);
      break;
    case 'insert':
    case 'update':
      // Clear out any existing grants for the node, and set new ones.
      db_query('DELETE FROM {node_access} WHERE nid = %d AND realm = \'example\'', $node->nid);
      $node->access_example = isset($node->access_example) ? $node->access_example : 0;

      if ($node->access_example == 0) {
        // If the node is public, we need to grant access to everyone.
        db_query('INSERT INTO {node_access} (nid, gid, realm, grant_view, grant_update, grant_delete) VALUES (%d, %d, \'example\', %d, %d, %d)', $node->nid, 0, 1, 0, 0);
      }
      break;
  }
}
 
 

All source code and documentation on this site is released under the terms of the GNU General Public License, version 2 and later. Drupal is a registered trademark of Dries Buytaert.