diff --git a/classes/invitation/core/Invitation.php b/classes/invitation/core/Invitation.php index fe288ab7e95..c98f2cd345d 100644 --- a/classes/invitation/core/Invitation.php +++ b/classes/invitation/core/Invitation.php @@ -71,6 +71,13 @@ abstract public static function getType(): string; */ abstract public function getInvitationActionRedirectController(): ?InvitationActionRedirectController; + /** + * Defines the controller that is responsible for the handle of the create/edit + * invitation views + * @return InvitationUIActionRedirectController|null + */ + abstract public function getInvitationUIActionRedirectController(): ?InvitationUIActionRedirectController; + /** * Get a specific payload instance for the child class. */ diff --git a/classes/invitation/core/InvitationUIActionRedirectController.php b/classes/invitation/core/InvitationUIActionRedirectController.php new file mode 100644 index 00000000000..f245f09cc3b --- /dev/null +++ b/classes/invitation/core/InvitationUIActionRedirectController.php @@ -0,0 +1,31 @@ +invitation = $invitation; + } + abstract public function createHandle(Request $request, $userId = null): void; + abstract public function editHandle(Request $request): void; +} diff --git a/classes/invitation/invitations/changeProfileEmail/ChangeProfileEmailInvite.php b/classes/invitation/invitations/changeProfileEmail/ChangeProfileEmailInvite.php index 556e7370249..a872a85746f 100644 --- a/classes/invitation/invitations/changeProfileEmail/ChangeProfileEmailInvite.php +++ b/classes/invitation/invitations/changeProfileEmail/ChangeProfileEmailInvite.php @@ -25,6 +25,7 @@ use PKP\invitation\core\enums\ValidationContext; use PKP\invitation\core\Invitation; use PKP\invitation\core\InvitationActionRedirectController; +use PKP\invitation\core\InvitationUIActionRedirectController; use PKP\invitation\core\traits\HasMailable; use PKP\invitation\core\traits\ShouldValidate; use PKP\invitation\invitations\changeProfileEmail\handlers\ChangeProfileEmailInviteRedirectController; @@ -138,10 +139,15 @@ public function getInvitationActionRedirectController(): ?InvitationActionRedire return new ChangeProfileEmailInviteRedirectController($this); } + public function getInvitationUIActionRedirectController(): ?InvitationUIActionRedirectController + { + return null; + } + /** * @inheritDoc */ - public function getValidationRules(ValidationContext $validationContext = ValidationContext::VALIDATION_CONTEXT_DEFAULT): array + public function getValidationRules(ValidationContext $validationContext = ValidationContext::VALIDATION_CONTEXT_DEFAULT): array { return [ 'newEmail' => 'required|email', @@ -151,7 +157,7 @@ public function getValidationRules(ValidationContext $validationContext = Valida /** * @inheritDoc */ - public function getValidationMessages(ValidationContext $validationContext = ValidationContext::VALIDATION_CONTEXT_DEFAULT): array + public function getValidationMessages(ValidationContext $validationContext = ValidationContext::VALIDATION_CONTEXT_DEFAULT): array { return []; } diff --git a/classes/invitation/invitations/registrationAccess/RegistrationAccessInvite.php b/classes/invitation/invitations/registrationAccess/RegistrationAccessInvite.php index bda6d4f37b3..19397a217fd 100644 --- a/classes/invitation/invitations/registrationAccess/RegistrationAccessInvite.php +++ b/classes/invitation/invitations/registrationAccess/RegistrationAccessInvite.php @@ -25,6 +25,7 @@ use PKP\invitation\core\enums\InvitationStatus; use PKP\invitation\core\Invitation; use PKP\invitation\core\InvitationActionRedirectController; +use PKP\invitation\core\InvitationUIActionRedirectController; use PKP\invitation\invitations\registrationAccess\handlers\RegistrationAccessInviteRedirectController; use PKP\user\User; @@ -101,4 +102,9 @@ public function getInvitationActionRedirectController(): ?InvitationActionRedire { return new RegistrationAccessInviteRedirectController($this); } + + public function getInvitationUIActionRedirectController(): ?InvitationUIActionRedirectController + { + return null; + } } diff --git a/classes/invitation/invitations/reviewerAccess/ReviewerAccessInvite.php b/classes/invitation/invitations/reviewerAccess/ReviewerAccessInvite.php index fe58f95fdfa..dbc783916a6 100644 --- a/classes/invitation/invitations/reviewerAccess/ReviewerAccessInvite.php +++ b/classes/invitation/invitations/reviewerAccess/ReviewerAccessInvite.php @@ -25,6 +25,7 @@ use PKP\invitation\core\enums\ValidationContext; use PKP\invitation\core\Invitation; use PKP\invitation\core\InvitationActionRedirectController; +use PKP\invitation\core\InvitationUIActionRedirectController; use PKP\invitation\core\traits\ShouldValidate; use PKP\invitation\invitations\reviewerAccess\handlers\ReviewerAccessInviteRedirectController; use PKP\invitation\invitations\reviewerAccess\payload\ReviewerAccessInvitePayload; @@ -148,10 +149,15 @@ public function getInvitationActionRedirectController(): ?InvitationActionRedire return new ReviewerAccessInviteRedirectController($this); } + public function getInvitationUIActionRedirectController(): ?InvitationUIActionRedirectController + { + return null; + } + /** * @inheritDoc */ - public function getValidationRules(ValidationContext $validationContext = ValidationContext::VALIDATION_CONTEXT_DEFAULT): array + public function getValidationRules(ValidationContext $validationContext = ValidationContext::VALIDATION_CONTEXT_DEFAULT): array { return [ 'reviewAssignmentId' => [ @@ -161,7 +167,7 @@ function ($attribute, $value, $fail) { $reviewAssignment = Repo::reviewAssignment()->get($value); if (!$reviewAssignment) { - $fail(__('invitation.reviewerAccess.validation.error.reviewAssignmentId.notExisting', + $fail(__('invitation.reviewerAccess.validation.error.reviewAssignmentId.notExisting', [ 'reviewAssignmentId' => $value ]) diff --git a/classes/invitation/invitations/userRoleAssignment/UserRoleAssignmentInvite.php b/classes/invitation/invitations/userRoleAssignment/UserRoleAssignmentInvite.php index ce4791110a0..9499f3ca76e 100644 --- a/classes/invitation/invitations/userRoleAssignment/UserRoleAssignmentInvite.php +++ b/classes/invitation/invitations/userRoleAssignment/UserRoleAssignmentInvite.php @@ -23,12 +23,14 @@ use PKP\invitation\core\enums\ValidationContext; use PKP\invitation\core\Invitation; use PKP\invitation\core\InvitationActionRedirectController; +use PKP\invitation\core\InvitationUIActionRedirectController; use PKP\invitation\core\ReceiveInvitationController; use PKP\invitation\core\traits\HasMailable; use PKP\invitation\core\traits\ShouldValidate; use PKP\invitation\invitations\userRoleAssignment\handlers\api\UserRoleAssignmentCreateController; use PKP\invitation\invitations\userRoleAssignment\handlers\api\UserRoleAssignmentReceiveController; use PKP\invitation\invitations\userRoleAssignment\handlers\UserRoleAssignmentInviteRedirectController; +use PKP\invitation\invitations\userRoleAssignment\handlers\UserRoleAssignmentInviteUIController; use PKP\invitation\invitations\userRoleAssignment\payload\UserRoleAssignmentInvitePayload; use PKP\invitation\invitations\userRoleAssignment\rules\EmailMustNotExistRule; use PKP\invitation\invitations\userRoleAssignment\rules\NoUserGroupChangesRule; @@ -116,7 +118,7 @@ public function getMailable(): Mailable return $this->mailable; } - public function getMailableReceiver(?string $locale = null): Identity + public function getMailableReceiver(?string $locale = null): Identity { $locale = $this->getUsedLocale($locale); @@ -138,18 +140,23 @@ public function getInvitationActionRedirectController(): ?InvitationActionRedire return new UserRoleAssignmentInviteRedirectController($this); } + public function getInvitationUIActionRedirectController(): ?InvitationUIActionRedirectController + { + return new UserRoleAssignmentInviteUIController($this); + } + /** * @inheritDoc */ - public function getCreateInvitationController(Invitation $invitation): CreateInvitationController + public function getCreateInvitationController(Invitation $invitation): CreateInvitationController { return new UserRoleAssignmentCreateController($invitation); } - + /** * @inheritDoc */ - public function getReceiveInvitationController(Invitation $invitation): ReceiveInvitationController + public function getReceiveInvitationController(Invitation $invitation): ReceiveInvitationController { return new UserRoleAssignmentReceiveController($invitation); } @@ -175,7 +182,7 @@ public function getValidationRules(ValidationContext $validationContext = Valida } $validationRules = array_merge( - $invitationValidationRules, + $invitationValidationRules, $this->getPayload()->getValidationRules($this, $validationContext) ); @@ -190,7 +197,7 @@ public function getValidationMessages(ValidationContext $validationContext = Val $invitationValidationMessages = []; $invitationValidationMessages = array_merge( - $invitationValidationMessages, + $invitationValidationMessages, $this->getPayload()->getValidationMessages($validationContext) ); diff --git a/classes/invitation/invitations/userRoleAssignment/handlers/UserRoleAssignmentInviteUIController.php b/classes/invitation/invitations/userRoleAssignment/handlers/UserRoleAssignmentInviteUIController.php new file mode 100644 index 00000000000..0c0818cdc8d --- /dev/null +++ b/classes/invitation/invitations/userRoleAssignment/handlers/UserRoleAssignmentInviteUIController.php @@ -0,0 +1,226 @@ +invitation = $invitation; + } + + /** + * Create new invitations for users + * @param Request $request + * @param $userId + * @return void + * @throws \Exception + */ + public function createHandle(Request $request, $userId = null): void + { + $invitationPayload = [ + 'userId' => null, + 'inviteeEmail' => '', + 'orcid' => '', + 'givenName' => '', + 'familyName' => '', + 'orcidValidation' => false, + 'disabled' => false, + 'userGroupsToAdd' => [ + [ + 'userGroupId' => null, + 'dateStart' => null, + 'dateEnd' => null, + 'masthead' => null, + ] + ], + 'currentUserGroups' => [], + 'userGroupsToRemove' => [], + 'emailComposer' => [ + 'body' => '', + 'subject' => '', + ] + ]; + $user = null; + $invitationMode = 'create'; + if ($userId) { + //send invitation using edit user action in user access table + $user = Repo::user()->get($userId, true); + $invitationPayload = ( + new UserRoleAssignmentInviteResource($this->invitation)) + ->transformInvitationPayload($userId, $user->getAllData(), $request->getContext() + ); + $invitationMode = 'editUser'; + } + $templateMgr = TemplateManager::getManager($request); + $breadcrumbs = $templateMgr->getTemplateVars('breadcrumbs'); + $context = $request->getContext(); + $breadcrumbs[] = [ + 'id' => 'contexts', + 'name' => __('navigation.access'), + 'url' => $request + ->getDispatcher() + ->url( + $request, + Application::ROUTE_PAGE, + null, + 'management', + 'settings', + ['access'] + ) + ]; + $breadcrumbs[] = [ + 'id' => 'invitationWizard', + 'name' => __('invitation.wizard.pageTitle'), + ]; + $steps = new SendInvitationStep(); + $templateMgr->setState([ + 'steps' => $steps->getSteps(null, $context, $user), + 'emailTemplatesApiUrl' => $request + ->getDispatcher() + ->url( + $request, + Application::ROUTE_API, + $context->getData('urlPath'), + 'emailTemplates' + ), + 'primaryLocale' => $context->getData('primaryLocale'), + 'invitationType' => 'userRoleAssignment', + 'invitationPayload' => $invitationPayload, + 'invitationMode' => $invitationMode, + 'invitationUserData' => $userId ? + ( + new UserRoleAssignmentInviteResource($this->invitation)) + ->transformInvitationUserData( + $user, + $request->getContext() + ) : [], + 'pageTitle' => $user ? '' : __('invitation.wizard.pageTitle'), + 'pageTitleDescription' => $user ? '' : __('invitation.wizard.pageTitleDescription'), + ]); + $templateMgr->assign([ + 'pageComponent' => 'Page', + 'breadcrumbs' => $breadcrumbs, + 'pageWidth' => TemplateManager::PAGE_WIDTH_FULL, + ]); + $templateMgr->display('/invitation/userInvitation.tpl'); + } + + /** + * Edit invitations + * @param Request $request + * @return void + * @throws \Exception + */ + public function editHandle(Request $request): void + { + $payload = $this->invitation->getPayload()->toArray(); + $invitationModel = $this->invitation->invitationModel->toArray(); + $invitationMode = 'edit'; + $payload['email'] = $invitationModel['email']; + $payloadDataToBeTransform = []; + $user = $invitationModel['userId'] ? Repo::user()->get($invitationModel['userId'], true) : null; + if($user){ + // if edit an invitation for existing user, used user data as invitation payload + $payloadDataToBeTransform = $user->getAllData(); + $payloadDataToBeTransform['userGroupsToAdd'] = $payload['userGroupsToAdd']; + } + $invitationPayload = ( + new UserRoleAssignmentInviteResource($this->invitation)) + ->transformInvitationPayload( + $invitationModel['userId'], + $invitationModel['userId'] ? $payloadDataToBeTransform : $payload, + $request->getContext() + ); + + $templateMgr = TemplateManager::getManager($request); + $breadcrumbs = $templateMgr->getTemplateVars('breadcrumbs'); + $context = $request->getContext(); + $breadcrumbs[] = [ + 'id' => 'contexts', + 'name' => __('navigation.access'), + 'url' => $request + ->getDispatcher() + ->url( + $request, + Application::ROUTE_PAGE, + null, + 'management', + 'settings', + ['access'] + ) + ]; + $breadcrumbs[] = [ + 'id' => 'invitationWizard', + 'name' => __('invitation.wizard.pageTitle'), + ]; + $steps = new SendInvitationStep(); + $templateMgr->setState([ + 'steps' => $steps->getSteps($this->invitation, $context, $user), + 'emailTemplatesApiUrl' => $request + ->getDispatcher() + ->url( + $request, + Application::ROUTE_API, + $context->getData('urlPath'), + 'emailTemplates' + ), + 'primaryLocale' => $context->getData('primaryLocale'), + 'invitationType' => 'userRoleAssignment', + 'invitationPayload' => $invitationPayload, + 'invitationMode' => $invitationMode, + 'invitationUserData' => $invitationModel['userId'] ? + ( + new UserRoleAssignmentInviteResource($this->invitation)) + ->transformInvitationUserData( + $user, + $request->getContext() + ) : [], + 'pageTitle' => + ($invitationPayload->givenName && $invitationPayload->familyName) ? + $invitationPayload->givenName[Locale::getLocale()] . ' ' + . $invitationPayload->familyName[Locale::getLocale()] : $invitationPayload->inviteeEmail + , + 'pageTitleDescription' => + __( + 'invitation.wizard.viewPageTitleDescription', + ['name' => + $invitationPayload->givenName[Locale::getLocale()] ? + $invitationPayload->givenName[Locale::getLocale()] : $invitationPayload->inviteeEmail] + ), + ]); + $templateMgr->assign([ + 'pageComponent' => 'Page', + 'breadcrumbs' => $breadcrumbs, + 'pageWidth' => TemplateManager::PAGE_WIDTH_FULL, + ]); + $templateMgr->display('/invitation/userInvitation.tpl'); + } +} diff --git a/classes/invitation/invitations/userRoleAssignment/resources/BaseUserRoleAssignmentInviteResource.php b/classes/invitation/invitations/userRoleAssignment/resources/BaseUserRoleAssignmentInviteResource.php index ad463b1211e..072dd10b083 100644 --- a/classes/invitation/invitations/userRoleAssignment/resources/BaseUserRoleAssignmentInviteResource.php +++ b/classes/invitation/invitations/userRoleAssignment/resources/BaseUserRoleAssignmentInviteResource.php @@ -17,8 +17,11 @@ use APP\facades\Repo; use Illuminate\Http\Request; use Illuminate\Http\Resources\Json\JsonResource; +use PKP\context\Context; +use PKP\facades\Locale; use PKP\invitation\invitations\userRoleAssignment\payload\UserRoleAssignmentInvitePayload; use PKP\user\User; +use PKP\userGroup\relationships\UserUserGroup; class BaseUserRoleAssignmentInviteResource extends JsonResource { @@ -91,4 +94,24 @@ protected function createNewUserFromPayload(UserRoleAssignmentInvitePayload $pay return $newUser; } + + protected function transformCurrentUserGroups(int $id , Context $context): array + { + $userGroups = []; + $userUserGroups = UserUserGroup::query() + ->withUserId($id) + ->withContextId($context->getId()) + ->get() + ->toArray(); + foreach ($userUserGroups as $key => $userUserGroup) { + $userGroup = Repo::userGroup() + ->get($userUserGroup['userGroupId']) + ->toArray(); + $userGroups[$key] = $userUserGroup; + $userGroups[$key]['masthead'] = $userUserGroup['masthead'] === 1; + $userGroups[$key]['name'] = $userGroup['name'][Locale::getLocale()]; + $userGroups[$key]['id'] = $userGroup['userGroupId']; + } + return $userGroups; + } } diff --git a/classes/invitation/invitations/userRoleAssignment/resources/UserRoleAssignmentInviteResource.php b/classes/invitation/invitations/userRoleAssignment/resources/UserRoleAssignmentInviteResource.php index eb94fc01716..26655cc5a83 100644 --- a/classes/invitation/invitations/userRoleAssignment/resources/UserRoleAssignmentInviteResource.php +++ b/classes/invitation/invitations/userRoleAssignment/resources/UserRoleAssignmentInviteResource.php @@ -15,6 +15,8 @@ namespace PKP\invitation\invitations\userRoleAssignment\resources; use Illuminate\Http\Request; +use PKP\context\Context; +use PKP\invitation\invitations\userRoleAssignment\payload\UserRoleAssignmentInvitePayload; use PKP\user\User; class UserRoleAssignmentInviteResource extends BaseUserRoleAssignmentInviteResource @@ -65,4 +67,55 @@ public function toArray(Request $request) 'newUser' => $this->transformUser($newUser), ]); } + + /** + * Transform invitation payload + * @param int|null $userId + * @param array $payload + * @param Context $context + * @return UserRoleAssignmentInvitePayload + */ + public function transformInvitationPayload(?int $userId, array $payload, Context $context): object + { + $invitationPayload = UserRoleAssignmentInvitePayload::fromArray($payload)->toArray(); + $invitationPayload['userId'] = !$userId ? null : $userId; + $invitationPayload['inviteeEmail'] = !$userId ?$invitationPayload['sendEmailAddress']:$payload['email']; + $invitationPayload['userGroupsToAdd'] = !$invitationPayload['userGroupsToAdd'] ? [] :$invitationPayload['userGroupsToAdd']; + $invitationPayload['currentUserGroups'] = !$userId ? [] : $this->transformCurrentUserGroups($userId,$context); + + return (object)$invitationPayload; + } + + /** + * Transform user data for invitation view + * @param User $user + * @param $context + * @return array + */ + public function transformInvitationUserData(User $user, $context): array + { + $userData = []; + $userData['country'] = $user->getCountryLocalized(); + $userData['biography'] = $user->getBiography(null); + $userData['phone'] = $user->getPhone(); + $userData['mailingAddress'] = $user->getMailingAddress(); + $userData['signature'] = $user->getSignature(null); + $userData['locales'] = $this->transformUserWorkingLanguages($context, $user->getLocales()); + $userData['reviewInterests'] = $user->getInterestString(); + $userData['homePageUrl'] = $user->getUrl(); + $userData['disabled'] = $user->getData('disabled'); + return $userData; + } + + /** + * get user working languages + * @param Context $context + * @param array $userLocales + * @return string + */ + private function transformUserWorkingLanguages(Context $context, array $userLocales): string + { + $locales = $context->getSupportedLocaleNames(); + return join(__('common.commaListSeparator'), array_map(fn($key) => $locales[$key], $userLocales)); + } } diff --git a/pages/invitation/InitializeInvitationUIHandler.php b/pages/invitation/InitializeInvitationUIHandler.php new file mode 100644 index 00000000000..5fea9f75b8a --- /dev/null +++ b/pages/invitation/InitializeInvitationUIHandler.php @@ -0,0 +1,123 @@ +addRoleAssignment( + [ + Role::ROLE_ID_SITE_ADMIN, + Role::ROLE_ID_MANAGER, + Role::ROLE_ID_SUB_EDITOR, + ROLE::ROLE_ID_ASSISTANT, + ], + [ + 'create', + 'edit', + ] + ); + } + + public function authorize($request, &$args, $roleAssignments) + { + $this->addPolicy(new UserRequiredPolicy($request)); + + $this->addPolicy(new UserRolesRequiredPolicy($request), true); + + $this->addPolicy(new ContextAccessPolicy($request, $roleAssignments)); + + $rolePolicy = new PolicySet(PolicySet::COMBINING_PERMIT_OVERRIDES); + foreach ($roleAssignments as $role => $operations) { + $rolePolicy->addPolicy(new RoleBasedHandlerOperationPolicy($request, $role, $operations)); + } + $this->addPolicy($rolePolicy); + + return parent::authorize($request, $args, $roleAssignments); + } + + /** + * Create an invitation for a user to accept new roles + * @param array $args + * @param Request $request + */ + public function create(array $args, Request $request): void + { + if (empty($args) || count($args) < 1) { + throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException(); + } + + $this->setupTemplate($request); + + $arg = $args[0]; // invitation type + + if (is_numeric($arg)) { + throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException(); + } else { + // Handle new invitation by type + $invitationType = $arg; + $invitation = app(Invitation::class)->createNew($invitationType); + $invitationHandler = $invitation->getInvitationUIActionRedirectController(); + $invitationHandler->createHandle($request); + } + } + + /** + * Edit an invitation + * @param array $args + * @param Request $request + * @return void + */ + public function edit(array $args, Request $request): void + { + if (empty($args) || count($args) < 1) { + throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException(); + } + + $this->setupTemplate($request); + + $arg = $args[0]; // invitation id + + if (is_numeric($arg)) { + // Handle existing invitation by ID + $invitationId = (int) $arg; + $invitation = Repo::invitation()->getById($invitationId); + if (!$invitation) { + throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException(); + } + $invitationHandler = $invitation->getInvitationUIActionRedirectController(); + $invitationHandler->editHandle($request); + } else { + throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException(); + } + } +} diff --git a/pages/invitation/InvitationHandler.php b/pages/invitation/InvitationHandler.php index 30e3779ec05..1f97c6aa1b2 100644 --- a/pages/invitation/InvitationHandler.php +++ b/pages/invitation/InvitationHandler.php @@ -21,17 +21,8 @@ use APP\core\Request; use APP\facades\Repo; use APP\handler\Handler; -use APP\template\TemplateManager; -use PKP\context\Context; -use PKP\core\PKPRequest; -use PKP\facades\Locale; use PKP\invitation\core\enums\InvitationAction; use PKP\invitation\core\Invitation; -use PKP\invitation\stepTypes\SendInvitationStep; -use PKP\security\authorization\PolicySet; -use PKP\security\authorization\RoleBasedHandlerOperationPolicy; -use PKP\security\Role; -use PKP\userGroup\relationships\UserUserGroup; class InvitationHandler extends Handler { @@ -105,20 +96,6 @@ private function getInvitationByKey(Request $request): Invitation return $invitation; } - /** - * Get invitation by invitation id - */ - private function getInvitationById(Request $request, int $id): Invitation - { - $invitation = Repo::invitation() - ->getById($id); - - if (is_null($invitation)) { - throw new \Symfony\Component\HttpKernel\Exception\GoneHttpException(); - } - return $invitation; - } - public static function getActionUrl(InvitationAction $action, Invitation $invitation): ?string { $invitationId = $invitation->getId(); @@ -145,259 +122,4 @@ public static function getActionUrl(InvitationAction $action, Invitation $invita ] ); } - - /** - * Create an invitation to accept new role - * - * @throws \Exception - */ - public function invite(array $args, Request $request): void - { - $invitationMode = 'create'; - $invitationPayload = [ - 'userId' => null, - 'inviteeEmail' => '', - 'orcid' => '', - 'givenName' => '', - 'familyName' => '', - 'orcidValidation' => false, - 'disabled' => false, - 'userGroupsToAdd' => [ - [ - 'userGroupId' => null, - 'dateStart' => null, - 'dateEnd' => null, - 'masthead' => null, - ] - ], - 'currentUserGroups' => [], - 'userGroupsToRemove' => [], - 'emailComposer' => [ - 'body' => '', - 'subject' => '', - ] - ]; - $invitation = null; - $user = null; - if (!empty($args)) { - $invitation = $this->getInvitationById($request, $args[0]); - $payload = $invitation->getPayload()->toArray(); - $invitationModel = $invitation->invitationModel->toArray(); - - $invitationMode = 'edit'; - $payload['email'] = $invitationModel['email']; - $invitationData = $this->generateInvitationPayload($invitationModel['userId'], $payload, $request->getContext()); - $user = $invitationData['user']; - $invitationPayload = $invitationData['invitationPayload']; - } - $templateMgr = TemplateManager::getManager($request); - $breadcrumbs = $templateMgr->getTemplateVars('breadcrumbs'); - $this->setupTemplate($request); - $context = $request->getContext(); - $breadcrumbs[] = [ - 'id' => 'contexts', - 'name' => __('navigation.access'), - 'url' => $request - ->getDispatcher() - ->url( - $request, - Application::ROUTE_PAGE, - null, - 'management', - 'settings', - ['access'] - ) - ]; - $breadcrumbs[] = [ - 'id' => 'invitationWizard', - 'name' => __('invitation.wizard.pageTitle'), - ]; - $steps = new SendInvitationStep(); - $templateMgr->setState([ - 'steps' => $steps->getSteps($invitation, $context, $user), - 'emailTemplatesApiUrl' => $request - ->getDispatcher() - ->url( - $request, - Application::ROUTE_API, - $context->getData('urlPath'), - 'emailTemplates' - ), - 'primaryLocale' => $context->getData('primaryLocale'), - 'invitationType' => 'userRoleAssignment', - 'invitationPayload' => $invitationPayload, - 'invitationMode' => $invitationMode, - 'pageTitle' => $invitation ? - ( - $invitationPayload['givenName'][Locale::getLocale()] . ' ' - . $invitationPayload['familyName'][Locale::getLocale()] - ) - : __('invitation.wizard.pageTitle'), - 'pageTitleDescription' => $invitation ? - __( - 'invitation.wizard.viewPageTitleDescription', - ['name' => $invitationPayload['givenName'][Locale::getLocale()] ? - $invitationPayload['givenName'][Locale::getLocale()] : $invitationPayload['inviteeEmail']] - ) - : __('invitation.wizard.pageTitleDescription'), - ]); - $templateMgr->assign([ - 'pageComponent' => 'Page', - 'breadcrumbs' => $breadcrumbs, - 'pageWidth' => TemplateManager::PAGE_WIDTH_FULL, - ]); - $templateMgr->display('/invitation/userInvitation.tpl'); - } - - /** - * Edit user using user access table action - * @param $args - * @param $request - * @return void - * @throws \Exception - */ - public function editUser($args, $request): void - { - $invitation = null; - if (!empty($args)) { - $invitationMode = 'editUser'; - $invitationData = $this->generateInvitationPayload($args[0], [], $request->getContext()); - $user = $invitationData['user']; - $invitationPayload = $invitationData['invitationPayload']; - $templateMgr = TemplateManager::getManager($request); - $breadcrumbs = $templateMgr->getTemplateVars('breadcrumbs'); - $this->setupTemplate($request); - $context = $request->getContext(); - $breadcrumbs[] = [ - 'id' => 'contexts', - 'name' => __('navigation.access'), - 'url' => $request - ->getDispatcher() - ->url( - $request, - Application::ROUTE_PAGE, - null, - 'management', - 'settings', - ['access'] - ) - ]; - $breadcrumbs[] = [ - 'id' => 'invitationWizard', - 'name' => __('invitation.wizard.pageTitle'), - ]; - $steps = new SendInvitationStep(); - $templateMgr->setState([ - 'steps' => $steps->getSteps($invitation, $context, $user), - 'emailTemplatesApiUrl' => $request - ->getDispatcher() - ->url( - $request, - Application::ROUTE_API, - $context->getData('urlPath'), - 'emailTemplates' - ), - 'primaryLocale' => $context->getData('primaryLocale'), - 'invitationType' => 'userRoleAssignment', - 'invitationPayload' => $invitationPayload, - 'invitationMode' => $invitationMode, - 'pageTitle' => - $invitationPayload['givenName'][Locale::getLocale()] . ' ' - . $invitationPayload['familyName'][Locale::getLocale()], - 'pageTitleDescription' => - __( - 'invitation.wizard.viewPageTitleDescription', - ['name' => $invitationPayload['givenName'][Locale::getLocale()]] - ), - ]); - $templateMgr->assign([ - 'pageComponent' => 'Page', - 'breadcrumbs' => $breadcrumbs, - 'pageWidth' => TemplateManager::PAGE_WIDTH_FULL, - ]); - $templateMgr->display('/invitation/userInvitation.tpl'); - } else { - $request->getDispatcher()->handle404(); - } - } - - /** - * Get current user user groups - * @param Context $context - * @param int $id - */ - private function getUserUserGroups(int $id, Context $context): array - { - $userGroups = []; - $userUserGroups = UserUserGroup::query() - ->withUserId($id) - ->withContextId($context->getId()) - ->get() - ->toArray(); - foreach ($userUserGroups as $key => $userUserGroup) { - $userGroup = Repo::userGroup() - ->get($userUserGroup['userGroupId']) - ->toArray(); - $userGroups[$key] = $userUserGroup; - $userGroups[$key]['masthead'] = $userUserGroup['masthead'] === 1; - $userGroups[$key]['name'] = $userGroup['name'][Locale::getLocale()]; - $userGroups[$key]['id'] = $userGroup['userGroupId']; - } - return $userGroups; - } - - /** - * generate invitation payload - * @param $userId - * @param array $payload - * @param Context $context - * @return array - */ - private function generateInvitationPayload($userId, array $payload, Context $context): array - { - $user = null; - if ($userId) { - $user = Repo::user()->get($userId, true); - } - - $invitationPayload = []; - $invitationPayload['userId'] = $user ? $user->getId() : $userId; - $invitationPayload['inviteeEmail'] = $user ? $user->getEmail() : $payload['email']; - $invitationPayload['orcid'] = $user ? $user->getData('orcid') : $payload['orcid']; - $invitationPayload['givenName'] = $user ? $user->getGivenName(null) : $payload['givenName']; - $invitationPayload['familyName'] = $user ? $user->getFamilyName(null) : $payload['familyName']; - $invitationPayload['affiliation'] = $user ? $user->getAffiliation(null) : $payload['affiliation']; - $invitationPayload['country'] = $user ? $user->getCountryLocalized() : $payload['userCountry']; - $invitationPayload['biography'] = $user?->getBiography(null); - $invitationPayload['phone'] = $user?->getPhone(); - $invitationPayload['mailingAddress'] = $user?->getMailingAddress(); - $invitationPayload['signature'] = $user?->getSignature(null); - $invitationPayload['locales'] = $user ? $this->getWorkingLanguages($context, $user->getLocales()) : null; - $invitationPayload['reviewInterests'] = $user?->getInterestString(); - $invitationPayload['homePageUrl'] = $user?->getUrl(); - $invitationPayload['disabled'] = $user?->getData('disabled'); - $invitationPayload['userGroupsToAdd'] = !$payload['userGroupsToAdd'] ? [] : $payload['userGroupsToAdd']; - $invitationPayload['currentUserGroups'] = !$userId ? [] : $this->getUserUserGroups($userId, $context); - $invitationPayload['userGroupsToRemove'] = []; - $invitationPayload['emailComposer'] = [ - 'emailBody' => '', - 'emailSubject' => '', - ]; - return [ - 'invitationPayload' => $invitationPayload, - 'user' => $user - ]; - } - - /** - * get user working languages - * @param Context $context - * @param $userLocales - * @return string - */ - private function getWorkingLanguages(Context $context, $userLocales): string - { - $locales = $context->getSupportedLocaleNames(); - return join(__('common.commaListSeparator'), array_map(fn($key) => $locales[$key], $userLocales)); - } } diff --git a/pages/invitation/index.php b/pages/invitation/index.php index 24720f14aca..84e8dff5f8e 100644 --- a/pages/invitation/index.php +++ b/pages/invitation/index.php @@ -16,7 +16,8 @@ switch ($op) { case 'decline': case 'accept': - case 'invite': - case 'editUser': return new PKP\pages\invitation\InvitationHandler(); + case 'create': + case 'edit': + return new PKP\pages\invitation\InitializeInvitationUIHandler(); } diff --git a/pages/management/ManagementHandler.php b/pages/management/ManagementHandler.php index c4e837d99be..8d876eb05ff 100644 --- a/pages/management/ManagementHandler.php +++ b/pages/management/ManagementHandler.php @@ -55,6 +55,8 @@ use PKP\context\Context; use PKP\core\PKPApplication; use PKP\core\PKPRequest; +use PKP\invitation\core\Invitation; +use PKP\invitation\invitations\userRoleAssignment\handlers\UserRoleAssignmentInviteUIController; use PKP\mail\Mailable; use PKP\security\authorization\CanAccessSettingsPolicy; use PKP\security\authorization\ContextAccessPolicy; @@ -134,6 +136,9 @@ public function settings($args, $request) case 'institutions': $this->institutions($args, $request); break; + case 'user': + $this->editUser($args, $request); + break; default: throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException(); } @@ -579,6 +584,26 @@ public function manageEmails(array $args, Request $request): void $templateMgr->display('management/manageEmails.tpl'); } + /** + * Edit or view user using user access table action + * @param array $args + * @param $request + * @return void + * @throws \Exception + */ + public function editUser(array $args, $request): void + { + $this->setupTemplate($request); + $userId = $args[0]; + if(!empty($userId)) { + $invitation = app(Invitation::class)->createNew('userRoleAssignment'); + $invitationHandler = $invitation->getInvitationUIActionRedirectController(); + $invitationHandler->createHandle($request,$userId); + } else { + $request->getDispatcher()->handle404(); + } + } + protected function getEmailTemplateForm(Context $context, string $apiUrl): EmailTemplateForm { $locales = $context->getSupportedFormLocaleNames(); diff --git a/templates/invitation/userInvitation.tpl b/templates/invitation/userInvitation.tpl index 2216ddff415..535bd4d48fb 100644 --- a/templates/invitation/userInvitation.tpl +++ b/templates/invitation/userInvitation.tpl @@ -21,5 +21,6 @@ :invitation-type="invitationType" :invitation-mode="invitationMode" :steps="steps" + :invitation-user-data="invitationUserData" /> {/block}