Files
OSJ/lib/pkp/classes/submission/reviewer/form/PKPReviewerReviewStep3Form.php
CHIEFSOFT\ameye df3a033196 first commit
2024-06-08 17:09:23 -04:00

407 lines
19 KiB
PHP

<?php
/**
* @file classes/submission/reviewer/form/PKPReviewerReviewStep3Form.php
*
* Copyright (c) 2014-2021 Simon Fraser University
* Copyright (c) 2003-2021 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class PKPReviewerReviewStep3Form
*
* @ingroup submission_reviewer_form
*
* @brief Form for Step 3 of a review.
*/
namespace PKP\submission\reviewer\form;
use APP\core\Application;
use APP\facades\Repo;
use APP\notification\NotificationManager;
use APP\submission\Submission;
use APP\template\TemplateManager;
use Illuminate\Support\Facades\Mail;
use PKP\controllers\confirmationModal\linkAction\ViewReviewGuidelinesLinkAction;
use PKP\core\Core;
use PKP\core\PKPApplication;
use PKP\core\PKPRequest;
use PKP\db\DAORegistry;
use PKP\log\event\PKPSubmissionEventLogEntry;
use PKP\mail\mailables\ReviewCompleteNotifyEditors;
use PKP\notification\NotificationDAO;
use PKP\notification\NotificationSubscriptionSettingsDAO;
use PKP\notification\PKPNotification;
use PKP\reviewForm\ReviewFormDAO;
use PKP\reviewForm\ReviewFormElement;
use PKP\reviewForm\ReviewFormElementDAO;
use PKP\reviewForm\ReviewFormResponse;
use PKP\reviewForm\ReviewFormResponseDAO;
use PKP\security\Role;
use PKP\security\Validation;
use PKP\stageAssignment\StageAssignmentDAO;
use PKP\submission\reviewAssignment\ReviewAssignment;
use PKP\submission\reviewAssignment\ReviewAssignmentDAO;
use PKP\submission\SubmissionComment;
use PKP\submission\SubmissionCommentDAO;
class PKPReviewerReviewStep3Form extends ReviewerReviewForm
{
/**
* Constructor.
*/
public function __construct(PKPRequest $request, Submission $reviewSubmission, ReviewAssignment $reviewAssignment)
{
parent::__construct($request, $reviewSubmission, $reviewAssignment, 3);
// Validation checks for this form
$reviewFormElementDao = DAORegistry::getDAO('ReviewFormElementDAO'); /** @var ReviewFormElementDAO $reviewFormElementDao */
$requiredReviewFormElementIds = $reviewFormElementDao->getRequiredReviewFormElementIds($reviewAssignment->getReviewFormId());
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'reviewFormResponses', 'required', 'reviewer.submission.reviewFormResponse.form.responseRequired', function ($reviewFormResponses) use ($requiredReviewFormElementIds) {
foreach ($requiredReviewFormElementIds as $requiredReviewFormElementId) {
if (!isset($reviewFormResponses[$requiredReviewFormElementId]) || $reviewFormResponses[$requiredReviewFormElementId] == '') {
return false;
}
}
return true;
}));
$this->addCheck(new \PKP\form\validation\FormValidatorPost($this));
$this->addCheck(new \PKP\form\validation\FormValidatorCSRF($this));
}
/**
* @copydoc ReviewerReviewForm::initData
*/
public function initData()
{
$reviewAssignment = $this->getReviewAssignment();
// Retrieve most recent reviewer comments, one private, one public.
$submissionCommentDao = DAORegistry::getDAO('SubmissionCommentDAO'); /** @var SubmissionCommentDAO $submissionCommentDao */
$submissionComments = $submissionCommentDao->getReviewerCommentsByReviewerId($reviewAssignment->getSubmissionId(), $reviewAssignment->getReviewerId(), $reviewAssignment->getId(), true);
$submissionComment = $submissionComments->next();
$this->setData('comments', $submissionComment ? $submissionComment->getComments() : '');
$submissionCommentsPrivate = $submissionCommentDao->getReviewerCommentsByReviewerId($reviewAssignment->getSubmissionId(), $reviewAssignment->getReviewerId(), $reviewAssignment->getId(), false);
$submissionCommentPrivate = $submissionCommentsPrivate->next();
$this->setData('commentsPrivate', $submissionCommentPrivate ? $submissionCommentPrivate->getComments() : '');
parent::initData();
}
//
// Implement protected template methods from Form
//
/**
* @see Form::readInputData()
*/
public function readInputData()
{
$this->readUserVars(
['reviewFormResponses', 'comments', 'recommendation', 'commentsPrivate']
);
}
/**
* @copydoc ReviewerReviewForm::fetch()
*
* @param null|mixed $template
*/
public function fetch($request, $template = null, $display = false)
{
$templateMgr = TemplateManager::getManager($request);
$reviewAssignment = $this->getReviewAssignment();
// Assign the objects and data to the template.
$context = $this->request->getContext();
$templateMgr->assign([
'reviewAssignment' => $reviewAssignment,
'reviewRoundId' => $reviewAssignment->getReviewRoundId(),
'reviewerRecommendationOptions' => ReviewAssignment::getReviewerRecommendationOptions(),
]);
if ($reviewAssignment->getReviewFormId()) {
// Get the review form components
$reviewFormElementDao = DAORegistry::getDAO('ReviewFormElementDAO'); /** @var ReviewFormElementDAO $reviewFormElementDao */
$reviewFormResponseDao = DAORegistry::getDAO('ReviewFormResponseDAO'); /** @var ReviewFormResponseDAO $reviewFormResponseDao */
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
$templateMgr->assign([
'reviewForm' => $reviewFormDao->getById($reviewAssignment->getReviewFormId(), Application::getContextAssocType(), $context->getId()),
'reviewFormElements' => $reviewFormElementDao->getByReviewFormId($reviewAssignment->getReviewFormId()),
'reviewFormResponses' => $reviewFormResponseDao->getReviewReviewFormResponseValues($reviewAssignment->getId()),
'disabled' => isset($reviewAssignment) && $reviewAssignment->getDateCompleted() != null,
]);
}
//
// Assign the link actions
//
$viewReviewGuidelinesAction = new ViewReviewGuidelinesLinkAction($request, $reviewAssignment->getStageId());
if ($viewReviewGuidelinesAction->getGuidelines()) {
$templateMgr->assign('viewGuidelinesAction', $viewReviewGuidelinesAction);
}
return parent::fetch($request, $template, $display);
}
/**
* @see Form::execute()
*/
public function execute(...$functionParams)
{
$reviewAssignment = $this->getReviewAssignment();
$notificationMgr = new NotificationManager();
// Save the answers to the review form
$this->saveReviewForm($reviewAssignment);
// Send notification
$submission = Repo::submission()->get($reviewAssignment->getSubmissionId());
$context = Application::getContextDAO()->getById($submission->getData('contextId'));
// Set review to next step.
$this->updateReviewStepAndSaveSubmission($this->getReviewAssignment());
// Mark the review assignment as completed.
$reviewAssignment->setDateCompleted(Core::getCurrentDate());
$reviewAssignment->stampModified();
// assign the recommendation to the review assignment, if there was one.
$reviewAssignment->setRecommendation((int) $this->getData('recommendation'));
// Persist the updated review assignment.
$reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); /** @var ReviewAssignmentDAO $reviewAssignmentDao */
$reviewAssignmentDao->updateObject($reviewAssignment);
$stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); /** @var StageAssignmentDAO $stageAssignmentDao */
$stageAssignments = $stageAssignmentDao->getBySubmissionAndStageId($submission->getId(), $submission->getStageId());
$receivedList = []; // Avoid sending twice to the same user.
/** @var NotificationSubscriptionSettingsDAO $notificationSubscriptionSettingsDao */
$notificationSubscriptionSettingsDao = DAORegistry::getDAO('NotificationSubscriptionSettingsDAO');
while ($stageAssignment = $stageAssignments->next()) {
$userId = $stageAssignment->getUserId();
$userGroup = Repo::userGroup()->get($stageAssignment->getUserGroupId());
// Never send reviewer comment notification to users other than managers and editors.
if (!in_array($userGroup->getRoleId(), [Role::ROLE_ID_MANAGER, Role::ROLE_ID_SUB_EDITOR]) || in_array($userId, $receivedList)) {
continue;
}
// Notify editors
$notification = $notificationMgr->createNotification(
Application::get()->getRequest(),
$userId,
PKPNotification::NOTIFICATION_TYPE_REVIEWER_COMMENT,
$submission->getContextId(),
PKPApplication::ASSOC_TYPE_REVIEW_ASSIGNMENT,
$reviewAssignment->getId()
);
// Check if user is subscribed to this type of notification emails
if (!$notification || in_array(
PKPNotification::NOTIFICATION_TYPE_REVIEWER_COMMENT,
$notificationSubscriptionSettingsDao->getNotificationSubscriptionSettings(
NotificationSubscriptionSettingsDAO::BLOCKED_EMAIL_NOTIFICATION_KEY,
$userId,
(int) $context->getId()
)
)
) {
continue;
}
$mailable = new ReviewCompleteNotifyEditors($context, $submission, $reviewAssignment);
$template = Repo::emailTemplate()->getByKey($context->getId(), ReviewCompleteNotifyEditors::getEmailTemplateKey());
// The template may not exist, see pkp/pkp-lib#9109
if (!$template) {
$template = Repo::emailTemplate()->getByKey($context->getId(), 'NOTIFICATION');
$request = Application::get()->getRequest();
$mailable->addData([
'notificationContents' => $notificationMgr->getNotificationContents($request, $notification),
'notificationUrl' => $notificationMgr->getNotificationUrl($request, $notification),
]);
}
$user = Repo::user()->get($userId);
$mailable
->from($context->getData('contactEmail'), $context->getData('contactName'))
->recipients([$user])
->subject($template->getLocalizedData('subject'))
->body($template->getLocalizedData('body'))
->allowUnsubscribe($notification);
Mail::send($mailable);
$receivedList[] = $userId;
}
// Remove the task
$notificationDao = DAORegistry::getDAO('NotificationDAO'); /** @var NotificationDAO $notificationDao */
$notificationDao->deleteByAssoc(
PKPApplication::ASSOC_TYPE_REVIEW_ASSIGNMENT,
$reviewAssignment->getId(),
$reviewAssignment->getReviewerId(),
PKPNotification::NOTIFICATION_TYPE_REVIEW_ASSIGNMENT
);
// Add log
$reviewer = Repo::user()->get($reviewAssignment->getReviewerId(), true);
$eventLog = Repo::eventLog()->newDataObject([
'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
'assocId' => $submission->getId(),
'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_REVIEW_READY,
'userId' => Validation::loggedInAs() ?? Application::get()->getRequest()->getUser()->getId(),
'message' => 'log.review.reviewReady',
'isTranslated' => false,
'dateLogged' => Core::getCurrentDate(),
'reviewAssignmentId' => $reviewAssignment->getId(),
'reviewerName' => $reviewer->getFullName(),
'submissionId' => $reviewAssignment->getSubmissionId(),
'round' => $reviewAssignment->getRound()
]);
Repo::eventLog()->add($eventLog);
parent::execute(...$functionParams);
}
/**
* Save the given answers for later
*/
public function saveForLater()
{
$reviewAssignment = $this->getReviewAssignment();
$notificationMgr = new NotificationManager();
// Save the answers to the review form
$this->saveReviewForm($reviewAssignment);
// Mark the review assignment as modified.
$reviewAssignment->stampModified();
// save the recommendation to the review assignment
$reviewAssignment->setRecommendation((int) $this->getData('recommendation'));
// Persist the updated review assignment.
$reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); /** @var ReviewAssignmentDAO $reviewAssignmentDao */
$reviewAssignmentDao->updateObject($reviewAssignment);
return true;
}
/**
* Save the given answers to the review form
*
* @param ReviewAssignment $reviewAssignment
*/
public function saveReviewForm($reviewAssignment)
{
if ($reviewAssignment->getReviewFormId()) {
$reviewFormResponseDao = DAORegistry::getDAO('ReviewFormResponseDAO'); /** @var ReviewFormResponseDAO $reviewFormResponseDao */
$reviewFormResponses = $this->getData('reviewFormResponses');
if (is_array($reviewFormResponses)) {
foreach ($reviewFormResponses as $reviewFormElementId => $reviewFormResponseValue) {
$reviewFormResponse = $reviewFormResponseDao->getReviewFormResponse($reviewAssignment->getId(), $reviewFormElementId);
if (!isset($reviewFormResponse)) {
$reviewFormResponse = new ReviewFormResponse();
}
$reviewFormElementDao = DAORegistry::getDAO('ReviewFormElementDAO'); /** @var ReviewFormElementDAO $reviewFormElementDao */
$reviewFormElement = $reviewFormElementDao->getById($reviewFormElementId);
$elementType = $reviewFormElement->getElementType();
switch ($elementType) {
case ReviewFormElement::REVIEW_FORM_ELEMENT_TYPE_SMALL_TEXT_FIELD:
case ReviewFormElement::REVIEW_FORM_ELEMENT_TYPE_TEXT_FIELD:
case ReviewFormElement::REVIEW_FORM_ELEMENT_TYPE_TEXTAREA:
$reviewFormResponse->setResponseType('string');
$reviewFormResponse->setValue($reviewFormResponseValue);
break;
case ReviewFormElement::REVIEW_FORM_ELEMENT_TYPE_RADIO_BUTTONS:
case ReviewFormElement::REVIEW_FORM_ELEMENT_TYPE_DROP_DOWN_BOX:
$reviewFormResponse->setResponseType('int');
$reviewFormResponse->setValue($reviewFormResponseValue);
break;
case ReviewFormElement::REVIEW_FORM_ELEMENT_TYPE_CHECKBOXES:
$reviewFormResponse->setResponseType('object');
$reviewFormResponse->setValue($reviewFormResponseValue);
break;
}
if ($reviewFormResponse->getReviewFormElementId() != null && $reviewFormResponse->getReviewId() != null) {
$reviewFormResponseDao->updateObject($reviewFormResponse);
} else {
$reviewFormResponse->setReviewFormElementId($reviewFormElementId);
$reviewFormResponse->setReviewId($reviewAssignment->getId());
$reviewFormResponseDao->insertObject($reviewFormResponse);
}
}
}
} else {
// No review form configured. Use the default form.
if (strlen($comments = $this->getData('comments')) > 0) {
// 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();
if (!isset($comment)) {
$comment = $submissionCommentDao->newDataObject();
}
$comment->setCommentType(SubmissionComment::COMMENT_TYPE_PEER_REVIEW);
$comment->setRoleId(Role::ROLE_ID_REVIEWER);
$comment->setAssocId($reviewAssignment->getId());
$comment->setSubmissionId($reviewAssignment->getSubmissionId());
$comment->setAuthorId($reviewAssignment->getReviewerId());
$comment->setComments($comments);
$comment->setCommentTitle('');
$comment->setViewable(true);
$comment->setDatePosted(Core::getCurrentDate());
// Save or update
if ($comment->getId() != null) {
$submissionCommentDao->updateObject($comment);
} else {
$submissionCommentDao->insertObject($comment);
}
}
unset($comment);
if (strlen($commentsPrivate = $this->getData('commentsPrivate')) > 0) {
// 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();
if (!isset($comment)) {
$comment = $submissionCommentDao->newDataObject();
}
$comment->setCommentType(SubmissionComment::COMMENT_TYPE_PEER_REVIEW);
$comment->setRoleId(Role::ROLE_ID_REVIEWER);
$comment->setAssocId($reviewAssignment->getId());
$comment->setSubmissionId($reviewAssignment->getSubmissionId());
$comment->setAuthorId($reviewAssignment->getReviewerId());
$comment->setComments($commentsPrivate);
$comment->setCommentTitle('');
$comment->setViewable(false);
$comment->setDatePosted(Core::getCurrentDate());
// Save or update
if ($comment->getId() != null) {
$submissionCommentDao->updateObject($comment);
} else {
$submissionCommentDao->insertObject($comment);
}
}
unset($comment);
}
}
}
if (!PKP_STRICT_MODE) {
class_alias('\PKP\submission\reviewer\form\PKPReviewerReviewStep3Form', '\PKPReviewerReviewStep3Form');
}