From 199ee9a0a9d0b84ecf033dc8f4258e5d9a0d4776 Mon Sep 17 00:00:00 2001 From: Vitalii Bezsheiko Date: Tue, 26 Mar 2024 10:43:54 +0200 Subject: [PATCH] pkp/pkp-lib#9825 Submission data in review assignment schema --- classes/submission/Collector.php | 32 +++++++++- .../reviewAssignment/maps/Schema.php | 64 +++++++++++++------ schemas/reviewAssignment.json | 6 ++ 3 files changed, 83 insertions(+), 19 deletions(-) diff --git a/classes/submission/Collector.php b/classes/submission/Collector.php index ccf1eb73c5e..9f5362c0aaf 100644 --- a/classes/submission/Collector.php +++ b/classes/submission/Collector.php @@ -79,6 +79,7 @@ abstract class Collector implements CollectorInterface, ViewsCount public ?bool $reviewsSubmitted = null; public ?bool $revisionsRequested = null; public ?bool $revisionsSubmitted = null; + public ?array $reviewIds = null; public function __construct(DAO $dao) { @@ -272,6 +273,17 @@ public function isReviewedBy(int|array|null $isReviewedBy): AppCollector return $this; } + /** + * Limit results by submissions with specific review assignment IDs + * + * @param array|null $reviewIds An array of review assignment IDs + */ + public function filterByReviewIds(?array $reviewIds): AppCollector + { + $this->reviewIds = $reviewIds; + return $this; + } + /** * Limit results to submissions matching this search query */ @@ -626,6 +638,17 @@ public function getQueryBuilder(): Builder // Filter out excluded submission IDs $q->when($this->excludeIds !== null, fn (Builder $q) => $q->whereNotIn('s.submission_id', $this->excludeIds)); + $q->when( + $this->reviewIds !== null, + fn (Builder $q) => $q + ->whereExists( + fn (Builder $q) => $q + ->from('review_assignments AS ra') + ->whereColumn('s.submission_id', 'ra.submission_id') + ->whereIn('ra.review_id', $this->reviewIds) + ) + ); + // Limit and offset results for pagination if (isset($this->count)) { $q->limit($this->count); @@ -645,7 +668,14 @@ public function getQueryBuilder(): Builder */ protected function buildReviewStageQueries(Builder $q): Builder { - $reviewFilters = collect([$this->isReviewedBy, $this->reviewersNumber, $this->awaitingReviews, $this->reviewsSubmitted, $this->revisionsRequested, $this->revisionsSubmitted])->filter(); + $reviewFilters = collect([ + $this->isReviewedBy, + $this->reviewersNumber, + $this->awaitingReviews, + $this->reviewsSubmitted, + $this->revisionsRequested, + $this->revisionsSubmitted + ])->filter(); if ($reviewFilters->isEmpty()) { return $q; } diff --git a/classes/submission/reviewAssignment/maps/Schema.php b/classes/submission/reviewAssignment/maps/Schema.php index 558d6b45028..c0328f14fb2 100644 --- a/classes/submission/reviewAssignment/maps/Schema.php +++ b/classes/submission/reviewAssignment/maps/Schema.php @@ -1,19 +1,20 @@ mapByProperties($this->getProps(), $item); + return $this->mapByProperties($this->getProps(), $item, $submission); } /** - * Summarize an announcement + * Summarize the Review Assignment * * Includes properties with the apiSummary flag in the review assignment schema. */ - public function summarize(ReviewAssignment $item): array + public function summarize(ReviewAssignment $item, Submission $submission): array { - return $this->mapByProperties($this->getSummaryProps(), $item); + return $this->mapByProperties($this->getSummaryProps(), $item, $submission); } /** @@ -52,9 +53,21 @@ public function summarize(ReviewAssignment $item): array public function mapMany(Enumerable $collection): Enumerable { $this->collection = $collection; - return $collection->map(function ($item) { - return $this->map($item); - }); + $submissions = Repo::submission()->getCollector() + ->filterByContextIds([$this->context->getId()]) + ->filterByReviewIds($collection->keys()->toArray()) + ->getMany() + ->remember(); + + $associatedSubmissions = $this->collection->map( + fn (ReviewAssignment $reviewAssignment) => + $reviewAssignment->getData('submissionId') + ); + + return $collection->map( + fn ($item) => + $this->map($item, $submissions->get($associatedSubmissions->get($item->getId()))) + ); } /** @@ -65,19 +78,34 @@ public function mapMany(Enumerable $collection): Enumerable public function summarizeMany(Enumerable $collection): Enumerable { $this->collection = $collection; - return $collection->map(function ($item) { - return $this->summarize($item); - }); + $submissions = Repo::submission()->getCollector() + ->filterByContextIds([$this->context->getId()]) + ->filterByReviewIds($collection->keys()->toArray()) + ->getMany() + ->remember(); + + $associatedSubmissions = $this->collection->map( + fn (ReviewAssignment $reviewAssignment) => + $reviewAssignment->getData('submissionId') + ); + + return $collection->map( + fn ($item) => + $this->summarize($item, $submissions->get($associatedSubmissions->get($item->getId()))) + ); } /** - * Map schema properties of an Announcement to an assoc array + * Map schema properties of the Review Assignment to an assoc array */ - protected function mapByProperties(array $props, ReviewAssignment $item): array + protected function mapByProperties(array $props, ReviewAssignment $item, Submission $submission): array { $output = []; foreach ($props as $prop) { switch ($prop) { + case 'publicationTitle': + $output[$prop] = $submission->getCurrentPublication()->getFullTitles('html'); + break; case '_href': $output[$prop] = $this->getApiUrl('_submissions/reviewAssignments/' . $item->getId()); break; diff --git a/schemas/reviewAssignment.json b/schemas/reviewAssignment.json index 09c8fe54539..f186d59d01f 100644 --- a/schemas/reviewAssignment.json +++ b/schemas/reviewAssignment.json @@ -228,6 +228,12 @@ "type": "integer", "description": "The ID of the submission associated with the assignment", "apiSummary": true + }, + "publicationTitle": { + "type": "string", + "multilingual": true, + "description": "The title of the associated with the current publication", + "readOnly": true } } }