PluginProbe
User Access Manager / 2.1.0
User Access Manager v2.1.0
2.3.20 2.3.19 2.3.18 2.3.17 2.3.16 2.3.15 2.3.14 2.3.13 trunk 0.6 0.6.1 0.6.2 0.7 0.7 Beta 0.7.0.1 0.8 0.8.0.1 0.8.0.2 0.9 0.9.1 0.9.1.1 0.9.1.2 0.9.1.3 0.9.1.4 1.0 All 136 releases
user-access-manager / src / Access / AccessHandler.php

AccessHandler.php in User Access Manager 2.1.0, at src/Access/AccessHandler.php

557 lines 16.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * AccessHandler.php
4 *
5 * The AccessHandler class file.
6 *
7 * PHP versions 5
8 *
9 * @author Alexander Schneider <alexanderschneider85@gmail.com>
10 * @copyright 2008-2017 Alexander Schneider
11 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2
12 * @version SVN: $id$
13 * @link http://wordpress.org/extend/plugins/user-access-manager/
14 */
15 namespace UserAccessManager\Access;
16
17 use UserAccessManager\Config\MainConfig;
18 use UserAccessManager\Config\WordpressConfig;
19 use UserAccessManager\Database\Database;
20 use UserAccessManager\Object\ObjectHandler;
21 use UserAccessManager\UserGroup\AbstractUserGroup;
22 use UserAccessManager\UserGroup\DynamicUserGroup;
23 use UserAccessManager\UserGroup\UserGroup;
24 use UserAccessManager\UserGroup\UserGroupFactory;
25 use UserAccessManager\User\UserHandler;
26 use UserAccessManager\Wrapper\Wordpress;
27
28 /**
29 * Class AccessHandler
30 *
31 * @package UserAccessManager\AccessHandler
32 */
33 class AccessHandler
34 {
35 /**
36 * @var Wordpress
37 */
38 private $wordpress;
39
40 /**
41 * @var WordpressConfig
42 */
43 private $wordpressConfig;
44
45 /**
46 * @var MainConfig
47 */
48 private $mainConfig;
49
50 /**
51 * @var Database
52 */
53 private $database;
54
55 /**
56 * @var ObjectHandler
57 */
58 private $objectHandler;
59
60 /**
61 * @var UserHandler
62 */
63 private $userHandler;
64
65 /**
66 * @var UserGroupFactory
67 */
68 private $userGroupFactory;
69
70 /**
71 * @var null|UserGroup[]
72 */
73 private $userGroups = null;
74
75 /**
76 * @var null|DynamicUserGroup[]
77 */
78 private $dynamicUserGroups = null;
79
80 /**
81 * @var null|UserGroup[]
82 */
83 private $filteredUserGroups = null;
84
85 /**
86 * @var null|AbstractUserGroup[]
87 */
88 private $userGroupsForUser = null;
89
90 /**
91 * @var null|array
92 */
93 private $excludedTerms = null;
94
95 /**
96 * @var null|array
97 */
98 private $excludedPosts = null;
99
100 /**
101 * @var array
102 */
103 private $objectUserGroups = [];
104
105 /**
106 * @var array
107 */
108 private $objectAccess = [];
109
110 /**
111 * @var null|array
112 */
113 private $noneHiddenPostTypes = null;
114
115 /**
116 * AccessHandler constructor.
117 *
118 * @param Wordpress $wordpress
119 * @param WordpressConfig $wordpressConfig
120 * @param MainConfig $mainConfig
121 * @param Database $database
122 * @param ObjectHandler $objectHandler
123 * @param UserHandler $userHandler
124 * @param UserGroupFactory $userGroupFactory
125 */
126 public function __construct(
127 Wordpress $wordpress,
128 WordpressConfig $wordpressConfig,
129 MainConfig $mainConfig,
130 Database $database,
131 ObjectHandler $objectHandler,
132 UserHandler $userHandler,
133 UserGroupFactory $userGroupFactory
134 ) {
135 $this->wordpress = $wordpress;
136 $this->wordpressConfig = $wordpressConfig;
137 $this->mainConfig = $mainConfig;
138 $this->database = $database;
139 $this->objectHandler = $objectHandler;
140 $this->userHandler = $userHandler;
141 $this->userGroupFactory = $userGroupFactory;
142 }
143
144 /**
145 * Returns all user groups.
146 *
147 * @return UserGroup[]
148 */
149 public function getUserGroups()
150 {
151 if ($this->userGroups === null) {
152 $this->userGroups = [];
153
154 $query = "SELECT ID FROM {$this->database->getUserGroupTable()}";
155 $userGroups = (array)$this->database->getResults($query);
156
157 foreach ($userGroups as $userGroup) {
158 $group = $this->userGroupFactory->createUserGroup($userGroup->ID);
159 $this->userGroups[$group->getId()] = $group;
160 }
161 }
162
163 return $this->userGroups;
164 }
165
166 /**
167 * Returns all dynamic user groups.
168 *
169 * @return null|DynamicUserGroup[]
170 */
171 public function getDynamicUserGroups()
172 {
173 if ($this->dynamicUserGroups === null) {
174 $this->dynamicUserGroups = [];
175
176 $notLoggedInUserGroup = $this->userGroupFactory->createDynamicUserGroup(
177 DynamicUserGroup::USER_TYPE,
178 DynamicUserGroup::NOT_LOGGED_IN_USER_ID
179 );
180 $this->dynamicUserGroups[$notLoggedInUserGroup->getId()] = $notLoggedInUserGroup;
181
182 $userGroupTypes = implode('\', \'', [DynamicUserGroup::ROLE_TYPE, DynamicUserGroup::USER_TYPE]);
183
184 $query = "SELECT group_id AS id, group_type AS type
185 FROM {$this->database->getUserGroupToObjectTable()}
186 WHERE group_type IN ('{$userGroupTypes}')
187 GROUP BY group_type, group_id";
188
189 $dynamicUserGroups = (array)$this->database->getResults($query);
190
191 foreach ($dynamicUserGroups as $dynamicUserGroup) {
192 $group = $this->userGroupFactory->createDynamicUserGroup(
193 $dynamicUserGroup->type,
194 $dynamicUserGroup->id
195 );
196
197 $this->dynamicUserGroups[$group->getId()] = $group;
198 }
199 }
200
201 return $this->dynamicUserGroups;
202 }
203
204 /**
205 * Returns the full user groups
206 *
207 * @return AbstractUserGroup[]
208 */
209 public function getFullUserGroups()
210 {
211 return $this->getUserGroups() + $this->getDynamicUserGroups();
212 }
213
214 /**
215 * Returns the user groups filtered by the user user groups.
216 *
217 * @return AbstractUserGroup[]
218 */
219 public function getFilteredUserGroups()
220 {
221 $userGroups = $this->getFullUserGroups();
222 $userUserGroups = $this->getUserGroupsForUser() + $this->getDynamicUserGroups();
223 return array_intersect_key($userGroups, $userUserGroups);
224 }
225
226 /**
227 * Adds a user group.
228 *
229 * @param UserGroup $userGroup The user group which we want to add.
230 */
231 public function addUserGroup(UserGroup $userGroup)
232 {
233 $this->getUserGroups();
234 $this->userGroups[$userGroup->getId()] = $userGroup;
235 $this->filteredUserGroups = null;
236 }
237
238 /**
239 * Deletes a user group.
240 *
241 * @param integer $userGroupId The user group _iId which we want to delete.
242 *
243 * @return bool
244 */
245 public function deleteUserGroup($userGroupId)
246 {
247 $userGroups = $this->getUserGroups();
248
249 if (isset($userGroups[$userGroupId])
250 && $userGroups[$userGroupId]->delete() === true
251 ) {
252 unset($this->userGroups[$userGroupId]);
253 $this->filteredUserGroups = null;
254
255 return true;
256 }
257
258 return false;
259 }
260
261 /**
262 * Returns the user groups for the given object.
263 *
264 * @param string $objectType The object type.
265 * @param integer $objectId The id of the object.
266 * @param bool $ignoreDates If true we ignore the dates for the object assignment.
267 *
268 * @return AbstractUserGroup[]
269 */
270 public function getUserGroupsForObject($objectType, $objectId, $ignoreDates = false)
271 {
272 if ($this->objectHandler->isValidObjectType($objectType) === false) {
273 return [];
274 }
275
276 if (isset($this->objectUserGroups[(int)$ignoreDates][$objectType][$objectId]) === false) {
277 $objectUserGroups = [];
278 $userGroups = $this->getFullUserGroups();
279
280 foreach ($userGroups as $userGroup) {
281 $userGroup->setIgnoreDates($ignoreDates);
282
283 if ($userGroup->isObjectMember($objectType, $objectId) === true) {
284 $objectUserGroups[$userGroup->getId()] = $userGroup;
285 }
286 }
287
288 $this->objectUserGroups[(int)$ignoreDates][$objectType][$objectId] = $objectUserGroups;
289 }
290
291 return $this->objectUserGroups[(int)$ignoreDates][$objectType][$objectId];
292 }
293
294 /**
295 * Unset the object user groups.
296 */
297 public function unsetUserGroupsForObject()
298 {
299 $this->objectUserGroups = [];
300 }
301
302 /**
303 * Checks if the current user is in the ip range or if the user group is public.
304 *
305 * @param UserGroup $userGroup
306 *
307 * @return bool
308 */
309 private function checkUserGroupAccess(UserGroup $userGroup)
310 {
311 return $this->userHandler->isIpInRange($_SERVER['REMOTE_ADDR'], $userGroup->getIpRangeArray())
312 || $this->wordpressConfig->atAdminPanel() === false && $userGroup->getReadAccess() === 'all'
313 || $this->wordpressConfig->atAdminPanel() === true && $userGroup->getWriteAccess() === 'all';
314 }
315
316 /**
317 * Assigns the dynamic user groups to the user user groups.
318 *
319 * @param \WP_User $currentUser
320 * @param array $userGroupsForUser
321 */
322 private function assignDynamicUserGroupsForUser(\WP_User $currentUser, array &$userGroupsForUser)
323 {
324 $userUserGroup = $this->userGroupFactory->createDynamicUserGroup(
325 DynamicUserGroup::USER_TYPE,
326 $currentUser->ID
327 );
328 $userGroupsForUser[$userUserGroup->getId()] = $userUserGroup;
329 $roles = $this->userHandler->getUserRole($currentUser);
330
331 foreach ($roles as $role) {
332 $group = $this->userGroupFactory->createDynamicUserGroup(
333 DynamicUserGroup::ROLE_TYPE,
334 $role
335 );
336
337 $userGroupsForUser[$group->getId()] = $group;
338 }
339 }
340
341 /**
342 * Returns the user groups for the user.
343 *
344 * @return AbstractUserGroup[]
345 */
346 public function getUserGroupsForUser()
347 {
348 if ($this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY) === true) {
349 return $this->getUserGroups();
350 }
351
352 if ($this->userGroupsForUser === null) {
353 $currentUser = $this->wordpress->getCurrentUser();
354 $userGroupsForUser = $this->getUserGroupsForObject(
355 ObjectHandler::GENERAL_USER_OBJECT_TYPE,
356 $currentUser->ID
357 );
358
359 $this->assignDynamicUserGroupsForUser($currentUser, $userGroupsForUser);
360 $userGroups = $this->getUserGroups();
361
362 foreach ($userGroups as $userGroup) {
363 if (isset($userGroupsForUser[$userGroup->getId()]) === false
364 && $this->checkUserGroupAccess($userGroup) === true
365 ) {
366 $userGroupsForUser[$userGroup->getId()] = $userGroup;
367 }
368 }
369
370 $this->userGroupsForUser = $userGroupsForUser;
371 }
372
373 return $this->userGroupsForUser;
374 }
375
376 /**
377 * Returns the user groups for the object filtered by the user user groups.
378 *
379 * @param string $objectType
380 * @param int $objectId
381 * @param bool $ignoreDates
382 *
383 * @return AbstractUserGroup[]
384 */
385 public function getFilteredUserGroupsForObject($objectType, $objectId, $ignoreDates = false)
386 {
387 $userGroups = $this->getUserGroupsForObject($objectType, $objectId, $ignoreDates);
388 $userUserGroups = $this->getUserGroupsForUser() + $this->getDynamicUserGroups();
389 return array_intersect_key($userGroups, $userUserGroups);
390 }
391
392 /**
393 * Checks it the user has access because he is the author.
394 *
395 * @param string $objectType
396 * @param string $objectId
397 *
398 * @return bool
399 */
400 private function hasAuthorAccess($objectType, $objectId)
401 {
402 if ($this->mainConfig->authorsHasAccessToOwn() === true
403 && $this->objectHandler->isPostType($objectType)
404 ) {
405 $currentUser = $this->wordpress->getCurrentUser();
406 $post = $this->objectHandler->getPost($objectId);
407 return ($post !== false && $currentUser->ID === (int)$post->post_author);
408 }
409
410 return false;
411 }
412
413 /**
414 * Checks if the current_user has access to the given post.
415 *
416 * @param string $objectType The object type which should be checked.
417 * @param integer $objectId The id of the object.
418 *
419 * @return bool
420 */
421 public function checkObjectAccess($objectType, $objectId)
422 {
423 if (isset($this->objectAccess[$objectType][$objectId]) === false) {
424 if ($this->objectHandler->isValidObjectType($objectType) === false
425 || $this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY) === true
426 || $this->hasAuthorAccess($objectType, $objectId) === true
427 ) {
428 $access = true;
429 } else {
430 $membership = $this->getUserGroupsForObject($objectType, $objectId);
431 $access = $membership === [] || array_intersect_key($membership, $this->getUserGroupsForUser()) !== [];
432 }
433
434 $this->objectAccess[$objectType][$objectId] = $access;
435 }
436
437 return $this->objectAccess[$objectType][$objectId];
438 }
439
440 /**
441 * Returns the excluded objects.
442 *
443 * @param string $type
444 * @param array $filterTypesMap
445 *
446 * @return array
447 */
448 private function getExcludedObjects($type, array $filterTypesMap = [])
449 {
450 $excludedObjects = [];
451 $userGroups = $this->getUserGroups();
452
453 foreach ($userGroups as $userGroup) {
454 $excludedObjects += $userGroup->getAssignedObjectsByType($type);
455 }
456
457 $userUserGroups = $this->getUserGroupsForUser();
458
459 foreach ($userUserGroups as $userGroup) {
460 $excludedObjects = array_diff_key($excludedObjects, $userGroup->getAssignedObjectsByType($type));
461 }
462
463 if ($filterTypesMap !== []) {
464 $excludedObjects = array_filter(
465 $excludedObjects,
466 function ($element) use ($filterTypesMap) {
467 return isset($filterTypesMap[$element]) === false;
468 }
469 );
470 }
471
472 $objectIds = array_keys($excludedObjects);
473 return array_combine($objectIds, $objectIds);
474 }
475
476 /**
477 * Returns the excluded terms for a user.
478 *
479 * @return array
480 */
481 public function getExcludedTerms()
482 {
483 if ($this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY)) {
484 $this->excludedTerms = [];
485 }
486
487 if ($this->excludedTerms === null) {
488 $this->excludedTerms = $this->getExcludedObjects(ObjectHandler::GENERAL_TERM_OBJECT_TYPE);
489 }
490
491 return $this->excludedTerms;
492 }
493
494 /**
495 * Returns the none hidden post types map.
496 *
497 * @return array
498 */
499 private function getNoneHiddenPostTypes()
500 {
501 if ($this->noneHiddenPostTypes === null) {
502 $this->noneHiddenPostTypes = [];
503
504 if ($this->wordpress->isAdmin() === false) {
505 $postTypes = $this->objectHandler->getPostTypes();
506
507 foreach ($postTypes as $postType) {
508 if ($this->mainConfig->hidePostType($postType) === false) {
509 $this->noneHiddenPostTypes[$postType] = $postType;
510 }
511 }
512 }
513 }
514
515 return $this->noneHiddenPostTypes;
516 }
517
518 /**
519 * Returns the excluded posts.
520 *
521 * @return array
522 */
523 public function getExcludedPosts()
524 {
525 if ($this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY)) {
526 $this->excludedPosts = [];
527 }
528
529 if ($this->excludedPosts === null) {
530 $noneHiddenPostTypes = $this->getNoneHiddenPostTypes();
531 $excludedPosts = $this->getExcludedObjects(ObjectHandler::GENERAL_POST_OBJECT_TYPE, $noneHiddenPostTypes);
532
533 if ($this->mainConfig->authorsHasAccessToOwn() === true) {
534 $query = $this->database->prepare(
535 "SELECT ID
536 FROM {$this->database->getPostsTable()}
537 WHERE post_author = %d",
538 $this->wordpress->getCurrentUser()->ID
539 );
540
541 $ownPosts = (array)$this->database->getResults($query);
542 $ownPostIds = [];
543
544 foreach ($ownPosts as $ownPost) {
545 $ownPostIds[$ownPost->ID] = $ownPost->ID;
546 }
547
548 $excludedPosts = array_diff_key($excludedPosts, $ownPostIds);
549 }
550
551 $this->excludedPosts = $excludedPosts;
552 }
553
554 return $this->excludedPosts;
555 }
556 }
557