PluginProbe
User Access Manager / 2.2.2
User Access Manager v2.2.2
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 +199 -102 trunk2.2.2 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,11 +137,14 @@
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 null|bool $isAdmin If set we force the admin mode.
143 + * @return AbstractUserGroup[]
64 144 * @throws UserGroupTypeException
65 145 */
66 - private function getUserUserGroupsForObjectAccess(?bool $isAdmin = null): array
146 + private function getUserUserGroupsForObjectAccess($isAdmin = null): array
67 147 {
68 148 $userUserGroups = $this->userGroupHandler->getUserGroupsForUser();
69 149
70 150 if ($this->isAdmin($isAdmin) === true) {
@@ -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,33 @@
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, $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 - }
92 -
93 - $membership = $this->userGroupHandler->getUserGroupsForObject($objectType, $objectId);
94 - $access = $membership === []
95 - || array_intersect_key($membership, $this->getUserUserGroupsForObjectAccess($isAdmin)) !== [];
96 -
97 - if ($access === true && $this->wordpress->isUserLoggedIn() && $this->wordpress->isMultiSite()) {
98 - return $this->wordpress->isUserMemberOfBlog();
99 - }
100 -
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 173 $isAdmin = $this->isAdmin($isAdmin);
111 174
112 175 if (isset($this->objectAccess[$isAdmin][$objectType][$objectId]) === false) {
113 - $this->objectAccess[$isAdmin][$objectType][$objectId] = $this->resolveObjectAccess(
114 - $objectType,
115 - $objectId,
116 - $isAdmin
117 - );
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)) !== [];
185 + }
186 +
187 + $this->objectAccess[$isAdmin][$objectType][$objectId] = $access;
118 188 }
119 189
120 190 return $this->objectAccess[$isAdmin][$objectType][$objectId];
121 191 }
@@ -120,43 +190,55 @@
120 190 return $this->objectAccess[$isAdmin][$objectType][$objectId];
121 191 }
122 192
123 193 /**
124 - * $ignoredObjectTypes is matched against the assigned object type (the array value), not the object id.
125 - *
194 + * Returns the excluded objects.
195 + * @param string $type
196 + * @param array $filterTypesMap
197 + * @return array
126 198 * @throws UserGroupTypeException
127 199 * @throws Exception
128 200 */
129 - private function getExcludedObjects(string $type, array $ignoredObjectTypes = []): array
201 + private function getExcludedObjects(string $type, array $filterTypesMap = []): array
130 202 {
131 203 $excludedObjects = [];
204 + $userGroups = $this->userGroupHandler->getFullUserGroups();
132 205
133 - foreach ($this->userGroupHandler->getFullUserGroups() as $userGroup) {
206 + foreach ($userGroups as $userGroup) {
134 207 $excludedObjects += $userGroup->getAssignedObjectsByType($type);
135 208 }
136 209
137 - foreach ($this->userGroupHandler->getUserGroupsForUser() as $userGroup) {
210 + $userUserGroups = $this->userGroupHandler->getUserGroupsForUser();
211 +
212 + foreach ($userUserGroups as $userGroup) {
138 213 $excludedObjects = array_diff_key($excludedObjects, $userGroup->getAssignedObjectsByType($type));
139 214 }
140 215
141 - $excludedObjects = array_filter(
142 - $excludedObjects,
143 - fn($objectType) => isset($ignoredObjectTypes[$objectType]) === false
144 - );
216 + if ($filterTypesMap !== []) {
217 + $excludedObjects = array_filter(
218 + $excludedObjects,
219 + function ($element) use ($filterTypesMap) {
220 + return isset($filterTypesMap[$element]) === false;
221 + }
222 + );
223 + }
145 224
146 225 $objectIds = array_keys($excludedObjects);
147 -
148 226 return array_combine($objectIds, $objectIds);
149 227 }
150 228
151 229 /**
230 + * Returns the excluded terms for a user.
231 + * @return array
152 232 * @throws UserGroupTypeException
153 233 */
154 234 public function getExcludedTerms(): ?array
155 235 {
156 - if ($this->canManageUserGroups() === true) {
236 + if ($this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY)) {
157 237 $this->excludedTerms = [];
158 - } elseif ($this->excludedTerms === null) {
238 + }
239 +
240 + if ($this->excludedTerms === null) {
159 241 $this->excludedTerms = $this->getExcludedObjects(ObjectHandler::GENERAL_TERM_OBJECT_TYPE);
160 242 }
161 243
162 244 return $this->excludedTerms;
@@ -161,54 +243,69 @@
161 243
162 244 return $this->excludedTerms;
163 245 }
164 246
165 - private function getVisiblePostTypes(): array
247 + /**
248 + * Returns the none hidden post types map.
249 + * @return array
250 + */
251 + private function getNoneHiddenPostTypes(): ?array
166 252 {
167 - if ($this->visiblePostTypes !== null) {
168 - return $this->visiblePostTypes;
169 - }
253 + if ($this->noneHiddenPostTypes === null) {
254 + $this->noneHiddenPostTypes = [];
170 255
171 - $this->visiblePostTypes = [];
256 + if ($this->wordpress->isAdmin() === false) {
257 + $postTypes = $this->objectHandler->getPostTypes();
172 258
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;
259 + foreach ($postTypes as $postType) {
260 + if ($this->mainConfig->hidePostType($postType) === false) {
261 + $this->noneHiddenPostTypes[$postType] = $postType;
262 + }
177 263 }
178 264 }
179 265 }
180 266
181 - return $this->visiblePostTypes;
267 + return $this->noneHiddenPostTypes;
182 268 }
183 269
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 270 /**
271 + * Returns the excluded posts.
272 + * @return array
196 273 * @throws UserGroupTypeException
197 274 */
198 275 public function getExcludedPosts(): ?array
199 276 {
200 - if ($this->canManageUserGroups() === true) {
277 + if ($this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY)) {
201 278 $this->excludedPosts = [];
202 - } elseif ($this->excludedPosts === null) {
203 - $excludedPosts = $this->getExcludedObjects(
204 - ObjectHandler::GENERAL_POST_OBJECT_TYPE,
205 - $this->getVisiblePostTypes()
206 - );
279 + }
207 280
208 - $this->excludedPosts = ($this->mainConfig->authorsHasAccessToOwn() === true)
209 - ? array_diff_key($excludedPosts, $this->getOwnPostIds())
210 - : $excludedPosts;
281 + if ($this->excludedPosts === null) {
282 + $noneHiddenPostTypes = $this->getNoneHiddenPostTypes();
283 + $excludedPosts = $this->getExcludedObjects(ObjectHandler::GENERAL_POST_OBJECT_TYPE, $noneHiddenPostTypes);
284 +
285 + if ($this->mainConfig->authorsHasAccessToOwn() === true) {
286 + $query = $this->database->prepare(
287 + "SELECT ID FROM {$this->database->getPostsTable()}
288 + WHERE post_author = %d",
289 + $this->wordpress->getCurrentUser()->ID
290 + );
291 +
292 + $ownPosts = array_filter(
293 + (array) $this->database->getResults($query),
294 + function ($ownPost) {
295 + return isset($ownPost->ID);
296 + }
297 + );
298 + $ownPostIds = [];
299 +
300 + foreach ($ownPosts as $ownPost) {
301 + $ownPostIds[$ownPost->ID] = $ownPost->ID;
302 + }
303 +
304 + $excludedPosts = array_diff_key($excludedPosts, $ownPostIds);
305 + }
306 +
307 + $this->excludedPosts = $excludedPosts;
211 308 }
212 309
213 310 return $this->excludedPosts;
214 311 }