Backup of database 9 Nov 17
[yaffs-website] / web / modules / contrib / permissions_by_term / src / AccessStorage.php
1 <?php
2
3 namespace Drupal\permissions_by_term;
4
5 use Drupal\Core\Database\Driver\mysql\Connection;
6 use Drupal\Component\Utility\Tags;
7 use Drupal\Core\Form\FormState;
8
9 /**
10  * Class AccessStorage.
11  *
12  * Defines an API to the database in the term access context.
13  *
14  * The "protected" class methods are meant for protection regarding Drupal's
15  * forms and presentation layer.
16  *
17  * The "public" class methods can be used for extensions.
18  *
19  * @package Drupal\permissions_by_term
20  */
21 class AccessStorage implements AccessStorageInterface {
22
23   /**
24    * Drupal\Core\Database\Driver\mysql\Connection definition.
25    *
26    * @var Drupal\Core\Database\Driver\mysql\Connection
27    */
28   protected $oDatabase;
29
30   /**
31    * The term name for which the access is set.
32    *
33    * @var string
34    */
35   protected $sTermName;
36
37   /**
38    * The user ids which gain granted access.
39    *
40    * @var array
41    */
42   protected $aUserIdsGrantedAccess;
43
44   /**
45    * The roles with granted access.
46    *
47    * @var array
48    */
49   protected $aSubmittedRolesGrantedAccess;
50
51   /**
52    * AccessStorageService constructor.
53    *
54    * @param \Drupal\Core\Database\Driver\mysql\Connection $database
55    *   The connection to the database.
56    */
57   public function __construct(Connection $database) {
58     $this->oDatabase  = $database;
59   }
60
61   /**
62    * Gets submitted roles with granted access from form.
63    *
64    * @return array
65    *   An array with chosen roles.
66    */
67   public function getSubmittedRolesGrantedAccess(FormState $form_state) {
68     $aRoles       = $form_state->getValue('access')['role'];
69     $aChosenRoles = [];
70     foreach ($aRoles as $sRole) {
71       if ($sRole !== 0) {
72         $aChosenRoles[] = $sRole;
73       }
74     }
75     return $aChosenRoles;
76   }
77
78   /**
79    * {@inheritdoc}
80    */
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)
87         ->execute();
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]));
92       }
93     }
94   }
95
96   /**
97    * {@inheritdoc}
98    */
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'])
103       ->execute()
104       ->fetchCol();
105   }
106
107   /**
108    * {@inheritdoc}
109    */
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'])
114       ->execute()
115       ->fetchCol();
116   }
117
118   /**
119    * {@inheritdoc}
120    */
121   public function getUserIdByName($sUsername) {
122     return $this->oDatabase->select('users_field_data', 'ufd')
123       ->condition('name', $sUsername)
124       ->fields('ufd', ['uid'])
125       ->execute()
126       ->fetchAssoc();
127   }
128
129   /**
130    * {@inheritdoc}
131    */
132   public function getUserIdsByNames($aUserNames) {
133     $aUserIds = [];
134     foreach ($aUserNames as $userName) {
135       $iUserId    = $this->getUserIdByName($userName)['uid'];
136       $aUserIds[] = $iUserId['uid'];
137     }
138     return $aUserIds;
139   }
140
141   /**
142    * {@inheritdoc}
143    */
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);
148
149     // fetchCol() returns all results, fetchAssoc() only "one" result.
150     return $query->execute()
151       ->fetchCol();
152   }
153
154   /**
155    * {@inheritdoc}
156    */
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, '=')
162         ->execute();
163     }
164   }
165
166   /**
167    * {@inheritdoc}
168    */
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, '=')
174         ->execute();
175     }
176   }
177
178   /**
179    * {@inheritdoc}
180    */
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])
185         ->execute();
186     }
187   }
188
189   /**
190    * {@inheritdoc}
191    */
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])
196         ->execute();
197     }
198   }
199
200   /**
201    * {@inheritdoc}
202    */
203   public function getTermIdByName($sTermName) {
204     $aTermId = \Drupal::entityQuery('taxonomy_term')
205       ->condition('name', $sTermName)
206       ->execute();
207     return key($aTermId);
208   }
209
210   /**
211    * {@inheritdoc}
212    */
213   public function getTermNameById($term_id) {
214     $term_name = \Drupal::entityQuery('taxonomy_term')
215       ->condition('id', $term_id)
216       ->execute();
217     return key($term_name);
218   }
219
220   /**
221    * Gets the user ids which have been submitted by form.
222    *
223    * Users which will gain granted access to taxonomy terms.
224    *
225    * @return array
226    *   The user ids which have been submitted.
227    */
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'];
233
234     if (empty($sRawUsers)) {
235       return [];
236     }
237
238     $aRawUsers = explode('),', $sRawUsers);
239     $aUserIds = [];
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);
249         }
250
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.
255           $aUserIds[] = 0;
256         }
257         else {
258           $aUserIds[] = $this->getUserIdByName($sRawUser)['uid'];
259         }
260       }
261     }
262
263     return $aUserIds;
264   }
265
266   /**
267    * {@inheritdoc}
268    */
269   public function saveTermPermissions(FormState $form_state, $term_id) {
270     $aExistingUserPermissions       = $this->getExistingUserTermPermissionsByTid($term_id);
271     $aSubmittedUserIdsGrantedAccess = $this->getSubmittedUserIds();
272
273     $aExistingRoleIdsGrantedAccess = $this->getExistingRoleTermPermissionsByTid($term_id);
274     $aSubmittedRolesGrantedAccess  = $this->getSubmittedRolesGrantedAccess($form_state);
275
276     $aRet = $this->getPreparedDataForDatabaseQueries($aExistingUserPermissions,
277       $aSubmittedUserIdsGrantedAccess, $aExistingRoleIdsGrantedAccess,
278       $aSubmittedRolesGrantedAccess);
279
280     // Run the database queries.
281     $this->deleteTermPermissionsByUserIds($aRet['UserIdPermissionsToRemove'], $term_id);
282     $this->addTermPermissionsByUserIds($aRet['UserIdPermissionsToAdd'], $term_id);
283
284     $this->deleteTermPermissionsByRoleIds($aRet['UserRolePermissionsToRemove'], $term_id);
285     $this->addTermPermissionsByRoleIds($aRet['aRoleIdPermissionsToAdd'], $term_id);
286
287     return $aRet;
288   }
289
290   /**
291    * Get array items to remove.
292    *
293    * The array items which aren't in the new items array, but are in old items
294    * array, will be returned.
295    *
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.
300    *
301    * @return array
302    *   The array items to remove.
303    */
304   private function getArrayItemsToRemove($aExistingItems, $aNewItems) {
305     $aRet = [];
306
307     foreach ($aExistingItems as $existingItem) {
308       if (!in_array($existingItem, $aNewItems)) {
309         $aRet[] = $existingItem;
310       }
311     }
312
313     return $aRet;
314   }
315
316   /**
317    * Get the array items to add.
318    *
319    * The items in the new items array, which aren't in the existing items array,
320    * will be returned.
321    *
322    * @param array $aNewItems
323    *   The new array items.
324    * @param array $aExistingItems
325    *   The existing array items.
326    *
327    * @return array
328    *   The items which needs to be added.
329    */
330   private function getArrayItemsToAdd($aNewItems, $aExistingItems) {
331     $aRet = [];
332
333     foreach ($aNewItems as $newItem) {
334       if (!in_array($newItem, $aExistingItems)) {
335         $aRet[] = $newItem;
336       }
337     }
338
339     return $aRet;
340   }
341
342   /**
343    * {@inheritdoc}
344    */
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);
353
354     // Fill array with user ids to add permission.
355     $aRet['UserIdPermissionsToAdd'] =
356       $this->getArrayItemsToAdd($aSubmittedUserIdsGrantedAccess,
357         $aExistingUserPermissions);
358
359     // Fill array with user roles to remove permission.
360     $aRet['UserRolePermissionsToRemove'] =
361       $this->getArrayItemsToRemove($aExistingRoleIdsGrantedAccess,
362         $aSubmittedRolesGrantedAccess);
363
364     // Fill array with user roles to add permission.
365     $aRet['aRoleIdPermissionsToAdd'] =
366       $this->getArrayItemsToAdd($aSubmittedRolesGrantedAccess,
367         $aExistingRoleIdsGrantedAccess);
368
369     return $aRet;
370   }
371
372   /**
373    * {@inheritdoc}
374    */
375   public function getUserFormValue($aAllowedUsers) {
376
377     $sUserInfos = '';
378
379     if (!empty($aAllowedUsers)) {
380
381       foreach ($aAllowedUsers as $oUser) {
382         $iUid = intval($oUser->id());
383         if ($iUid !== 0) {
384           $sUsername = $oUser->getUsername();
385         }
386         else {
387           $sUsername = t('Anonymous User');
388         }
389
390         $sUserInfos .= "$sUsername ($iUid), ";
391       }
392
393       // Remove space and comma at the end of the string.
394       $sUserInfos = substr($sUserInfos, 0, -2);
395     }
396
397     return $sUserInfos;
398   }
399
400   /**
401    * @return array
402    */
403   public function getAllNids()
404   {
405     $query = $this->oDatabase->select('node', 'n')
406         ->fields('n', ['nid']);
407
408     return $query->execute()
409         ->fetchCol();
410   }
411
412   public function getTidsByNid($nid)
413   {
414     $node = $this->entityManager->getStorage('node')->load($nid);
415     $tids = [];
416
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'];
424             }
425           }
426         }
427       }
428     }
429
430     return $tids;
431   }
432
433   public function getAllUids()
434   {
435     $nodes = \Drupal::entityQuery('user')
436       ->execute();
437
438     return array_values($nodes);
439   }
440
441   public function getNodeType($nid)
442   {
443     $query = $this->oDatabase->select('node', 'n')
444       ->fields('n', ['type'])
445       ->condition('n.nid', $nid);
446
447     return $query->execute()
448       ->fetchAssoc()['type'];
449   }
450
451   public function getLangCode($nid)
452   {
453     $query = $this->oDatabase->select('node', 'n')
454       ->fields('n', ['langcode'])
455       ->condition('n.nid', $nid);
456
457     return $query->execute()
458       ->fetchAssoc()['langcode'];
459   }
460
461   public function getGidsByRealm($realm)
462   {
463     $query = $this->oDatabase->select('node_access', 'na')
464       ->fields('na', ['gid'])
465       ->condition('na.realm', $realm);
466
467     $gids = $query->execute()->fetchCol();
468
469     foreach ($gids as $gid) {
470       $grants[$realm][] = $gid;
471     }
472
473     return $grants;
474   }
475
476   public function getAllNidsUserCanAccess($uid)
477   {
478     $query = $this->oDatabase->select('node_access', 'na')
479       ->fields('na', ['nid'])
480       ->condition('na.realm', 'permissions_by_term__uid_' . $uid);
481
482     return $query->execute()
483       ->fetchCol();
484   }
485
486   public function getNidsByTid($tid)
487   {
488       $query = $this->oDatabase->select('taxonomy_index', 'ti')
489         ->fields('ti', ['nid'])
490         ->condition('ti.tid', $tid);
491
492       return $query->execute()->fetchCol();
493   }
494
495 }