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
user-access-manager / src / UserGroup / UserGroupHandler.php

UserGroupHandler.php in User Access Manager trunk, at src/UserGroup/UserGroupHandler.php

279 lines 8.6 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\UserGroup;
6
7 use Exception;
8 use UserAccessManager\Config\MainConfig;
9 use UserAccessManager\Config\WordpressConfig;
10 use UserAccessManager\Database\Database;
11 use UserAccessManager\Object\ObjectHandler;
12 use UserAccessManager\User\UserHandler;
13 use UserAccessManager\Wrapper\Wordpress;
14 use WP_User;
15
16 class UserGroupHandler
17 {
18 /** @var null|UserGroup[] */
19 private ?array $userGroups = null;
20 /** @var null|DynamicUserGroup[] */
21 private ?array $dynamicUserGroups = null;
22 /** @var null|AbstractUserGroup[] */
23 private ?array $userGroupsForUser = null;
24 /** @var AbstractUserGroup[] */
25 private array $objectUserGroups = [];
26
27 public function __construct(
28 private Wordpress $wordpress,
29 private WordpressConfig $wordpressConfig,
30 private MainConfig $mainConfig,
31 private Database $database,
32 private ObjectHandler $objectHandler,
33 private UserHandler $userHandler,
34 private UserGroupFactory $userGroupFactory
35 ) {
36 }
37
38 /**
39 * @return UserGroup[]
40 * @throws UserGroupTypeException
41 */
42 public function getUserGroups(): array
43 {
44 return $this->userGroups ??= $this->loadUserGroups();
45 }
46
47 /**
48 * @return UserGroup[]
49 * @throws UserGroupTypeException
50 */
51 private function loadUserGroups(): array
52 {
53 $query = "SELECT * FROM `{$this->database->getUserGroupTable()}`";
54 $userGroups = [];
55
56 foreach ((array) $this->database->getResults($query) as $databaseUserGroup) {
57 $userGroup = $this->userGroupFactory->createUserGroupFromDatabaseRow($databaseUserGroup);
58 $userGroups[$userGroup->getId()] = $userGroup;
59 }
60
61 return $userGroups;
62 }
63
64 /**
65 * @return DynamicUserGroup[]
66 * @throws UserGroupTypeException
67 */
68 public function getDynamicUserGroups(): array
69 {
70 return $this->dynamicUserGroups ??= $this->loadDynamicUserGroups();
71 }
72
73 /**
74 * @return DynamicUserGroup[]
75 * @throws UserGroupTypeException
76 */
77 private function loadDynamicUserGroups(): array
78 {
79 $notLoggedInUserGroup = $this->userGroupFactory->createDynamicUserGroup(
80 DynamicUserGroup::USER_TYPE,
81 DynamicUserGroup::NOT_LOGGED_IN_USER_ID
82 );
83 $dynamicUserGroups = [$notLoggedInUserGroup->getId() => $notLoggedInUserGroup];
84
85 $userGroupTypes = implode('\', \'', [DynamicUserGroup::ROLE_TYPE, DynamicUserGroup::USER_TYPE]);
86
87 $query = "SELECT `group_id` AS `id`, `group_type` AS `type`
88 FROM `{$this->database->getUserGroupToObjectTable()}`
89 WHERE `group_type` IN ('$userGroupTypes')
90 GROUP BY `group_type`, `group_id`";
91
92 foreach ((array) $this->database->getResults($query) as $databaseUserGroup) {
93 $userGroup = $this->userGroupFactory->createDynamicUserGroup(
94 $databaseUserGroup->type,
95 $databaseUserGroup->id
96 );
97
98 $dynamicUserGroups[$userGroup->getId()] = $userGroup;
99 }
100
101 return $dynamicUserGroups;
102 }
103
104 /**
105 * @return AbstractUserGroup[]
106 * @throws UserGroupTypeException
107 */
108 public function getFullUserGroups(): array
109 {
110 return $this->getUserGroups() + $this->getDynamicUserGroups();
111 }
112
113 /**
114 * Reduces the given user groups to those the current user is allowed to see.
115 *
116 * @param AbstractUserGroup[] $userGroups
117 * @return AbstractUserGroup[]
118 * @throws UserGroupTypeException
119 */
120 private function filterByUserGroupsOfUser(array $userGroups): array
121 {
122 return array_intersect_key($userGroups, $this->getUserGroupsForUser() + $this->getDynamicUserGroups());
123 }
124
125 /**
126 * @return AbstractUserGroup[]
127 * @throws UserGroupTypeException
128 */
129 public function getFilteredUserGroups(): array
130 {
131 return $this->filterByUserGroupsOfUser($this->getFullUserGroups());
132 }
133
134 /**
135 * @throws UserGroupTypeException
136 */
137 public function addUserGroup(UserGroup $userGroup): void
138 {
139 $this->getUserGroups();
140 $this->userGroups[$userGroup->getId()] = $userGroup;
141 }
142
143 /**
144 * @throws UserGroupTypeException
145 * @throws Exception
146 */
147 public function deleteUserGroup(int|string $userGroupId): bool
148 {
149 $userGroups = $this->getUserGroups();
150
151 if (isset($userGroups[$userGroupId]) === false || $userGroups[$userGroupId]->delete() === false) {
152 return false;
153 }
154
155 unset($this->userGroups[$userGroupId]);
156
157 return true;
158 }
159
160 /**
161 * @return AbstractUserGroup[]
162 * @throws UserGroupTypeException
163 * @throws Exception
164 */
165 public function getUserGroupsForObject(
166 string $objectType,
167 int|string|null $objectId,
168 bool $ignoreDates = false
169 ): array {
170 if ($this->objectHandler->isValidObjectType($objectType) === false) {
171 return [];
172 }
173
174 if (isset($this->objectUserGroups[$ignoreDates][$objectType][$objectId]) === false) {
175 $objectUserGroups = [];
176
177 foreach ($this->getFullUserGroups() as $userGroup) {
178 $userGroup->setIgnoreDates($ignoreDates);
179
180 if ($userGroup->isObjectMember($objectType, $objectId) === true) {
181 $objectUserGroups[$userGroup->getId()] = $userGroup;
182 }
183 }
184
185 $this->objectUserGroups[$ignoreDates][$objectType][$objectId] = $objectUserGroups;
186 }
187
188 return $this->objectUserGroups[$ignoreDates][$objectType][$objectId];
189 }
190
191 public function unsetUserGroupsForObject(): void
192 {
193 $this->objectUserGroups = [];
194 }
195
196 private function getUserIp(): string
197 {
198 $extraIpHeader = $this->mainConfig->getExtraIpHeader();
199
200 return ($extraIpHeader !== null && isset($_SERVER[$extraIpHeader]) === true) ?
201 (string) $_SERVER[$extraIpHeader] : (string) ($_SERVER['REMOTE_ADDR'] ?? '');
202 }
203
204 private function checkUserGroupAccess(UserGroup $userGroup): bool
205 {
206 return $this->userHandler->isIpInRange($this->getUserIp(), $userGroup->getIpRangeArray())
207 || $this->wordpressConfig->atAdminPanel() === false && $userGroup->getReadAccess() === 'all'
208 || $this->wordpressConfig->atAdminPanel() === true && $userGroup->getWriteAccess() === 'all';
209 }
210
211 /**
212 * @param AbstractUserGroup[] $userGroupsForUser
213 * @throws UserGroupTypeException
214 */
215 private function assignDynamicUserGroupsForUser(WP_User $currentUser, array &$userGroupsForUser): void
216 {
217 $userUserGroup = $this->userGroupFactory->createDynamicUserGroup(
218 DynamicUserGroup::USER_TYPE,
219 $currentUser->ID
220 );
221 $userGroupsForUser[$userUserGroup->getId()] = $userUserGroup;
222
223 foreach ($this->userHandler->getUserRole($currentUser) as $role) {
224 $roleUserGroup = $this->userGroupFactory->createDynamicUserGroup(DynamicUserGroup::ROLE_TYPE, $role);
225 $userGroupsForUser[$roleUserGroup->getId()] = $roleUserGroup;
226 }
227 }
228
229 /**
230 * @return AbstractUserGroup[]
231 * @throws UserGroupTypeException
232 */
233 public function getUserGroupsForUser(): array
234 {
235 if ($this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY) === true) {
236 return $this->getUserGroups();
237 }
238
239 return $this->userGroupsForUser ??= $this->loadUserGroupsForUser();
240 }
241
242 /**
243 * @return AbstractUserGroup[]
244 * @throws UserGroupTypeException
245 */
246 private function loadUserGroupsForUser(): array
247 {
248 $currentUser = $this->wordpress->getCurrentUser();
249 $userGroupsForUser = $this->getUserGroupsForObject(
250 ObjectHandler::GENERAL_USER_OBJECT_TYPE,
251 $currentUser->ID
252 );
253
254 $this->assignDynamicUserGroupsForUser($currentUser, $userGroupsForUser);
255
256 foreach ($this->getUserGroups() as $userGroup) {
257 if (isset($userGroupsForUser[$userGroup->getId()]) === false
258 && $this->checkUserGroupAccess($userGroup) === true
259 ) {
260 $userGroupsForUser[$userGroup->getId()] = $userGroup;
261 }
262 }
263
264 return $userGroupsForUser;
265 }
266
267 /**
268 * @return AbstractUserGroup[]
269 * @throws UserGroupTypeException
270 */
271 public function getFilteredUserGroupsForObject(
272 string $objectType,
273 int|string|null $objectId,
274 bool $ignoreDates = false
275 ): array {
276 return $this->filterByUserGroupsOfUser($this->getUserGroupsForObject($objectType, $objectId, $ignoreDates));
277 }
278 }
279