PluginProbe
User Access Manager / 2.1.4
User Access Manager v2.1.4
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.4, at src/Access/AccessHandler.php

559 lines 16.1 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 $userIp = isset($_SERVER['HTTP_X_REAL_IP']) ? $_SERVER['HTTP_X_REAL_IP'] : $_SERVER['REMOTE_ADDR'];
312
313 return $this->userHandler->isIpInRange($userIp, $userGroup->getIpRangeArray())
314 || $this->wordpressConfig->atAdminPanel() === false && $userGroup->getReadAccess() === 'all'
315 || $this->wordpressConfig->atAdminPanel() === true && $userGroup->getWriteAccess() === 'all';
316 }
317
318 /**
319 * Assigns the dynamic user groups to the user user groups.
320 *
321 * @param \WP_User $currentUser
322 * @param array $userGroupsForUser
323 */
324 private function assignDynamicUserGroupsForUser(\WP_User $currentUser, array &$userGroupsForUser)
325 {
326 $userUserGroup = $this->userGroupFactory->createDynamicUserGroup(
327 DynamicUserGroup::USER_TYPE,
328 $currentUser->ID
329 );
330 $userGroupsForUser[$userUserGroup->getId()] = $userUserGroup;
331 $roles = $this->userHandler->getUserRole($currentUser);
332
333 foreach ($roles as $role) {
334 $group = $this->userGroupFactory->createDynamicUserGroup(
335 DynamicUserGroup::ROLE_TYPE,
336 $role
337 );
338
339 $userGroupsForUser[$group->getId()] = $group;
340 }
341 }
342
343 /**
344 * Returns the user groups for the user.
345 *
346 * @return AbstractUserGroup[]
347 */
348 public function getUserGroupsForUser()
349 {
350 if ($this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY) === true) {
351 return $this->getUserGroups();
352 }
353
354 if ($this->userGroupsForUser === null) {
355 $currentUser = $this->wordpress->getCurrentUser();
356 $userGroupsForUser = $this->getUserGroupsForObject(
357 ObjectHandler::GENERAL_USER_OBJECT_TYPE,
358 $currentUser->ID
359 );
360
361 $this->assignDynamicUserGroupsForUser($currentUser, $userGroupsForUser);
362 $userGroups = $this->getUserGroups();
363
364 foreach ($userGroups as $userGroup) {
365 if (isset($userGroupsForUser[$userGroup->getId()]) === false
366 && $this->checkUserGroupAccess($userGroup) === true
367 ) {
368 $userGroupsForUser[$userGroup->getId()] = $userGroup;
369 }
370 }
371
372 $this->userGroupsForUser = $userGroupsForUser;
373 }
374
375 return $this->userGroupsForUser;
376 }
377
378 /**
379 * Returns the user groups for the object filtered by the user user groups.
380 *
381 * @param string $objectType
382 * @param int $objectId
383 * @param bool $ignoreDates
384 *
385 * @return AbstractUserGroup[]
386 */
387 public function getFilteredUserGroupsForObject($objectType, $objectId, $ignoreDates = false)
388 {
389 $userGroups = $this->getUserGroupsForObject($objectType, $objectId, $ignoreDates);
390 $userUserGroups = $this->getUserGroupsForUser() + $this->getDynamicUserGroups();
391 return array_intersect_key($userGroups, $userUserGroups);
392 }
393
394 /**
395 * Checks it the user has access because he is the author.
396 *
397 * @param string $objectType
398 * @param string $objectId
399 *
400 * @return bool
401 */
402 private function hasAuthorAccess($objectType, $objectId)
403 {
404 if ($this->mainConfig->authorsHasAccessToOwn() === true
405 && $this->objectHandler->isPostType($objectType)
406 ) {
407 $currentUser = $this->wordpress->getCurrentUser();
408 $post = $this->objectHandler->getPost($objectId);
409 return ($post !== false && $currentUser->ID === (int)$post->post_author);
410 }
411
412 return false;
413 }
414
415 /**
416 * Checks if the current_user has access to the given post.
417 *
418 * @param string $objectType The object type which should be checked.
419 * @param integer $objectId The id of the object.
420 *
421 * @return bool
422 */
423 public function checkObjectAccess($objectType, $objectId)
424 {
425 if (isset($this->objectAccess[$objectType][$objectId]) === false) {
426 if ($this->objectHandler->isValidObjectType($objectType) === false
427 || $this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY) === true
428 || $this->hasAuthorAccess($objectType, $objectId) === true
429 ) {
430 $access = true;
431 } else {
432 $membership = $this->getUserGroupsForObject($objectType, $objectId);
433 $access = $membership === [] || array_intersect_key($membership, $this->getUserGroupsForUser()) !== [];
434 }
435
436 $this->objectAccess[$objectType][$objectId] = $access;
437 }
438
439 return $this->objectAccess[$objectType][$objectId];
440 }
441
442 /**
443 * Returns the excluded objects.
444 *
445 * @param string $type
446 * @param array $filterTypesMap
447 *
448 * @return array
449 */
450 private function getExcludedObjects($type, array $filterTypesMap = [])
451 {
452 $excludedObjects = [];
453 $userGroups = $this->getUserGroups();
454
455 foreach ($userGroups as $userGroup) {
456 $excludedObjects += $userGroup->getAssignedObjectsByType($type);
457 }
458
459 $userUserGroups = $this->getUserGroupsForUser();
460
461 foreach ($userUserGroups as $userGroup) {
462 $excludedObjects = array_diff_key($excludedObjects, $userGroup->getAssignedObjectsByType($type));
463 }
464
465 if ($filterTypesMap !== []) {
466 $excludedObjects = array_filter(
467 $excludedObjects,
468 function ($element) use ($filterTypesMap) {
469 return isset($filterTypesMap[$element]) === false;
470 }
471 );
472 }
473
474 $objectIds = array_keys($excludedObjects);
475 return array_combine($objectIds, $objectIds);
476 }
477
478 /**
479 * Returns the excluded terms for a user.
480 *
481 * @return array
482 */
483 public function getExcludedTerms()
484 {
485 if ($this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY)) {
486 $this->excludedTerms = [];
487 }
488
489 if ($this->excludedTerms === null) {
490 $this->excludedTerms = $this->getExcludedObjects(ObjectHandler::GENERAL_TERM_OBJECT_TYPE);
491 }
492
493 return $this->excludedTerms;
494 }
495
496 /**
497 * Returns the none hidden post types map.
498 *
499 * @return array
500 */
501 private function getNoneHiddenPostTypes()
502 {
503 if ($this->noneHiddenPostTypes === null) {
504 $this->noneHiddenPostTypes = [];
505
506 if ($this->wordpress->isAdmin() === false) {
507 $postTypes = $this->objectHandler->getPostTypes();
508
509 foreach ($postTypes as $postType) {
510 if ($this->mainConfig->hidePostType($postType) === false) {
511 $this->noneHiddenPostTypes[$postType] = $postType;
512 }
513 }
514 }
515 }
516
517 return $this->noneHiddenPostTypes;
518 }
519
520 /**
521 * Returns the excluded posts.
522 *
523 * @return array
524 */
525 public function getExcludedPosts()
526 {
527 if ($this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY)) {
528 $this->excludedPosts = [];
529 }
530
531 if ($this->excludedPosts === null) {
532 $noneHiddenPostTypes = $this->getNoneHiddenPostTypes();
533 $excludedPosts = $this->getExcludedObjects(ObjectHandler::GENERAL_POST_OBJECT_TYPE, $noneHiddenPostTypes);
534
535 if ($this->mainConfig->authorsHasAccessToOwn() === true) {
536 $query = $this->database->prepare(
537 "SELECT ID
538 FROM {$this->database->getPostsTable()}
539 WHERE post_author = %d",
540 $this->wordpress->getCurrentUser()->ID
541 );
542
543 $ownPosts = (array)$this->database->getResults($query);
544 $ownPostIds = [];
545
546 foreach ($ownPosts as $ownPost) {
547 $ownPostIds[$ownPost->ID] = $ownPost->ID;
548 }
549
550 $excludedPosts = array_diff_key($excludedPosts, $ownPostIds);
551 }
552
553 $this->excludedPosts = $excludedPosts;
554 }
555
556 return $this->excludedPosts;
557 }
558 }
559