Index: book_access.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/book_access/book_access.module,v
retrieving revision 1.15
diff -u -r1.15 book_access.module
--- book_access.module 26 Jan 2009 05:56:15 -0000 1.15
+++ book_access.module 7 Feb 2009 00:39:06 -0000
@@ -21,7 +21,7 @@
switch ($path) {
case 'admin/content/book/access':
return t('
-
Configure access control per book based on user roles. Settings
+
Configure access control per book based on users or roles. Settings
affect all pages within the given book. If a page is moved into a
different book, it will assume that book\'s access control settings.
Important: If you are going to manage access control here,
@@ -98,10 +98,11 @@
/**
* This function supplies the book access grants. book_access simply uses
- * roles as grant IDs.
+ * roles and user IDs as grant IDs.
*/
function book_access_node_grants($user, $op) {
$grants['book_access'] = array_keys($user->roles);
+ $grants['book_access_user'] = array($user->uid);
return $grants;
}
@@ -128,6 +129,19 @@
);
}
+ // Add the per-user grants.
+ $result = db_query("SELECT * FROM {book_access_user} WHERE nid = %d", $book_nid);
+ while ($grant = db_fetch_object($result)) {
+ $grants[] = array(
+ 'realm' => 'book_access_user',
+ 'gid' => $grant->uid,
+ 'grant_view' => $grant->grant_view,
+ 'grant_update' => $grant->grant_update,
+ 'grant_delete' => $grant->grant_delete,
+ 'priority' => BOOK_ACCESS_GRANT_PRIORITY,
+ );
+ }
+
return $grants;
}
}
@@ -241,6 +255,62 @@
'#title' => t('Delete pages in this book'),
'#default_value' => $delete
);
+
+ // Note that the autocomplete widget will only enable for users with the
+ // 'access profiles' permission. Other users will have to specify the name
+ // manually.
+ $form['access'][$book_nid]['search_user'] = array(
+ '#type' => 'textfield',
+ '#prefix' => '
',
+ '#suffix' => '
',
+ '#title' => t('Add a User'),
+ '#description' => t('Enter a user name to set permissions for that user on this book.'),
+ '#size' => 40,
+ '#autocomplete_path' => 'user/autocomplete',
+ );
+ $form['access'][$book_nid]['user_view'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('View this book'),
+ '#default_value' => TRUE,
+ );
+ $form['access'][$book_nid]['user_update'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Edit pages in this book'),
+ );
+ $form['access'][$book_nid]['user_delete'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Delete pages in this book'),
+ );
+
+ // Show a table of existing user grants.
+ $result = db_query("SELECT * FROM {book_access_user} where nid = %d", $book_nid);
+ $form['access'][$book_nid]['users'] = array();
+ while ($book_access = db_fetch_object($result)) {
+ $user = user_load($book_access->uid);
+ $defaults = array();
+ if ($book_access->grant_view) {
+ $defaults[] = 'view';
+ }
+ if ($book_access->grant_update) {
+ $defaults[] = 'update';
+ }
+ if ($book_access->grant_delete) {
+ $defaults[] = 'delete';
+ }
+ $form['access'][$book_nid]['users'][$user->uid] = array(
+ '#type' => 'checkboxes',
+ '#title' => t('Permissions for %user', array('%user' => $user->name)),
+ '#prefix' => '',
+ '#suffix' => '
',
+ '#options' => array(
+ 'view' => t('View pages in this book'),
+ 'update' => t('Edit pages in this book'),
+ 'delete' => t('Delete pages in this book'),
+ 'remove' => t('Reset permissions for this user to defaults'),
+ ),
+ '#default_value' => $defaults,
+ );
+ }
}
$form['clearer'] = array(
@@ -259,8 +329,31 @@
return $form;
}
-function book_access_admin_form_submit($form, &$form_state) {
+/**
+ * Implementation of the Form API validation handler.
+ *
+ * @param $form
+ * The form to validate.
+ * @param $form_state
+ * The current state of the form as submitted.
+ */
+function book_access_admin_form_validate($form, &$form_state) {
+ foreach ($form_state['values']['access'] as $book_nid => $access) {
+ if (!empty($access['search_user']) && !user_load(array('name' => $access['search_user']))) {
+ form_set_error("access][$book_nid][search_user", t('%user is not a valid user name.', array('%user' => $access['search_user'])));
+ }
+ }
+}
+/**
+ * Implementation of the Form API submission handler.
+ *
+ * @param $form
+ * The form to validate.
+ * @param $form_state
+ * The current state of the form as submitted.
+ */
+function book_access_admin_form_submit($form, &$form_state) {
foreach ($form_state['values']['access'] as $book_nid => $access) {
db_query("DELETE FROM {book_access} WHERE nid = %d", $book_nid);
@@ -276,6 +369,38 @@
db_query($sql, $book_nid, $rid, $grant_view, $grant_update, $grant_delete);
}
+
+ // If a user has been specified, update the permissions for that user. Also
+ // update a user if it currently has existing permissions.
+ if (!empty($access['search_user'])) {
+ $user = user_load(array('name' => $access['search_user']));
+ db_query("DELETE FROM {book_access_user} WHERE nid = %d AND uid = %d", $book_nid, $user->uid);
+ $grant_view = ($access['user_view'] > 0);
+ $grant_update = ($access['user_update'] > 0);
+ $grant_delete = ($access['user_delete'] > 0);
+ $sql = "
+ INSERT INTO {book_access_user} (nid, uid, grant_view, grant_update, grant_delete)
+ VALUES (%d, %d, %d, %d, %d)
+ ";
+ db_query($sql, $book_nid, $user->uid, $grant_view, $grant_update, $grant_delete);
+ }
+ // If an existing user has been changed, update that user.
+ if (!empty($access['users'])) {
+ foreach($access['users'] as $uid => $checked) {
+ $user = user_load($uid);
+ db_query("DELETE FROM {book_access_user} WHERE nid = %d AND uid = %d", $book_nid, $user->uid);
+ if (!$checked['remove']) {
+ $grant_view = !empty($checked['view']);
+ $grant_update = !empty($checked['update']);
+ $grant_delete = !empty($checked['delete']);
+ $sql = "
+ INSERT INTO {book_access_user} (nid, uid, grant_view, grant_update, grant_delete)
+ VALUES (%d, %d, %d, %d, %d)
+ ";
+ db_query($sql, $book_nid, $user->uid, $grant_view, $grant_update, $grant_delete);
+ }
+ }
+ }
}
node_access_rebuild();
}
@@ -331,6 +456,21 @@
$permitted_bids[$result->nid] = $result->nid;
}
+ // Add in the per-user grants.
+ $sql = "
+ SELECT nid
+ FROM {node_access}
+ WHERE realm = 'book_access_user'
+ AND gid = %d
+ AND grant_update > 0
+ ";
+
+ $results = db_query($sql, $user->uid);
+
+ while ($result = db_fetch_object($results)) {
+ $permitted_bids[$result->nid] = $result->nid;
+ }
+
if (isset($options)) {
foreach ($options as $bid => $value) {
// option uses current nid as the key, skip it
@@ -338,7 +478,7 @@
continue;
}
if ($bid > 0 && !isset($permitted_bids[$bid])) {
- unset($options[$nid]);
+ unset($options[$bid]);
}
}
}
Index: book_access.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/book_access/book_access.install,v
retrieving revision 1.4
diff -u -r1.4 book_access.install
--- book_access.install 5 Sep 2008 23:35:45 -0000 1.4
+++ book_access.install 7 Feb 2009 00:39:06 -0000
@@ -59,6 +59,48 @@
),
'primary key' => array('nid', 'rid'),
);
+ $schema['book_access_user'] = array(
+ 'description' => t('Table for tracking book access by user.'),
+ 'fields' => array(
+ 'nid' => array(
+ 'description' => t('Primary key: The node ID of the book.'),
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ ),
+ 'uid' => array(
+ 'description' => t('Primary key: A user ID associated with a book node ID.'),
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ ),
+ 'grant_view' => array(
+ 'description' => t('View book is allowed. 1 = TRUE, 0 = FALSE.'),
+ 'type' => 'int',
+ 'size' => 'tiny',
+ 'insigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ ),
+ 'grant_update' => array(
+ 'description' => t('Edit book pages is allowed. 1 = TRUE, 0 = FALSE.'),
+ 'type' => 'int',
+ 'size' => 'tiny',
+ 'insigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ ),
+ 'grant_delete' => array(
+ 'description' => t('Delete book pages is allowed. 1 = TRUE, 0 = FALSE.'),
+ 'type' => 'int',
+ 'size' => 'tiny',
+ 'insigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ ),
+ ),
+ 'primary key' => array('nid', 'uid'),
+ );
return $schema;
}
@@ -69,3 +111,57 @@
function book_access_uninstall() {
drupal_uninstall_schema('book_access');
}
+
+/**
+ * Add a table allowing specific users to be added to book access.
+ * @return
+ * Array of results from the update queries.
+ */
+function book_access_update_6001() {
+ $ret = array();
+ $schema = array();
+ $schema['book_access_user'] = array(
+ 'description' => t('Table for tracking book access by user.'),
+ 'fields' => array(
+ 'nid' => array(
+ 'description' => t('Primary key: The node ID of the book.'),
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ ),
+ 'uid' => array(
+ 'description' => t('Primary key: A user ID associated with a book node ID.'),
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ ),
+ 'grant_view' => array(
+ 'description' => t('View book is allowed. 1 = TRUE, 0 = FALSE.'),
+ 'type' => 'int',
+ 'size' => 'tiny',
+ 'insigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ ),
+ 'grant_update' => array(
+ 'description' => t('Edit book pages is allowed. 1 = TRUE, 0 = FALSE.'),
+ 'type' => 'int',
+ 'size' => 'tiny',
+ 'insigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ ),
+ 'grant_delete' => array(
+ 'description' => t('Delete book pages is allowed. 1 = TRUE, 0 = FALSE.'),
+ 'type' => 'int',
+ 'size' => 'tiny',
+ 'insigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ ),
+ ),
+ 'primary key' => array('nid', 'uid'),
+ );
+ db_create_table($ret, 'book_access_user', $schema['book_access_user']);
+ return $ret;
+}