PluginProbe
User Access Manager / 2.3.18
User Access Manager v2.3.18
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 / Access / AccessHandler.php

AccessHandler.php in User Access Manager 2.3.18, at src/Access/AccessHandler.php

216 lines 6.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace UserAccessManager\Access;
6
7 use Exception;
8 use UserAccessManager\Config\MainConfig;
9 use UserAccessManager\Database\Database;
10 use UserAccessManager\Object\ObjectHandler;
11 use UserAccessManager\User\UserHandler;
12 use UserAccessManager\UserGroup\AbstractUserGroup;
13 use UserAccessManager\UserGroup\UserGroupHandler;
14 use UserAccessManager\UserGroup\UserGroupTypeException;
15 use UserAccessManager\Wrapper\Wordpress;
16
17 class AccessHandler
18 {
19 private ?array $excludedTerms = null;
20 private ?array $excludedPosts = null;
21 private array $objectAccess = [];
22 private ?array $visiblePostTypes = null;
23
24 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
31 ) {
32 }
33
34 private function canManageUserGroups(): bool
35 {
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
43 ) {
44 return false;
45 }
46
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;
56 }
57
58 private function isAdmin(?bool $isAdmin): bool
59 {
60 return ($isAdmin === null) ? $this->wordpress->isAdmin() : $isAdmin;
61 }
62
63 /**
64 * @throws UserGroupTypeException
65 */
66 private function getUserUserGroupsForObjectAccess(?bool $isAdmin = null): array
67 {
68 $userUserGroups = $this->userGroupHandler->getUserGroupsForUser();
69
70 if ($this->isAdmin($isAdmin) === true) {
71 $userUserGroups = array_filter(
72 $userUserGroups,
73 fn(AbstractUserGroup $userGroup) => $userGroup->getWriteAccess() !== 'none'
74 );
75 }
76
77 return $this->wordpress->applyFilters('uam_get_user_user_groups_for_object_access', $userUserGroups, $isAdmin);
78 }
79
80 /**
81 * @throws UserGroupTypeException
82 * @throws Exception
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 */
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.
125 *
126 * @throws UserGroupTypeException
127 * @throws Exception
128 */
129 private function getExcludedObjects(string $type, array $ignoredObjectTypes = []): array
130 {
131 $excludedObjects = [];
132
133 foreach ($this->userGroupHandler->getFullUserGroups() as $userGroup) {
134 $excludedObjects += $userGroup->getAssignedObjectsByType($type);
135 }
136
137 foreach ($this->userGroupHandler->getUserGroupsForUser() as $userGroup) {
138 $excludedObjects = array_diff_key($excludedObjects, $userGroup->getAssignedObjectsByType($type));
139 }
140
141 $excludedObjects = array_filter(
142 $excludedObjects,
143 fn($objectType) => isset($ignoredObjectTypes[$objectType]) === false
144 );
145
146 $objectIds = array_keys($excludedObjects);
147
148 return array_combine($objectIds, $objectIds);
149 }
150
151 /**
152 * @throws UserGroupTypeException
153 */
154 public function getExcludedTerms(): ?array
155 {
156 if ($this->canManageUserGroups() === true) {
157 $this->excludedTerms = [];
158 } elseif ($this->excludedTerms === null) {
159 $this->excludedTerms = $this->getExcludedObjects(ObjectHandler::GENERAL_TERM_OBJECT_TYPE);
160 }
161
162 return $this->excludedTerms;
163 }
164
165 private function getVisiblePostTypes(): array
166 {
167 if ($this->visiblePostTypes !== null) {
168 return $this->visiblePostTypes;
169 }
170
171 $this->visiblePostTypes = [];
172
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;
177 }
178 }
179 }
180
181 return $this->visiblePostTypes;
182 }
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
195 /**
196 * @throws UserGroupTypeException
197 */
198 public function getExcludedPosts(): ?array
199 {
200 if ($this->canManageUserGroups() === true) {
201 $this->excludedPosts = [];
202 } elseif ($this->excludedPosts === null) {
203 $excludedPosts = $this->getExcludedObjects(
204 ObjectHandler::GENERAL_POST_OBJECT_TYPE,
205 $this->getVisiblePostTypes()
206 );
207
208 $this->excludedPosts = ($this->mainConfig->authorsHasAccessToOwn() === true)
209 ? array_diff_key($excludedPosts, $this->getOwnPostIds())
210 : $excludedPosts;
211 }
212
213 return $this->excludedPosts;
214 }
215 }
216