class AccessStorage in Permissions by Term 8
Same name and namespace in other branches
- 8.2 src/Service/AccessStorage.php \Drupal\permissions_by_term\Service\AccessStorage
Class AccessStorage.
@package Drupal\permissions_by_term
Hierarchy
- class \Drupal\permissions_by_term\Service\AccessStorage
Expanded class hierarchy of AccessStorage
4 files declare their use of AccessStorage
- AccessCheckTest.php in tests/
src/ Kernel/ AccessCheckTest.php - KernelEventListener.php in src/
Listener/ KernelEventListener.php - NodeEntityBundleController.php in src/
Controller/ NodeEntityBundleController.php - PBTKernelTestBase.php in tests/
src/ Kernel/ PBTKernelTestBase.php
1 string reference to 'AccessStorage'
1 service uses AccessStorage
File
- src/
Service/ AccessStorage.php, line 18
Namespace
Drupal\permissions_by_term\ServiceView source
class AccessStorage {
/**
* The database connection.
*
* @var Connection
*/
protected $database;
/**
* The term name for which the access is set.
*
* @var string
*/
protected $sTermName;
/**
* The user ids which gain granted access.
*
* @var array
*/
protected $aUserIdsGrantedAccess;
/**
* The roles with granted access.
*
* @var array
*/
protected $aSubmittedRolesGrantedAccess;
/**
* @var TermHandler
*/
protected $term;
/**
* @var string
*/
const NODE_ACCESS_REALM = 'permissions_by_term';
/**
* @var AccessCheck
*/
protected $accessCheck;
/**
* AccessStorageService constructor.
*
* @param Connection $database
* @param TermHandler $term
* @param AccessCheck $accessCheck
*/
public function __construct(Connection $database, TermHandler $term, AccessCheck $accessCheck) {
$this->database = $database;
$this->term = $term;
$this->accessCheck = $accessCheck;
}
/**
* Gets submitted roles with granted access from form.
*
* @return array
* An array with chosen roles.
*/
public function getSubmittedRolesGrantedAccess(FormStateInterface $form_state) {
$aRoles = $form_state
->getValue('access')['role'];
$aChosenRoles = [];
foreach ($aRoles as $sRole) {
if ($sRole !== 0) {
$aChosenRoles[] = $sRole;
}
}
return $aChosenRoles;
}
/**
* @param FormState $form_state
*/
public function checkIfUsersExists(FormState $form_state) {
$sAllowedUsers = $form_state
->getValue('access')['user'];
$aAllowedUsers = Tags::explode($sAllowedUsers);
foreach ($aAllowedUsers as $sUserId) {
$aUserId = \Drupal::entityQuery('user')
->condition('uid', $sUserId)
->execute();
if (empty($aUserId)) {
$form_state
->setErrorByName('access][user', t('The user with ID %user_id does not exist.', [
'%user_id' => $sUserId,
]));
}
}
}
/**
* @param int $term_id
*
* @return array
*/
public function getUserTermPermissionsByTid($term_id, $langcode) {
return $this->database
->select('permissions_by_term_user', 'pu')
->condition('tid', $term_id)
->condition('langcode', $langcode)
->fields('pu', [
'uid',
])
->execute()
->fetchCol();
}
/**
* @param int $uid
* @param array $rids
*
* @return array
*/
public function getPermittedTids($uid, $rids) {
$permittedTids = $this->database
->select('permissions_by_term_user', 'pu')
->condition('uid', $uid)
->fields('pu', [
'tid',
])
->execute()
->fetchCol();
foreach ($rids as $rid) {
$permittedTidsByRid = $this->database
->select('permissions_by_term_role', 'pr')
->condition('rid', $rid)
->fields('pr', [
'tid',
])
->execute()
->fetchCol();
$permittedTids = array_merge($permittedTidsByRid, $permittedTids);
}
return array_unique($permittedTids);
}
/**
* @param array $tids
* @param string $langcode
* @return array
*/
public function getUserTermPermissionsByTids($tids, $langcode) {
$uids = [];
foreach ($tids as $tid) {
if (!empty($tmpUids = $this
->getUserTermPermissionsByTid($tid, $langcode))) {
foreach ($tmpUids as $tmpUid) {
$uids[] = $tmpUid;
}
}
}
return $uids;
}
/**
* @param int $term_id
* @param string $langcode
*
* @return array
*/
public function getRoleTermPermissionsByTid($term_id, $langcode) {
return $this->database
->select('permissions_by_term_role', 'pr')
->condition('tid', $term_id)
->condition('langcode', $langcode)
->fields('pr', [
'rid',
])
->execute()
->fetchCol();
}
/**
* @param array $tids
* @param string $langcode
* @return array
*/
public function getRoleTermPermissionsByTids($tids, $langcode) {
$rids = [];
foreach ($tids as $tid) {
$tmpRids = $this
->getRoleTermPermissionsByTid($tid, $langcode);
if (!empty($tmpRids)) {
foreach ($tmpRids as $tmpRid) {
$rids[] = $tmpRid;
}
}
}
return $rids;
}
/**
* @param string $sUsername
*
* @return int
*/
public function getUserIdByName($sUsername) {
return $this->database
->select('users_field_data', 'ufd')
->condition('name', $sUsername)
->fields('ufd', [
'uid',
])
->execute()
->fetchAssoc();
}
/**
* @param array $aUserNames
*
* @return array
*/
public function getUserIdsByNames($aUserNames) {
$aUserIds = [];
foreach ($aUserNames as $userName) {
$iUserId = $this
->getUserIdByName($userName)['uid'];
$aUserIds[] = $iUserId['uid'];
}
return $aUserIds;
}
/**
* @param int $term_id
*
* @return array
*/
public function getAllowedUserIds($term_id, $langcode) {
$query = $this->database
->select('permissions_by_term_user', 'p')
->fields('p', [
'uid',
])
->condition('p.tid', $term_id)
->condition('p.langcode', $langcode);
// fetchCol() returns all results, fetchAssoc() only "one" result.
return $query
->execute()
->fetchCol();
}
/**
* @param array $aUserIdsAccessRemove
* @param int $term_id
*/
public function deleteTermPermissionsByUserIds($aUserIdsAccessRemove, $term_id, $langcode) {
foreach ($aUserIdsAccessRemove as $iUserId) {
$this->database
->delete('permissions_by_term_user')
->condition('uid', $iUserId, '=')
->condition('tid', $term_id, '=')
->condition('langcode', $langcode, '=')
->execute();
}
}
/**
* @param array $aRoleIdsAccessRemove
* @param int $term_id
*/
public function deleteTermPermissionsByRoleIds($aRoleIdsAccessRemove, $term_id, $langcode) {
foreach ($aRoleIdsAccessRemove as $sRoleId) {
$this->database
->delete('permissions_by_term_role')
->condition('rid', $sRoleId, '=')
->condition('tid', $term_id, '=')
->condition('langcode', $langcode, '=')
->execute();
}
}
/**
* @param int $userId
*/
public function deleteAllTermPermissionsByUserId($userId) {
$this->database
->delete('permissions_by_term_user')
->condition('uid', $userId, '=')
->execute();
}
/**
* Delete access storage when a term is removed.
*
* @param int $term_id
* The term ID being deleted.
*/
public function deleteAllTermPermissionsByTid($term_id) {
$this->database
->delete('permissions_by_term_user')
->condition('tid', $term_id, '=')
->execute();
$this->database
->delete('permissions_by_term_role')
->condition('tid', $term_id, '=')
->execute();
}
/**
* @param array $aUserIdsGrantedAccess
* @param int $term_id
* @param string $langcode
*
* @throws \Exception
*/
public function addTermPermissionsByUserIds($aUserIdsGrantedAccess, $term_id, $langcode = '') {
$langcode = $langcode === '' ? \Drupal::languageManager()
->getCurrentLanguage()
->getId() : $langcode;
foreach ($aUserIdsGrantedAccess as $iUserIdGrantedAccess) {
$queryResult = $this->database
->query("SELECT uid FROM {permissions_by_term_user} WHERE tid = :tid AND uid = :uid AND langcode = :langcode", [
':tid' => $term_id,
':uid' => $iUserIdGrantedAccess,
':langcode' => $langcode,
])
->fetchField();
if (empty($queryResult)) {
$this->database
->insert('permissions_by_term_user')
->fields([
'tid',
'uid',
'langcode',
], [
$term_id,
$iUserIdGrantedAccess,
$langcode,
])
->execute();
}
}
}
/**
* @param array $aRoleIdsGrantedAccess
* @param int $term_id
* @param string $langcode
*
* @throws \Exception
*/
public function addTermPermissionsByRoleIds($aRoleIdsGrantedAccess, $term_id, $langcode = '') {
$langcode = $langcode === '' ? \Drupal::languageManager()
->getCurrentLanguage()
->getId() : $langcode;
$roles = Role::loadMultiple();
foreach ($roles as $role => $roleObj) {
if ($roleObj
->hasPermission('bypass node access')) {
$aRoleIdsGrantedAccess[] = $roleObj
->id();
}
}
$aRoleIdsGrantedAccess = array_unique($aRoleIdsGrantedAccess);
foreach ($aRoleIdsGrantedAccess as $sRoleIdGrantedAccess) {
$queryResult = $this->database
->query("SELECT rid FROM {permissions_by_term_role} WHERE tid = :tid AND rid = :rid AND langcode = :langcode", [
':tid' => $term_id,
':rid' => $sRoleIdGrantedAccess,
':langcode' => $langcode,
])
->fetchField();
if (empty($queryResult)) {
$this->database
->insert('permissions_by_term_role')
->fields([
'tid',
'rid',
'langcode',
], [
$term_id,
$sRoleIdGrantedAccess,
$langcode,
])
->execute();
}
}
}
/**
* Gets the user ids which have been submitted by form.
*
* Users which will gain granted access to taxonomy terms.
*
* @return array
* The user ids which have been submitted.
*/
public function getSubmittedUserIds($formState) {
/* There's a $this->oFormState->getValues() method, but
* it is loosing multiple form values. Don't know why.
* So there're some custom lines on the $_REQUEST array. */
$sRawUsers = $_REQUEST['access']['user'];
if (empty($sRawUsers)) {
return [];
}
$aRawUsers = Tags::explode($sRawUsers);
$aUserIds = [];
if (!empty($aRawUsers)) {
foreach ($aRawUsers as $sRawUser) {
if (preg_match("/.+\\s\\(([^\\)]+)\\)/", $sRawUser, $matches)) {
$aUserIds[] = $matches[1];
}
}
}
return $aUserIds;
}
/**
* @param FormState $formState
* @param int $term_id
*
* @return array
* @throws \Exception
*/
public function saveTermPermissions(FormStateInterface $formState, $term_id) {
$langcode = \Drupal::languageManager()
->getCurrentLanguage()
->getId();
if (!empty($formState
->getValue('langcode'))) {
$langcode = $formState
->getValue('langcode')['0']['value'];
}
$aExistingUserPermissions = $this
->getUserTermPermissionsByTid($term_id, $langcode);
$aSubmittedUserIdsGrantedAccess = $this
->getSubmittedUserIds($formState);
$aExistingRoleIdsGrantedAccess = $this
->getRoleTermPermissionsByTid($term_id, $langcode);
$aSubmittedRolesGrantedAccess = $this
->getSubmittedRolesGrantedAccess($formState);
$aRet = $this
->getPreparedDataForDatabaseQueries($aExistingUserPermissions, $aSubmittedUserIdsGrantedAccess, $aExistingRoleIdsGrantedAccess, $aSubmittedRolesGrantedAccess);
$this
->deleteTermPermissionsByUserIds($aRet['UserIdPermissionsToRemove'], $term_id, $langcode);
$this
->addTermPermissionsByUserIds($aRet['UserIdPermissionsToAdd'], $term_id, $langcode);
$this
->deleteTermPermissionsByRoleIds($aRet['UserRolePermissionsToRemove'], $term_id, $langcode);
if (!empty($aRet['aRoleIdPermissionsToAdd'])) {
$this
->addTermPermissionsByRoleIds($aRet['aRoleIdPermissionsToAdd'], $term_id, $langcode);
}
return $aRet;
}
/**
* Get array items to remove.
*
* The array items which aren't in the new items array, but are in old items
* array, will be returned.
*
* @param array $aExistingItems
* The existing array items.
* @param array|bool $aNewItems
* Either false if there're no new items or an array with items.
*
* @return array
* The array items to remove.
*/
private function getArrayItemsToRemove($aExistingItems, $aNewItems) {
$aRet = [];
foreach ($aExistingItems as $existingItem) {
if (!in_array($existingItem, $aNewItems)) {
$aRet[] = $existingItem;
}
}
return $aRet;
}
/**
* Get the array items to add.
*
* The items in the new items array, which aren't in the existing items array,
* will be returned.
*
* @param array $aNewItems
* The new array items.
* @param array $aExistingItems
* The existing array items.
*
* @return array
* The items which needs to be added.
*/
private function getArrayItemsToAdd($aNewItems, $aExistingItems) {
$aRet = [];
foreach ($aNewItems as $newItem) {
if (!in_array($newItem, $aExistingItems)) {
$aRet[] = $newItem;
}
}
return $aRet;
}
/**
* Prepares the data which has to be applied to the database.
*
* @param array $aExistingUserPermissions
* The permissions for existing user.
* @param array $aSubmittedUserIdsGrantedAccess
* The user ids which get access.
* @param array $aExistingRoleIdsGrantedAccess
* The existing role ids.
* @param array $aSubmittedRolesGrantedAccess
* The user roles which get access.
*
* @return array
* User ID and role data.
*/
public function getPreparedDataForDatabaseQueries($aExistingUserPermissions, $aSubmittedUserIdsGrantedAccess, $aExistingRoleIdsGrantedAccess, $aSubmittedRolesGrantedAccess) {
// Fill array with user ids to remove permission.
$aRet['UserIdPermissionsToRemove'] = $this
->getArrayItemsToRemove($aExistingUserPermissions, $aSubmittedUserIdsGrantedAccess);
// Fill array with user ids to add permission.
$aRet['UserIdPermissionsToAdd'] = $this
->getArrayItemsToAdd($aSubmittedUserIdsGrantedAccess, $aExistingUserPermissions);
// Fill array with user roles to remove permission.
$aRet['UserRolePermissionsToRemove'] = $this
->getArrayItemsToRemove($aExistingRoleIdsGrantedAccess, $aSubmittedRolesGrantedAccess);
// Fill array with user roles to add permission.
$aRet['aRoleIdPermissionsToAdd'] = $this
->getArrayItemsToAdd($aSubmittedRolesGrantedAccess, $aExistingRoleIdsGrantedAccess);
return $aRet;
}
/**
* The form value for allowed users as string to be shown to the user.
*
* @param User[] $aAllowedUsers
* An array with the allowed users.
*
* @return null|string
* Either null or the user name.
*/
public function getUserFormValue($aAllowedUsers) {
$sUserInfos = '';
if (!empty($aAllowedUsers)) {
foreach ($aAllowedUsers as $oUser) {
$iUid = intval($oUser
->id());
if ($iUid !== 0) {
$sUsername = $oUser
->getDisplayName();
}
else {
$sUsername = t('Anonymous User');
}
$sUserInfos .= "{$sUsername} ({$iUid}), ";
}
// Remove space and comma at the end of the string.
$sUserInfos = substr($sUserInfos, 0, -2);
}
return $sUserInfos;
}
/**
* @param $nid
*
* @return array
*/
public function getTidsByNid($nid) {
$node = \Drupal::entityTypeManager()
->getStorage('node')
->load($nid);
$tids = [];
foreach ($node
->getFields() as $field) {
if ($field
->getFieldDefinition()
->getType() == 'entity_reference' && $field
->getFieldDefinition()
->getSetting('target_type') == 'taxonomy_term') {
$aReferencedTaxonomyTerms = $field
->getValue();
if (!empty($aReferencedTaxonomyTerms)) {
foreach ($aReferencedTaxonomyTerms as $aReferencedTerm) {
if (isset($aReferencedTerm['target_id'])) {
$tids[] = $aReferencedTerm['target_id'];
}
}
}
}
}
return $tids;
}
/**
* @return array
*/
public function getAllUids() {
$nodes = \Drupal::entityQuery('user')
->execute();
return array_values($nodes);
}
/**
* @param $nid
*
* @return array
*/
public function getNodeType($nid) {
$query = $this->database
->select('node', 'n')
->fields('n', [
'type',
])
->condition('n.nid', $nid);
return $query
->execute()
->fetchAssoc()['type'];
}
/**
* @param $nid
*
* @return array
*/
public function getLangCode($nid) {
$query = $this->database
->select('node', 'n')
->fields('n', [
'langcode',
])
->condition('n.nid', $nid);
return $query
->execute()
->fetchAssoc()['langcode'];
}
/**
* @param AccountInterface $user
*
* @return array
*/
public function getGids(AccountInterface $user) {
$grants = null;
if (!empty($permittedNids = $this
->computePermittedTids($user))) {
$query = $this->database
->select('node_access', 'na')
->fields('na', [
'gid',
])
->condition('na.nid', $permittedNids, 'IN')
->condition('na.realm', self::NODE_ACCESS_REALM);
$gids = $query
->execute()
->fetchCol();
foreach ($gids as $gid) {
$grants[self::NODE_ACCESS_REALM][] = $gid;
}
}
return $grants;
}
private function computePermittedTids(AccountInterface $user) {
$nidsWithNoTidRestriction = $this
->getUnrestrictedNids();
$nidsByTids = $this->term
->getNidsByTids($this
->getPermittedTids($user
->id(), $user
->getRoles()));
if (\Drupal::config('permissions_by_term.settings.single_term_restriction')
->get('value')) {
$permittedNids = [];
foreach ($nidsByTids as $nid) {
if ($this->accessCheck
->canUserAccessByNodeId($nid, $user
->id(), $this
->getLangCode($nid))) {
$permittedNids[] = $nid;
}
}
$nidsByTids = $permittedNids;
}
if (!empty($nidsByTids)) {
return array_merge($this
->getUnrestrictedNids(), $nidsByTids);
}
return $nidsWithNoTidRestriction;
}
private function getUnrestrictedNids() {
$tidsRestrictedUserQuery = $this->database
->select('permissions_by_term_user', 'u')
->fields('u', [
'tid',
]);
$restrictedTids = $this->database
->select('permissions_by_term_role', 'r')
->fields('r', [
'tid',
])
->union($tidsRestrictedUserQuery)
->execute()
->fetchCol();
if (empty($restrictedTids)) {
return $this
->getAllNids();
}
$restrictedNids = $this->database
->select('taxonomy_index', 't')
->fields('t', [
'nid',
])
->condition('t.tid', $restrictedTids, 'IN')
->distinct(TRUE)
->execute()
->fetchCol();
if (empty($restrictedNids)) {
return $this
->getAllNids();
}
$unrestrictedNids = $this->database
->select('taxonomy_index', 't')
->fields('t', [
'nid',
])
->condition('t.nid', $restrictedNids, 'NOT IN')
->distinct(TRUE)
->execute()
->fetchCol();
return $unrestrictedNids;
}
/**
* @return array
*/
public function getAllNids() {
return $this->database
->select('node', 'n')
->fields('n', [
'nid',
])
->execute()
->fetchCol();
}
/**
* @param $uid
*
* @return array
*/
public function getAllNidsUserCanAccess($uid) {
$query = $this->database
->select('node_access', 'na')
->fields('na', [
'nid',
])
->condition('na.realm', 'permissions_by_term__uid_' . $uid);
return $query
->execute()
->fetchCol();
}
/**
* @param $tid
*
* @return array
*/
public function getNidsByTid($tid) {
$query = $this->database
->select('taxonomy_index', 'ti')
->fields('ti', [
'nid',
])
->condition('ti.tid', $tid);
return $query
->execute()
->fetchCol();
}
}