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