forum_access-8.x-1.0-alpha2/forum_access.module
forum_access.module
<?php
/**
* @file
* Contains forum_access.module.
*/
use Drupal\comment\CommentInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\node\Entity\Node;
use Drupal\node\NodeInterface;
use Drupal\user\Entity\Role;
/**
* Implements hook_help().
*
* @inheritdoc
*/
function forum_access_help($route_name, RouteMatchInterface $route_match) {
$output = '';
switch ($route_name) {
// Main module help for the forum_access module.
case 'help.page.forum_access':
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('Allows forums to be set private and to be given moderators.') . '</p>';
}
return $output;
}
/**
* Implements hook_theme().
*
* @inheritdoc
*/
function forum_access_theme($existing, $type, $theme, $path) {
$result['forum_access_table'] = [
'render element' => 'form',
];
return $result;
}
/**
* Implements hook_node_grants().
*
* This function supplies the forum access grants. forum_access simply uses
* roles as ACLs, so rids translate directly to gids.
*
* @inheritdoc
*/
function forum_access_node_grants(AccountInterface $account, $op) {
$roles_gids = \Drupal::configFactory()
->getEditable('forum_access.settings')
->get('forum_access_roles_gids');
$grants = [];
/** @var string $role */
foreach ($account->getRoles() as $role) {
if (isset($roles_gids[$role])) {
$grants['forum_access'][] = $roles_gids[$role];
}
}
return $grants;
}
/**
* Implements hook_node_access().
*
* @inheritdoc
*/
function forum_access_node_access(NodeInterface $node, $op, AccountInterface $account) {
if ($node->bundle() != 'forum') {
return AccessResult::neutral();
}
// Disallow if user has no access to view.
\Drupal::moduleHandler()->loadInclude('forum_access', 'inc', 'includes/forum_access.common');
if (!forum_access_entity_access_by_tid('view', $node)) {
return AccessResult::forbidden();
}
$author = $node->get('uid')->first()->get('entity')->getTarget()->getValue();
switch ($op) {
case 'view':
if ($node->isPublished()) {
$access = forum_access_entity_access_by_tid($op, $node);
}
elseif ($author->id() == $account->id() && $account->hasPermission('view own unpublished content')) {
$access = forum_access_entity_access_by_tid($op, $node);
}
break;
case 'update':
if ($op == 'update' && ($account->hasPermission('edit any forum content') || ($author->id() == $account->id() && $account->hasPermission('edit own forum content')))) {
$access = forum_access_entity_access_by_tid('view', $node);
}
break;
case 'delete':
if ($op == 'delete' && ($account->hasPermission('delete any forum content') || ($author->id() == $account->id() && $account->hasPermission('delete own forum content')))) {
$access = forum_access_entity_access_by_tid('view', $node);
}
break;
}
if (isset($access)) {
return $access ? AccessResult::allowed() : AccessResult::forbidden();
}
return AccessResult::neutral();
}
/**
* Implements hook_node_access_records().
*
* Returns a list of grant records for the passed in node object.
* Checks to see if maybe we're being disabled.
*
* @inheritdoc
*/
function forum_access_node_access_records(NodeInterface $node) {
\Drupal::moduleHandler()->loadInclude('forum_access', 'inc', 'includes/forum_access.common');
$grants = &drupal_static(__FUNCTION__, []);
$seers = &drupal_static(__FUNCTION__ . '__seers');
$tid = forum_access_get_tid($node);
$roles_gids = \Drupal::configFactory()
->getEditable('forum_access.settings')
->get('forum_access_roles_gids');
if ($tid) {
// We want to give our rights only for published nodes.
if ($node->isPublished()) {
if (!isset($grants[$tid])) {
if (!isset($seers)) {
$bypass_node_access_permission = 'bypass node access';
$seers = array_filter(Role::loadMultiple(), function ($role) use ($bypass_node_access_permission) {
return $role->hasPermission($bypass_node_access_permission);
});
}
$result = forum_access_get_grants_by_tid($tid);
foreach ($result as $grant) {
if (isset($seers[$grant->rid])) {
// Don't provide any useless grants!
continue;
}
$grants[$tid][] = [
'realm' => 'forum_access',
// We change machine_name of role to its numeric equivalent.
'gid' => $roles_gids[$grant->rid],
'grant_view' => $grant->grant_view,
'grant_update' => $grant->grant_update,
'grant_delete' => $grant->grant_delete,
'priority' => $grant->priority,
];
}
}
if (isset($grants[$tid])) {
return $grants[$tid];
}
}
}
return [];
}
/**
* Implements hook_ENTITY_TYPE_create_access() for node entities.
*
* @inheritdoc
*/
function forum_access_node_create_access(AccountInterface $account, array $context, $entity_bundle) {
if ($entity_bundle != 'forum') {
return AccessResult::neutral();
}
// If we are on forum page we want to restrict access
// to create forum according to the forum access rules.
\Drupal::moduleHandler()->loadInclude('forum_access', 'inc', 'includes/forum_access.common');
$route = \Drupal::routeMatch();
$route_name = $route->getCurrentRouteMatch()->getRouteName();
switch ($route_name) {
case 'forum.page':
$term = $route->getParameter('taxonomy_term');
return forum_access_access('create', $term->id()) ? AccessResult::allowed() : AccessResult::forbidden();
case 'node.add':
$forum_id = \Drupal::request()->get('forum_id');
return forum_access_access('create', $forum_id) ? AccessResult::allowed() : AccessResult::forbidden();
}
return AccessResult::neutral();
}
/**
* Implements hook_ENTITY_TYPE_insert() for node entities.
*
* @inheritdoc
*/
function forum_access_node_insert(EntityInterface $entity) {
if ($entity->bundle() != 'forum') {
return;
}
\Drupal::moduleHandler()->loadInclude('forum_access', 'inc', 'includes/forum_access.common');
\Drupal::moduleHandler()->loadInclude('forum_access', 'inc', 'includes/forum_access.acl');
if ($tid = forum_access_get_tid($entity)) {
$acl_id = forum_access_get_acl($tid, 'moderate');
acl_node_add_acl($entity->id(), $acl_id, 1, 1, 1);
}
$node = Node::load($entity->id());
// To preserve database integrity, only write grants if the node
// loads successfully.
if (!empty($node)) {
/** @var \Drupal\node\NodeAccessControlHandlerInterface $access_control_handler */
$access_control_handler = \Drupal::entityTypeManager()->getAccessControlHandler('node');
$grants = $access_control_handler->acquireGrants($node);
\Drupal::service('node.grant_storage')->write($node, $grants);
}
}
/**
* Implements hook_ENTITY_TYPE_update() for node entities.
*
* @inheritdoc
*/
function forum_access_node_update(EntityInterface $entity) {
if ($entity->bundle() != 'forum') {
return;
}
\Drupal::moduleHandler()->loadInclude('forum_access', 'inc', 'includes/forum_access.common');
$old_tid = forum_access_get_tid($entity->original);
$current_tid = forum_access_get_tid($entity);
if (isset($old_tid)) {
if ($current_tid == $old_tid) {
return;
}
acl_node_clear_acls($entity->id(), 'forum_access');
}
// For changed and for previously unassigned terms we need to fake an insert.
forum_access_node_insert($entity);
}
/**
* Implements hook_ENTITY_TYPE_view_alter() for node entities.
*
* @inheritdoc
*/
function forum_access_node_view_alter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display) {
if ($entity->bundle() != 'forum') {
return;
}
// Don't show comment form is user has no access to it.
\Drupal::moduleHandler()->loadInclude('forum_access', 'inc', 'includes/forum_access.common');
if (!forum_access_entity_access_by_tid('create', $entity)) {
$build['comment_forum'][0]['comment_form'] = [];
}
}
/**
* Implements hook_node_links_alter().
*
* @inheritdoc
*/
function forum_access_node_links_alter(array &$links, NodeInterface $entity, array &$context) {
if ($entity->bundle() != 'forum') {
return;
}
// Don't show Comment link is user has no access to it.
if (!forum_access_entity_access_by_tid('create', $entity)) {
unset($links['comment__comment_forum']);
}
}
/**
* Implements hook_ENTITY_TYPE_access() for comment entities.
*
* @inheritdoc
*/
function forum_access_comment_access(EntityInterface $entity, $operation, AccountInterface $account) {
// Get parent entity of comment.
$parent = $entity->get('entity_id')
->first()
->get('entity')
->getTarget()
->getValue();
if (!($parent->getEntityTypeId() == 'node' && $parent->bundle() == 'forum')) {
return AccessResult::neutral();
}
if ($account->hasPermission('administer comments')) {
return AccessResult::neutral();
}
\Drupal::moduleHandler()->loadInclude('forum_access', 'inc', 'includes/forum_access.common');
if ($tid = forum_access_get_tid($parent)) {
// Disallow if user has no access to view.
if (!forum_access_access('view', $tid)) {
return AccessResult::forbidden();
}
$comment_author = $entity->get('uid')
->first()
->get('entity')
->getTarget()
->getValue();
// Check if user is author of comment.
$is_author = $account->id() == $comment_author->id();
if ($operation == 'view' && forum_access_access('view', $tid)) {
return AccessResult::allowed();
}
elseif ($operation == 'update'
&& (forum_access_access('update', $tid) || $account->hasPermission('edit any forum content') || ($is_author && $account->hasPermission('edit own forum content')))) {
return AccessResult::allowed();
}
// Delete operation.
elseif ($operation == 'delete'
&& (forum_access_access('delete', $tid) || $account->hasPermission('delete any forum content') || ($is_author && $account->hasPermission('delete own forum content')))) {
return AccessResult::allowed();
}
// Approve operation.
elseif ($operation == 'approve' && (forum_access_access('update', $tid) || forum_access_access('delete', $tid))) {
return AccessResult::allowed();
}
}
return AccessResult::forbidden();
}
/**
* Implements hook_query_TAG_alter() for tag 'comment_filter'.
*
* @inheritdoc
*/
function forum_access_query_comment_filter_alter(AlterableInterface $query) {
$entity = $query->getMetaData('entity');
if (!($entity->getEntityTypeId() == 'node' && $entity->bundle() == 'forum')) {
return;
}
\Drupal::moduleHandler()->loadInclude('forum_access', 'inc', 'includes/forum_access.common');
// @todo Replace it with the function.
$tid = forum_access_get_tid($entity);
$access = [
'update' => forum_access_access('update', $tid),
'delete' => forum_access_access('delete', $tid),
];
// If the user has access to update or delete posts or is moderator
// of the forum, allow to see unpublished comments.
if (!($access['update'] || $access['delete'])) {
return;
}
$conditions =& $query->conditions();
foreach ($conditions as $key => $condition) {
if (!is_numeric($key)) {
continue;
}
if ($condition['field'] == 'c.status' && $condition['value'] == CommentInterface::PUBLISHED && $condition['operator'] == '=') {
unset($conditions[$key]);
}
}
}
/**
* Implements hook_comment_links_alter().
*
* @inheritdoc
*/
function forum_access_comment_links_alter(array &$links, CommentInterface $entity, array &$context) {
// Get parent entity of comment.
$parent = $entity->get('entity_id')
->first()
->get('entity')
->getTarget()
->getValue();
$account = \Drupal::currentUser();
if (!($parent->getEntityTypeId() == 'node' && $parent->bundle() == 'forum')) {
return;
}
if ($account->hasPermission('administer comments')) {
return;
}
if (!forum_access_entity_access_by_tid('create', $parent)) {
unset($links['comment']['#links']['comment-reply']);
}
}
/**
* Implements hook_ENTITY_TYPE_delete() for taxonomy_term entities.
*
* @inheritdoc
*/
function forum_access_taxonomy_term_delete(EntityInterface $entity) {
$vid = $entity->get('vid')->first()->getValue()['target_id'];
// Delete {forum_access} records when forums are deleted.
if ($vid == \Drupal::config('forum.settings')->get('vocabulary')) {
\Drupal::database()->delete('forum_access')
->condition('tid', $entity->id())
->execute();
}
}
/**
* Implements hook_ENTITY_TYPE_access() for entity_type 'taxonomy_term'.
*
* @inheritdoc
*/
function forum_access_taxonomy_term_access(EntityInterface $entity, string $operation, AccountInterface $account) {
if ($entity->bundle() == 'forums') {
\Drupal::moduleHandler()->loadInclude('forum_access', 'inc', 'includes/forum_access.common');
if (!forum_access_access('view', $entity->id())) {
return AccessResult::forbidden();
}
}
return AccessResult::neutral();
}
/**
* Implements hook_query_TAG_alter() for tag 'taxonomy_term_access'.
*
* @inheritdoc
*/
function forum_access_query_taxonomy_term_access_alter(SelectInterface $query) {
// Read meta-data from query, if provided.
if (!$account = $query->getMetaData('account')) {
$account = \Drupal::currentUser();
}
if (!$op = $query->getMetaData('op')) {
$op = 'view';
}
// If $account can bypass node access, we let them administer the full forum
// structure and see the nodes, i.e. we don't restrict the query.
$route = \Drupal::routeMatch()->getRouteName();
if ($account->hasPermission('bypass node access') && ($route == 'forum.overview' || $route == 'entity.taxonomy_vocabulary.overview_form')) {
return;
}
// Prevent duplicate records.
$query->distinct();
// Find all instances of the {taxonomy_term_data} table being joined --
// could appear more than once in the query, and could be aliased.
// Join each one to the forum_access table.
$tables = $query->getTables();
$rids = $account->getRoles();
foreach ($tables as $talias => $tableinfo) {
$table = $tableinfo['table'];
if ($table == 'taxonomy_term_field_data') {
// The node_access table has the access grants for any given node.
$access_alias = $query->leftJoin('forum_access', 'fa', '%alias.tid = ' . $talias . '.tid');
$acl_alias = $query->leftJoin('acl', 'acl', "%alias.figure = $talias.tid AND %alias.module = 'forum_access' AND %alias.name=:name",
[
':name' => 'moderate',
]);
if ($account->hasPermission('bypass node access')) {
// If $account can bypass node access, we allow access if any role or
// account has access.
$aclu_alias = $query->leftJoin('acl_user', 'aclu', "%alias.acl_id = $acl_alias.acl_id");
$or = $query->orConditionGroup();
$or
->isNull("$access_alias.rid")
->condition("$access_alias.grant_$op", 1, '>=')
->isNotNull("$aclu_alias.uid");
$query->condition($or);
}
else {
$aclu_alias = $query->leftJoin('acl_user', 'aclu', "%alias.acl_id = $acl_alias.acl_id AND %alias.uid = " . $account->id());
$and = $query->andConditionGroup();
$and
->condition("$access_alias.rid", $rids, 'IN')
->condition("$access_alias.grant_$op", 1, '>=');
$condition = $query->orConditionGroup();
$condition
->isNull("$access_alias.rid")
->condition($and)
->condition("$aclu_alias.uid", $account->id());
$query->condition($condition);
}
}
}
}
/**
* Implements hook_ENTITY_TYPE_insert() for user_role entities.
*
* @inheritdoc
*/
function forum_access_user_role_insert(EntityInterface $entity) {
$config = \Drupal::configFactory()->getEditable('forum_access.settings');
$roles_gids = array_flip($config->get('forum_access_roles_gids'));
$roles_gids[] = $entity->id();
$config->set('forum_access_roles_gids', array_flip($roles_gids));
$config->save();
}
/**
* Implements hook_ENTITY_TYPE_delete() for user_role entities.
*
* @inheritdoc
*/
function forum_access_user_role_delete(EntityInterface $entity) {
// Delete records from access tables.
\Drupal::database()->delete('forum_access')
->condition('rid', $entity->id())
->execute();
\Drupal::database()->delete('node_access')
->condition('gid', $entity->id())
->condition('realm', 'forum_access')
->execute();
// Delete accordance between roles and numeric value.
$config = \Drupal::configFactory()->getEditable('forum_access.settings');
$roles_gids = $config->get('forum_access_roles_gids');
unset($roles_gids[$entity->id()]);
$config->set('forum_access_roles_gids', $roles_gids);
$config->save();
}
/**
* Implements hook_form_FORM_ID_alter() for node_form.
*
* @inheritdoc
*/
function forum_access_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {
if (!isset($form['taxonomy_forums'])) {
return;
}
$node = $form_state->getFormObject()->getEntity();
$account = \Drupal::currentUser();
// True node administrators are all powerful
// and do NOT get their forms rewritten here.
if ($account->hasPermission('bypass node access')) {
return;
}
// Get list of available lists.
$tids = forum_access_form_node_form_get_available_tids($account, $node);
$forum_tid = forum_access_get_tid($node);
// Leave only that forum options for which user has access.
$form_options = &$form['taxonomy_forums']['widget']['#options'];
foreach ($form_options as $tid => $name) {
if (!isset($tids[$tid])) {
unset($form_options[$tid]);
}
}
// Apply modifications for Moderators (by role or uid).
if (!$account->hasPermission('administer nodes') && forum_access_is_moderator($account, $forum_tid)) {
foreach (Element::children($form) as $key) {
switch ($key) {
case 'sticky':
$form[$key]['#access'] = TRUE;
break;
case 'revision':
$form['revision']['#access'] = TRUE;
break;
case 'comment_forum':
$form[$key]['#access'] = TRUE;
break;
case 'shadow':
$form[$key]['#description'] .= ' ' . t('Note: Access to this topic and its shadows is controlled by the forum that contains the topic.');
break;
case 'taxonomy_forums':
$form[$key]['widget']['#description'] .= t('Note: Moving a topic to a different forum may change its accessibility.');
break;
}
}
}
}
/**
* Implements hook_form_FORM_ID_alter() for taxonomy_term_forums_forum_form.
*
* @inheritdoc
*/
function forum_access_form_taxonomy_term_forums_forum_form_alter(&$form, FormStateInterface $form_state, $form_id) {
\Drupal::moduleHandler()->loadInclude('forum_access', 'inc', 'includes/forum_access.admin');
\Drupal::moduleHandler()->loadInclude('forum_access', 'inc', 'includes/forum_access.acl');
$tid = $form['tid']['#value'];
$settings = forum_access_get_settings($tid);
$form['forum_access'] = [
'#type' => 'details',
'#title' => t('Access control'),
'#collapsible' => TRUE,
'#tree' => TRUE,
];
// Moderators fields.
$form['forum_access']['permissions'] = _forum_access_forum_permissions_form();
$form['forum_access']['grants'] = _forum_access_forum_grants_form($form_state, $settings);
$form['forum_access']['moderators'] = _forum_access_forum_moderators_form($form_state, $tid);
$form['actions']['submit']['#submit'][] = '_forum_access_admin_forum_form_submit';
if (!empty($form['actions']['overview'])) {
$form['actions']['overview']['#submit'][] = '_forum_access_admin_forum_form_submit';
}
if (isset($tid) /*&& !node_access_needs_rebuild()*/) {
// Count number of nodes which are attached to this term.
$count = Drupal::database()
->select('node__taxonomy_forums')
->condition('taxonomy_forums_target_id', $tid)
->countQuery()
->distinct()
->execute()
->fetchField();
$limit = $threshold = 20;
$form['forum_access']['update_limit'] = [
'#type' => 'value',
'#value' => $limit,
];
$form['forum_access']['update_choice'] = [
'#type' => 'radios',
'#title' => t('Update the permissions'),
'#options' => array_flip(['all_now', 'all_later']),
'#default_value' => 'all_now',
'all_now' => [
'#type' => 'radio',
'#title' => t('rebuild <strong>all</strong> permissions now'),
],
'all_later' => [
'#type' => 'radio',
'#title' => t('rebuild <strong>all</strong> permissions later — do not forget to <a href=":rebuild">Rebuild permissions</a> as soon as possible!', [
':rebuild' => Url::fromRoute('node.configure_rebuild_confirm')->toString(),
]),
'#attributes' => ['title' => t("This option will only set a flag to remind you to rebuild all permissions later; this is useful if you want to make multiple changes to your node access settings quickly and delay the updating until you're done.")],
],
'#attributes' => ['class' => ['forum-access-flowed']],
];
}
if (isset($tid)) {
$form['forum_access']['force_update'] = [
'#type' => 'checkbox',
'#title' => t('Update even if unchanged'),
];
}
$form['forum_access']['#after_build'][] = 'forum_access_form_taxonomy_term_forums_x_form_alter_after_build';
}
/**
* Check for moderators, past or new.
*/
function forum_access_form_taxonomy_term_forums_x_form_alter_after_build(array $form, FormStateInterface $form_state) {
// Open the Moderators details if past or new moderators are set.
$moderators_form = &$form['moderators'];
$past_moderators = acl_edit_form_get_user_list($moderators_form, TRUE);
$future_moderators = acl_edit_form_get_user_list($moderators_form);
$moderators_form['#open'] = !empty($past_moderators) || !empty($future_moderators);
if (acl_edit_form_get_user_list_changed($moderators_form)) {
$form['#open'] = TRUE;
}
return $form;
}
/**
* Submit handler for forum access administrative form.
*/
function _forum_access_admin_forum_form_submit($form, FormStateInterface $form_state) {
// Shared code.
_forum_access_admin_container_form_submit($form, $form_state);
if (\Drupal::routeMatch()->getRouteName() != 'forum.add_forum') {
// Update access records.
_forum_access_update_access_records($form, $form_state);
}
}
/**
* Implements hook_form_FORM_ID_alter() for taxonomy_term_forums_container_form.
*
* @inheritdoc
*/
function forum_access_form_taxonomy_term_forums_container_form_alter(&$form, FormStateInterface $form_state, $form_id) {
\Drupal::moduleHandler()->loadInclude('forum_access', 'inc', 'includes/forum_access.admin');
\Drupal::moduleHandler()->loadInclude('forum_access', 'inc', 'includes/forum_access.acl');
$tid = $form['tid']['#value'];
$settings = forum_access_get_settings($tid);
$form['forum_access'] = [
'#type' => 'details',
'#title' => t('Access control'),
'#collapsible' => TRUE,
'#tree' => TRUE,
];
// Moderators fields.
$form['forum_access']['grants'] = _forum_access_container_grants_form($form_state, $settings);
$form['forum_access']['moderators'] = _forum_access_forum_moderators_form($form_state, $tid);
$form['forum_access']['#after_build'][] = 'forum_access_form_taxonomy_term_forums_x_form_alter_after_build';
$form['actions']['submit']['#submit'][] = '_forum_access_admin_container_form_submit';
if (!empty($form['actions']['overview'])) {
$form['actions']['overview']['#submit'][] = '_forum_access_admin_container_form_submit';
}
}
/**
* Submit handler for container access administrative form.
*/
function _forum_access_admin_container_form_submit($form, FormStateInterface $form_state) {
\Drupal::moduleHandler()->loadInclude('forum_access', 'inc', 'includes/forum_access.admin');
// Save roles permissions.
_forum_access_form_roles_permissions_save($form_state);
// (We can't use $form_state here because D8 fails to call #after_build.)
if (acl_edit_form_get_user_list_changed($form['forum_access']['moderators'])) {
// Save moderators list.
_forum_access_form_moderators_save($form_state);
}
}
/**
* This is also required by ACL module.
*
* @see acl_node_access_records()
*/
function forum_access_enabled($set = NULL) {
// Not drupal_static!
static $enabled = TRUE;
if ($set !== NULL) {
$enabled = $set;
}
return $enabled;
}
/**
* Retrieve the settings for a taxonomy term.
*
* @param int $tid
* (optional) Taxonomy term id.
*
* @return array
* Settings for a taxonomy term.
*/
function forum_access_get_settings($tid = NULL) {
$settings = [
'view' => [],
'create' => [],
'update' => [],
'delete' => [],
'priority' => 0,
];
$result = \Drupal::database()->select('forum_access', 'a')
->fields('a', [
'tid',
'rid',
'grant_view',
'grant_update',
'grant_delete',
'grant_create',
'priority',
])
->condition('tid', $tid)
->execute();
foreach ($result as $access) {
if ($access->grant_view) {
$settings['view'][] = $access->rid;
}
if ($access->grant_update) {
$settings['update'][] = $access->rid;
}
if ($access->grant_delete) {
$settings['delete'][] = $access->rid;
}
if ($access->grant_create) {
$settings['create'][] = $access->rid;
}
if ($access->rid == AccountInterface::AUTHENTICATED_ROLE) {
// This is our reference.
$settings['priority'] = $access->priority;
}
}
return $settings;
}
/**
* Set settings for taxonomy term.
*
* @param int $tid
* Taxonomy term id.
* @param array $settings
* Forum Access settings.
*/
function forum_access_set_settings($tid, array $settings) {
\Drupal::database()->delete('forum_access')
->condition('tid', $tid)
->execute();
$insert = \Drupal::database()->insert('forum_access');
$insert->fields([
'tid',
'rid',
'grant_view',
'grant_update',
'grant_delete',
'grant_create',
'priority',
]);
foreach ($settings['view'] as $rid => $checked) {
$insert->values([
'tid' => $tid,
'rid' => $rid,
'grant_view' => (int) !empty($checked),
'grant_update' => (int) !empty($settings['update'][$rid]),
'grant_delete' => (int) !empty($settings['delete'][$rid]),
'grant_create' => (int) !empty($settings['create'][$rid]),
'priority' => 0,
]);
}
$insert->execute();
}
/**
* Get list of available tids for specific account.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The user object for the user whose access is being checked.
* @param \Drupal\node\NodeInterface $node
* The node to check.
*
* @return array
* List of available tids for specific account.
*/
function forum_access_form_node_form_get_available_tids(AccountInterface $account, NodeInterface $node) {
\Drupal::moduleHandler()->loadInclude('forum_access', 'inc', 'includes/forum_access.common');
// We figure out what tids we want to show in form according
// to the forum access settings.
$forum_access_settings = forum_access_get_settings_by_roles($account->getRoles(), 'create');
$tids = [];
foreach ($forum_access_settings as $setting) {
$tids[$setting->tid] = $setting->tid;
}
// Also get all forums they happen to be able to moderate.
$acl_access_settings = forum_access_get_settings_by_user('forum_access', $account->id(), 'moderate');
foreach ($acl_access_settings as $setting) {
$tids[$setting->figure] = $setting->figure;
}
// Make available current forum for existed node.
if (!empty($node)) {
$forum_tid = forum_access_get_tid($node);
$tids[$forum_tid] = $forum_tid;
}
return $tids;
}
/**
* Preprocess for output of form with roles and permissions.
*
* @param array $variables
* An associative array containing:
* - form: A render element representing the form with
* - check_boxes: A render element representing the forum_access table.
*/
function template_preprocess_forum_access_table(array &$variables) {
$checkboxes = &$variables['form']['checkboxes'];
foreach (Element::children($checkboxes) as $child) {
foreach (Element::children($checkboxes[$child]) as $child2) {
$variables['form']['rows'][$child2][] = $checkboxes[$child][$child2];
}
}
}
