Same filename and directory in other branches
  1. 4.6.x developer/examples/node_access_example.module
  2. 5.x developer/examples/node_access_example.module

This is an example illustrating how to restrict access to nodes based on some criterion associated with the user.

Database definition:


  DELETE FROM node_access;
  INSERT INTO node_access (nid, gid, realm, grant_view, grant_update,
     grant_delete) VALUES (0, 1, 'example', 1, 0, 0)

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().

File

developer/examples/node_access_example.module
View source
<?php

/**
 * @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;
  }
}

Functions