node_access_example.module

Tracking 6.x-1.x branch
  1. drupal
    1. 4.6 documentation/developer/examples/node_access_example.module
    2. 4.7 documentation/developer/examples/node_access_example.module
    3. 5 documentation/developer/examples/node_access_example.module
    4. 6 contributions/examples/node_access_example/node_access_example.module
    5. 7 contributions/examples/node_access_example/node_access_example.module
    6. 8 contributions/examples/node_access_example/node_access_example.module

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

This example module will simply set a single flag on a node: 'private'. If the flag is set, only users with the 'view private content' flag can see the node, and all users with 'edit private content' can edit (but not delete) the node.

Additionally we will ensure that the node author can always view, edit, and delete the node by providing an additional access realm that grants privileges to the node's author.

Database definition:

  CREATE TABLE node_access_example (
    nid int(10) unsigned NOT NULL default '0' PRIMARY KEY,
    private int,
    KEY `node_example_nid` (nid)
  )

Functions & methods

NameDescription
node_access_example_form_alterImplementation of hook_form_alter()
node_access_example_nodeapiImplementation of hook_nodeapi().
node_access_example_node_access_recordsImplements hook_node_access_records().
node_access_example_node_grantsImplements hook_node_grants().
node_access_example_permImplementation of hook_perm().

Constants

NameDescription
NODE_ACCESS_EXAMPLE_GRANT_ALLHere we define a constant for our node access grant ID, for the example realm. This ID could be any integer, but here we choose 23, because it is this author's favorite number.

File

View source
  1. <?php
  2. /**
  3. * @file
  4. *
  5. * This is an example illustrating how to restrict access to nodes based
  6. * on some criterion associated with the user.
  7. *
  8. * This example module will simply set a single flag on a node:
  9. * 'private'. If the flag is set, only users with the 'view private
  10. * content' flag can see the node, and all users with 'edit private
  11. * content' can edit (but not delete) the node.
  12. *
  13. * Additionally we will ensure that the node author can always view,
  14. * edit, and delete the node by providing an additional access realm that
  15. * grants privileges to the node's author.
  16. *
  17. * Database definition:
  18. * @code
  19. * CREATE TABLE node_access_example (
  20. * nid int(10) unsigned NOT NULL default '0' PRIMARY KEY,
  21. * private int,
  22. * KEY `node_example_nid` (nid)
  23. * )
  24. * @endcode
  25. */
  26. /**
  27. * @defgroup node_access_example Example: Node Access
  28. * @ingroup examples
  29. * @{
  30. * Examples of node access restriction. (drupal 6)
  31. *
  32. * This is an example illustrating how to restrict access to nodes based
  33. * on some criterion associated with the user.
  34. *
  35. * This example module will simply set a single flag on a node:
  36. * 'private'. If the flag is set, only users with the 'view private
  37. * content' flag can see the node, and all users with 'edit private
  38. * content' can edit (but not delete) the node.
  39. *
  40. * Additionally we will ensure that the node author can always view,
  41. * edit, and delete the node by providing an additional access realm that
  42. * grants privileges to the node's author.
  43. *
  44. * Database definition:
  45. * @code
  46. * CREATE TABLE node_access_example (
  47. * nid int(10) unsigned NOT NULL default '0' PRIMARY KEY,
  48. * private int,
  49. * KEY `node_example_nid` (nid)
  50. * )
  51. * @endcode
  52. *
  53. * This example is part of the Examples for Developers Project which you can download
  54. * and experiment with here: http://drupal.org/project/examples
  55. */
  56. /**
  57. * Implementation of hook_perm().
  58. *
  59. * In this example, we will use a simple permission to determine whether a user
  60. * has access to "private" content. This permission is defined here.
  61. */
  62. function node_access_example_perm() {
  63. return array('access private content', 'edit private content');
  64. }
  65. /**
  66. * Here we define a constant for our node access grant ID, for the example realm.
  67. * This ID could be any integer, but here we choose 23,
  68. * because it is this author's favorite number.
  69. */
  70. define('NODE_ACCESS_EXAMPLE_GRANT_ALL', 23);
  71. /**
  72. * Implements hook_node_grants().
  73. *
  74. * Tell the node access system what grant IDs the user belongs to for
  75. * each realm, based on the operation being performed.
  76. *
  77. * When the user tries to perform an operation on the node, Drupal calls
  78. * hook_node_grants() to determine grant ID and realm for the user.
  79. * Drupal looks up the grant ID and realm for the node, and compares them
  80. * to the grant ID and realm provided here. If grant ID and realm match
  81. * for both user and node, then the operation is allowed.
  82. *
  83. * Grant ID and realm are both determined per node, by your module in
  84. * hook_node_access_records().
  85. *
  86. * In our example, we've created three access realms: One for authorship,
  87. * and two that track with the permission system.
  88. *
  89. * We always add node_access_example_author to the list of grants, with a
  90. * grant ID equal to their user ID. We do this because in our model,
  91. * authorship always gives you permission to edit or delete your nodes,
  92. * even if they're marked private.
  93. *
  94. * Then we compare the user's permissions to the operation to determine
  95. * whether the user falls into the other two realms:
  96. * node_access_example_view, and/or node_access_example_edit. If the user
  97. * has the 'access any private content' permission we defined in
  98. * hook_permission(), they're declared as belonging to the
  99. * node_access_example_realm. Similarly, if they have the 'edit any
  100. * private content' permission, we add the node_access_example_edit realm
  101. * to the list of grants they have.
  102. *
  103. * @see node_access_example_perm()
  104. * @see node_access_example_node_access_records()
  105. */
  106. function node_access_example_node_grants($account, $op) {
  107. if ($op == 'view' && user_access('access private content', $account)) {
  108. $grants['node_access_example'] = array(NODE_ACCESS_EXAMPLE_GRANT_ALL);
  109. }
  110. if (($op == 'update' || $op == 'delete') && user_access('edit private content', $account)) {
  111. $grants['node_access_example'] = array(NODE_ACCESS_EXAMPLE_GRANT_ALL);
  112. }
  113. $grants['node_access_example_author'] = array($account->uid);
  114. return $grants;
  115. }
  116. /**
  117. * Implements hook_node_access_records().
  118. *
  119. * All node access modules must implement this hook. If the module is
  120. * interested in the privacy of the node passed in, return a list of node
  121. * access values for each grant ID we offer.
  122. *
  123. * In this example, for each node which is marked private, we define two
  124. * realms:
  125. *
  126. * The first realm is 'node_access_example' which have a single grant ID.
  127. * The user is either a member of these realms or not, depending upon the
  128. * operation and the access permission set.
  129. *
  130. * The second is 'node_access_example_author.' It gives the node author
  131. * special privileges. 'node_access_example_author' has one grant ID for
  132. * every UID, and each user is automatically a member of the group where
  133. * GID == UID. This has the effect of giving each user their own grant ID
  134. * for nodes they authored, within this realm.
  135. *
  136. * Drupal calls this hook when a node is saved, or when access
  137. * permissions change in order to rebuild the node access database
  138. * table(s).
  139. *
  140. * The array you return will define the realm and the grant ID for the
  141. * given node. This is stored in the {node_access} table for subsequent
  142. * comparison against the user's realm and grant IDs, which you'll supply
  143. * in hook_node_grants().
  144. *
  145. * Realm names and grant IDs are arbitrary. Official drupal naming
  146. * conventions do not cover access realms, but since all realms are
  147. * stored in the same database table, it's probably a good idea to use
  148. * descriptive names which follow the module name, such as
  149. * 'mymodule_realmname'.
  150. *
  151. * @see node_access_example_node_grants()
  152. */
  153. function node_access_example_node_access_records($node) {
  154. // We only care about the node if it's been marked private. If not, it is
  155. // treated just like any other node and we completely ignore it.
  156. if (!empty($node->private)) {
  157. $grants = array();
  158. $grants[] = array(
  159. 'realm' => 'node_access_example',
  160. 'gid' => NODE_ACCESS_EXAMPLE_GRANT_ALL,
  161. 'grant_view' => TRUE,
  162. 'grant_update' => FALSE,
  163. 'grant_delete' => FALSE,
  164. 'priority' => 0,
  165. );
  166. // For the example_author array, the GID is equivalent to a UID, which
  167. // means there are many many groups of just 1 user.
  168. $grants[] = array(
  169. 'realm' => 'node_access_example_author',
  170. 'gid' => $node->uid,
  171. 'grant_view' => TRUE,
  172. 'grant_update' => TRUE,
  173. 'grant_delete' => TRUE,
  174. 'priority' => 0,
  175. );
  176. return $grants;
  177. }
  178. }
  179. /**
  180. * Implementation of hook_form_alter()
  181. *
  182. * This module adds a simple checkbox to the node form labeled
  183. * private. If the checkbox is labelled, only the node author and
  184. * users with 'access private content' privileges may see it.
  185. */
  186. function node_access_example_form_alter(&$form, $form_state) {
  187. if ($form['#id'] == 'node-form') {
  188. $form['private'] = array(
  189. '#type' => 'checkbox',
  190. '#title' => t('Private'),
  191. '#description' => t('Check here if this content should be set private and only shown to privileged users.'),
  192. '#default_value' => isset($form['#node']->private) ? $form['#node']->private : FALSE,
  193. );
  194. }
  195. }
  196. /**
  197. * Implementation of hook_nodeapi().
  198. *
  199. * The module must track the access status of the node.
  200. */
  201. function node_access_example_nodeapi(&$node, $op, $arg = 0) {
  202. switch ($op) {
  203. case 'load':
  204. $node->private = db_result(db_query('SELECT private FROM {node_access_example} WHERE nid = %d', $node->nid));
  205. break;
  206. case 'insert':
  207. db_query('INSERT INTO {node_access_example} (nid, private) VALUES (%d, %d)', $node->nid, $node->private);
  208. break;
  209. case 'update':
  210. db_query('UPDATE {node_access_example} SET private = %d WHERE nid = %d', $node->private, $node->nid);
  211. break;
  212. case 'delete':
  213. db_query('DELETE FROM {node_access_example} WHERE nid = %d', $node->nid);
  214. break;
  215. }
  216. }
  217. /**
  218. * @} End of "defgroup node_access_example".
  219. */