X-Git-Url: http://www.aleph1.co.uk/gitweb/?a=blobdiff_plain;f=web%2Fmodules%2Fcontrib%2Fpermissions_by_term%2Fpermissions_by_term.module;fp=web%2Fmodules%2Fcontrib%2Fpermissions_by_term%2Fpermissions_by_term.module;h=5886d9859907ce04adc3c9174b02781d6f174349;hb=a2bd1bf0c2c1f1a17d188f4dc0726a45494cefae;hp=0000000000000000000000000000000000000000;hpb=57c063afa3f66b07c4bbddc2d6129a96d90f0aad;p=yaffs-website diff --git a/web/modules/contrib/permissions_by_term/permissions_by_term.module b/web/modules/contrib/permissions_by_term/permissions_by_term.module new file mode 100644 index 000000000..5886d9859 --- /dev/null +++ b/web/modules/contrib/permissions_by_term/permissions_by_term.module @@ -0,0 +1,300 @@ +' . 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']); +}