content_access.module in Content Access 8
Same filename and directory in other branches
Content access module file.
File
content_access.moduleView source
<?php
/**
* @file
* Content access module file.
*/
use Drupal\Core\Session\AccountInterface;
use Drupal\node\NodeInterface;
use Drupal\node\NodeTypeInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Cache\Cache;
use Drupal\user\RoleInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Url;
use Drupal\user\Entity\Role;
use Drupal\node\Entity\Node;
use Drupal\content_access\ContentAccessInterface;
/**
* Implements hook_help().
*/
function content_access_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.content_access':
case 'entity.node.content_access':
case 'entity.node_type.content_access_form':
$hint_service = FALSE;
if (!empty(\Drupal::hasService('advanced_help_hint.gethint'))) {
$hint_service = \Drupal::service('advanced_help_hint.gethint');
}
$output = '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The <strong>Content Access</strong> module let you content manage access permission in a flexible and transparant way.') . '</p>';
$output .= '<h3>' . t('Use') . '</h3>';
$output .= '<p>' . t('It provides two new permissions: <em>view all</em> (allows anyone to view the content) and <em>view own</em> (allows only the content creator to see his/her own content). It also gives access to the existing core permissions <em>edit</em> and <em>delete</em> on the same settings page.') . '</p>';
$output .= '<p>' . t('It provides the following modalities:') . '</p><ul>';
$output .= '<li>' . t('Each <a href=":url"><em>content type</em></a> can have its own default content access settings by role.', [
':url' => Url::fromRoute('entity.node_type.collection')
->toString(),
]) . '</li>';
$output .= '<li>' . t('Optionally you can enable role based access control settings per <em>content node</em>.') . '</li>';
$output .= '<li>' . t('Access control can be further customized per <em>user</em> if you have the <a href=":url"><strong>ACL</strong></a> module enabled.', [
':url' => Url::fromUri('https://www.drupal.org/project/acl/')
->toString(),
]) . '</li></ul>';
if ($hint_service) {
$output .= '<p>' . $hint_service
->produceHint('content_access', 'https://www.drupal.org/docs/7/modules/content-access', TRUE) . '</p>';
}
else {
$output .= '<p>' . t('If you install and enable the module <a href=":url"><strong>Advanced Help Hint</strong></a>, you will get more help for <strong>Content Access</strong>.', [
':url' => Url::fromUri('https://www.drupal.org/project/advanced_help_hint')
->toString(),
]) . '</p>';
}
return $output;
}
}
/**
* Implements hook_node_grants().
*/
function content_access_node_grants(AccountInterface $account, $op) {
$gids = [];
$roles = $account
->getRoles();
foreach ($roles as $role) {
$gids[] = content_access_get_role_gid($role);
}
return [
'content_access_author' => [
$account
->id(),
],
'content_access_roles' => $gids,
];
}
/**
* Implements hook_node_access_records().
*/
function content_access_node_access_records(NodeInterface $node) {
if (content_access_disabling() || !$node
->isPublished()) {
return;
}
// Apply per node settings if necessary.
if (content_access_get_settings('per_node', $node
->getType())) {
$grants = [];
foreach ([
'view',
'update',
'delete',
] as $op) {
foreach (content_access_get_rids_per_node_op($op, $node) as $rid) {
$gid = content_access_get_role_gid($rid);
$grants[$gid]['grant_' . $op] = 1;
}
}
foreach ($grants as $gid => $grant) {
$grants[$gid] = content_access_proccess_grant($grant, $gid, $node);
}
// Care for the author grant.
$grant = [];
foreach ([
'view',
'update',
'delete',
] as $op) {
// Get all roles that have access to use $op on this node.
$per_node_settings = content_access_per_node_setting($op, $node);
$any_roles = array_combine($per_node_settings, $per_node_settings);
$any_roles = $any_roles ? $any_roles : [];
$any_roles += $op != 'view' ? content_access_get_settings($op, $node
->getType()) : [];
$grant['grant_' . $op] = content_access_own_op($node, $any_roles, content_access_get_rids_per_node_op($op . '_own', $node));
}
if (array_filter($grant)) {
$grant['realm'] = 'content_access_author';
$grants[] = content_access_proccess_grant($grant, $node
->getOwnerId(), $node);
}
}
else {
// Apply the content type defaults.
$grants = content_access_get_type_grant($node);
}
if (empty($grants)) {
// This means we grant no access.
$grants[] = content_access_proccess_grant([], 0, $node);
}
else {
content_access_optimize_grants($grants, $node);
}
return $grants;
}
/**
* Implements hook_node_delete().
*/
function content_access_node_delete(NodeInterface $node) {
\Drupal::database()
->delete('content_access')
->condition('nid', $node
->id())
->execute();
}
/**
* Implements hook_entity_insert().
*/
function content_access_entity_insert(EntityInterface $entity) {
$config = \Drupal::configFactory()
->getEditable('content_access.settings');
if ($entity instanceof RoleInterface) {
$roles_gids = array_flip($config
->get('content_access_roles_gids'));
$roles_gids[] = $entity
->id();
$config
->set('content_access_roles_gids', array_flip($roles_gids));
$config
->save();
}
}
/**
* Implements hook_entity_operation().
*/
function content_access_entity_operation(EntityInterface $entity) {
$operations = [];
$info = $entity
->getEntityType();
if ($info
->getBundleOf() == 'node') {
$account = \Drupal::currentUser();
if ($account
->hasPermission('bypass node access') && $account
->hasPermission('administer content types')) {
$operations['access-control'] = [
'title' => t('Access control'),
'weight' => 25,
'url' => Url::fromRoute('entity.node_type.content_access_form', [
'node_type' => $entity
->id(),
]),
];
}
}
return $operations;
}
/**
* Implements hook_entity_delete().
*/
function content_access_entity_delete(EntityInterface $entity) {
$config = \Drupal::configFactory()
->getEditable('content_access.settings');
if ($entity instanceof RoleInterface) {
$roles_gids = $config
->get('content_access_roles_gids');
unset($roles_gids[$entity
->id()]);
$config
->set('content_access_roles_gids', $roles_gids)
->save();
}
}
/**
* Used by the ACL module.
*/
function content_access_enabled() {
return !content_access_disabling();
}
/**
* Remembers if we have disabled access.
*/
function content_access_disabling($set = NULL) {
static $disabling = FALSE;
if (isset($set)) {
$disabling = $set;
}
return $disabling;
}
/**
* Return content_access' settings.
*
* @param string $setting
* One of the content_access_available_settings(), e.g. 'view' or 'per_node'.
* If 'all' is passed, all available settings are returned.
* @param string $type_name
* The name of the content type to return settings for.
*
* @return mixed
* The value of the given setting or an array of all settings.
*/
function content_access_get_settings($setting, $type_name) {
$config = \Drupal::configFactory()
->getEditable('content_access.settings');
$settings = unserialize($config
->get('content_access_node_type.' . $type_name));
if (empty($settings)) {
$settings = [];
}
$settings += content_access_get_setting_defaults($type_name);
if ($setting == 'all') {
return $settings;
}
return isset($settings[$setting]) ? $settings[$setting] : NULL;
}
/**
* Save content_access settings of a content type.
*/
function content_access_set_settings($settings, $type_name) {
$config = \Drupal::configFactory()
->getEditable('content_access.settings');
// Do not store default values so we do not have to care about syncing our
// settings with the permissions.
foreach (content_access_get_setting_defaults($type_name) as $setting => $default_value) {
if (isset($settings[$setting]) && $settings[$setting] == $default_value) {
unset($settings[$setting]);
}
}
$config
->set('content_access_node_type.' . $type_name, serialize($settings));
$config
->save();
}
/**
* Return an array containing all available content_access settings.
*/
function content_access_available_settings() {
return [
'view',
'update',
'delete',
'view_own',
'update_own',
'delete_own',
'per_node',
'priority',
];
}
/**
* Defines default values for settings.
*/
function content_access_get_setting_defaults($type) {
$defaults = [];
$defaults['view'] = $defaults['view_own'] = [
AccountInterface::ANONYMOUS_ROLE,
AccountInterface::AUTHENTICATED_ROLE,
];
foreach ([
'update',
'delete',
] as $op) {
$defaults[$op] = content_access_get_permission_access(content_access_get_permission_by_op($op, $type));
$defaults[$op . '_own'] = content_access_get_permission_access(content_access_get_permission_by_op($op . '_own', $type));
}
$defaults['priority'] = 0;
$defaults['per_node'] = FALSE;
return $defaults;
}
/**
* Returns an array of role ids that contain the given permission.
*/
function content_access_get_permission_access($perm, $reset = FALSE) {
$roles =& drupal_static(__FUNCTION__, []);
if ($reset) {
$roles = [];
}
if (!isset($roles[$perm]) && $perm) {
$user_roles = Role::loadMultiple();
foreach ($user_roles as $role) {
if ($role
->hasPermission($perm)) {
$roles[$perm][] = $role
->id();
}
}
}
return isset($roles[$perm]) ? $roles[$perm] : [];
}
/**
* Gets the name of a perm for the given operation, if there is a suiting one.
*/
function content_access_get_permission_by_op($op, $type) {
switch ($op) {
case 'update':
return 'edit any ' . $type . ' content';
case 'update_own':
return 'edit own ' . $type . ' content';
case 'delete':
return 'delete any ' . $type . ' content';
case 'delete_own':
return 'delete own ' . $type . ' content';
default:
return FALSE;
}
}
/**
* Returns the default grants for a given node type.
*/
function content_access_get_type_grant(NodeInterface $node) {
// Cache per type default grants in a static array.
static $defaults = [];
$node_type = $node
->getType();
if (!isset($defaults[$node_type])) {
$grants = [];
// Only process the 'view' op as node_access() will take care of
// edit and delete.
foreach (content_access_get_settings('view', $node_type) as $rid) {
$gid = content_access_get_role_gid($rid);
$grant['grant_view'] = 1;
$grants[] = content_access_proccess_grant($grant, $gid, $node);
}
$defaults[$node_type] = $grants;
}
// Care for the author grant.
$grant = $grants = [];
$settings = [
'view' => content_access_get_settings('view', $node_type),
'view_own' => content_access_get_settings('view_own', $node_type),
];
$grant['grant_view'] = content_access_own_op($node, $settings['view'], $settings['view_own']);
if ($grant['grant_view']) {
$grant['realm'] = 'content_access_author';
$grants = [
'author' => content_access_proccess_grant($grant, $node
->getOwnerId(), $node),
];
}
return $defaults[$node_type] + $grants;
}
/**
* Process a grant, which means add priority, realm and other properties.
*/
function content_access_proccess_grant($grant, $gid, NodeInterface $node) {
$grant += [
'grant_view' => 0,
'grant_update' => 0,
'grant_delete' => 0,
'realm' => 'content_access_roles',
];
$grant['gid'] = $gid;
$grant['priority'] = content_access_get_settings('priority', $node
->getType());
return $grant;
}
/**
* Determines grant for node author and the gives allowed roles of operation.
*
* @param array $any_roles
* The roles with which anybody has access (not optimized!).
* @param array $own_roles
* The roles with which only the author has access (optimized!).
*
* @return int
* Returns 0 if permission is granted, otherwise 1.
*/
function content_access_own_op(NodeInterface $node, array $any_roles, array $own_roles) {
static $roles = [];
$owner = $node
->getOwner();
if (!isset($roles[$owner
->id()])) {
$roles[$owner
->id()] = $owner
->id() ? [
AccountInterface::AUTHENTICATED_ROLE,
] : [
AccountInterface::ANONYMOUS_ROLE,
];
$result = $owner
->get('roles');
foreach ($result as $role) {
$roles[$owner
->id()][] = $role->target_id;
}
}
if (array_intersect($roles[$owner
->id()], $any_roles)) {
// If there is access due to "any permissions" there is no need to
// add an author grant.
return 0;
}
return array_intersect($roles[$owner
->id()], $own_roles) ? 1 : 0;
}
/**
* Get rids per node.
*
* Returns optimized role ids for the given operation and node to
* grant access for.
*
* If to a role access is granted by permissions, it's not necessary
* to write a grant for it. So it won't be returned.
*
* @param string $op
* One of the supported operations.
* @param \Drupal\node\NodeInterface $node
* The node object.
*/
function content_access_get_rids_per_node_op($op, NodeInterface $node) {
$rids = content_access_per_node_setting($op, $node);
if ($permission = content_access_get_permission_by_op($op, $node
->getType())) {
$perm_roles = content_access_get_permission_access($permission);
$rids = array_diff($rids, $perm_roles);
if (in_array(AccountInterface::AUTHENTICATED_ROLE, $perm_roles)) {
if (in_array(AccountInterface::ANONYMOUS_ROLE, $rids)) {
return [
AccountInterface::ANONYMOUS_ROLE,
AccountInterface::AUTHENTICATED_ROLE,
];
}
else {
return [
AccountInterface::AUTHENTICATED_ROLE,
];
}
}
}
return $rids;
}
/**
* Access per node setting.
*
* Returns the per node role settings. If no per node settings are available,
* it will return the content type settings.
*
* @param string $op
* One of the supported operations.
* @param \Drupal\node\NodeInterface $node
* The node object.
* @param array $settings
* Optional array used to update the settings cache with the given settings.
*
* @return array
* An array of role ids which have access.
*/
function content_access_per_node_setting($op, NodeInterface $node, array $settings = NULL) {
static $grants = [];
if (isset($settings)) {
// Update settings cache.
$grants[$node
->id()] = $settings;
return $settings;
}
if (!isset($grants[$node
->id()]) || $grants[$node
->id()] === FALSE) {
$grants[$node
->id()] = content_access_get_per_node_settings($node);
}
// Return the content type defaults if no per node settings are available.
return isset($grants[$node
->id()][$op]) ? $grants[$node
->id()][$op] : content_access_get_settings($op, $node
->getType());
}
/**
* Gets the per node settings of a node.
*
* @note
* This function won't apply defaults, so if there are no other settings
* it will return an empty array.
*/
function content_access_get_per_node_settings(NodeInterface $node) {
$query = \Drupal::database()
->query("SELECT settings FROM {content_access} WHERE nid = :nid", [
':nid' => $node
->id(),
]);
$result = $query
->fetch(PDO::FETCH_OBJ);
if (!empty($result->settings)) {
return unserialize($result->settings);
}
return [];
}
/**
* Saves custom per node settings in the own content_access table.
*/
function content_access_save_per_node_settings(NodeInterface $node, $settings) {
$database = \Drupal::database();
$count = $database
->select('content_access')
->fields('c', [
'settings',
])
->condition('nid', $node
->id())
->countQuery()
->execute()
->fetchField();
if ($count > 0) {
$database
->update('content_access')
->condition('nid', $node
->id())
->fields([
'settings' => serialize($settings),
])
->execute();
}
else {
$database
->insert('content_access')
->fields([
'nid' => $node
->id(),
'settings' => serialize($settings),
])
->execute();
}
// Make content_access_per_node_setting() use the new settings.
content_access_per_node_setting(NULL, $node, $settings);
}
/**
* Delete per node settings.
*
* Deletes all custom per node settings, so that content type defaults
* are used again.
*/
function content_access_delete_per_node_settings(NodeInterface $node) {
\Drupal::database()
->delete('content_access')
->condition('nid', $node
->id())
->execute();
// Clear the cache.
content_access_per_node_setting(NULL, $node);
// Delete possible acl settings.
if (\Drupal::moduleHandler()
->moduleExists('acl')) {
module_load_include('inc', 'content_access', 'content_access.admin');
foreach ([
'view',
'update',
'delete',
] as $op) {
$acl_id = content_access_get_acl_id($node, $op);
acl_delete_acl($acl_id);
}
}
}
/**
* Removes grants that doesn't change anything.
*
* @note
* The grants are compared with the normal access control settings.
*/
function content_access_optimize_grants(&$grants, NodeInterface $node) {
$rids = [
'view' => [],
'update' => [],
'delete' => [],
];
foreach ($grants as $key => $grant) {
foreach ([
'view',
'update',
'delete',
] as $op) {
if (!empty($grant['grant_' . $op])) {
$rids[$op][] = $grant['gid'];
}
}
}
// Detect if all are allowed to view.
$anonymous_gid = content_access_get_role_gid(AccountInterface::ANONYMOUS_ROLE);
$authenticated_gid = content_access_get_role_gid(AccountInterface::AUTHENTICATED_ROLE);
$all = [
$anonymous_gid,
$authenticated_gid,
];
if (empty(array_diff($all, $rids['view']))) {
// Grant view access to all instead of single roles.
$rids['view'] = [
'all',
];
$grants['all'] = [
'realm' => 'all',
'gid' => 0,
'grant_view' => 1,
'grant_update' => 0,
'grant_delete' => 0,
'priority' => content_access_get_settings('priority', $node
->getType()),
];
}
// If authenticated users are involved, remove unnecessary other roles.
foreach ([
'view',
'update',
'delete',
] as $op) {
if (in_array($authenticated_gid, $rids[$op])) {
$rids[$op] = in_array($anonymous_gid, $rids[$op]) ? [
$anonymous_gid,
$authenticated_gid,
] : [
$authenticated_gid,
];
}
}
// Now let's remove unnecessary grants, if any.
foreach ($grants as $key => $grant) {
if (!is_numeric($key)) {
continue;
}
foreach ([
'view',
'update',
'delete',
] as $op) {
if ($grant['grant_' . $op] && in_array($grant['gid'], $rids[$op])) {
// It is still here, so we cannot remove this grant.
continue 2;
}
}
// ok, remove it.
unset($grants[$key]);
}
}
/**
* Implements hook_node_type_delete().
*/
function content_access_node_type_delete(NodeTypeInterface $info) {
$config = \Drupal::configFactory()
->getEditable('content_access.settings');
$config
->clear('content_access_node_type.' . $info
->id())
->save();
}
/**
* Implements hook_node_type_update().
*
* Updates settings on node type name change.
*/
function content_access_node_type_update(NodeTypeInterface $info) {
$config = \Drupal::configFactory()
->getEditable('content_access.settings');
$original_id = $info
->getOriginalId();
if (!empty($original_id) && $info
->getOriginalId() != $info
->id()) {
$settings = content_access_get_settings('all', $info
->getOriginalId());
content_access_set_settings($settings, $info
->id());
$config
->clear('content_access_node_type.' . $info
->getOriginalId())
->save();
}
}
/**
* Implements hook_node_access_explain().
*/
function content_access_node_access_explain($row) {
static $roles;
if (!isset($roles)) {
$roles = user_roles();
}
if (!$row->gid && $row->realm == 'content_access_roles') {
return t('Content access: No access is granted.');
}
switch ($row->realm) {
case 'content_access_author':
return t('Content access: author of the content can access');
case 'content_access_roles':
return t('Content access: %role can access', [
'%role' => $roles[$row->gid],
]);
}
}
/**
* Implements hook_form_alter().
*/
function content_access_form_alter(&$form, FormStateInterface $form_state, $form_id) {
if ($form_id == 'user_admin_perm') {
$build_info = $form_state
->getBuildInfo();
$build_info['files'][] = [
'module' => 'content_access',
'type' => 'inc',
'name' => 'content_access.admin',
];
$form_state
->setBuildInfo($build_info);
$form['actions']['submit']['#submit'][] = 'content_access_user_admin_perm_submit';
}
}
/**
* Returns an array of possible operations on content and their labels.
*/
function _content_access_get_operations($type = NULL) {
$operations = [
'view' => t('View any @type content', [
'@type' => $type,
]),
'view_own' => t('View own @type content', [
'@type' => $type,
]),
'update' => t('Edit any @type content', [
'@type' => $type,
]),
'update_own' => t('Edit own @type content', [
'@type' => $type,
]),
'delete' => t('Delete any @type content', [
'@type' => $type,
]),
'delete_own' => t('Delete own @type content', [
'@type' => $type,
]),
];
return $operations;
}
/**
* Gets node's access permissions.
*/
function _content_access_get_node_permissions($type) {
return array_filter(array_map('content_access_get_permission_by_op', array_flip(_content_access_get_operations()), array_fill(0, 6, $type)));
}
/**
* Helper providing numeric id for role.
*/
function content_access_get_role_gid($role) {
$config = \Drupal::configFactory()
->getEditable('content_access.settings');
$roles_gids = $config
->get('content_access_roles_gids');
if (empty($roles_gids) || !array_key_exists($role, $roles_gids)) {
return null;
}
return $roles_gids[$role];
}
/**
* Gets the content access acl id of the node.
*/
function content_access_get_acl_id(NodeInterface $node, $op) {
$acl_id = acl_get_id_by_name('content_access', $op . '_' . $node
->id());
if (!$acl_id) {
$acl_id = acl_create_acl('content_access', $op . '_' . $node
->id());
}
return $acl_id;
}
/**
* Detaches all our ACLs for the nodes of the given type.
*/
function _content_access_remove_acls($type) {
$result = \Drupal::database()
->query("SELECT n.nid FROM {node} n WHERE type = :type", [
'type' => $type,
]);
foreach ($result as $node) {
acl_node_clear_acls($node->nid, 'content_access');
}
}
/**
* Mass updates node access records for nodes of the given types.
*
* @param array $types
* An array of content type names.
*
* @return bool
* Whether the operation has been processed successfully or postponed.
*/
function content_access_mass_update(array $types) {
$query = \Drupal::database()
->select('node', 'n')
->fields('n', [
'nid',
])
->condition('n.type', $types, 'IN');
$count = $query
->countQuery()
->execute()
->fetchField();
node_access_needs_rebuild(TRUE);
// If there not too much nodes affected, try to do it.
if ($count <= ContentAccessInterface::CONTENT_ACCESS_MASS_UPDATE_THRESHOLD) {
$records = $query
->execute();
foreach ($records as $node) {
$node = Node::load($node->nid);
$grants = \Drupal::entityTypeManager()
->getAccessControlHandler('node')
->acquireGrants($node);
\Drupal::service('node.grant_storage')
->write($node, $grants);
}
foreach (Cache::getBins() as $cache_backend) {
$cache_backend
->deleteAll();
}
node_access_needs_rebuild(FALSE);
return TRUE;
}
return FALSE;
}
/**
* Submit callback for the user permissions form.
*
* Trigger changes to node permissions to rebuild our grants.
*/
function content_access_user_admin_perm_submit($form, FormStateInterface $form_state) {
// Check for each content type, which has per node access activated
// whether permissions have been changed.
$types = [];
foreach (array_filter(content_access_get_settings('per_node', 'all')) as $type => $value) {
foreach (_content_access_get_node_permissions($type) as $perm) {
foreach (user_roles() as $rid => $role) {
$values = $form_state
->getValues();
if (isset($values[$rid]) && in_array($perm, $form['checkboxes'][$rid]['#default_value']) != in_array($perm, $values[$rid])) {
// Permission changed.
$types[$type] = node_type_get_names();
continue 2;
}
}
}
}
if ($types && content_access_mass_update(array_keys($types))) {
\Drupal::messenger()
->addMessage(\Drupal::translation()
->formatPlural(count($types), 'Permissions have been successfully rebuilt for the content type @types.', 'Permissions have been successfully rebuilt for the content types @types.', [
'@types' => implode(', ', $types),
]));
}
}
Functions
Name | Description |
---|---|
content_access_available_settings | Return an array containing all available content_access settings. |
content_access_delete_per_node_settings | Delete per node settings. |
content_access_disabling | Remembers if we have disabled access. |
content_access_enabled | Used by the ACL module. |
content_access_entity_delete | Implements hook_entity_delete(). |
content_access_entity_insert | Implements hook_entity_insert(). |
content_access_entity_operation | Implements hook_entity_operation(). |
content_access_form_alter | Implements hook_form_alter(). |
content_access_get_acl_id | Gets the content access acl id of the node. |
content_access_get_permission_access | Returns an array of role ids that contain the given permission. |
content_access_get_permission_by_op | Gets the name of a perm for the given operation, if there is a suiting one. |
content_access_get_per_node_settings | Gets the per node settings of a node. |
content_access_get_rids_per_node_op | Get rids per node. |
content_access_get_role_gid | Helper providing numeric id for role. |
content_access_get_settings | Return content_access' settings. |
content_access_get_setting_defaults | Defines default values for settings. |
content_access_get_type_grant | Returns the default grants for a given node type. |
content_access_help | Implements hook_help(). |
content_access_mass_update | Mass updates node access records for nodes of the given types. |
content_access_node_access_explain | Implements hook_node_access_explain(). |
content_access_node_access_records | Implements hook_node_access_records(). |
content_access_node_delete | Implements hook_node_delete(). |
content_access_node_grants | Implements hook_node_grants(). |
content_access_node_type_delete | Implements hook_node_type_delete(). |
content_access_node_type_update | Implements hook_node_type_update(). |
content_access_optimize_grants | Removes grants that doesn't change anything. |
content_access_own_op | Determines grant for node author and the gives allowed roles of operation. |
content_access_per_node_setting | Access per node setting. |
content_access_proccess_grant | Process a grant, which means add priority, realm and other properties. |
content_access_save_per_node_settings | Saves custom per node settings in the own content_access table. |
content_access_set_settings | Save content_access settings of a content type. |
content_access_user_admin_perm_submit | Submit callback for the user permissions form. |
_content_access_get_node_permissions | Gets node's access permissions. |
_content_access_get_operations | Returns an array of possible operations on content and their labels. |
_content_access_remove_acls | Detaches all our ACLs for the nodes of the given type. |