View source
<?php
function node_privacy_byrole_help($section) {
switch ($section) {
case 'admin/help#node_privacy_byrole':
$output = '<p>' . t('The node privacy by role module allows users, when creating or editing a post, to select which roles of users on a site will have <em>view</em> permissions for the node and which users on a site will have <em>edit</em> permissions. Community leaders frequently want to give permissions to roles to create and manage content for a site. The ability to publish information, that would traditionally be hoarded, allows communities to educate each other while still preserving the value of knowledge.') . '</p>';
$output .= '<p>' . t('The node privacy by-role permissions are set by users for their nodes. If the node privacy by role module is disabled, the default permissions scheme will be in effect again, in which all users have view permissions for all nodes. However, if the module is re-enabled, the node-by-node permissions that were in place during the previous period in which the module was enabled will take effect again. Roles given edit permissions are automatically given view permissions even if the user tries to give <em>edit</em> permissions to a particular role, but not view permissions.') . '</p>';
$output .= t('<p>You can:</p>
<ul>
<li>set default permissions for each content type in the default workflow settings at <a href="@admin-node-configure-types">Administer >> Content management >> Content types</a> for each content type.</li>
<li>decide who can ignore the default permissions for each content type in the default workflow settings at <a href="@admin-node-configure-types">Administer >> Content management >> Content types</a> for each content type.</li>
</ul>', array(
'@admin-node-configure-types' => url('admin/content/types'),
));
$output .= '<p>' . t('For more information please read the configuration and customization handbook <a href="@node_privacy_byrole">Node privacy by role page</a>.', array(
'@node_privacy_byrole' => 'http://www.drupal.org/handbook/modules/node_privacy_byrole/',
)) . '</p>';
return $output;
}
}
function node_privacy_byrole_enable() {
node_access_rebuild();
}
function node_privacy_byrole_disable() {
node_privacy_byrole_disabling(TRUE);
node_access_rebuild();
}
function node_privacy_byrole_disabling($set = NULL) {
static $disabling = FALSE;
if ($set != NULL) {
$disabling = $set;
}
return $disabling;
}
function node_privacy_byrole_node_grants($account, $op) {
return array(
'node_privacy_byrole_role' => array_keys($account->roles),
'node_privacy_byrole_user' => array(
$account->uid,
),
);
}
function node_privacy_byrole_node_access_records($node) {
if (node_privacy_byrole_disabling()) {
return;
}
node_privacy_byrole_nodeapi_prepare($node);
$grants = array();
if ($node->uid > 0) {
$grants[] = array(
'realm' => 'node_privacy_byrole_user',
'gid' => $node->uid,
'grant_view' => TRUE,
'grant_update' => FALSE,
'grant_delete' => FALSE,
'priority' => 0,
);
}
foreach (array_keys(user_roles()) as $rid) {
$edit_perm = $node->node_privacy_byrole['roles'][$rid]['edit'] ? 1 : 0;
$delete_perm = $node->node_privacy_byrole['roles'][$rid]['delete'] ? 1 : 0;
$view_perm = $edit_perm || $delete_perm ? 1 : $node->node_privacy_byrole['roles'][$rid]['view'];
$grants[] = array(
'realm' => 'node_privacy_byrole_role',
'gid' => $rid,
'grant_view' => $view_perm,
'grant_update' => $edit_perm,
'grant_delete' => $delete_perm,
'priority' => 0,
);
}
return $grants;
}
function node_privacy_byrole_nodeapi(&$node, $op, $arg = 0) {
$roles = array_keys(user_roles());
switch ($op) {
case 'load':
case 'prepare':
node_privacy_byrole_nodeapi_prepare($node);
break;
case 'delete':
db_query('DELETE FROM {node_privacy_byrole} WHERE nid = %d', $node->nid);
break;
case 'insert':
node_privacy_byrole_nodeapi_prepare($node);
foreach ($roles as $rid) {
db_query("INSERT INTO {node_privacy_byrole} (nid, gid, realm, grant_view, grant_update, grant_delete)\n VALUES (%d, %d, '%s', %d, %d, %d)", $node->nid, $rid, 'node_privacy_byrole_role', $node->node_privacy_byrole['roles'][$rid]['view'], $node->node_privacy_byrole['roles'][$rid]['edit'], $node->node_privacy_byrole['roles'][$rid]['delete']);
}
db_query("INSERT INTO {node_privacy_byrole} (nid, gid, realm, grant_view, grant_update, grant_delete)\n VALUES (%d, %d, '%s', %d, %d, %d)", $node->nid, $node->uid, 'node_privacy_byrole_user', 1, 1, 1);
break;
case 'update':
node_privacy_byrole_nodeapi_prepare($node);
db_query("DELETE FROM {node_privacy_byrole} WHERE nid = %d AND realm = 'node_privacy_byrole_role'", $node->nid);
foreach ($roles as $rid) {
db_query("INSERT INTO {node_privacy_byrole} (nid, gid, realm, grant_view, grant_update, grant_delete)\n VALUES (%d, %d, '%s', %d, %d, %d)", $node->nid, $rid, 'node_privacy_byrole_role', $node->node_privacy_byrole['roles'][$rid]['view'], $node->node_privacy_byrole['roles'][$rid]['edit'], $node->node_privacy_byrole['roles'][$rid]['delete']);
}
if (isset($node->node_privacy_byrole['author'])) {
db_query("UPDATE {node_privacy_byrole} SET grant_view = %d, grant_update = %d, grant_delete = %d\n WHERE nid = %d AND gid = %d AND realm = 'node_privacy_byrole_user'", (int) $node->node_privacy_byrole['author']['view'], (int) $node->node_privacy_byrole['author']['edit'], (int) $node->node_privacy_byrole['author']['delete'], $node->nid, $node->uid);
}
else {
db_query("UPDATE {node_privacy_byrole} SET grant_view = %d, grant_update = %d, grant_delete = %d\n WHERE nid = %d AND gid = %d AND realm = 'node_privacy_byrole_user'", 1, 0, 0, $node->nid, $node->uid);
}
break;
}
}
function node_privacy_byrole_nodeapi_prepare(&$node) {
if (!isset($node->node_privacy_byrole)) {
$roles = array_keys(user_roles());
$perms = array(
'view',
'edit',
'delete',
);
if ($node->nid && !$node->is_new) {
$result = db_query("SELECT gid, grant_view, grant_update, grant_delete FROM {node_privacy_byrole} " . "WHERE nid = %d AND realm = 'node_privacy_byrole_role'", $node->nid);
$current_perms = array();
while ($role = db_fetch_object($result)) {
$current_perms[$role->gid]['view'] = $role->grant_view;
$current_perms[$role->gid]['edit'] = $role->grant_update;
$current_perms[$role->gid]['delete'] = $role->grant_delete;
}
while (list(, $rid) = each($roles)) {
if (isset($current_perms[$rid])) {
while (list(, $perm) = each($perms)) {
$node->node_privacy_byrole['roles'][$rid][$perm] = $current_perms[$rid][$perm] ? 1 : 0;
}
}
else {
while (list(, $perm) = each($perms)) {
$default_roles = _node_privacy_byrole_get_default_roles($node->type, $perm);
$node->node_privacy_byrole['roles'][$rid][$perm] = in_array($rid, $default_roles) ? 1 : 0;
}
}
reset($perms);
}
}
else {
while (list(, $rid) = each($roles)) {
while (list(, $perm) = each($perms)) {
$default_roles = _node_privacy_byrole_get_default_roles($node->type, $perm);
$node->node_privacy_byrole['roles'][$rid][$perm] = in_array($rid, $default_roles) ? 1 : 0;
}
reset($perms);
}
}
}
}
function node_privacy_byrole_form_alter($form_id, &$form) {
if ('node_type_form' == $form_id) {
$form += node_privacy_byrole_node_type_form($form);
}
elseif ($form['#id'] == 'node-form') {
if (node_privacy_byrole_user_has_meta_perm($form['#node'])) {
$form += node_privacy_byrole_node_form($form);
}
}
}
function node_privacy_byrole_user_has_meta_perm($node) {
global $user;
if ($user->uid == 1) {
return TRUE;
}
$permitted_roles = _node_privacy_byrole_get_default_roles($node->type, 'grant');
$user_roles = array_keys($user->roles);
return count(array_intersect($permitted_roles, $user_roles)) ? TRUE : FALSE;
}
function _node_privacy_byrole_get_default_roles($type, $action) {
return variable_get('npbr_default_' . $action . '_perms_' . $type, array());
}
function node_privacy_byrole_node_type_form($form) {
$type = $form['#node_type']->type;
$roles = user_roles();
$perms = array(
'view' => array(
'title' => t('Default View Permissions'),
'description' => t('Select roles to be given view permisions by default.'),
),
'edit' => array(
'title' => t('Default Edit Permissions'),
'description' => t('Select roles to be given edit permissions by default.'),
),
'delete' => array(
'title' => t('Default Delete Permissions'),
'description' => t('Select roles to be given delete permissions by default.'),
),
'grant' => array(
'title' => t('Roles with rights to update permissions'),
'description' => t('Select which roles will have rights to alter permissions on nodes.'),
),
);
$form['npbr_workflow_settings'] = array(
'#type' => 'fieldset',
'#title' => t('Node privacy by role'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
while (list($perm, $permdata) = each($perms)) {
$permname = 'npbr_default_' . $perm . '_perms';
$form['npbr_workflow_settings'][$permname] = array(
'#tree' => TRUE,
'#type' => 'fieldset',
'#title' => $permdata['title'],
'#collapsible' => FALSE,
'#collapsed' => FALSE,
'#description' => $permdata['description'],
'#weight' => 0,
);
$default_perms = _node_privacy_byrole_get_default_roles($type, $perm);
foreach (array_keys($roles) as $rid) {
$form['npbr_workflow_settings'][$permname][$rid] = array(
'#type' => 'checkbox',
'#title' => $roles[$rid],
'#return_value' => 1,
'#default_value' => in_array($rid, $default_perms),
);
}
}
return $form;
}
function node_privacy_byrole_node_form($form) {
$roles = array_keys(user_roles());
$perms = array(
'view',
'edit',
'delete',
);
$form['node_privacy_byrole'] = array(
'#tree' => TRUE,
'#theme' => 'node_privacy_byrole_node_form_items',
'#type' => 'fieldset',
'#title' => t('View/Edit Permissions'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => 9,
);
while (list(, $rid) = each($roles)) {
$form['node_privacy_byrole']['roles'][$rid] = array(
'#type' => 'fieldset',
'#collapsible' => FALSE,
'#collapsed' => FALSE,
'#weight' => 0,
);
while (list(, $perm) = each($perms)) {
$form['node_privacy_byrole']['roles'][$rid][$perm] = array(
'#type' => 'checkbox',
'#title' => NULL,
'#return_value' => 1,
'#default_value' => empty($form['#node']->node_privacy_byrole['roles'][$rid][$perm]) ? array() : $form['#node']->node_privacy_byrole['roles'][$rid][$perm],
);
}
reset($perms);
}
return $form;
}
function theme_node_privacy_byrole_node_form_items($form) {
$roles = user_roles();
$header = array(
t('Role'),
t('View'),
t('Edit'),
t('Delete'),
);
$rows = array();
foreach (element_children($form['roles']) as $rid) {
$row = array();
$row[] = $roles[$rid];
foreach (element_children($form['roles'][$rid]) as $i) {
$row[] = drupal_render($form['roles'][$rid][$i]);
}
$rows[] = $row;
}
return theme('form_element', array(
'#description' => t('Select which users can view/edit your post based on their role.'),
), theme('table', $header, $rows));
}
function node_privacy_byrole_node_operations() {
global $form_values;
$operations = array();
foreach (user_roles() as $rid => $role) {
$grants = array();
$revokes = array();
foreach (array(
'view',
'edit',
'delete',
) as $priv) {
$grants['grant-' . $rid . '-' . $priv] = t('Grant !priv for !role', array(
'!priv' => $priv,
'!role' => $role,
));
$revokes['revoke-' . $rid . '-' . $priv] = t('Revoke !priv for !role', array(
'!priv' => $priv,
'!role' => $role,
));
}
$operations[t('Access for role !role', array(
'!role' => $role,
))] = array(
'label' => $grants + $revokes,
);
}
if ($form_values) {
$operation_args = explode('-', $form_values['operation']);
if ($operation_args[0] == 'grant' || $operation_args[0] == 'revoke') {
if (user_access('administer content')) {
$op = $operation_args[0] == 'grant' ? 1 : 0;
$operations[$form_values['operation']] = array(
'callback' => 'node_privacy_byrole_node_operations_update',
'callback arguments' => array(
$op,
$operation_args[1],
$operation_args[2],
),
);
}
else {
watchdog('security', t('Detected unauthorized attempt to alter content access permissions.'), WATCHDOG_WARNING);
return;
}
}
}
return $operations;
}
function node_privacy_byrole_node_operations_update($nodes, $perm, $rid, $priv) {
if (user_access('administer content')) {
foreach ($nodes as $node_to_update) {
$node = node_load($node_to_update);
$node->node_privacy_byrole['roles'][$rid][$priv] = $perm;
node_save($node);
}
}
else {
drupal_set_message('You do not have permission to administer content.', 'error');
watchdog('security', t('Detected unauthorized attempt to alter content access permissions.'), WATCHDOG_WARNING);
}
}
function node_privacy_byrole_action_info() {
return array(
'node_privacy_byrole_change_role_action' => array(
'description' => t('Change role permissions'),
'configurable' => TRUE,
'type' => 'node',
'hooks' => array(
'nodeapi' => array(
'insert',
'update',
),
),
),
'node_privacy_byrole_rolereference_action' => array(
'description' => t('Change permissions based on rolereference field'),
'type' => 'node',
'configurable' => TRUE,
'hooks' => array(
'nodeapi' => array(
'insert',
'update',
),
),
),
);
}
function node_privacy_byrole_change_role_action($node, $context) {
if (isset($context['node_privacy_byrole']['roles'])) {
$node->node_privacy_byrole['roles'] = $context['node_privacy_byrole']['roles'];
}
module_invoke('node_privacy_byrole', 'nodeapi', $node, 'update');
}
function node_privacy_byrole_change_role_action_form($context) {
$form = array();
$defaults['#node']->node_privacy_byrole = $context['node_privacy_byrole'];
$form += node_privacy_byrole_node_form($defaults);
unset($form['node_privacy_byrole']['#weight']);
$form['node_privacy_byrole']['#collapsed'] = FALSE;
return $form;
}
function node_privacy_byrole_change_role_action_validate($form_id, $form_values) {
$errors = array();
if (empty($form_values['node_privacy_byrole'])) {
$errors['node_privacy_byrole'] = t('Please use the supplied form to submit access permissions.');
}
foreach ($errors as $name => $message) {
form_set_error($name, $message);
}
return count($errors) == 0;
}
function node_privacy_byrole_change_role_action_submit($form_id, $form_values) {
return array(
'node_privacy_byrole' => $form_values['node_privacy_byrole'],
);
}
function node_privacy_byrole_rolereference_action($node, $context) {
if (isset($context['node_privacy_byrole']['roles'])) {
$node->node_privacy_byrole['roles'] = $context['node_privacy_byrole']['roles'];
}
$node->node_privacy_byrole['author'] = $context['node_author'];
foreach ($context['permissions'] as $key => $value) {
$context['permissions'][$key] = empty($context['permissions'][$key]) ? 0 : 1;
}
foreach (_node_privacy_byrole_walk_role_fields($node->{$context}['field']) as $rid) {
$node->node_privacy_byrole['roles'][$rid] = $context['permissions'];
}
module_invoke('node_privacy_byrole', 'nodeapi', $node, 'update');
}
function node_privacy_byrole_rolereference_action_form($context) {
$form = array();
$defaults['#node']->node_privacy_byrole = $context['node_privacy_byrole'];
$form += node_privacy_byrole_node_form($defaults);
unset($form['node_privacy_byrole']['#weight']);
$form['node_privacy_byrole']['#title'] = t('Default permissions');
$form['new'] = array(
'#type' => 'fieldset',
'#title' => t('New permission'),
'#description' => t('The new permissions to set that will override the defaults. The value of the field is expected to match a numerical role id.'),
'#collapsed' => TRUE,
'#collapsible' => TRUE,
);
$fields = content_fields();
$options = array();
foreach ($fields as $field) {
$options[$field['field_name']] = t($field['widget']['label']) . ' (' . $field['field_name'] . ')';
}
asort($options, SORT_LOCALE_STRING);
$form['new']['field'] = array(
'#title' => t('Field'),
'#type' => 'select',
'#options' => $options,
'#default_value' => $context['field'],
);
unset($fields, $field, $options);
$form['new']['permissions'] = array(
'#title' => t('Permissions'),
'#type' => 'checkboxes',
'#options' => array(
'view' => t('view'),
'edit' => t('edit'),
'delete' => t('delete'),
),
'#default_value' => $context['permissions'],
'#description' => t('Edit permission implies view. Delete permission implies edit.'),
);
$form['author'] = array(
'#type' => 'fieldset',
'#title' => t('Node Author'),
'#collapsed' => TRUE,
'#collapsible' => TRUE,
);
$form['author']['node_author'] = array(
'#type' => 'checkboxes',
'#options' => array(
'view' => t('view'),
'edit' => t('edit'),
'delete' => t('delete'),
),
'#default_value' => $context['node_author'],
'#description' => t('Edit permission implies view. Delete permission implies edit.'),
);
return $form;
}
function node_privacy_byrole_rolereference_action_validate($form_id, $form_values) {
$errors = array();
if (empty($values['node_privacy_byrole']) && empty($form_values['field']) && empty($form_values['permissions']) && empty($form_values['node_author'])) {
$errors['node_privacy_byrole'] = t('Please use the supplied form to submit access permissions.');
}
foreach ($errors as $name => $message) {
form_set_error($name, $message);
}
return count($errors) == 0;
}
function node_privacy_byrole_rolereference_action_submit($form_id, $form_values) {
$params = array(
'node_privacy_byrole' => $form_values['node_privacy_byrole'],
'field' => $form_values['field'],
'permissions' => $form_values['permissions'],
'node_author' => $form_values['node_author'],
);
return $params;
}
function action_node_privacy_byrole_actions_change_role($op, $edit = array(), $node) {
switch ($op) {
case 'do':
node_privacy_byrole_change_role_action($node, $edit);
break;
case 'metadata':
return array(
'description' => t('Change role permissions'),
'type' => t('Role permission change'),
'batchable' => FALSE,
'configurable' => TRUE,
);
case 'form':
return node_privacy_byrole_change_role_action_form($edit);
case 'validate':
$errors = array();
if (empty($edit['node_privacy_byrole'])) {
$errors['node_privacy_byrole'] = t('Please use the supplied form to submit access permissions.');
}
foreach ($errors as $name => $message) {
form_set_error($name, $message);
}
return count($errors) == 0;
case 'submit':
$params = array(
'node_privacy_byrole' => $edit['node_privacy_byrole'],
);
return $params;
}
}
function action_node_privacy_byrole_actions_rolereference($op, $edit = array(), $node) {
switch ($op) {
case 'do':
node_privacy_byrole_rolereference_action($node, $edit);
break;
case 'metadata':
if (module_exists('rolereference')) {
return array(
'description' => t('Change permissions from rolereference'),
'type' => t('Rolereference permission change'),
'batchable' => false,
'configurable' => true,
);
}
else {
break;
}
case 'form':
return node_privacy_byrole_rolereference_action_form($edit);
case 'validate':
$errors = array();
if (empty($edit['node_privacy_byrole']) && empty($edit['field']) && empty($edit['permissions']) && empty($edit['node_author'])) {
$errors['node_privacy_byrole'] = t('Please use the supplied form to submit access permissions.');
}
foreach ($errors as $name => $message) {
form_set_error($name, $message);
}
return count($errors) == 0;
case 'submit':
$params = array(
'node_privacy_byrole' => $edit['node_privacy_byrole'],
'field' => $edit['field'],
'permissions' => $edit['permissions'],
'node_author' => $edit['node_author'],
);
return $params;
}
}
function _node_privacy_byrole_walk_role_fields($form) {
if (!is_array($form)) {
return array(
$form,
);
}
else {
$rids = array();
foreach (array_keys($form) as $getvar) {
if (element_child($getvar) && is_array($form) && !is_null($form[$getvar])) {
$returned = _node_privacy_byrole_walk_role_fields($form[$getvar]);
$rids = array_merge($rids, $returned);
}
else {
$rids[] = $getvar;
}
}
}
return $rids;
}