PluginProbe
User Access Manager / trunk
User Access Manager vtrunk
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 +88 -87 2.3.14trunk View file →
@@ -18,9 +18,9 @@
18 18 {
19 19 private ?array $excludedTerms = null;
20 20 private ?array $excludedPosts = null;
21 21 private array $objectAccess = [];
22 - private ?array $noneHiddenPostTypes = null;
22 + private ?array $visiblePostTypes = null;
23 23
24 24 public function __construct(
25 25 private Wordpress $wordpress,
26 26 private MainConfig $mainConfig,
@@ -30,25 +30,30 @@
30 30 private UserGroupHandler $userGroupHandler
31 31 ) {
32 32 }
33 33
34 + private function canManageUserGroups(): bool
35 + {
36 + return $this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY) === true;
37 + }
38 +
34 39 private function hasAuthorAccess(string $objectType, int|string|null $objectId): bool
35 40 {
36 - if ($this->mainConfig->authorsHasAccessToOwn() === true
37 - && $this->objectHandler->isPostType($objectType)
41 + if ($this->mainConfig->authorsHasAccessToOwn() !== true
42 + || $this->objectHandler->isPostType($objectType) === false
38 43 ) {
39 - $post = $this->objectHandler->getPost($objectId);
44 + return false;
45 + }
40 46
41 - if ($post === false) {
42 - return false;
43 - }
47 + $post = $this->objectHandler->getPost($objectId);
44 48
45 - $currentUserId = $this->wordpress->getCurrentUser()->ID;
46 - return $currentUserId !== 0
47 - && $currentUserId === (int) $post->post_author;
49 + if ($post === false) {
50 + return false;
48 51 }
49 52
50 - return false;
53 + $currentUserId = $this->wordpress->getCurrentUser()->ID;
54 +
55 + return $currentUserId !== 0 && $currentUserId === (int) $post->post_author;
51 56 }
52 57
53 58 private function isAdmin(?bool $isAdmin): bool
54 59 {
@@ -64,11 +69,9 @@
64 69
65 70 if ($this->isAdmin($isAdmin) === true) {
66 71 $userUserGroups = array_filter(
67 72 $userUserGroups,
68 - function (AbstractUserGroup $userGroup) {
69 - return $userGroup->getWriteAccess() !== 'none';
70 - }
73 + fn(AbstractUserGroup $userGroup) => $userGroup->getWriteAccess() !== 'none'
71 74 );
72 75 }
73 76
74 77 return $this->wordpress->applyFilters('uam_get_user_user_groups_for_object_access', $userUserGroups, $isAdmin);
@@ -77,29 +80,42 @@
77 80 /**
78 81 * @throws UserGroupTypeException
79 82 * @throws Exception
80 83 */
84 + private function resolveObjectAccess(?string $objectType, int|string|null $objectId, bool $isAdmin): bool
85 + {
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 + */
81 108 public function checkObjectAccess(?string $objectType, int|string|null $objectId, ?bool $isAdmin = null): bool
82 109 {
83 110 $isAdmin = $this->isAdmin($isAdmin);
84 111
85 112 if (isset($this->objectAccess[$isAdmin][$objectType][$objectId]) === false) {
86 - if ($this->objectHandler->isValidObjectType($objectType) === false
87 - || $this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY) === true
88 - || $this->hasAuthorAccess($objectType, $objectId) === true
89 - ) {
90 - $access = true;
91 - } else {
92 - $membership = $this->userGroupHandler->getUserGroupsForObject($objectType, $objectId);
93 - $access = $membership === []
94 - || array_intersect_key($membership, $this->getUserUserGroupsForObjectAccess($isAdmin)) !== [];
95 -
96 - if ($access && $this->wordpress->isUserLoggedIn() && $this->wordpress->isMultiSite()) {
97 - $access = $this->wordpress->isUserMemberOfBlog();
98 - }
99 - }
100 -
101 - $this->objectAccess[$isAdmin][$objectType][$objectId] = $access;
113 + $this->objectAccess[$isAdmin][$objectType][$objectId] = $this->resolveObjectAccess(
114 + $objectType,
115 + $objectId,
116 + $isAdmin
117 + );
102 118 }
103 119
104 120 return $this->objectAccess[$isAdmin][$objectType][$objectId];
105 121 }
@@ -104,36 +120,32 @@
104 120 return $this->objectAccess[$isAdmin][$objectType][$objectId];
105 121 }
106 122
107 123 /**
124 + * $ignoredObjectTypes is matched against the assigned object type (the array value), not the object id.
125 + *
108 126 * @throws UserGroupTypeException
109 127 * @throws Exception
110 128 */
111 - private function getExcludedObjects(string $type, array $filterTypesMap = []): array
129 + private function getExcludedObjects(string $type, array $ignoredObjectTypes = []): array
112 130 {
113 131 $excludedObjects = [];
114 - $userGroups = $this->userGroupHandler->getFullUserGroups();
115 132
116 - foreach ($userGroups as $userGroup) {
133 + foreach ($this->userGroupHandler->getFullUserGroups() as $userGroup) {
117 134 $excludedObjects += $userGroup->getAssignedObjectsByType($type);
118 135 }
119 136
120 - $userUserGroups = $this->userGroupHandler->getUserGroupsForUser();
121 -
122 - foreach ($userUserGroups as $userGroup) {
137 + foreach ($this->userGroupHandler->getUserGroupsForUser() as $userGroup) {
123 138 $excludedObjects = array_diff_key($excludedObjects, $userGroup->getAssignedObjectsByType($type));
124 139 }
125 140
126 - if ($filterTypesMap !== []) {
127 - $excludedObjects = array_filter(
128 - $excludedObjects,
129 - function ($element) use ($filterTypesMap) {
130 - return isset($filterTypesMap[$element]) === false;
131 - }
132 - );
133 - }
141 + $excludedObjects = array_filter(
142 + $excludedObjects,
143 + fn($objectType) => isset($ignoredObjectTypes[$objectType]) === false
144 + );
134 145
135 146 $objectIds = array_keys($excludedObjects);
147 +
136 148 return array_combine($objectIds, $objectIds);
137 149 }
138 150
139 151 /**
@@ -140,13 +152,11 @@
140 152 * @throws UserGroupTypeException
141 153 */
142 154 public function getExcludedTerms(): ?array
143 155 {
144 - if ($this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY)) {
156 + if ($this->canManageUserGroups() === true) {
145 157 $this->excludedTerms = [];
146 - }
147 -
148 - if ($this->excludedTerms === null) {
158 + } elseif ($this->excludedTerms === null) {
149 159 $this->excludedTerms = $this->getExcludedObjects(ObjectHandler::GENERAL_TERM_OBJECT_TYPE);
150 160 }
151 161
152 162 return $this->excludedTerms;
@@ -151,63 +161,54 @@
151 161
152 162 return $this->excludedTerms;
153 163 }
154 164
155 - private function getNoneHiddenPostTypes(): ?array
165 + private function getVisiblePostTypes(): array
156 166 {
157 - if ($this->noneHiddenPostTypes === null) {
158 - $this->noneHiddenPostTypes = [];
167 + if ($this->visiblePostTypes !== null) {
168 + return $this->visiblePostTypes;
169 + }
159 170
160 - if ($this->wordpress->isAdmin() === false) {
161 - $postTypes = $this->objectHandler->getPostTypes();
171 + $this->visiblePostTypes = [];
162 172
163 - foreach ($postTypes as $postType) {
164 - if ($this->mainConfig->hidePostType($postType) === false) {
165 - $this->noneHiddenPostTypes[$postType] = $postType;
166 - }
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;
167 177 }
168 178 }
169 179 }
170 180
171 - return $this->noneHiddenPostTypes;
181 + return $this->visiblePostTypes;
172 182 }
173 183
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 +
174 195 /**
175 196 * @throws UserGroupTypeException
176 197 */
177 198 public function getExcludedPosts(): ?array
178 199 {
179 - if ($this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY)) {
200 + if ($this->canManageUserGroups() === true) {
180 201 $this->excludedPosts = [];
181 - }
202 + } elseif ($this->excludedPosts === null) {
203 + $excludedPosts = $this->getExcludedObjects(
204 + ObjectHandler::GENERAL_POST_OBJECT_TYPE,
205 + $this->getVisiblePostTypes()
206 + );
182 207
183 - if ($this->excludedPosts === null) {
184 - $noneHiddenPostTypes = $this->getNoneHiddenPostTypes();
185 - $excludedPosts = $this->getExcludedObjects(ObjectHandler::GENERAL_POST_OBJECT_TYPE, $noneHiddenPostTypes);
186 -
187 - if ($this->mainConfig->authorsHasAccessToOwn() === true) {
188 - $query = $this->database->prepare(
189 - "SELECT ID FROM {$this->database->getPostsTable()}
190 - WHERE post_author = %d",
191 - $this->wordpress->getCurrentUser()->ID
192 - );
193 -
194 - $ownPosts = array_filter(
195 - (array) $this->database->getResults($query),
196 - function ($ownPost) {
197 - return isset($ownPost->ID);
198 - }
199 - );
200 - $ownPostIds = [];
201 -
202 - foreach ($ownPosts as $ownPost) {
203 - $ownPostIds[$ownPost->ID] = $ownPost->ID;
204 - }
205 -
206 - $excludedPosts = array_diff_key($excludedPosts, $ownPostIds);
207 - }
208 -
209 - $this->excludedPosts = $excludedPosts;
208 + $this->excludedPosts = ($this->mainConfig->authorsHasAccessToOwn() === true)
209 + ? array_diff_key($excludedPosts, $this->getOwnPostIds())
210 + : $excludedPosts;
210 211 }
211 212
212 213 return $this->excludedPosts;
213 214 }