PluginProbe
User Access Manager / 2.2.16
User Access Manager v2.2.16
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 / Controller / Backend / ObjectController.php

ObjectController.php in User Access Manager 2.2.16, at src/Controller/Backend/ObjectController.php

482 lines 15.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * ObjectController.php
4 *
5 * The ObjectController 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 */
15
16 declare(strict_types=1);
17
18 namespace UserAccessManager\Controller\Backend;
19
20 use Exception;
21 use UserAccessManager\Access\AccessHandler;
22 use UserAccessManager\Config\MainConfig;
23 use UserAccessManager\Config\WordpressConfig;
24 use UserAccessManager\Controller\Controller;
25 use UserAccessManager\Database\Database;
26 use UserAccessManager\Object\ObjectHandler;
27 use UserAccessManager\ObjectMembership\MissingObjectMembershipHandlerException;
28 use UserAccessManager\User\UserHandler;
29 use UserAccessManager\UserGroup\AbstractUserGroup;
30 use UserAccessManager\UserGroup\AssignmentInformation;
31 use UserAccessManager\UserGroup\DynamicUserGroup;
32 use UserAccessManager\UserGroup\UserGroupAssignmentException;
33 use UserAccessManager\UserGroup\UserGroupAssignmentHandler;
34 use UserAccessManager\UserGroup\UserGroupHandler;
35 use UserAccessManager\UserGroup\UserGroupTypeException;
36 use UserAccessManager\Util\DateUtil;
37 use UserAccessManager\Wrapper\Php;
38 use UserAccessManager\Wrapper\Wordpress;
39
40 /**
41 * Class ObjectController
42 *
43 * @package UserAccessManager\Controller
44 */
45 class ObjectController extends Controller
46 {
47 const COLUMN_NAME = 'uam_access';
48 const BULK_ADD = 'add';
49 const BULK_REMOVE = 'remove';
50 const BULK_OVERWRITE = 'overwrite';
51 const DEFAULT_GROUPS_FORM_NAME = 'uam_user_groups';
52 const DEFAULT_DYNAMIC_GROUPS_FORM_NAME = 'uam_dynamic_user_groups';
53 const UPDATE_GROUPS_FORM_NAME = 'uam_update_groups';
54
55 /**
56 * @var MainConfig
57 */
58 protected $mainConfig;
59
60 /**
61 * @var Database
62 */
63 protected $database;
64
65 /**
66 * @var DateUtil
67 */
68 protected $dateUtil;
69
70 /**
71 * @var ObjectHandler
72 */
73 protected $objectHandler;
74
75 /**
76 * @var UserHandler
77 */
78 protected $userHandler;
79
80 /**
81 * @var UserGroupHandler
82 */
83 protected $userGroupHandler;
84
85 /**
86 * @var AccessHandler
87 */
88 protected $accessHandler;
89
90 /**
91 * @var UserGroupAssignmentHandler
92 */
93 protected $userGroupAssignmentHandler;
94
95 /**
96 * @var ObjectInformation
97 */
98 protected $objectInformation;
99
100 /**
101 * @var null|string
102 */
103 protected $groupsFromName = null;
104
105 /**
106 * ObjectController constructor.
107 * @param Php $php
108 * @param Wordpress $wordpress
109 * @param WordpressConfig $wordpressConfig
110 * @param MainConfig $mainConfig
111 * @param Database $database
112 * @param DateUtil $dateUtil
113 * @param ObjectHandler $objectHandler
114 * @param UserHandler $userHandler
115 * @param UserGroupHandler $userGroupHandler
116 * @param UserGroupAssignmentHandler $userGroupAssignmentHandler
117 * @param AccessHandler $accessHandler
118 * @param ObjectInformationFactory $objectInformationFactory
119 */
120 public function __construct(
121 Php $php,
122 Wordpress $wordpress,
123 WordpressConfig $wordpressConfig,
124 MainConfig $mainConfig,
125 Database $database,
126 DateUtil $dateUtil,
127 ObjectHandler $objectHandler,
128 UserHandler $userHandler,
129 UserGroupHandler $userGroupHandler,
130 UserGroupAssignmentHandler $userGroupAssignmentHandler,
131 AccessHandler $accessHandler,
132 ObjectInformationFactory $objectInformationFactory
133 ) {
134 parent::__construct($php, $wordpress, $wordpressConfig);
135 $this->mainConfig = $mainConfig;
136 $this->database = $database;
137 $this->dateUtil = $dateUtil;
138 $this->objectHandler = $objectHandler;
139 $this->userHandler = $userHandler;
140 $this->userGroupHandler = $userGroupHandler;
141 $this->userGroupAssignmentHandler = $userGroupAssignmentHandler;
142 $this->accessHandler = $accessHandler;
143 $this->objectInformation = $objectInformationFactory->createObjectInformation();
144 }
145
146 /**
147 * Sets the current object type, the object id and the user groups.
148 * @param string $objectType
149 * @param int|string|null $objectId
150 * @param array|null $objectUserGroups
151 * @throws UserGroupTypeException
152 */
153 protected function setObjectInformation(string $objectType, $objectId, ?array $objectUserGroups = null)
154 {
155 $userGroupDiff = 0;
156
157 if ($objectUserGroups === null && $objectId !== null) {
158 $objectUserGroups = $this->userGroupHandler->getFilteredUserGroupsForObject($objectType, $objectId, true);
159 $fullObjectUserGroups = $this->userGroupHandler->getUserGroupsForObject($objectType, $objectId, true);
160 $userGroupDiff = count((array) $fullObjectUserGroups) - count((array) $objectUserGroups);
161 }
162
163 $this->objectInformation->setObjectType($objectType)
164 ->setObjectId($objectId)
165 ->setObjectUserGroups((array) $objectUserGroups)
166 ->setUserGroupDiff($userGroupDiff);
167 }
168
169 /**
170 * Returns the object information.
171 * @return ObjectInformation
172 */
173 public function getObjectInformation(): ObjectInformation
174 {
175 return $this->objectInformation;
176 }
177
178 /**
179 * Returns the default groups form name.
180 * @return string
181 */
182 public function getGroupsFormName(): string
183 {
184 return ($this->groupsFromName !== null) ? (string) $this->groupsFromName : self::DEFAULT_GROUPS_FORM_NAME;
185 }
186
187 /**
188 * Returns the filtered user groups.
189 * @return AbstractUserGroup[]
190 * @throws UserGroupTypeException
191 */
192 public function getFilteredUserGroups(): array
193 {
194 return $this->userGroupHandler->getFilteredUserGroups();
195 }
196
197 /**
198 * Sorts the user groups.
199 * @param array $userGroups
200 */
201 public function sortUserGroups(array &$userGroups)
202 {
203 uasort(
204 $userGroups,
205 function (
206 AbstractUserGroup $userGroupOne,
207 AbstractUserGroup $userGroupTwo
208 ) {
209 $notLoggedInUserGroupId = DynamicUserGroup::USER_TYPE . '|' . DynamicUserGroup::NOT_LOGGED_IN_USER_ID;
210
211 if ($userGroupOne->getId() === $notLoggedInUserGroupId) {
212 return 1;
213 } elseif ($userGroupTwo->getId() === $notLoggedInUserGroupId) {
214 return -1;
215 }
216
217 return strnatcasecmp($userGroupOne->getName(), $userGroupTwo->getName());
218 }
219 );
220 }
221
222 /**
223 * Returns the date util.
224 * @return DateUtil
225 */
226 public function getDateUtil(): DateUtil
227 {
228 return $this->dateUtil;
229 }
230
231 /**
232 * Checks if the current user is an admin.
233 * @return bool
234 */
235 public function isCurrentUserAdmin(): bool
236 {
237 if ($this->objectInformation->getObjectType() === ObjectHandler::GENERAL_USER_OBJECT_TYPE
238 && $this->objectInformation->getObjectId() !== null
239 ) {
240 return $this->userHandler->userIsAdmin($this->objectInformation->getObjectId());
241 }
242
243 return false;
244 }
245
246 /**
247 * Returns the wordpress role names.
248 * @return array
249 */
250 public function getRoleNames(): array
251 {
252 $roles = $this->wordpress->getRoles();
253 return $roles->role_names;
254 }
255
256 /**
257 * Checks the user access.
258 * @return bool
259 */
260 public function checkUserAccess(): bool
261 {
262 return $this->userHandler->checkUserAccess(UserHandler::MANAGE_USER_GROUPS_CAPABILITY);
263 }
264
265 /**
266 * Returns the recursive object membership.
267 * @param AbstractUserGroup $userGroup
268 * @return array
269 * @throws Exception
270 * @throws Exception
271 */
272 public function getRecursiveMembership(AbstractUserGroup $userGroup): array
273 {
274 $recursiveMembership = [];
275 $objectType = $this->objectInformation->getObjectType();
276 $objectId = $this->objectInformation->getObjectId();
277 $recursiveMembershipForObject = $userGroup->getRecursiveMembershipForObject($objectType, $objectId);
278
279 /**
280 * @var AssignmentInformation[] $assignmentInformation
281 */
282 foreach ($recursiveMembershipForObject as $recursiveType => $assignmentInformation) {
283 foreach ($assignmentInformation as $objectId => $information) {
284 try {
285 $membershipHandler = $this->objectHandler->getObjectMembershipHandler($information->getType());
286 $typeName = $membershipHandler->getGeneralObjectType();
287 $objectName = $membershipHandler->getObjectName($objectId, $typeName);
288 $recursiveMembership[$typeName][$objectId] = $objectName;
289 } catch (MissingObjectMembershipHandlerException $exception) {
290 // Do nothing
291 }
292 }
293 }
294
295 return $recursiveMembership;
296 }
297
298 /**
299 * Checks the access and dies if the user has no access.
300 * @param string $objectType
301 * @param int|string $objectId
302 * @throws UserGroupTypeException
303 */
304 private function dieOnNoAccess(string $objectType, $objectId)
305 {
306 if ($this->accessHandler->checkObjectAccess($objectType, $objectId) === false) {
307 $this->wordpress->wpDie(TXT_UAM_NO_RIGHTS_MESSAGE, TXT_UAM_NO_RIGHTS_TITLE, ['response' => 403]);
308 }
309 }
310
311 /**
312 * Shows the error if the user has no rights to edit the content.
313 * @throws UserGroupTypeException
314 */
315 public function checkRightsToEditContent()
316 {
317 $postIdParameter = $this->getRequestParameter('post', $this->getRequestParameter('attachment_id'));
318
319 if ($postIdParameter !== null) {
320 $postIds = is_array($postIdParameter) === false ? [$postIdParameter] : $postIdParameter;
321
322 foreach ($postIds as $postId) {
323 $this->dieOnNoAccess(ObjectHandler::GENERAL_POST_OBJECT_TYPE, $postId);
324 }
325 }
326
327 $tagId = $this->getRequestParameter('tag_ID');
328
329 if ($tagId !== null) {
330 $this->dieOnNoAccess(ObjectHandler::GENERAL_TERM_OBJECT_TYPE, $tagId);
331 }
332 }
333
334 /**
335 * Returns the user groups by reference which should be add and removed from the object.
336 * @param string $objectType
337 * @param int|string $objectId
338 * @param array|null $addUserGroups
339 * @param array|null $removeUserGroups
340 * @throws UserGroupTypeException
341 */
342 private function getAddRemoveGroups(
343 string $objectType,
344 $objectId,
345 ?array &$addUserGroups = [],
346 ?array &$removeUserGroups = []
347 ) {
348 $groupsToChange = (array) $this->getRequestParameter(self::DEFAULT_GROUPS_FORM_NAME, []);
349 $filteredUserGroupsForObject = $this->userGroupHandler->getFilteredUserGroupsForObject(
350 $objectType,
351 $objectId
352 );
353
354 $addUserGroups = $addUserGroups ?? $groupsToChange;
355 $removeUserGroups = array_flip(array_keys($filteredUserGroupsForObject));
356 $bulkType = $this->getRequestParameter('uam_bulk_type');
357
358 if ($bulkType === self::BULK_ADD) {
359 $addUserGroups = $groupsToChange;
360 $removeUserGroups = [];
361 } elseif ($bulkType === self::BULK_REMOVE) {
362 $addUserGroups = [];
363 $removeUserGroups = array_filter(
364 $groupsToChange,
365 function (array $group) {
366 return isset($group['id']);
367 }
368 );
369 }
370 }
371
372 /**
373 * Saves the object data to the database.
374 * @param string $objectType The object type.
375 * @param int|string|null $objectId The id of the object.
376 * @param array|null $addUserGroups The new user groups for the object.
377 * @param bool $force If true we force the assignment.
378 * @throws UserGroupTypeException
379 */
380 public function saveObjectData(string $objectType, $objectId, ?array $addUserGroups = null, $force = false)
381 {
382 $isUpdateForm = (bool) $this->getRequestParameter(self::UPDATE_GROUPS_FORM_NAME, false) === true
383 || $this->getRequestParameter('uam_bulk_type') !== null;
384
385 $hasRights = $this->checkUserAccess() === true || $this->mainConfig->authorsCanAddPostsToGroups() === true;
386
387 if ($isUpdateForm === true && $hasRights === true || $force === true) {
388 $this->getAddRemoveGroups($objectType, $objectId, $addUserGroups, $removeUserGroups);
389
390 try {
391 $this->userGroupAssignmentHandler->assignObjectToUserGroups(
392 $objectType,
393 $objectId,
394 $addUserGroups,
395 $removeUserGroups,
396 $this->getRequestParameter(self::DEFAULT_DYNAMIC_GROUPS_FORM_NAME, [])
397 );
398 } catch (UserGroupAssignmentException $exception) {
399 $this->addErrorMessage(sprintf(TXT_UAM_ERROR, $exception->getMessage()));
400 }
401 }
402 }
403
404 /**
405 * Removes the object data.
406 * @param string $objectType The object type.
407 * @param int|string $id The object id.
408 */
409 public function removeObjectData(string $objectType, $id)
410 {
411 $this->database->delete(
412 $this->database->getUserGroupToObjectTable(),
413 [
414 'object_id' => $id,
415 'object_type' => $objectType,
416 ],
417 [
418 '%d',
419 '%s'
420 ]
421 );
422 }
423
424 /**
425 * Returns the group selection form for pluggable objects.
426 * @param string $objectType The object type.
427 * @param int|string $objectId The id of the object.
428 * @param null $formName The formName.
429 * @param array|null $objectUserGroups If set we force this user groups for the object.
430 * @return string
431 * @throws UserGroupTypeException
432 */
433 public function showGroupSelectionForm(
434 string $objectType,
435 $objectId,
436 $formName = null,
437 array $objectUserGroups = null
438 ): string {
439 $this->setObjectInformation($objectType, $objectId, $objectUserGroups);
440
441 $this->groupsFromName = $formName;
442 $formContent = $this->getIncludeContents('GroupSelectionForm.php');
443 $this->groupsFromName = null;
444
445 return $formContent;
446 }
447
448 /**
449 * Returns the column for a pluggable object.
450 * @param string $objectType The object type.
451 * @param int|string $objectId The object id.
452 * @return string
453 * @throws UserGroupTypeException
454 */
455 public function getGroupColumn(string $objectType, $objectId): string
456 {
457 $this->setObjectInformation($objectType, $objectId);
458 return $this->getIncludeContents('ObjectColumn.php');
459 }
460
461 /**
462 * Checks if the current object is a new object.
463 * @return bool
464 * @throws Exception
465 */
466 public function isNewObject(): bool
467 {
468 $objectType = $this->objectInformation->getObjectType();
469
470 if ($objectType !== null) {
471 $generalObjectType = $this->objectHandler->getGeneralObjectType($objectType);
472
473 return ($this->objectInformation->getObjectId() === null
474 || ($generalObjectType === ObjectHandler::GENERAL_POST_OBJECT_TYPE &&
475 $this->getRequestParameter('action') !== 'edit')
476 );
477 }
478
479 return false;
480 }
481 }
482