PluginProbe
User Access Manager / 2.0.9
User Access Manager v2.0.9
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 / UserAccessManager / AccessHandler / AccessHandler.php

AccessHandler.php in User Access Manager 2.0.9, at src/UserAccessManager/AccessHandler/AccessHandler.php

546 lines 15.4 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\AccessHandler;
16
17 use UserAccessManager\Cache\Cache;
18 use UserAccessManager\Config\Config;
19 use UserAccessManager\Database\Database;
20 use UserAccessManager\ObjectHandler\ObjectHandler;
21 use UserAccessManager\UserGroup\UserGroup;
22 use UserAccessManager\UserGroup\UserGroupFactory;
23 use UserAccessManager\Util\Util;
24 use UserAccessManager\Wrapper\Wordpress;
25
26 /**
27 * Class AccessHandler
28 *
29 * @package UserAccessManager\AccessHandler
30 */
31 class AccessHandler
32 {
33 /**
34 * @var Wordpress
35 */
36 private $wordpress;
37
38 /**
39 * @var Config
40 */
41 private $config;
42
43 /**
44 * @var Cache
45 */
46 private $cache;
47
48 /**
49 * @var Database
50 */
51 private $database;
52
53 /**
54 * @var ObjectHandler
55 */
56 private $objectHandler;
57
58 /**
59 * @var Util
60 */
61 private $util;
62
63 /**
64 * @var UserGroupFactory
65 */
66 private $userGroupFactory;
67
68 /**
69 * @var null|array
70 */
71 private $userGroups = null;
72
73 /**
74 * @var null|array
75 */
76 private $filteredUserGroups = null;
77
78 /**
79 * @var null|array
80 */
81 private $userGroupsForUser = null;
82
83 /**
84 * @var null|array
85 */
86 private $excludedTerms = null;
87
88 /**
89 * @var null|array
90 */
91 private $excludedPosts = null;
92
93 /**
94 * @var array
95 */
96 private $objectUserGroups = [];
97
98 /**
99 * @var array
100 */
101 private $objectAccess = [];
102
103 /**
104 * The constructor
105 *
106 * @param Wordpress $wordpress
107 * @param Config $config
108 * @param Cache $cache
109 * @param Database $database
110 * @param ObjectHandler $objectHandler
111 * @param Util $util
112 * @param UserGroupFactory $userGroupFactory
113 */
114 public function __construct(
115 Wordpress $wordpress,
116 Config $config,
117 Cache $cache,
118 Database $database,
119 ObjectHandler $objectHandler,
120 Util $util,
121 UserGroupFactory $userGroupFactory
122 ) {
123 $this->wordpress = $wordpress;
124 $this->config = $config;
125 $this->cache = $cache;
126 $this->database = $database;
127 $this->objectHandler = $objectHandler;
128 $this->util = $util;
129 $this->userGroupFactory = $userGroupFactory;
130 }
131
132 /**
133 * Returns all user groups or one requested by the user group id.
134 *
135 * @return UserGroup[]
136 */
137 public function getUserGroups()
138 {
139 if ($this->userGroups === null) {
140 $this->userGroups = [];
141
142 $query = "SELECT ID FROM {$this->database->getUserGroupTable()}";
143 $userGroupsDb = (array)$this->database->getResults($query);
144
145 foreach ($userGroupsDb as $userGroupDb) {
146 $this->userGroups[$userGroupDb->ID] = $this->userGroupFactory->createUserGroup($userGroupDb->ID);
147 }
148 }
149
150 return $this->userGroups;
151 }
152
153 /**
154 * Returns the user groups filtered by the user user groups.
155 *
156 * @return UserGroup[]
157 */
158 public function getFilteredUserGroups()
159 {
160 $userGroups = $this->getUserGroups();
161 $userUserGroups = $this->getUserGroupsForUser();
162 return array_intersect_key($userGroups, $userUserGroups);
163 }
164
165 /**
166 * Adds a user group.
167 *
168 * @param UserGroup $userGroup The user group which we want to add.
169 */
170 public function addUserGroup(UserGroup $userGroup)
171 {
172 $this->getUserGroups();
173 $this->userGroups[$userGroup->getId()] = $userGroup;
174 $this->filteredUserGroups = null;
175 }
176
177 /**
178 * Deletes a user group.
179 *
180 * @param integer $userGroupId The user group _iId which we want to delete.
181 *
182 * @return bool
183 */
184 public function deleteUserGroup($userGroupId)
185 {
186 $userGroups = $this->getUserGroups();
187
188 if (isset($userGroups[$userGroupId])
189 && $userGroups[$userGroupId]->delete() === true
190 ) {
191 unset($this->userGroups[$userGroupId]);
192 $this->filteredUserGroups = null;
193
194 return true;
195 }
196
197 return false;
198 }
199
200 /**
201 * Returns the user groups for the given object.
202 *
203 * @param string $objectType The object type.
204 * @param integer $objectId The _iId of the object.
205 *
206 * @return UserGroup[]
207 */
208 public function getUserGroupsForObject($objectType, $objectId)
209 {
210 if ($this->objectHandler->isValidObjectType($objectType) === false) {
211 return [];
212 } elseif (isset($this->objectUserGroups[$objectType]) === false) {
213 $this->objectUserGroups[$objectType] = [];
214 }
215
216 if (isset($this->objectUserGroups[$objectType][$objectId]) === false) {
217 $cacheKey = $this->cache->generateCacheKey(
218 'getUserGroupsForObject',
219 $objectType,
220 $objectId
221 );
222 $objectUserGroups = $this->cache->getFromCache($cacheKey);
223
224 if ($objectUserGroups !== null) {
225 $this->objectUserGroups[$objectType][$objectId] = $objectUserGroups;
226 } else {
227 $objectUserGroups = [];
228 $userGroups = $this->getUserGroups();
229
230 foreach ($userGroups as $userGroup) {
231 if ($userGroup->isObjectMember($objectType, $objectId) === true) {
232 $objectUserGroups[$userGroup->getId()] = $userGroup;
233 }
234 }
235
236 $this->cache->addToCache($cacheKey, $objectUserGroups);
237 }
238
239 $this->objectUserGroups[$objectType][$objectId] = $objectUserGroups;
240 }
241
242 return $this->objectUserGroups[$objectType][$objectId];
243 }
244
245 /**
246 * Unset the user groups for _aObjects.
247 */
248 public function unsetUserGroupsForObject()
249 {
250 $this->objectUserGroups = [];
251 }
252
253 /**
254 * Converts the ip to an integer.
255 *
256 * @param array $ip
257 *
258 * @return int
259 */
260 private function calculateIp(array $ip)
261 {
262 return ($ip[0] << 24) + ($ip[1] << 16) + ($ip[2] << 8) + $ip[3];
263 }
264
265 /**
266 * Checks if the given ip matches with the range.
267 *
268 * @param string $currentIp The ip of the current user.
269 * @param array $ipRanges The ip ranges.
270 *
271 * @return bool
272 */
273 public function isIpInRange($currentIp, array $ipRanges)
274 {
275 $currentIp = explode('.', $currentIp);
276 $curIp = $this->calculateIp($currentIp);
277
278 foreach ($ipRanges as $ipRange) {
279 $ipRange = explode('-', $ipRange);
280 $rangeBegin = explode('.', $ipRange[0]);
281 $rangeEnd = isset($ipRange[1]) ? explode('.', $ipRange[1]) : explode('.', $ipRange[0]);
282
283 if (count($rangeBegin) === 4 && count($rangeEnd) === 4) {
284 $rangeBegin = $this->calculateIp($rangeBegin);
285 $rangeEnd = $this->calculateIp($rangeEnd);
286
287 if ($rangeBegin <= $curIp && $curIp <= $rangeEnd) {
288 return true;
289 }
290 }
291 }
292
293 return false;
294 }
295
296 /**
297 * Returns the user groups for the user.
298 *
299 * @return UserGroup[]
300 */
301 public function getUserGroupsForUser()
302 {
303 if ($this->checkUserAccess('manage_user_groups') === true) {
304 return $this->getUserGroups();
305 }
306
307 if ($this->userGroupsForUser === null) {
308 $currentUser = $this->wordpress->getCurrentUser();
309 $userGroupsForUser = $this->getUserGroupsForObject(
310 ObjectHandler::GENERAL_USER_OBJECT_TYPE,
311 $currentUser->ID
312 );
313
314 $userGroups = $this->getUserGroups();
315
316 foreach ($userGroups as $userGroup) {
317 if (isset($userGroupsForUser[$userGroup->getId()]) === false
318 && ($this->isIpInRange($_SERVER['REMOTE_ADDR'], $userGroup->getIpRangeArray())
319 || $this->config->atAdminPanel() === false && $userGroup->getReadAccess() === 'all'
320 || $this->config->atAdminPanel() === true && $userGroup->getWriteAccess() === 'all')
321 ) {
322 $userGroupsForUser[$userGroup->getId()] = $userGroup;
323 }
324 }
325
326 $this->userGroupsForUser = $userGroupsForUser;
327 }
328
329 return $this->userGroupsForUser;
330 }
331
332 /**
333 * Returns the user groups for the object filtered by the user user groups.
334 *
335 * @param string $objectType
336 * @param int $objectId
337 *
338 * @return UserGroup[]
339 */
340 public function getFilteredUserGroupsForObject($objectType, $objectId)
341 {
342 $userGroups = $this->getUserGroupsForObject($objectType, $objectId);
343 $userUserGroups = $this->getUserGroupsForUser();
344 return array_intersect_key($userGroups, $userUserGroups);
345 }
346
347 /**
348 * Return the role of the user.
349 *
350 * @param \WP_User|false $user The user.
351 *
352 * @return array
353 */
354 private function getUserRole($user)
355 {
356 if ($user instanceof \WP_User && isset($user->{$this->database->getPrefix().'capabilities'}) === true) {
357 $capabilities = (array)$user->{$this->database->getPrefix().'capabilities'};
358 } else {
359 $capabilities = [];
360 }
361
362 return (count($capabilities) > 0) ? array_keys($capabilities) : [UserGroup::NONE_ROLE];
363 }
364
365 /**
366 * Checks the user access by user level.
367 *
368 * @param bool|string $allowedCapability If set check also for the capability.
369 *
370 * @return bool
371 */
372 public function checkUserAccess($allowedCapability = false)
373 {
374 $currentUser = $this->wordpress->getCurrentUser();
375
376 if ($this->wordpress->isSuperAdmin($currentUser->ID) === true
377 || $allowedCapability !== false && $currentUser->has_cap($allowedCapability) === true
378 ) {
379 return true;
380 }
381
382 $roles = $this->getUserRole($currentUser);
383 $rolesMap = array_flip($roles);
384
385 $orderedRoles = [UserGroup::NONE_ROLE, 'subscriber', 'contributor', 'author', 'editor', 'administrator'];
386 $orderedRolesMap = array_flip($orderedRoles);
387
388 $userRoles = array_intersect_key($orderedRolesMap, $rolesMap);
389 $rightsLevel = (count($userRoles) > 0) ? end($userRoles) : -1;
390 $fullAccessRole = $this->config->getFullAccessRole();
391
392 return (isset($orderedRolesMap[$fullAccessRole]) === true && $rightsLevel >= $orderedRolesMap[$fullAccessRole]
393 || isset($rolesMap['administrator']) === true
394 );
395 }
396
397 /**
398 * Checks if the user is an admin user
399 *
400 * @param integer $userId The user id.
401 *
402 * @return bool
403 */
404 public function userIsAdmin($userId)
405 {
406 $user = $this->objectHandler->getUser($userId);
407 $roles = $this->getUserRole($user);
408 $rolesMap = array_flip($roles);
409
410 return (isset($rolesMap['administrator']) === true || $this->wordpress->isSuperAdmin($userId) === true);
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 ($this->objectHandler->isValidObjectType($objectType) === false) {
424 return true;
425 } elseif (isset($this->objectAccess[$objectType]) === false) {
426 $this->objectAccess[$objectType] = [];
427 }
428
429 if (isset($this->objectAccess[$objectType][$objectId]) === false) {
430 $access = false;
431 $currentUser = $this->wordpress->getCurrentUser();
432
433 if ($this->checkUserAccess('manage_user_groups') === true) {
434 $access = true;
435 } elseif ($this->config->authorsHasAccessToOwn() === true
436 && $this->objectHandler->isPostType($objectType)
437 ) {
438 $post = $this->objectHandler->getPost($objectId);
439 $access = ($post !== false && $currentUser->ID === (int)$post->post_author);
440 }
441
442 if ($access === false) {
443 $membership = $this->getUserGroupsForObject($objectType, $objectId);
444
445 if (count($membership) > 0) {
446 $userUserGroups = $this->getUserGroupsForUser();
447
448 foreach ($membership as $userGroupId => $userGroup) {
449 if (isset($userUserGroups[$userGroupId]) === true) {
450 $access = true;
451 break;
452 }
453 }
454 } else {
455 $access = true;
456 }
457 }
458
459 $this->objectAccess[$objectType][$objectId] = $access;
460 }
461
462 return $this->objectAccess[$objectType][$objectId];
463 }
464
465 /**
466 * Returns the excluded terms for a user.
467 *
468 * @return array
469 */
470 public function getExcludedTerms()
471 {
472 if ($this->checkUserAccess('manage_user_groups')) {
473 $this->excludedTerms = [];
474 }
475
476 if ($this->excludedTerms === null) {
477 $excludedTerms = [];
478 $userGroups = $this->getUserGroups();
479
480 $userUserGroups = $this->getUserGroupsForUser();
481
482 foreach ($userGroups as $userGroup) {
483 $excludedTerms += $userGroup->getFullTerms();
484 }
485
486 foreach ($userUserGroups as $userGroup) {
487 $excludedTerms = array_diff_key($excludedTerms, $userGroup->getFullTerms());
488 }
489
490 $termIds = array_keys($excludedTerms);
491 $this->excludedTerms = array_combine($termIds, $termIds);
492 }
493
494 return $this->excludedTerms;
495 }
496
497 /**
498 * Returns the excluded posts.
499 *
500 * @return array
501 */
502 public function getExcludedPosts()
503 {
504 if ($this->checkUserAccess('manage_user_groups')) {
505 $this->excludedPosts = [];
506 }
507
508 if ($this->excludedPosts === null) {
509 $excludedPosts = [];
510 $userGroups = $this->getUserGroups();
511
512 $userUserGroups = $this->getUserGroupsForUser();
513
514 foreach ($userGroups as $userGroup) {
515 $excludedPosts += $userGroup->getFullPosts();
516 }
517
518 foreach ($userUserGroups as $userGroup) {
519 $excludedPosts = array_diff_key($excludedPosts, $userGroup->getFullPosts());
520 }
521
522 if ($this->wordpress->isAdmin() === false) {
523 $noneHiddenPostTypes = [];
524 $postTypes = $this->objectHandler->getPostTypes();
525
526 foreach ($postTypes as $postType) {
527 if ($this->config->hidePostType($postType) === false) {
528 $noneHiddenPostTypes[$postType] = $postType;
529 }
530 }
531
532 foreach ($excludedPosts as $postId => $type) {
533 if (isset($noneHiddenPostTypes[$type]) === true) {
534 unset($excludedPosts[$postId]);
535 }
536 }
537 }
538
539 $postIds = array_keys($excludedPosts);
540 $this->excludedPosts = array_combine($postIds, $postIds);
541 }
542
543 return $this->excludedPosts;
544 }
545 }
546