PluginProbe
User Access Manager / 2.2.25
User Access Manager v2.2.25
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
← All changes | src/Access/AccessHandler.php +202 -101 trunk2.2.25 View file →
@@ -1,5 +1,18 @@
1 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 + */
2 15
3 16 declare(strict_types=1);
4 17
5 18 namespace UserAccessManager\Access;
@@ -13,49 +26,113 @@
13 26 use UserAccessManager\UserGroup\UserGroupHandler;
14 27 use UserAccessManager\UserGroup\UserGroupTypeException;
15 28 use UserAccessManager\Wrapper\Wordpress;
16 29
30 +/**
31 + * Class AccessHandler
32 + * @package UserAccessManager\AccessHandler
33 + */
17 34 class AccessHandler
18 35 {
19 - private ?array $excludedTerms = null;
20 - private ?array $excludedPosts = null;
21 - private array $objectAccess = [];
22 - private ?array $visiblePostTypes = null;
36 + /**
37 + * @var Wordpress
38 + */
39 + private $wordpress;
23 40
41 + /**
42 + * @var MainConfig
43 + */
44 + private $mainConfig;
45 +
46 + /**
47 + * @var Database
48 + */
49 + private $database;
50 +
51 + /**
52 + * @var ObjectHandler
53 + */
54 + private $objectHandler;
55 +
56 + /**
57 + * @var UserHandler
58 + */
59 + private $userHandler;
60 +
61 + /**
62 + * @var UserGroupHandler
63 + */
64 + private $userGroupHandler;
65 +
66 + /**
67 + * @var null|array
68 + */
69 + private $excludedTerms = null;
70 +
71 + /**
72 + * @var null|array
73 + */
74 + private $excludedPosts = null;
75 +
76 + /**
77 + * @var array
78 + */
79 + private $objectAccess = [];
80 +
81 + /**
82 + * @var null|array
83 + */
84 + private $noneHiddenPostTypes = null;
85 +
86 + /**
87 + * AccessHandler constructor.
88 + * @param Wordpress $wordpress
89 + * @param MainConfig $mainConfig
90 + * @param Database $database
91 + * @param ObjectHandler $objectHandler
92 + * @param UserHandler $userHandler
93 + * @param UserGroupHandler $userGroupHandler
94 + */
24 95 public function __construct(
25 - private Wordpress $wordpress,
26 - private MainConfig $mainConfig,
27 - private Database $database,
28 - private ObjectHandler $objectHandler,
29 - private UserHandler $userHandler,
30 - private UserGroupHandler $userGroupHandler
96 + Wordpress $wordpress,
97 + MainConfig $mainConfig,
98 + Database $database,
99 + ObjectHandler $objectHandler,
100 + UserHandler $userHandler,
101 + UserGroupHandler $userGroupHandler
31 102 ) {
103 + $this->wordpress = $wordpress;
104 + $this->mainConfig = $mainConfig;
105 + $this->database = $database;
106 + $this->objectHandler = $objectHandler;
107 + $this->userHandler = $userHandler;
108 + $this->userGroupHandler = $userGroupHandler;
32 109 }
33 110
34 - private function canManageUserGroups(): bool
111 + /**
112 + * Checks it the user has access because he is the author.
113 + * @param string $objectType
114 + * @param int|string $objectId
115 + * @return bool
116 + */
117 + private function hasAuthorAccess(string $objectType, $objectId): bool
35 118 {
36 - return $this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY) === true;
37 - }
38 -
39 - private function hasAuthorAccess(string $objectType, int|string|null $objectId): bool
40 - {
41 - if ($this->mainConfig->authorsHasAccessToOwn() !== true
42 - || $this->objectHandler->isPostType($objectType) === false
119 + if ($this->mainConfig->authorsHasAccessToOwn() === true
120 + && $this->objectHandler->isPostType($objectType)
43 121 ) {
44 - return false;
122 + $post = $this->objectHandler->getPost($objectId);
123 + return $post !== false
124 + && $this->wordpress->getCurrentUser()->ID === (int) $post->post_author;
45 125 }
46 126
47 - $post = $this->objectHandler->getPost($objectId);
48 -
49 - if ($post === false) {
50 - return false;
51 - }
52 -
53 - $currentUserId = $this->wordpress->getCurrentUser()->ID;
54 -
55 - return $currentUserId !== 0 && $currentUserId === (int) $post->post_author;
127 + return false;
56 128 }
57 129
130 + /**
131 + * Checks if the is admin value is set if not grabs it from the wordpress function.
132 + * @param null|bool $isAdmin
133 + * @return bool
134 + */
58 135 private function isAdmin(?bool $isAdmin): bool
59 136 {
60 137 return ($isAdmin === null) ? $this->wordpress->isAdmin() : $isAdmin;
61 138 }
@@ -60,8 +137,11 @@
60 137 return ($isAdmin === null) ? $this->wordpress->isAdmin() : $isAdmin;
61 138 }
62 139
63 140 /**
141 + * Returns the user user groups filtered by the write access.
142 + * @param bool|null $isAdmin If set we force the admin mode.
143 + * @return AbstractUserGroup[]
64 144 * @throws UserGroupTypeException
65 145 */
66 146 private function getUserUserGroupsForObjectAccess(?bool $isAdmin = null): array
67 147 {
@@ -69,9 +149,11 @@
69 149
70 150 if ($this->isAdmin($isAdmin) === true) {
71 151 $userUserGroups = array_filter(
72 152 $userUserGroups,
73 - fn(AbstractUserGroup $userGroup) => $userGroup->getWriteAccess() !== 'none'
153 + function (AbstractUserGroup $userGroup) {
154 + return $userGroup->getWriteAccess() !== 'none';
155 + }
74 156 );
75 157 }
76 158
77 159 return $this->wordpress->applyFilters('uam_get_user_user_groups_for_object_access', $userUserGroups, $isAdmin);
@@ -77,45 +159,37 @@
77 159 return $this->wordpress->applyFilters('uam_get_user_user_groups_for_object_access', $userUserGroups, $isAdmin);
78 160 }
79 161
80 162 /**
163 + * Checks if the current_user has access to the given post.
164 + * @param string|null $objectType The object type which should be checked.
165 + * @param int|string $objectId The id of the object.
166 + * @param null|bool $isAdmin If set we force the admin mode.
167 + * @return bool
81 168 * @throws UserGroupTypeException
82 169 * @throws Exception
83 170 */
84 - private function resolveObjectAccess(?string $objectType, int|string|null $objectId, bool $isAdmin): bool
171 + public function checkObjectAccess(?string $objectType, $objectId, ?bool $isAdmin = null): bool
85 172 {
86 - if ($this->objectHandler->isValidObjectType($objectType) === false
87 - || $this->canManageUserGroups() === true
88 - || $this->hasAuthorAccess($objectType, $objectId) === true
89 - ) {
90 - return true;
91 - }
173 + $isAdmin = $this->isAdmin($isAdmin);
92 174
93 - $membership = $this->userGroupHandler->getUserGroupsForObject($objectType, $objectId);
94 - $access = $membership === []
95 - || array_intersect_key($membership, $this->getUserUserGroupsForObjectAccess($isAdmin)) !== [];
175 + if (isset($this->objectAccess[$isAdmin][$objectType][$objectId]) === false) {
176 + if ($this->objectHandler->isValidObjectType($objectType) === false
177 + || $this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY) === true
178 + || $this->hasAuthorAccess($objectType, $objectId) === true
179 + ) {
180 + $access = true;
181 + } else {
182 + $membership = $this->userGroupHandler->getUserGroupsForObject($objectType, $objectId);
183 + $access = $membership === []
184 + || array_intersect_key($membership, $this->getUserUserGroupsForObjectAccess($isAdmin)) !== [];
96 185
97 - if ($access === true && $this->wordpress->isUserLoggedIn() && $this->wordpress->isMultiSite()) {
98 - return $this->wordpress->isUserMemberOfBlog();
99 - }
186 + if ($access && $this->wordpress->isUserLoggedIn() && $this->wordpress->isMultiSite()) {
187 + $access = $this->wordpress->isUserMemberOfBlog();
188 + }
189 + }
100 190
101 - return $access;
102 - }
103 -
104 - /**
105 - * @throws UserGroupTypeException
106 - * @throws Exception
107 - */
108 - public function checkObjectAccess(?string $objectType, int|string|null $objectId, ?bool $isAdmin = null): bool
109 - {
110 - $isAdmin = $this->isAdmin($isAdmin);
111 -
112 - if (isset($this->objectAccess[$isAdmin][$objectType][$objectId]) === false) {
113 - $this->objectAccess[$isAdmin][$objectType][$objectId] = $this->resolveObjectAccess(
114 - $objectType,
115 - $objectId,
116 - $isAdmin
117 - );
191 + $this->objectAccess[$isAdmin][$objectType][$objectId] = $access;
118 192 }
119 193
120 194 return $this->objectAccess[$isAdmin][$objectType][$objectId];
121 195 }
@@ -120,43 +194,55 @@
120 194 return $this->objectAccess[$isAdmin][$objectType][$objectId];
121 195 }
122 196
123 197 /**
124 - * $ignoredObjectTypes is matched against the assigned object type (the array value), not the object id.
125 - *
198 + * Returns the excluded objects.
199 + * @param string $type
200 + * @param array $filterTypesMap
201 + * @return array
126 202 * @throws UserGroupTypeException
127 203 * @throws Exception
128 204 */
129 - private function getExcludedObjects(string $type, array $ignoredObjectTypes = []): array
205 + private function getExcludedObjects(string $type, array $filterTypesMap = []): array
130 206 {
131 207 $excludedObjects = [];
208 + $userGroups = $this->userGroupHandler->getFullUserGroups();
132 209
133 - foreach ($this->userGroupHandler->getFullUserGroups() as $userGroup) {
210 + foreach ($userGroups as $userGroup) {
134 211 $excludedObjects += $userGroup->getAssignedObjectsByType($type);
135 212 }
136 213
137 - foreach ($this->userGroupHandler->getUserGroupsForUser() as $userGroup) {
214 + $userUserGroups = $this->userGroupHandler->getUserGroupsForUser();
215 +
216 + foreach ($userUserGroups as $userGroup) {
138 217 $excludedObjects = array_diff_key($excludedObjects, $userGroup->getAssignedObjectsByType($type));
139 218 }
140 219
141 - $excludedObjects = array_filter(
142 - $excludedObjects,
143 - fn($objectType) => isset($ignoredObjectTypes[$objectType]) === false
144 - );
220 + if ($filterTypesMap !== []) {
221 + $excludedObjects = array_filter(
222 + $excludedObjects,
223 + function ($element) use ($filterTypesMap) {
224 + return isset($filterTypesMap[$element]) === false;
225 + }
226 + );
227 + }
145 228
146 229 $objectIds = array_keys($excludedObjects);
147 -
148 230 return array_combine($objectIds, $objectIds);
149 231 }
150 232
151 233 /**
234 + * Returns the excluded terms for a user.
235 + * @return array
152 236 * @throws UserGroupTypeException
153 237 */
154 238 public function getExcludedTerms(): ?array
155 239 {
156 - if ($this->canManageUserGroups() === true) {
240 + if ($this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY)) {
157 241 $this->excludedTerms = [];
158 - } elseif ($this->excludedTerms === null) {
242 + }
243 +
244 + if ($this->excludedTerms === null) {
159 245 $this->excludedTerms = $this->getExcludedObjects(ObjectHandler::GENERAL_TERM_OBJECT_TYPE);
160 246 }
161 247
162 248 return $this->excludedTerms;
@@ -161,54 +247,69 @@
161 247
162 248 return $this->excludedTerms;
163 249 }
164 250
165 - private function getVisiblePostTypes(): array
251 + /**
252 + * Returns the none hidden post types map.
253 + * @return array
254 + */
255 + private function getNoneHiddenPostTypes(): ?array
166 256 {
167 - if ($this->visiblePostTypes !== null) {
168 - return $this->visiblePostTypes;
169 - }
257 + if ($this->noneHiddenPostTypes === null) {
258 + $this->noneHiddenPostTypes = [];
170 259
171 - $this->visiblePostTypes = [];
260 + if ($this->wordpress->isAdmin() === false) {
261 + $postTypes = $this->objectHandler->getPostTypes();
172 262
173 - if ($this->wordpress->isAdmin() === false) {
174 - foreach ($this->objectHandler->getPostTypes() as $postType) {
175 - if ($this->mainConfig->hidePostType($postType) === false) {
176 - $this->visiblePostTypes[$postType] = $postType;
263 + foreach ($postTypes as $postType) {
264 + if ($this->mainConfig->hidePostType($postType) === false) {
265 + $this->noneHiddenPostTypes[$postType] = $postType;
266 + }
177 267 }
178 268 }
179 269 }
180 270
181 - return $this->visiblePostTypes;
271 + return $this->noneHiddenPostTypes;
182 272 }
183 273
184 - private function getOwnPostIds(): array
185 - {
186 - $query = $this->database->prepare(
187 - "SELECT `ID` FROM `{$this->database->getPostsTable()}`
188 - WHERE `post_author` = %d",
189 - $this->wordpress->getCurrentUser()->ID
190 - );
191 -
192 - return array_column((array) $this->database->getResults($query), 'ID', 'ID');
193 - }
194 -
195 274 /**
275 + * Returns the excluded posts.
276 + * @return array
196 277 * @throws UserGroupTypeException
197 278 */
198 279 public function getExcludedPosts(): ?array
199 280 {
200 - if ($this->canManageUserGroups() === true) {
281 + if ($this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY)) {
201 282 $this->excludedPosts = [];
202 - } elseif ($this->excludedPosts === null) {
203 - $excludedPosts = $this->getExcludedObjects(
204 - ObjectHandler::GENERAL_POST_OBJECT_TYPE,
205 - $this->getVisiblePostTypes()
206 - );
283 + }
207 284
208 - $this->excludedPosts = ($this->mainConfig->authorsHasAccessToOwn() === true)
209 - ? array_diff_key($excludedPosts, $this->getOwnPostIds())
210 - : $excludedPosts;
285 + if ($this->excludedPosts === null) {
286 + $noneHiddenPostTypes = $this->getNoneHiddenPostTypes();
287 + $excludedPosts = $this->getExcludedObjects(ObjectHandler::GENERAL_POST_OBJECT_TYPE, $noneHiddenPostTypes);
288 +
289 + if ($this->mainConfig->authorsHasAccessToOwn() === true) {
290 + $query = $this->database->prepare(
291 + "SELECT ID FROM {$this->database->getPostsTable()}
292 + WHERE post_author = %d",
293 + $this->wordpress->getCurrentUser()->ID
294 + );
295 +
296 + $ownPosts = array_filter(
297 + (array) $this->database->getResults($query),
298 + function ($ownPost) {
299 + return isset($ownPost->ID);
300 + }
301 + );
302 + $ownPostIds = [];
303 +
304 + foreach ($ownPosts as $ownPost) {
305 + $ownPostIds[$ownPost->ID] = $ownPost->ID;
306 + }
307 +
308 + $excludedPosts = array_diff_key($excludedPosts, $ownPostIds);
309 + }
310 +
311 + $this->excludedPosts = $excludedPosts;
211 312 }
212 313
213 314 return $this->excludedPosts;
214 315 }