3 namespace Drupal\permissions_by_term;
5 use Drupal\Core\Database\Driver\mysql\Connection;
6 use Drupal\Component\Utility\Tags;
7 use Drupal\Core\Form\FormState;
10 * Class AccessStorage.
12 * Defines an API to the database in the term access context.
14 * The "protected" class methods are meant for protection regarding Drupal's
15 * forms and presentation layer.
17 * The "public" class methods can be used for extensions.
19 * @package Drupal\permissions_by_term
21 class AccessStorage implements AccessStorageInterface {
24 * Drupal\Core\Database\Driver\mysql\Connection definition.
26 * @var Drupal\Core\Database\Driver\mysql\Connection
31 * The term name for which the access is set.
38 * The user ids which gain granted access.
42 protected $aUserIdsGrantedAccess;
45 * The roles with granted access.
49 protected $aSubmittedRolesGrantedAccess;
52 * AccessStorageService constructor.
54 * @param \Drupal\Core\Database\Driver\mysql\Connection $database
55 * The connection to the database.
57 public function __construct(Connection $database) {
58 $this->oDatabase = $database;
62 * Gets submitted roles with granted access from form.
65 * An array with chosen roles.
67 public function getSubmittedRolesGrantedAccess(FormState $form_state) {
68 $aRoles = $form_state->getValue('access')['role'];
70 foreach ($aRoles as $sRole) {
72 $aChosenRoles[] = $sRole;
81 public function checkIfUsersExists(FormState $form_state) {
82 $sAllowedUsers = $form_state->getValue('access')['user'];
83 $aAllowedUsers = Tags::explode($sAllowedUsers);
84 foreach ($aAllowedUsers as $sUserId) {
85 $aUserId = \Drupal::entityQuery('user')
86 ->condition('uid', $sUserId)
88 if (empty($aUserId)) {
89 $form_state->setErrorByName('access][user',
90 t('The user with ID %user_id does not exist.',
91 ['%user_id' => $sUserId]));
99 public function getExistingUserTermPermissionsByTid($term_id) {
100 return $this->oDatabase->select('permissions_by_term_user', 'pu')
101 ->condition('tid', $term_id)
102 ->fields('pu', ['uid'])
110 public function getExistingRoleTermPermissionsByTid($term_id) {
111 return $this->oDatabase->select('permissions_by_term_role', 'pr')
112 ->condition('tid', $term_id)
113 ->fields('pr', ['rid'])
121 public function getUserIdByName($sUsername) {
122 return $this->oDatabase->select('users_field_data', 'ufd')
123 ->condition('name', $sUsername)
124 ->fields('ufd', ['uid'])
132 public function getUserIdsByNames($aUserNames) {
134 foreach ($aUserNames as $userName) {
135 $iUserId = $this->getUserIdByName($userName)['uid'];
136 $aUserIds[] = $iUserId['uid'];
144 public function getAllowedUserIds($term_id) {
145 $query = $this->oDatabase->select('permissions_by_term_user', 'p')
146 ->fields('p', ['uid'])
147 ->condition('p.tid', $term_id);
149 // fetchCol() returns all results, fetchAssoc() only "one" result.
150 return $query->execute()
157 public function deleteTermPermissionsByUserIds($aUserIdsAccessRemove, $term_id) {
158 foreach ($aUserIdsAccessRemove as $iUserId) {
159 $this->oDatabase->delete('permissions_by_term_user')
160 ->condition('uid', $iUserId, '=')
161 ->condition('tid', $term_id, '=')
169 public function deleteTermPermissionsByRoleIds($aRoleIdsAccessRemove, $term_id) {
170 foreach ($aRoleIdsAccessRemove as $sRoleId) {
171 $this->oDatabase->delete('permissions_by_term_role')
172 ->condition('rid', $sRoleId, '=')
173 ->condition('tid', $term_id, '=')
181 public function addTermPermissionsByUserIds($aUserIdsGrantedAccess, $term_id) {
182 foreach ($aUserIdsGrantedAccess as $iUserIdGrantedAccess) {
183 $this->oDatabase->insert('permissions_by_term_user')
184 ->fields(['tid', 'uid'], [$term_id, $iUserIdGrantedAccess])
192 public function addTermPermissionsByRoleIds($aRoleIdsGrantedAccess, $term_id) {
193 foreach ($aRoleIdsGrantedAccess as $sRoleIdGrantedAccess) {
194 $this->oDatabase->insert('permissions_by_term_role')
195 ->fields(['tid', 'rid'], [$term_id, $sRoleIdGrantedAccess])
203 public function getTermIdByName($sTermName) {
204 $aTermId = \Drupal::entityQuery('taxonomy_term')
205 ->condition('name', $sTermName)
207 return key($aTermId);
213 public function getTermNameById($term_id) {
214 $term_name = \Drupal::entityQuery('taxonomy_term')
215 ->condition('id', $term_id)
217 return key($term_name);
221 * Gets the user ids which have been submitted by form.
223 * Users which will gain granted access to taxonomy terms.
226 * The user ids which have been submitted.
228 public function getSubmittedUserIds() {
229 /* There's a $this->oFormState->getValues() method, but
230 * it is loosing multiple form values. Don't know why.
231 * So there're some custom lines on the $_REQUEST array. */
232 $sRawUsers = $_REQUEST['access']['user'];
234 if (empty($sRawUsers)) {
238 $aRawUsers = explode('),', $sRawUsers);
240 if (!empty($aRawUsers)) {
241 foreach ($aRawUsers as $sRawUser) {
242 $aTempRawUser = explode(' (', $sRawUser);
243 // We check the user id by user name. If we get null back, the user might
244 // be the Anonymous user. In that case we get null back and then we use
245 // this id, which is 0.
246 if (!empty($aTempRawUser[1])) {
247 $fallback_user_id = str_replace(')', '', $aTempRawUser[1]);
248 $fallback_user_id = intval($fallback_user_id);
251 $sRawUser = trim($aTempRawUser['0']);
252 $uid = $this->getUserIdByName($sRawUser)['uid'];
253 if ($uid == NULL && $fallback_user_id == 0) {
254 // We might want to give access to the Anonymous user.
258 $aUserIds[] = $this->getUserIdByName($sRawUser)['uid'];
269 public function saveTermPermissions(FormState $form_state, $term_id) {
270 $aExistingUserPermissions = $this->getExistingUserTermPermissionsByTid($term_id);
271 $aSubmittedUserIdsGrantedAccess = $this->getSubmittedUserIds();
273 $aExistingRoleIdsGrantedAccess = $this->getExistingRoleTermPermissionsByTid($term_id);
274 $aSubmittedRolesGrantedAccess = $this->getSubmittedRolesGrantedAccess($form_state);
276 $aRet = $this->getPreparedDataForDatabaseQueries($aExistingUserPermissions,
277 $aSubmittedUserIdsGrantedAccess, $aExistingRoleIdsGrantedAccess,
278 $aSubmittedRolesGrantedAccess);
280 // Run the database queries.
281 $this->deleteTermPermissionsByUserIds($aRet['UserIdPermissionsToRemove'], $term_id);
282 $this->addTermPermissionsByUserIds($aRet['UserIdPermissionsToAdd'], $term_id);
284 $this->deleteTermPermissionsByRoleIds($aRet['UserRolePermissionsToRemove'], $term_id);
285 $this->addTermPermissionsByRoleIds($aRet['aRoleIdPermissionsToAdd'], $term_id);
291 * Get array items to remove.
293 * The array items which aren't in the new items array, but are in old items
294 * array, will be returned.
296 * @param array $aExistingItems
297 * The existing array items.
298 * @param array|bool $aNewItems
299 * Either false if there're no new items or an array with items.
302 * The array items to remove.
304 private function getArrayItemsToRemove($aExistingItems, $aNewItems) {
307 foreach ($aExistingItems as $existingItem) {
308 if (!in_array($existingItem, $aNewItems)) {
309 $aRet[] = $existingItem;
317 * Get the array items to add.
319 * The items in the new items array, which aren't in the existing items array,
322 * @param array $aNewItems
323 * The new array items.
324 * @param array $aExistingItems
325 * The existing array items.
328 * The items which needs to be added.
330 private function getArrayItemsToAdd($aNewItems, $aExistingItems) {
333 foreach ($aNewItems as $newItem) {
334 if (!in_array($newItem, $aExistingItems)) {
345 public function getPreparedDataForDatabaseQueries($aExistingUserPermissions,
346 $aSubmittedUserIdsGrantedAccess,
347 $aExistingRoleIdsGrantedAccess,
348 $aSubmittedRolesGrantedAccess) {
349 // Fill array with user ids to remove permission.
350 $aRet['UserIdPermissionsToRemove'] =
351 $this->getArrayItemsToRemove($aExistingUserPermissions,
352 $aSubmittedUserIdsGrantedAccess);
354 // Fill array with user ids to add permission.
355 $aRet['UserIdPermissionsToAdd'] =
356 $this->getArrayItemsToAdd($aSubmittedUserIdsGrantedAccess,
357 $aExistingUserPermissions);
359 // Fill array with user roles to remove permission.
360 $aRet['UserRolePermissionsToRemove'] =
361 $this->getArrayItemsToRemove($aExistingRoleIdsGrantedAccess,
362 $aSubmittedRolesGrantedAccess);
364 // Fill array with user roles to add permission.
365 $aRet['aRoleIdPermissionsToAdd'] =
366 $this->getArrayItemsToAdd($aSubmittedRolesGrantedAccess,
367 $aExistingRoleIdsGrantedAccess);
375 public function getUserFormValue($aAllowedUsers) {
379 if (!empty($aAllowedUsers)) {
381 foreach ($aAllowedUsers as $oUser) {
382 $iUid = intval($oUser->id());
384 $sUsername = $oUser->getUsername();
387 $sUsername = t('Anonymous User');
390 $sUserInfos .= "$sUsername ($iUid), ";
393 // Remove space and comma at the end of the string.
394 $sUserInfos = substr($sUserInfos, 0, -2);
403 public function getAllNids()
405 $query = $this->oDatabase->select('node', 'n')
406 ->fields('n', ['nid']);
408 return $query->execute()
412 public function getTidsByNid($nid)
414 $node = $this->entityManager->getStorage('node')->load($nid);
417 foreach ($node->getFields() as $field) {
418 if ($field->getFieldDefinition()->getType() == 'entity_reference' && $field->getFieldDefinition()->getSetting('target_type') == 'taxonomy_term') {
419 $aReferencedTaxonomyTerms = $field->getValue();
420 if (!empty($aReferencedTaxonomyTerms)) {
421 foreach ($aReferencedTaxonomyTerms as $aReferencedTerm) {
422 if (isset($aReferencedTerm['target_id'])) {
423 $tids[] = $aReferencedTerm['target_id'];
433 public function getAllUids()
435 $nodes = \Drupal::entityQuery('user')
438 return array_values($nodes);
441 public function getNodeType($nid)
443 $query = $this->oDatabase->select('node', 'n')
444 ->fields('n', ['type'])
445 ->condition('n.nid', $nid);
447 return $query->execute()
448 ->fetchAssoc()['type'];
451 public function getLangCode($nid)
453 $query = $this->oDatabase->select('node', 'n')
454 ->fields('n', ['langcode'])
455 ->condition('n.nid', $nid);
457 return $query->execute()
458 ->fetchAssoc()['langcode'];
461 public function getGidsByRealm($realm)
463 $query = $this->oDatabase->select('node_access', 'na')
464 ->fields('na', ['gid'])
465 ->condition('na.realm', $realm);
467 $gids = $query->execute()->fetchCol();
469 foreach ($gids as $gid) {
470 $grants[$realm][] = $gid;
476 public function getAllNidsUserCanAccess($uid)
478 $query = $this->oDatabase->select('node_access', 'na')
479 ->fields('na', ['nid'])
480 ->condition('na.realm', 'permissions_by_term__uid_' . $uid);
482 return $query->execute()
486 public function getNidsByTid($tid)
488 $query = $this->oDatabase->select('taxonomy_index', 'ti')
489 ->fields('ti', ['nid'])
490 ->condition('ti.tid', $tid);
492 return $query->execute()->fetchCol();