diff --git a/api/v1/submissions/PKPSubmissionController.php b/api/v1/submissions/PKPSubmissionController.php index 9b8bb930dd8..97f1ef1001f 100644 --- a/api/v1/submissions/PKPSubmissionController.php +++ b/api/v1/submissions/PKPSubmissionController.php @@ -902,7 +902,7 @@ public function getParticipants(Request $illuminateRequest): JsonResponse $context = $request->getContext(); $submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION); $args = $illuminateRequest->input(); - $stageId = $args['stageId'] ?? null; + $stageId = $args['stageId'] ?? $illuminateRequest->route('stageId') !== null ? (int) $illuminateRequest->route('stageId') : null; if (!$submission || $submission->getData('contextId') !== $context->getId()) { return response()->json([ @@ -919,7 +919,7 @@ public function getParticipants(Request $illuminateRequest): JsonResponse $map = Repo::user()->getSchemaMap(); foreach ($usersIterator as $user) { - $data[] = $map->summarizeReviewer($user); + $data[] = $map->summarizeReviewer($user, ['submission' => $submission, 'stageId' => $stageId]); } return response()->json($data, Response::HTTP_OK); diff --git a/classes/stageAssignment/StageAssignment.php b/classes/stageAssignment/StageAssignment.php index 7103657b4a1..04da0d97002 100644 --- a/classes/stageAssignment/StageAssignment.php +++ b/classes/stageAssignment/StageAssignment.php @@ -90,7 +90,7 @@ public function scopeWithStageIds(Builder $query, ?array $stageIds): Builder public function scopeWithSubmissionIds(Builder $query, ?array $submissionIds): Builder { return $query->when($submissionIds !== null, function ($query) use ($submissionIds) { - return $query->whereIn('submission_id', $submissionIds); + return $query->whereIn('stage_assignments.submission_id', $submissionIds); }); } @@ -142,7 +142,7 @@ public function scopeWithContextId(Builder $query, ?int $contextId): Builder { return $query->when($contextId !== null, function ($query) use ($contextId) { return $query->join('submissions', 'stage_assignments.submission_id', '=', 'submissions.submission_id') - ->where('submissions.context_id', $contextId); + ->where('submissions.context_id', $contextId); }); } } diff --git a/classes/user/maps/Schema.php b/classes/user/maps/Schema.php index 182e1accde8..30e960bc97e 100644 --- a/classes/user/maps/Schema.php +++ b/classes/user/maps/Schema.php @@ -17,8 +17,12 @@ use Illuminate\Support\Enumerable; use PKP\db\DAORegistry; use PKP\plugins\Hook; +use PKP\security\Role; use PKP\services\PKPSchemaService; +use PKP\stageAssignment\StageAssignment; use PKP\user\User; +use PKP\workflow\WorkflowStageDAO; +use Submission; class Schema extends \PKP\core\maps\Schema { @@ -51,9 +55,9 @@ public function summarize(User $item): array * * Includes properties with the apiSummary flag in the user schema. */ - public function summarizeReviewer(User $item): array + public function summarizeReviewer(User $item, array $auxiliaryData = []): array { - return $this->mapByProperties(array_merge($this->getSummaryProps(), ['reviewsActive', 'reviewsCompleted', 'reviewsDeclined', 'reviewsCancelled', 'averageReviewCompletionDays', 'dateLastReviewAssignment', 'reviewerRating']), $item); + return $this->mapByProperties(array_merge($this->getSummaryProps(), ['reviewsActive', 'reviewsCompleted', 'reviewsDeclined', 'reviewsCancelled', 'averageReviewCompletionDays', 'dateLastReviewAssignment', 'reviewerRating']), $item, $auxiliaryData); } /** @@ -98,9 +102,11 @@ public function summarizeManyReviewers(Enumerable $collection): Enumerable /** * Map schema properties of a user to an assoc array * + * @param array $auxiliaryData - Associative array used to provide supplementary data needed to populate properties on the response. + * * @hook UserSchema::getProperties::values [[$this, &$output, $user, $props]] */ - protected function mapByProperties(array $props, User $user): array + protected function mapByProperties(array $props, User $user, array $auxiliaryData = []): array { $output = []; @@ -180,6 +186,54 @@ protected function mapByProperties(array $props, User $user): array } } } + break; + case 'stageAssignments': + $submission = $auxiliaryData['submission']; + $stageId = $auxiliaryData['stageId']; + + if((!isset($submission) || !isset($stageId)) || (!($submission instanceof Submission) || !is_numeric($auxiliaryData['stageId']))) { + $output['stageAssignments'] = []; + break; + } + + // Get User's stage assignments for submission. + // Note: + // - A User can potentially have multiple assignments for a submission. + // - A User can potentially have multiple assignments for a stage of a submission. + $stageAssignments = StageAssignment::withSubmissionIds([$submission->getId()]) + ->withStageIds($stageId ? [$stageId] : []) + ->withUserId($user->getId()) + ->withContextId($this->context->getId()) + ->get(); + + $results = []; + + foreach ($stageAssignments as $stageAssignment /**@var StageAssignment $stageAssignment*/) { + // Get related user group info for stage assignment + $userGroup = Repo::userGroup()->get($stageAssignment->userGroupId); + + // Only prepare data for non-reviewer participants + if ($userGroup->getRoleId() !== Role::ROLE_ID_REVIEWER) { + $entry = [ + 'stageAssignmentId' => $stageAssignment->id, + 'stageAssignmentUserGroup' => $userGroup->getAllData(), + 'stageAssignmentStageId' => $stageId, + 'recommendOnly' => (bool)$stageAssignment->recommendOnly, + 'canChangeMetadata' => (bool)$stageAssignment->canChangeMetadata + ]; + + $workflowStageDao = DAORegistry::getDAO('WorkflowStageDAO'); /** @var WorkflowStageDAO $workflowStageDao */ + $entry['stageAssignmentStage'] = [ + 'id' => $stageId, + 'label' => __($workflowStageDao->getTranslationKeyFromId($stageId)), + ]; + + $results[] = $entry; + } + + $output['stageAssignments'] = $results; + } + break; default: $output[$prop] = $user->getData($prop); diff --git a/schemas/user.json b/schemas/user.json index ee96b45233e..d10b7de76e8 100644 --- a/schemas/user.json +++ b/schemas/user.json @@ -290,6 +290,43 @@ "validation": [ "nullable" ] + }, + "stageAssignments": { + "apiSummary": true, + "readOnly": true, + "type": "array", + "items": { + "type": "object", + "properties": { + "stageAssignmentId": { + "type": "integer" + }, + "stageAssignmentUserGroup": { + "type": "object", + "$ref": "#/definitions/UserGroup" + }, + "stageAssignmentStageId": { + "type": "integer" + }, + "stageAssignmentStage": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + } + } + }, + "canChangeMetadata": { + "type": "boolean" + }, + "recommendOnly": { + "type": "boolean" + } + } + } } } }