From db1f977ce77463f55f8cd79abe3d2771c1f85897 Mon Sep 17 00:00:00 2001 From: Touhidur Rahman Date: Tue, 19 Nov 2024 13:39:35 +0600 Subject: [PATCH] pkp/pkp-lib#1660 dynamic recommendations ability complete --- .../users/reviewer/PKPReviewerGridHandler.php | 4 +- .../ReviewAssignmentEmailVariable.php | 2 +- .../ReviewerRecommendationsMigration.php | 5 -- .../v3_6_0/I1660_ReviewerRecommendations.php | 13 ++- .../reviewAssignment/ReviewAssignment.php | 84 ++++++++++++------- .../form/PKPReviewerReviewStep3Form.php | 10 +-- .../recommendation/ReviewerRecommendation.php | 6 +- .../reviewer/AuthorReviewerGridHandler.php | 4 +- pages/dashboard/PKPDashboardHandlerNext.php | 22 +++-- pages/dashboard/index.php | 6 +- 10 files changed, 89 insertions(+), 67 deletions(-) diff --git a/classes/controllers/grid/users/reviewer/PKPReviewerGridHandler.php b/classes/controllers/grid/users/reviewer/PKPReviewerGridHandler.php index a703b7eccea..dcec3712068 100644 --- a/classes/controllers/grid/users/reviewer/PKPReviewerGridHandler.php +++ b/classes/controllers/grid/users/reviewer/PKPReviewerGridHandler.php @@ -814,6 +814,7 @@ public function editThankReviewer($args, $request) */ public function readReview($args, $request) { + $context = $request->getContext(); $templateMgr = TemplateManager::getManager($request); $reviewAssignment = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_REVIEW_ASSIGNMENT); $starHtml = ''; @@ -828,12 +829,11 @@ public function readReview($args, $request) ReviewAssignment::SUBMISSION_REVIEWER_RATING_POOR => str_repeat($starHtml, ReviewAssignment::SUBMISSION_REVIEWER_RATING_POOR), ReviewAssignment::SUBMISSION_REVIEWER_RATING_VERY_POOR => str_repeat($starHtml, ReviewAssignment::SUBMISSION_REVIEWER_RATING_VERY_POOR), ], - 'reviewerRecommendationOptions' => ReviewAssignment::getReviewerRecommendationOptions(), + 'reviewerRecommendationOptions' => ReviewAssignment::getReviewerRecommendationOptions($context), ]); if ($reviewAssignment->getReviewFormId()) { // Retrieve review form - $context = $request->getContext(); $reviewFormElementDao = DAORegistry::getDAO('ReviewFormElementDAO'); /** @var ReviewFormElementDAO $reviewFormElementDao */ $reviewFormElements = $reviewFormElementDao->getByReviewFormId($reviewAssignment->getReviewFormId()); $reviewFormResponseDao = DAORegistry::getDAO('ReviewFormResponseDAO'); /** @var ReviewFormResponseDAO $reviewFormResponseDao */ diff --git a/classes/mail/variables/ReviewAssignmentEmailVariable.php b/classes/mail/variables/ReviewAssignmentEmailVariable.php index b6920350a2f..d9b9d04af2a 100644 --- a/classes/mail/variables/ReviewAssignmentEmailVariable.php +++ b/classes/mail/variables/ReviewAssignmentEmailVariable.php @@ -95,7 +95,7 @@ protected function formatDate(string $date, string $locale, Context $context): ? protected function getRecommendation(string $locale): string { - $recommendationOptions = ReviewAssignment::getReviewerRecommendationOptions(); + $recommendationOptions = ReviewAssignment::getReviewerRecommendationOptions($this->getContext()); return isset($recommendationOptions[$this->reviewAssignment->getRecommendation()]) ? __($recommendationOptions[$this->reviewAssignment->getRecommendation()], [], $locale) diff --git a/classes/migration/install/ReviewerRecommendationsMigration.php b/classes/migration/install/ReviewerRecommendationsMigration.php index c99f858d8b7..f927aa898a9 100644 --- a/classes/migration/install/ReviewerRecommendationsMigration.php +++ b/classes/migration/install/ReviewerRecommendationsMigration.php @@ -15,12 +15,7 @@ namespace PKP\migration\install; use Illuminate\Database\Schema\Blueprint; -use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; -use PKP\facades\Locale; -use PKP\submission\reviewer\recommendation\ReviewerRecommendation; -use stdClass; -use Throwable; abstract class ReviewerRecommendationsMigration extends \PKP\migration\Migration { diff --git a/classes/migration/upgrade/v3_6_0/I1660_ReviewerRecommendations.php b/classes/migration/upgrade/v3_6_0/I1660_ReviewerRecommendations.php index 2ab8eeee13d..4fcbb78bfd2 100644 --- a/classes/migration/upgrade/v3_6_0/I1660_ReviewerRecommendations.php +++ b/classes/migration/upgrade/v3_6_0/I1660_ReviewerRecommendations.php @@ -14,16 +14,12 @@ namespace PKP\migration\upgrade\v3_6_0; +use APP\migration\install\ReviewerRecommendationsMigration; use Illuminate\Support\Facades\DB; +use PKP\facades\Locale; use PKP\install\Installer; - -use Throwable; - -use stdClass; - use PKP\submission\reviewer\recommendation\ReviewerRecommendation; -use PKP\facades\Locale; -use APP\migration\install\ReviewerRecommendationsMigration; +use Throwable; abstract class I1660_ReviewerRecommendations extends \PKP\migration\Migration { @@ -50,6 +46,8 @@ public function __construct(Installer $installer, array $attributes) public function up(): void { $this->recommendationInstallMigration->up(); + + $this->seedNonRemovableRecommendations(); } /** @@ -147,7 +145,6 @@ protected function seedNonRemovableRecommendations(): void Locale::setLocale($currentLocale); ReviewerRecommendation::reguard(); - ray($exception); throw $exception; } } diff --git a/classes/submission/reviewAssignment/ReviewAssignment.php b/classes/submission/reviewAssignment/ReviewAssignment.php index d87ee2de57e..182935bfea9 100644 --- a/classes/submission/reviewAssignment/ReviewAssignment.php +++ b/classes/submission/reviewAssignment/ReviewAssignment.php @@ -16,16 +16,19 @@ namespace PKP\submission\reviewAssignment; +use APP\core\Application; +use PKP\submission\reviewer\recommendation\ReviewerRecommendation; +use PKP\context\Context; use PKP\core\Core; class ReviewAssignment extends \PKP\core\DataObject { - public const SUBMISSION_REVIEWER_RECOMMENDATION_ACCEPT = 1; - public const SUBMISSION_REVIEWER_RECOMMENDATION_PENDING_REVISIONS = 2; - public const SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_HERE = 3; - public const SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_ELSEWHERE = 4; - public const SUBMISSION_REVIEWER_RECOMMENDATION_DECLINE = 5; - public const SUBMISSION_REVIEWER_RECOMMENDATION_SEE_COMMENTS = 6; + // public const SUBMISSION_REVIEWER_RECOMMENDATION_ACCEPT = 1; + // public const SUBMISSION_REVIEWER_RECOMMENDATION_PENDING_REVISIONS = 2; + // public const SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_HERE = 3; + // public const SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_ELSEWHERE = 4; + // public const SUBMISSION_REVIEWER_RECOMMENDATION_DECLINE = 5; + // public const SUBMISSION_REVIEWER_RECOMMENDATION_SEE_COMMENTS = 6; public const SUBMISSION_REVIEWER_RATING_VERY_GOOD = 5; public const SUBMISSION_REVIEWER_RATING_GOOD = 4; @@ -798,36 +801,53 @@ public function getWeeksDue() } /** - * Get an associative array matching reviewer recommendation codes with locale strings. + * Get an associative array matching reviewer recommendation code/value mapped to localized title. * (Includes default '' => "Choose One" string.) * - * @return array recommendation => localeString + * @return array recommendation => localizedTitle */ - public static function getReviewerRecommendationOptions() + public static function getReviewerRecommendationOptions(?Context $context = null, ?bool $active = true): array { - static $reviewerRecommendationOptions = [ - '' => 'common.chooseOne', - self::SUBMISSION_REVIEWER_RECOMMENDATION_ACCEPT => 'reviewer.article.decision.accept', - self::SUBMISSION_REVIEWER_RECOMMENDATION_PENDING_REVISIONS => 'reviewer.article.decision.pendingRevisions', - self::SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_HERE => 'reviewer.article.decision.resubmitHere', - self::SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_ELSEWHERE => 'reviewer.article.decision.resubmitElsewhere', - self::SUBMISSION_REVIEWER_RECOMMENDATION_DECLINE => 'reviewer.article.decision.decline', - self::SUBMISSION_REVIEWER_RECOMMENDATION_SEE_COMMENTS => 'reviewer.article.decision.seeComments' - ]; - return $reviewerRecommendationOptions; + $context ??= Application::get()->getRequest()->getContext(); + static $reviewerRecommendationOptions = []; + + if (!empty($reviewerRecommendationOptions)) { + return $reviewerRecommendationOptions; + } + + // static $reviewerRecommendationOptions = [ + // '' => 'common.chooseOne', + // self::SUBMISSION_REVIEWER_RECOMMENDATION_ACCEPT => 'reviewer.article.decision.accept', + // self::SUBMISSION_REVIEWER_RECOMMENDATION_PENDING_REVISIONS => 'reviewer.article.decision.pendingRevisions', + // self::SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_HERE => 'reviewer.article.decision.resubmitHere', + // self::SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_ELSEWHERE => 'reviewer.article.decision.resubmitElsewhere', + // self::SUBMISSION_REVIEWER_RECOMMENDATION_DECLINE => 'reviewer.article.decision.decline', + // self::SUBMISSION_REVIEWER_RECOMMENDATION_SEE_COMMENTS => 'reviewer.article.decision.seeComments' + // ]; + + return $reviewerRecommendationOptions = ReviewerRecommendation::query() + ->withContextId($context->getId()) + ->when(!is_null($active), fn ($query) => $query->withActive($active)) + ->get() + ->mapWithKeys( + fn (ReviewerRecommendation $recommendation): array => [ + $recommendation->value => $recommendation->getLocalizedData('title') + ] + ) + ->prepend(__('common.chooseOne'), '') + ->toArray(); } /** * Return a localized string representing the reviewer recommendation. */ - public function getLocalizedRecommendation() + public function getLocalizedRecommendation(): string { - $options = self::getReviewerRecommendationOptions(); - if (array_key_exists($this->getRecommendation(), $options)) { - return __($options[$this->getRecommendation()]); - } else { - return ''; - } + $options = static::getReviewerRecommendationOptions(); + + return array_key_exists($this->getRecommendation(), $options) + ? $options[$this->getRecommendation()] + : ''; } /** @@ -850,12 +870,12 @@ public function canResendReviewRequest(): bool if (!PKP_STRICT_MODE) { class_alias('\PKP\submission\reviewAssignment\ReviewAssignment', '\ReviewAssignment'); foreach ([ - 'SUBMISSION_REVIEWER_RECOMMENDATION_ACCEPT', - 'SUBMISSION_REVIEWER_RECOMMENDATION_PENDING_REVISIONS', - 'SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_HERE', - 'SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_ELSEWHERE', - 'SUBMISSION_REVIEWER_RECOMMENDATION_DECLINE', - 'SUBMISSION_REVIEWER_RECOMMENDATION_SEE_COMMENTS', + // 'SUBMISSION_REVIEWER_RECOMMENDATION_ACCEPT', + // 'SUBMISSION_REVIEWER_RECOMMENDATION_PENDING_REVISIONS', + // 'SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_HERE', + // 'SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_ELSEWHERE', + // 'SUBMISSION_REVIEWER_RECOMMENDATION_DECLINE', + // 'SUBMISSION_REVIEWER_RECOMMENDATION_SEE_COMMENTS', 'SUBMISSION_REVIEWER_RATING_VERY_GOOD', 'SUBMISSION_REVIEWER_RATING_GOOD', 'SUBMISSION_REVIEWER_RATING_AVERAGE', diff --git a/classes/submission/reviewer/form/PKPReviewerReviewStep3Form.php b/classes/submission/reviewer/form/PKPReviewerReviewStep3Form.php index ccfbe78418a..fbaec132bf3 100644 --- a/classes/submission/reviewer/form/PKPReviewerReviewStep3Form.php +++ b/classes/submission/reviewer/form/PKPReviewerReviewStep3Form.php @@ -80,11 +80,11 @@ public function initData() $submissionCommentDao = DAORegistry::getDAO('SubmissionCommentDAO'); /** @var SubmissionCommentDAO $submissionCommentDao */ $submissionComments = $submissionCommentDao->getReviewerCommentsByReviewerId($reviewAssignment->getSubmissionId(), $reviewAssignment->getReviewerId(), $reviewAssignment->getId(), true); - $submissionComment = $submissionComments->next(); + $submissionComment = $submissionComments->next(); /** @var \PKP\submission\SubmissionComment $submissionComment */ $this->setData('comments', $submissionComment ? $submissionComment->getComments() : ''); $submissionCommentsPrivate = $submissionCommentDao->getReviewerCommentsByReviewerId($reviewAssignment->getSubmissionId(), $reviewAssignment->getReviewerId(), $reviewAssignment->getId(), false); - $submissionCommentPrivate = $submissionCommentsPrivate->next(); + $submissionCommentPrivate = $submissionCommentsPrivate->next(); /** @var \PKP\submission\SubmissionComment $submissionCommentPrivate */ $this->setData('commentsPrivate', $submissionCommentPrivate ? $submissionCommentPrivate->getComments() : ''); parent::initData(); @@ -118,7 +118,7 @@ public function fetch($request, $template = null, $display = false) $templateMgr->assign([ 'reviewAssignment' => $reviewAssignment, 'reviewRoundId' => $reviewAssignment->getReviewRoundId(), - 'reviewerRecommendationOptions' => ReviewAssignment::getReviewerRecommendationOptions(), + 'reviewerRecommendationOptions' => ReviewAssignment::getReviewerRecommendationOptions($context), ]); if ($reviewAssignment->getReviewFormId()) { @@ -331,7 +331,7 @@ public function saveReviewForm($reviewAssignment) // Create a comment with the review. $submissionCommentDao = DAORegistry::getDAO('SubmissionCommentDAO'); /** @var SubmissionCommentDAO $submissionCommentDao */ $submissionComments = $submissionCommentDao->getReviewerCommentsByReviewerId($reviewAssignment->getSubmissionId(), $reviewAssignment->getReviewerId(), $reviewAssignment->getId(), true); - $comment = $submissionComments->next(); + $comment = $submissionComments->next(); /** @var \PKP\submission\SubmissionComment $comment */ if (!isset($comment)) { $comment = $submissionCommentDao->newDataObject(); @@ -360,7 +360,7 @@ public function saveReviewForm($reviewAssignment) // Create a comment with the review. $submissionCommentDao = DAORegistry::getDAO('SubmissionCommentDAO'); /** @var SubmissionCommentDAO $submissionCommentDao */ $submissionCommentsPrivate = $submissionCommentDao->getReviewerCommentsByReviewerId($reviewAssignment->getSubmissionId(), $reviewAssignment->getReviewerId(), $reviewAssignment->getId(), false); - $comment = $submissionCommentsPrivate->next(); + $comment = $submissionCommentsPrivate->next(); /** @var \PKP\submission\SubmissionComment $comment */ if (!isset($comment)) { $comment = $submissionCommentDao->newDataObject(); diff --git a/classes/submission/reviewer/recommendation/ReviewerRecommendation.php b/classes/submission/reviewer/recommendation/ReviewerRecommendation.php index a56603c3751..c9b5f5ccca4 100644 --- a/classes/submission/reviewer/recommendation/ReviewerRecommendation.php +++ b/classes/submission/reviewer/recommendation/ReviewerRecommendation.php @@ -9,7 +9,6 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Casts\Attribute; -use PKP\submission\reviewer\recommendation\cast\ReviewerRecommendationValueCast; class ReviewerRecommendation extends Model { @@ -179,4 +178,9 @@ public function scopeWithContextId(Builder $query, int $contextId): Builder { return $query->where('context_id', $contextId); } + + public function scopeWithActive(Builder $query, bool $active = true): Builder + { + return $query->where('status', $active); + } } diff --git a/controllers/grid/users/reviewer/AuthorReviewerGridHandler.php b/controllers/grid/users/reviewer/AuthorReviewerGridHandler.php index ace0de69594..698fb78c49f 100644 --- a/controllers/grid/users/reviewer/AuthorReviewerGridHandler.php +++ b/controllers/grid/users/reviewer/AuthorReviewerGridHandler.php @@ -178,18 +178,18 @@ protected function loadData($request, $filter) */ public function readReview($args, $request) { + $context = $request->getContext(); $templateMgr = TemplateManager::getManager($request); $reviewAssignment = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_REVIEW_ASSIGNMENT); $templateMgr->assign([ 'submission' => $this->getSubmission(), 'reviewAssignment' => $reviewAssignment, - 'reviewerRecommendationOptions' => ReviewAssignment::getReviewerRecommendationOptions(), + 'reviewerRecommendationOptions' => ReviewAssignment::getReviewerRecommendationOptions($context), ]); if ($reviewAssignment->getReviewFormId()) { // Retrieve review form - $context = $request->getContext(); $reviewFormElementDao = DAORegistry::getDAO('ReviewFormElementDAO'); /** @var ReviewFormElementDAO $reviewFormElementDao */ // Get review form elements visible for authors $reviewFormElements = $reviewFormElementDao->getByReviewFormId($reviewAssignment->getReviewFormId(), null, true); diff --git a/pages/dashboard/PKPDashboardHandlerNext.php b/pages/dashboard/PKPDashboardHandlerNext.php index 0d0a839db7f..626b3cc91d4 100644 --- a/pages/dashboard/PKPDashboardHandlerNext.php +++ b/pages/dashboard/PKPDashboardHandlerNext.php @@ -35,9 +35,9 @@ use PKP\submissionFile\SubmissionFile; use PKP\components\forms\publication\ContributorForm; use PKP\plugins\PluginRegistry; - use PKP\notification\Notification; use PKP\log\SubmissionEmailLogEventType; +use PKP\submission\reviewer\recommendation\ReviewerRecommendation; define('SUBMISSIONS_LIST_ACTIVE', 'active'); define('SUBMISSIONS_LIST_ARCHIVE', 'archive'); @@ -169,7 +169,13 @@ public function index($args, $request) 'componentForms' => [ 'contributorForm' => $contributorForm->getConfig(), 'logResponseForm' => $logResponseForm->getConfig(), - ] + ], + 'recommendations' => ReviewerRecommendation::query() + ->withContextId($context->getId()) + ->get() + ->select(['recommendationId', 'status', 'value', 'title']) + ->values() + ->toArray(), ] ]); @@ -212,12 +218,12 @@ public function index($args, $request) 'SUBMISSION_REVIEW_METHOD_DOUBLEANONYMOUS' => ReviewAssignment::SUBMISSION_REVIEW_METHOD_DOUBLEANONYMOUS, 'SUBMISSION_REVIEW_METHOD_OPEN' => ReviewAssignment::SUBMISSION_REVIEW_METHOD_OPEN, - 'SUBMISSION_REVIEWER_RECOMMENDATION_ACCEPT' => ReviewAssignment::SUBMISSION_REVIEWER_RECOMMENDATION_ACCEPT, - 'SUBMISSION_REVIEWER_RECOMMENDATION_PENDING_REVISIONS' => ReviewAssignment::SUBMISSION_REVIEWER_RECOMMENDATION_PENDING_REVISIONS, - 'SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_HERE' => ReviewAssignment::SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_HERE, - 'SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_ELSEWHERE' => ReviewAssignment::SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_ELSEWHERE, - 'SUBMISSION_REVIEWER_RECOMMENDATION_DECLINE' => ReviewAssignment::SUBMISSION_REVIEWER_RECOMMENDATION_DECLINE, - 'SUBMISSION_REVIEWER_RECOMMENDATION_SEE_COMMENTS' => ReviewAssignment::SUBMISSION_REVIEWER_RECOMMENDATION_SEE_COMMENTS, + // 'SUBMISSION_REVIEWER_RECOMMENDATION_ACCEPT' => ReviewAssignment::SUBMISSION_REVIEWER_RECOMMENDATION_ACCEPT, + // 'SUBMISSION_REVIEWER_RECOMMENDATION_PENDING_REVISIONS' => ReviewAssignment::SUBMISSION_REVIEWER_RECOMMENDATION_PENDING_REVISIONS, + // 'SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_HERE' => ReviewAssignment::SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_HERE, + // 'SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_ELSEWHERE' => ReviewAssignment::SUBMISSION_REVIEWER_RECOMMENDATION_RESUBMIT_ELSEWHERE, + // 'SUBMISSION_REVIEWER_RECOMMENDATION_DECLINE' => ReviewAssignment::SUBMISSION_REVIEWER_RECOMMENDATION_DECLINE, + // 'SUBMISSION_REVIEWER_RECOMMENDATION_SEE_COMMENTS' => ReviewAssignment::SUBMISSION_REVIEWER_RECOMMENDATION_SEE_COMMENTS, 'DECISION_ACCEPT' => Decision::ACCEPT, 'DECISION_DECLINE' => Decision::DECLINE, diff --git a/pages/dashboard/index.php b/pages/dashboard/index.php index f591107206b..68b4361162e 100644 --- a/pages/dashboard/index.php +++ b/pages/dashboard/index.php @@ -21,9 +21,9 @@ switch ($op) { case 'index': case 'editorial': - return new PKP\pages\dashboard\DashboardHandlerNext(PKP\pages\dashboard\DashboardPage::EditorialDashboard); + return new APP\pages\dashboard\DashboardHandlerNext(PKP\pages\dashboard\DashboardPage::EditorialDashboard); case 'mySubmissions': - return new PKP\pages\dashboard\DashboardHandlerNext(PKP\pages\dashboard\DashboardPage::MySubmissions); + return new APP\pages\dashboard\DashboardHandlerNext(PKP\pages\dashboard\DashboardPage::MySubmissions); case 'reviewAssignments': - return new PKP\pages\dashboard\DashboardHandlerNext(PKP\pages\dashboard\DashboardPage::MyReviewAssignments); + return new APP\pages\dashboard\DashboardHandlerNext(PKP\pages\dashboard\DashboardPage::MyReviewAssignments); }