From c2f9b5e9f9a0d925e3c2350a55b9a37e4d147813 Mon Sep 17 00:00:00 2001 From: ipula Date: Tue, 25 Feb 2025 12:34:34 +0100 Subject: [PATCH] fix bugs in user edit and invitation workflow --- api/v1/users/PKPUserController.php | 4 ++-- classes/mail/mailables/UserRoleEndNotify.php | 2 +- classes/user/maps/Schema.php | 9 ++++---- .../userGroup/relationships/UserUserGroup.php | 8 +++++++ .../grid/settings/user/UserGridHandler.php | 2 +- locale/en/grid.po | 18 +++++++++++++-- locale/en/invitation.po | 23 +++++++++++-------- locale/en/user.po | 15 ++++++++++++ pages/invitation/InvitationHandler.php | 17 +++++++++----- pages/user/ProfileHandler.php | 13 ++++++++++- .../settings/user/form/userDisableForm.tpl | 2 ++ templates/layouts/backend.tpl | 8 ++++--- templates/user/profile.tpl | 6 +++++ 13 files changed, 98 insertions(+), 29 deletions(-) diff --git a/api/v1/users/PKPUserController.php b/api/v1/users/PKPUserController.php index 57f9227182a..03bf27dd0f6 100644 --- a/api/v1/users/PKPUserController.php +++ b/api/v1/users/PKPUserController.php @@ -298,7 +298,7 @@ public function endRole(Request $request): JsonResponse { // Ensure user exists $userId = $request->route('userId'); - $user = Repo::user()->get($userId); + $user = Repo::user()->get($userId, true); if (!$user) { return response()->json([ 'error' => __('api.404.resourceNotFound') @@ -331,7 +331,7 @@ public function endRole(Request $request): JsonResponse Mail::send($mailable); // Return updated user model - $user = Repo::user()->get($userId); + $user = Repo::user()->get($userId, true); return response()->json(Repo::user()->getSchemaMap()->map($user), Response::HTTP_OK); } diff --git a/classes/mail/mailables/UserRoleEndNotify.php b/classes/mail/mailables/UserRoleEndNotify.php index bb2f5d642c8..fb219f914cc 100644 --- a/classes/mail/mailables/UserRoleEndNotify.php +++ b/classes/mail/mailables/UserRoleEndNotify.php @@ -78,7 +78,7 @@ public function setData(?string $locale = null): void $targetPath = Core::getBaseDir() . '/lib/pkp/styles/mailables/style.css'; $emailTemplateStyle = file_get_contents($targetPath); - $role = $this->userGroup->getName($locale); + $role = $this->userGroup->getLocalizedData('name'); // Set view data for the template $this->viewData = array_merge( diff --git a/classes/user/maps/Schema.php b/classes/user/maps/Schema.php index 7b9b9af5dd9..0de9ac848d6 100644 --- a/classes/user/maps/Schema.php +++ b/classes/user/maps/Schema.php @@ -169,8 +169,7 @@ protected function mapByProperties(array $props, User $user, array $auxiliaryDat $userGroups = UserGroup::query() ->withContextIds($this->context->getId()) ->whereHas('userUserGroups', function ($query) use ($user) { - $query->withUserId($user->getId()) - ->withActive(); + $query->withUserId($user->getId()); }) ->get(); @@ -186,9 +185,11 @@ protected function mapByProperties(array $props, User $user, array $auxiliaryDat 'permitMetadataEdit' => (bool) $userGroup->permitMetadataEdit, 'recommendOnly' => (bool) $userGroup->recommendOnly, 'dateStart' => UserUserGroup::withUserId($user->getId()) - ->withActive() ->withUserGroupIds([$userGroup->id]) - ->pluck('date_start')->first() + ->pluck('date_start')->first(), + 'dateEnd' => UserUserGroup::withUserId($user->getId()) + ->withUserGroupIds([$userGroup->id]) + ->pluck('date_end')->first(), ]; } } diff --git a/classes/userGroup/relationships/UserUserGroup.php b/classes/userGroup/relationships/UserUserGroup.php index 525e705546e..68d3b4ac3af 100644 --- a/classes/userGroup/relationships/UserUserGroup.php +++ b/classes/userGroup/relationships/UserUserGroup.php @@ -104,4 +104,12 @@ public function scopeSortBy(Builder $query, string $column, ?string $direction = { return $query->orderBy('user_user_groups.' . $column, $direction); } + + public function scopeWithActiveInFuture(Builder $query): Builder + { + $currentDateTime = Core::getCurrentDate(); + return $query->whereNotNull('user_user_groups.date_start') + ->where('user_user_groups.date_start', '>', $currentDateTime) + ->orderBy('user_user_groups.date_start', 'asc'); + } } diff --git a/controllers/grid/settings/user/UserGridHandler.php b/controllers/grid/settings/user/UserGridHandler.php index 56ddeb66620..c839d195ad0 100644 --- a/controllers/grid/settings/user/UserGridHandler.php +++ b/controllers/grid/settings/user/UserGridHandler.php @@ -581,7 +581,7 @@ public function removeUser($args, $request) ->whereHas('userGroup', function ($query) use ($context) { $query->withContextIds($context->getId()); }) - ->update(['dateEnd' => now()]); + ->update(['date_end' => now()]); return \PKP\db\DAO::getDataChangedEvent($userId); } diff --git a/locale/en/grid.po b/locale/en/grid.po index f50a11b79f8..179fd06661d 100644 --- a/locale/en/grid.po +++ b/locale/en/grid.po @@ -508,10 +508,10 @@ msgid "grid.user.email" msgstr "Email" msgid "grid.user.enable" -msgstr "Enable" +msgstr "Enable User" msgid "grid.user.disable" -msgstr "Disable" +msgstr "Disable User" msgid "grid.user.disableReason" msgstr "Reason for disabling user" @@ -716,3 +716,17 @@ msgstr "In Browse Lists" msgid "grid.action.editContributor" msgstr "Edit Contributor" + +msgid "grid.user.remove" +msgstr "Remove User" + +msgid "grid.user.logInAs" +msgstr "Login As" + +msgid "grid.user.enableReasonDescription" +msgstr "Once the user is enabled, they will regain access to the site, and you'll be able to invite them to roles as needed." + +msgid "grid.user.disableReasonDescription" +msgstr "Please note that once a user is disabled, you won't be able to add them to any roles until the user is enabled again." + + diff --git a/locale/en/invitation.po b/locale/en/invitation.po index 19fcb9d9417..cc7c333b3f7 100644 --- a/locale/en/invitation.po +++ b/locale/en/invitation.po @@ -134,16 +134,10 @@ msgid "userInvitation.searchUser.nextButtonLabel" msgstr "Search User" msgid "userInvitation.searchUser.stepDescription" -msgstr "Search for the user using their email address, username or ORCID ID. Enter at least one details to get started. If the user does not exist, you can invite them to take up roles and be a part of your journal. If the user already exist in the system, you can view user information and invite to take a additional roles." +msgstr "If the user does not exist, you can invite them to take on roles. If the user already exists in the system, you can view their information and invite them to take on additional roles." -msgid "userInvitation.emailField.description" -msgstr "e.g. aeinstein@example.com" - -msgid "userInvitation.usernameField.description" -msgstr "e.g. mickeymouse" - -msgid "userInvitation.orcidField.description" -msgstr "e.g. 0000-0000-0000-0000" +msgid "userInvitation.searchField.description" +msgstr "e.g. aeinstein@example.com or aeinstein or 0000-0002-1825-0097" msgid "userInvitation.enterDetails.stepName" msgstr "Enter details" @@ -372,3 +366,14 @@ msgstr "Invitation not accepted. You're logged in as a different user." msgid "acceptInvitation.authorization.message" msgstr "Please log out and sign in with the correct account to accept this invitation." + +msgid "userInvitation.searchField" +msgstr "Search for a user by email address, username, or ORCID iD. Enter only one to get started!" + +msgid "userInvitation.user.disableTitle" +msgstr "The user is currently disabled." + +msgid "userInvitation.user.disableMessage" +msgstr "The user was disabled. You cannot assign them a role while they are disabled. Please enable the user first to invite them to a role." + + diff --git a/locale/en/user.po b/locale/en/user.po index ff2df32c011..899c5e67728 100644 --- a/locale/en/user.po +++ b/locale/en/user.po @@ -853,3 +853,18 @@ msgstr "This ORCID has not been verified. Please remove this unverified ORCID an msgid "user.removeRole.message" msgstr "Are you sure want remove this role permanently?" + +msgid "user.futureRole.notification.message" +msgstr "Your role is scheduled to begin on {$roleStartDate}" + +msgid "user.futureRole.notification.description" +msgstr "Until then, you can review and update your profile. If you believe this is an error, please contact the administrator." + +msgid "user.disabledModal.description" +msgstr "Current Roles : {$roles}" + +msgid "user.disabledModal.title" +msgstr "Disable {$fullName}" + +msgid "user.enabledModal.title" +msgstr "Enable {$fullName}" diff --git a/pages/invitation/InvitationHandler.php b/pages/invitation/InvitationHandler.php index 582b4ff4017..ddace4d5e4c 100644 --- a/pages/invitation/InvitationHandler.php +++ b/pages/invitation/InvitationHandler.php @@ -129,6 +129,7 @@ public function invite(array $args, Request $request): void 'givenName' => '', 'familyName' => '', 'orcidValidation' => false, + 'disabled' => false, 'userGroupsToAdd' => [ [ 'userGroupId' => null, @@ -169,6 +170,7 @@ public function invite(array $args, Request $request): void 'emailBody' => $payload['emailBody'], 'emailSubject' => $payload['emailSubject'], ]; + $invitationPayload['disabled'] = false; } $templateMgr = TemplateManager::getManager($request); $breadcrumbs = $templateMgr->getTemplateVars('breadcrumbs'); @@ -181,10 +183,11 @@ public function invite(array $args, Request $request): void ->getDispatcher() ->url( $request, - PKPApplication::ROUTE_PAGE, - $request->getContext()->getPath(), + Application::ROUTE_PAGE, + null, 'management', 'settings', + ['access'] ) ]; $breadcrumbs[] = [ @@ -239,8 +242,8 @@ public function editUser($args, $request): void $invitation = null; $invitationPayload =[]; if(!empty($args)) { - $invitationMode = 'edit'; - $user = Repo::user()->get($args[0]); + $invitationMode = 'editUser'; + $user = Repo::user()->get($args[0],true); $invitationPayload['userId'] = $args[0]; $invitationPayload['inviteeEmail'] = $user->getEmail(); $invitationPayload['orcid'] = $user->getData('orcid'); @@ -250,6 +253,7 @@ public function editUser($args, $request): void $invitationPayload['country'] = $user->getCountry(); $invitationPayload['biography'] = $user->getBiography(null); $invitationPayload['phone'] = $user->getPhone(); + $invitationPayload['disabled'] = $user->getData('disabled'); $invitationPayload['userGroupsToAdd'] = []; $invitationPayload['currentUserGroups'] = $this->getUserUserGroups($args[0],$request->getContext()); $invitationPayload['userGroupsToRemove'] = []; @@ -268,10 +272,11 @@ public function editUser($args, $request): void ->getDispatcher() ->url( $request, - PKPApplication::ROUTE_PAGE, - $request->getContext()->getPath(), + Application::ROUTE_PAGE, + null, 'management', 'settings', + ['access'] ) ]; $breadcrumbs[] = [ diff --git a/pages/user/ProfileHandler.php b/pages/user/ProfileHandler.php index 495fc66fdbe..9d110428116 100644 --- a/pages/user/ProfileHandler.php +++ b/pages/user/ProfileHandler.php @@ -22,6 +22,7 @@ use PKP\core\PKPRequest; use PKP\security\authorization\PKPSiteAccessPolicy; use PKP\security\authorization\UserRequiredPolicy; +use PKP\userGroup\relationships\UserUserGroup; class ProfileHandler extends UserHandler { @@ -58,8 +59,9 @@ public function authorize($request, &$args, $roleAssignments) public function profile($args, $request) { $context = $request->getContext(); + $user = $request->getUser(); + $date_start = null; if (!$context) { - $user = $request->getUser(); $contextDao = Application::getContextDAO(); $workingContexts = $contextDao->getAvailable($user ? $user->getId() : null); [$firstContext, $secondContext] = [$workingContexts->next(), $workingContexts->next()]; @@ -74,11 +76,20 @@ public function profile($args, $request) $request->redirect(null, null, null, null, null, $anchor); } + if(count($user->getRoles($context->getId())) === 0){ + $userFutureRoleStartDate = UserUserGroup::withUserId($user->getId()) + ->withActiveInFuture() + ->pluck('date_start') + ->first(); + $date_start = new \DateTime($userFutureRoleStartDate); + } + $this->setupTemplate($request); $templateMgr = TemplateManager::getManager($request); $templateMgr->assign([ 'pageTitle' => __('user.profile'), + 'userFutureRoleStartDate'=> $date_start?->format('Y-m-d'), ]); $templateMgr->display('user/profile.tpl'); } diff --git a/templates/controllers/grid/settings/user/form/userDisableForm.tpl b/templates/controllers/grid/settings/user/form/userDisableForm.tpl index c3456db693b..637369eab03 100644 --- a/templates/controllers/grid/settings/user/form/userDisableForm.tpl +++ b/templates/controllers/grid/settings/user/form/userDisableForm.tpl @@ -21,10 +21,12 @@ {if $enable} {fbvFormSection title="grid.user.enableReason" for="disableReason"} +

{translate key ="grid.user.enableReasonDescription"}

{fbvElement type="textarea" id="disableReason" value=$disableReason size=$fbvStyles.size.LARGE} {/fbvFormSection} {else} {fbvFormSection title="grid.user.disableReason" for="disableReason"} +

{translate key ="grid.user.disableReasonDescription"}

{fbvElement type="textarea" id="disableReason" value=$disableReason size=$fbvStyles.size.LARGE} {/fbvFormSection} {/if} diff --git a/templates/layouts/backend.tpl b/templates/layouts/backend.tpl index 17ee06a17ce..c134c446d9d 100644 --- a/templates/layouts/backend.tpl +++ b/templates/layouts/backend.tpl @@ -92,7 +92,7 @@ {/if} > {if $isUserLoggedInAs} - {block name="menu"} - - + {if isset($currentContext) && isset($currentUser) && $currentUser->getRoles($currentContext->getId())|count > 0} + + + {/if} {/block}
diff --git a/templates/user/profile.tpl b/templates/user/profile.tpl index 3baf1f33f57..5ab1e29b14d 100644 --- a/templates/user/profile.tpl +++ b/templates/user/profile.tpl @@ -10,6 +10,12 @@ {extends file="layouts/backend.tpl"} {block name="page"} + {if $userFutureRoleStartDate} + +

{translate key="user.futureRole.notification.message" roleStartDate=$userFutureRoleStartDate}

+

{translate key="user.futureRole.notification.description"}

+
+ {/if}

{translate key="user.profile"}