From f6ef15d929be301bbb9d304ab7eae89f53bad668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jarda=20Kot=C4=9B=C5=A1ovec?= Date: Thu, 27 Nov 2025 18:13:02 +0100 Subject: [PATCH] pkp/pkp-lib#12002 Ensure correct stage assignment for JOURNAL_MANAGERS on login --- classes/security/Validation.php | 48 +++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/classes/security/Validation.php b/classes/security/Validation.php index 155d59f8448..eb381624245 100644 --- a/classes/security/Validation.php +++ b/classes/security/Validation.php @@ -27,6 +27,7 @@ use PKP\site\SiteDAO; use PKP\user\User; use PKP\userGroup\UserGroup; +use PKP\userGroup\relationships\UserGroupStage; use PKP\security\Role; use PKP\core\PKPApplication; @@ -114,12 +115,59 @@ public static function registerUserSession($user, &$reason) $request = Application::get()->getRequest(); $request->getSessionGuard()->setUserDataToSession($user)->updateSession($user->getId()); + // Ensure manager userGroups have all workflow stages assigned + static::ensureManagerUserGroupStages($user); + $user->setDateLastLogin(Core::getCurrentDate()); Repo::user()->edit($user); return $user; } + /** + * Ensure that all manager role userGroups for a user have all workflow stages assigned. + * This corrects any inconsistent database state where manager userGroups are missing stage assignments. + */ + protected static function ensureManagerUserGroupStages(User $user): void + { + // Get application-specific workflow stages (differs between OJS, OMP, OPS) + $allWorkflowStages = Application::getApplicationStages(); + + // Get manager userGroups for this user with their current stage assignments + $managerUserGroups = UserGroup::query() + ->withRoleIds([Role::ROLE_ID_MANAGER]) + ->whereHas('userUserGroups', function ($query) use ($user) { + $query->withUserId($user->getId())->withActive(); + }) + ->with('userGroupStages') + ->get(); + + if ($managerUserGroups->isEmpty()) { + return; + } + + // Collect all missing stage assignments for batch insert + $missingStages = []; + foreach ($managerUserGroups as $userGroup) { + $assignedStageIds = $userGroup->userGroupStages->pluck('stage_id')->toArray(); + + foreach ($allWorkflowStages as $stageId) { + if (!in_array($stageId, $assignedStageIds)) { + $missingStages[] = [ + 'context_id' => $userGroup->context_id, + 'user_group_id' => $userGroup->user_group_id, + 'stage_id' => $stageId, + ]; + } + } + } + + // Batch insert missing stages + if (!empty($missingStages)) { + UserGroupStage::insert($missingStages); + } + } + /** * Mark the user as logged out in the current session. *