' . t('About') . ''; $output .= '

' . t('The "Permissions by Term" (PbT) module allows taxonomy administrators the ability to restrict setting individual terms on nodes by user or role. If a user is unable to set any terms for a required vocabulary, they are blocked from adding or editing content with that vocabulary. For more information, see the online documentation for Permissions by Term.', [':PbT-documentation' => 'https://www.drupal.org/project/permissions_by_term']) . '

'; $output .= '

' . t('Uses') . '

'; $output .= '
'; $output .= '
' . t('General') . '
'; $output .= '
' . t('Use Permissions by Term to easily build access-restricted content areas on your websites.') . '
'; $output .= '
' . t('Lightweight Access Control') . '
'; $output .= '
' . t('Permissions by Term restricts user access to specified Drupal nodes based on taxonomy terms - a core part of Drupal’s functionality. PbT lets you restrict content access while relying on very little contributed code.') . '
'; $output .= '
' . t('Example use cases') . '
'; $output .= '
' . t('A club or service site with premium- or member-only content.') . '
'; $output .= '
' . t('School websites with content intended for teachers only and content aimed at individual classes within the school.') . '
'; $output .= '
' . t('Company intranets with sensitive or proprietary content alongside non-restricted content.') . '
'; $output .= '
'; return $output; } } /** * Validation handler for permissions_by_term_form_alter(). */ function permissions_by_term_validate($form, FormState $oFormState) { foreach ($form as $field) { if (!is_object($field) && !empty($field['widget']['target_id']['#target_type']) && $field['widget']['target_id']['#target_type'] == 'taxonomy_term') { $field_name = $field['widget']['#field_name']; $terms = $oFormState->getValues()[$field_name]['target_id']; $not_allowed_term_names = []; if (!empty($terms)) { foreach ($terms as $term) { $term_id = $term['target_id']; /* @var \Drupal\permissions_by_term\AccessCheck $access_check_service */ $access_check_service = \Drupal::service('permissions_by_term.access_check'); if (!$access_check_service->isAccessAllowedByDatabase($term_id)) { $term = Term::load($term_id); $not_allowed_term_names[] = $term->getName(); } } } } } if (!empty($not_allowed_term_names)) { if (count($not_allowed_term_names) > 1) { $term_names = implode(', ', $not_allowed_term_names); } else { $term_names = $not_allowed_term_names['0']; } $oFormState->setErrorByName('field_tags', t('You are not allowed to use specific taxonomy terms like the following: "term-names". Remove the restricted taxonomy terms from the form field and try again.', ['term-names' => $term_names])); } } /** * Submit handler for permissions_by_term_form_alter(). */ function permissions_by_term_submit($form, FormState $formState) { $termId = $formState->getFormObject()->getEntity()->id(); /* @var \Drupal\permissions_by_term\AccessStorage $access_storage */ $access_storage = \Drupal::service('permissions_by_term.access_storage'); $access_storage->saveTermPermissions($formState, $termId); /** * @var \Drupal\permissions_by_term\NodeAccess $nodeAccess */ $nodeAccess = \Drupal::service('permissions_by_term.node_access'); $nodeAccess->rebuildByTid($termId, $formState); Cache::invalidateTags(['search_index:node_search']); } /** * Implements hook_form_alter(). */ function permissions_by_term_form_taxonomy_term_form_alter(&$form, FormStateInterface $oFormState, $form_id) { if (\Drupal::currentUser()->hasPermission('show term permission form on term page')) { $iTermId = $oFormState->getFormObject()->getEntity()->id(); /* @var \Drupal\permissions_by_term\AccessStorage $access_storage */ $access_storage = \Drupal::service('permissions_by_term.access_storage'); $form['access'] = [ '#type' => 'fieldset', '#title' => t('Permissions'), '#description' => t('To limit access to this term by user or roles, add users or roles to the following lists. Leave empty to allow node access by single node view, node listing in views and taxonomy term selection by all users.'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#attributes' => ['id' => 'fieldset_term_access'], '#weight' => -5, '#tree' => TRUE, ]; $aAllowedUsers = $access_storage->getAllowedUserIds($iTermId); if (!empty($aAllowedUsers)) { $aAllowedUsers = user_load_multiple($aAllowedUsers); $sUserFormValue = $access_storage->getUserFormValue($aAllowedUsers); } else { $sUserFormValue = NULL; } // 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']['user'] = [ '#type' => 'entity_autocomplete', '#target_type' => 'user', '#title' => t('Allowed users'), '#description' => t('Enter a comma-seperated list of user names to give') . ' ' . t('them permission to use this term and access related nodes in single node view and views listings.'), '#value' => $sUserFormValue, '#size' => 60, '#autocomplete_route_name' => 'permissions_by_term.autocomplete_multiple', '#weight' => -10, ]; $aAllowedRoles = $access_storage->getExistingRoleTermPermissionsByTid($iTermId); // Firstly fetch all translated allowed role names. $aTranslatedAllowedRoleNames = []; foreach ($aAllowedRoles as $role) { $aTranslatedAllowedRoleNames[] = $role; } // Get all roles for the complete form and translate them. $aTranslatedUserRoles = []; $array_key_counter = 1; foreach (user_roles() as $user_role_id => $user_role_name) { $aTranslatedUserRoles[$user_role_id] = $user_role_name->label(); $array_key_counter++; } // Generate the default values for the form. $aSetRoles = []; if (!empty($aTranslatedAllowedRoleNames)) { foreach ($aTranslatedAllowedRoleNames as $role_name) { $aSetRoles[] = $role_name; } } // Now, lets do the Roles table. $form['access']['role'] = [ '#type' => 'checkboxes', '#title' => t('Allowed roles'), '#description' => t('Select a role to allow all members of this role to use this term and access related nodes in single node view and views listings.'), '#default_value' => $aSetRoles, '#options' => $aTranslatedUserRoles, '#multiple' => FALSE, '#weight' => 5, ]; $form['#validate'][] = 'permissions_by_term_validate'; $form['actions']['submit']['#submit'][] = 'permissions_by_term_submit'; } } /** * Implements hook_form_alter(). */ function permissions_by_term_form_alter(&$form, FormStateInterface $oFormState, $form_id) { $form['#validate'][] = 'permissions_by_term_validate'; } /** * Implements hook_node_access(). * * Forwards user by drupal_access_denied(); to an access denied page, if a * single restricted node is called. * * This hook is not fired if admin is logged in. Users with the * "bypass node access" permission may always view and edit content * through the administrative interface. */ function permissions_by_term_node_access(NodeInterface $node, $op, AccountInterface $account) { if (method_exists($node, 'id') && $op == 'view') { if (!$node->isPublished() && !$account->hasPermission('Bypass content access control', $account)) { return AccessResult::forbidden(); } /* @var \Drupal\permissions_by_term\AccessCheck $access_check_service */ $access_check_service = \Drupal::service('permissions_by_term.access_check'); $oPermissionsByTermController = new PermissionsByTermController($access_check_service); return $oPermissionsByTermController->handleNode($node->id()); } } /** * Implements hook_node_grants(). */ function permissions_by_term_node_grants(\Drupal\Core\Session\AccountInterface $account, $op) { if ($op == 'view') { /** * @var \Drupal\permissions_by_term\AccessStorage $accessStorage */ $accessStorage = \Drupal::service('permissions_by_term.access_storage'); $grants = $accessStorage->getGidsByRealm('permissions_by_term__uid_' . \Drupal::currentUser()->id()); return $grants; } } /** * Implements hook_node_access_records(). * * Permissions can be rebuild at /admin/reports/status/rebuild. */ function permissions_by_term_node_access_records(\Drupal\node\NodeInterface $node) { /** * @var \Drupal\permissions_by_term\NodeAccess $nodeAccess */ $nodeAccess = \Drupal::service('permissions_by_term.node_access'); $grantsForThisNode = $nodeAccess->createGrants($node->id()); $grants = []; if (!empty($grantsForThisNode)) { foreach ($grantsForThisNode as $grantObject) { $grants[] = [ 'realm' => $grantObject->realm, 'gid' => $grantObject->gid, 'grant_view' => $grantObject->grant_view, 'grant_update' => $grantObject->grant_update, 'grant_delete' => $grantObject->grant_delete, 'langcode' => $grantObject->langcode, 'fallback' => 1, 'nid' => $node->id(), ]; } } return $grants; } /** * Implements hook_user_insert(). */ function permissions_by_term_user_insert($user) { /** * @var \Drupal\permissions_by_term\NodeAccess $nodeAccess */ $nodeAccess = \Drupal::service('permissions_by_term.node_access'); $nodeAccess->rebuildByUid($user->id(), TRUE); Cache::invalidateTags(['search_index:node_search']); } /** * Implements hook_user_update(). */ function permissions_by_term_user_update($user) { /** * @var \Drupal\permissions_by_term\NodeAccess $nodeAccess */ $nodeAccess = \Drupal::service('permissions_by_term.node_access'); $nodeAccess->rebuildByUid($user->id()); Cache::invalidateTags(['search_index:node_search']); } /** * Implements hook_node_insert(). */ function permissions_by_term_node_insert($node) { /** * @var \Drupal\permissions_by_term\NodeAccess $nodeAccess */ $nodeAccess = \Drupal::service('permissions_by_term.node_access'); $nodeAccess->rebuildByNid($node->id()); Cache::invalidateTags(['search_index:node_search']); }