273 lines
11 KiB
PHP
273 lines
11 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @file classes/submission/action/EditorAction.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 EditorAction
|
|
*
|
|
* @ingroup submission_action
|
|
*
|
|
* @brief Editor actions.
|
|
*/
|
|
|
|
namespace PKP\submission\action;
|
|
|
|
use APP\facades\Repo;
|
|
use APP\notification\Notification;
|
|
use APP\notification\NotificationManager;
|
|
use APP\submission\Submission;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use PKP\context\Context;
|
|
use PKP\core\Core;
|
|
use PKP\core\PKPApplication;
|
|
use PKP\core\PKPRequest;
|
|
use PKP\core\PKPServices;
|
|
use PKP\core\PKPString;
|
|
use PKP\db\DAORegistry;
|
|
use PKP\log\event\PKPSubmissionEventLogEntry;
|
|
use PKP\mail\mailables\ReviewRequest;
|
|
use PKP\mail\mailables\ReviewRequestSubsequent;
|
|
use PKP\mail\variables\ReviewAssignmentEmailVariable;
|
|
use PKP\notification\PKPNotification;
|
|
use PKP\notification\PKPNotificationManager;
|
|
use PKP\plugins\Hook;
|
|
use PKP\security\AccessKeyManager;
|
|
use PKP\security\Validation;
|
|
use PKP\submission\PKPSubmission;
|
|
use PKP\submission\reviewAssignment\ReviewAssignment;
|
|
use PKP\submission\reviewAssignment\ReviewAssignmentDAO;
|
|
use PKP\submission\reviewRound\ReviewRound;
|
|
use PKP\submission\reviewRound\ReviewRoundDAO;
|
|
use PKP\user\User;
|
|
use Symfony\Component\Mailer\Exception\TransportException;
|
|
|
|
class EditorAction
|
|
{
|
|
/**
|
|
* Constructor.
|
|
*/
|
|
public function __construct()
|
|
{
|
|
}
|
|
|
|
//
|
|
// Actions.
|
|
//
|
|
|
|
/**
|
|
* Assigns a reviewer to a submission.
|
|
*
|
|
* @param PKPRequest $request
|
|
* @param object $submission
|
|
* @param int $reviewerId
|
|
* @param ReviewRound $reviewRound
|
|
* @param string $reviewDueDate
|
|
* @param string $responseDueDate
|
|
* @param null|mixed $reviewMethod
|
|
*/
|
|
public function addReviewer($request, $submission, $reviewerId, &$reviewRound, $reviewDueDate, $responseDueDate, $reviewMethod = null)
|
|
{
|
|
$reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); /** @var ReviewAssignmentDAO $reviewAssignmentDao */
|
|
$reviewer = Repo::user()->get($reviewerId);
|
|
|
|
// Check to see if the requested reviewer is not already
|
|
// assigned to review this submission.
|
|
|
|
$assigned = $reviewAssignmentDao->reviewerExists($reviewRound->getId(), $reviewerId);
|
|
|
|
// Only add the reviewer if he has not already
|
|
// been assigned to review this submission.
|
|
$stageId = $reviewRound->getStageId();
|
|
$round = $reviewRound->getRound();
|
|
if (!$assigned && isset($reviewer) && !Hook::call('EditorAction::addReviewer', [&$submission, $reviewerId])) {
|
|
$reviewAssignment = $reviewAssignmentDao->newDataObject();
|
|
$reviewAssignment->setSubmissionId($submission->getId());
|
|
$reviewAssignment->setReviewerId($reviewerId);
|
|
$reviewAssignment->setDateAssigned(Core::getCurrentDate());
|
|
$reviewAssignment->setStageId($stageId);
|
|
$reviewAssignment->setRound($round);
|
|
$reviewAssignment->setReviewRoundId($reviewRound->getId());
|
|
if (isset($reviewMethod)) {
|
|
$reviewAssignment->setReviewMethod($reviewMethod);
|
|
}
|
|
$reviewAssignmentDao->insertObject($reviewAssignment);
|
|
|
|
$this->setDueDates($request, $submission, $reviewAssignment, $reviewDueDate, $responseDueDate);
|
|
// Add notification
|
|
$notificationMgr = new NotificationManager();
|
|
$notificationMgr->createNotification(
|
|
$request,
|
|
$reviewerId,
|
|
PKPNotification::NOTIFICATION_TYPE_REVIEW_ASSIGNMENT,
|
|
$submission->getContextId(),
|
|
PKPApplication::ASSOC_TYPE_REVIEW_ASSIGNMENT,
|
|
$reviewAssignment->getId(),
|
|
Notification::NOTIFICATION_LEVEL_TASK
|
|
);
|
|
|
|
// Add log
|
|
$user = $request->getUser();
|
|
$eventLog = Repo::eventLog()->newDataObject([
|
|
'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
|
|
'assocId' => $submission->getId(),
|
|
'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_REVIEW_ASSIGN,
|
|
'userId' => Validation::loggedInAs() ?? $user->getId(),
|
|
'message' => 'log.review.reviewerAssigned',
|
|
'isTranslated' => false,
|
|
'dateLogged' => Core::getCurrentDate(),
|
|
'reviewAssignment' => $reviewAssignment->getId(),
|
|
'reviewerName' => $reviewer->getFullName(),
|
|
'submissionId' => $submission->getId(),
|
|
'stageId' => $stageId,
|
|
'round' => $round
|
|
]);
|
|
Repo::eventLog()->add($eventLog);
|
|
|
|
// Send mail
|
|
if (!$request->getUserVar('skipEmail')) {
|
|
$context = PKPServices::get('context')->get($submission->getData('contextId'));
|
|
$emailTemplate = Repo::emailTemplate()->getByKey($submission->getData('contextId'), $request->getUserVar('template'));
|
|
$emailBody = $request->getUserVar('personalMessage');
|
|
$emailSubject = $emailTemplate->getLocalizedData('subject');
|
|
$mailable = $this->createMail($submission, $reviewAssignment, $reviewer, $user, $emailBody, $emailSubject, $context);
|
|
|
|
try {
|
|
Mail::send($mailable);
|
|
} catch (TransportException $e) {
|
|
$notificationMgr = new PKPNotificationManager();
|
|
$notificationMgr->createTrivialNotification(
|
|
$user->getId(),
|
|
PKPNotification::NOTIFICATION_TYPE_ERROR,
|
|
['contents' => __('email.compose.error')]
|
|
);
|
|
trigger_error('Failed to send email: ' . $e->getMessage(), E_USER_WARNING);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the due date for a review assignment.
|
|
*
|
|
* @param PKPRequest $request
|
|
* @param Submission $submission
|
|
* @param ReviewAssignment $reviewAssignment
|
|
* @param string $reviewDueDate
|
|
* @param string $responseDueDate
|
|
* @param bool $logEntry
|
|
*/
|
|
public function setDueDates($request, $submission, $reviewAssignment, $reviewDueDate, $responseDueDate, $logEntry = false)
|
|
{
|
|
$context = $request->getContext();
|
|
|
|
$reviewer = Repo::user()->get($reviewAssignment->getReviewerId());
|
|
if (!isset($reviewer)) {
|
|
return false;
|
|
}
|
|
|
|
if ($reviewAssignment->getSubmissionId() == $submission->getId() && !Hook::call('EditorAction::setDueDates', [&$reviewAssignment, &$reviewer, &$reviewDueDate, &$responseDueDate])) {
|
|
// Set the review due date
|
|
$defaultNumWeeks = $context->getData('numWeeksPerReview');
|
|
$reviewAssignment->setDateDue($reviewDueDate);
|
|
|
|
// Set the response due date
|
|
$defaultNumWeeks = $context->getData('numWeeksPerResponse');
|
|
$reviewAssignment->setDateResponseDue($responseDueDate);
|
|
|
|
// update the assignment (with both the new dates)
|
|
$reviewAssignment->stampModified();
|
|
$reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); /** @var ReviewAssignmentDAO $reviewAssignmentDao */
|
|
$reviewAssignmentDao->updateObject($reviewAssignment);
|
|
|
|
// N.B. Only logging Date Due
|
|
if ($logEntry) {
|
|
// Add log
|
|
$eventLog = Repo::eventLog()->newDataObject([
|
|
'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
|
|
'assocId' => $submission->getId(),
|
|
'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_REVIEW_SET_DUE_DATE,
|
|
'userId' => Validation::loggedInAs() ?? $request->getUser()->getId(),
|
|
'message' => 'log.review.reviewDueDateSet',
|
|
'isTranslated' => false,
|
|
'dateLogged' => Core::getCurrentDate(),
|
|
'reviewAssignmentId' => $reviewAssignment->getId(),
|
|
'reviewerName' => $reviewer->getFullName(),
|
|
'reviewDueDate' => date(
|
|
PKPString::convertStrftimeFormat($context->getLocalizedDateFormatShort()),
|
|
strtotime($reviewAssignment->getDateDue())
|
|
),
|
|
'submissionId' => $submission->getId(),
|
|
'stageId' => $reviewAssignment->getStageId(),
|
|
'round' => $reviewAssignment->getRound()
|
|
]);
|
|
Repo::eventLog()->add($eventLog);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create an email representation based on data entered by the editor to the ReviewerForm
|
|
* Associated templates: REVIEW_REQUEST, REVIEW_REQUEST_SUBSEQUENT
|
|
*/
|
|
protected function createMail(
|
|
PKPSubmission $submission,
|
|
ReviewAssignment $reviewAssignment,
|
|
User $reviewer,
|
|
User $sender,
|
|
string $emailBody,
|
|
string $emailSubject,
|
|
Context $context
|
|
): ReviewRequest|ReviewRequestSubsequent {
|
|
$reviewRoundDao = DAORegistry::getDAO('ReviewRoundDAO'); /** @var ReviewRoundDAO $reviewRoundDao */
|
|
$reviewRound = $reviewRoundDao->getById($reviewAssignment->getReviewRoundId());
|
|
$mailable = $reviewRound->getRound() == 1 ?
|
|
new ReviewRequest($context, $submission, $reviewAssignment) :
|
|
new ReviewRequestSubsequent($context, $submission, $reviewAssignment);
|
|
|
|
if ($context->getData('reviewerAccessKeysEnabled')) {
|
|
$accessKeyManager = new AccessKeyManager();
|
|
$expiryDays = ($context->getData('numWeeksPerReview') + 4) * 7;
|
|
$accessKey = $accessKeyManager->createKey($context->getId(), $reviewer->getId(), $reviewAssignment->getId(), $expiryDays);
|
|
$mailable->buildViewDataUsing(function () use ($context, $reviewAssignment, $accessKey) {
|
|
return [
|
|
ReviewAssignmentEmailVariable::REVIEW_ASSIGNMENT_URL => PKPApplication::get()->getDispatcher()->url(
|
|
PKPApplication::get()->getRequest(),
|
|
PKPApplication::ROUTE_PAGE,
|
|
$context->getData('urlPath'),
|
|
'reviewer',
|
|
'submission',
|
|
null,
|
|
[
|
|
'submissionId' => $reviewAssignment->getSubmissionId(),
|
|
'reviewId' => $reviewAssignment->getId(),
|
|
'key' => $accessKey,
|
|
]
|
|
)
|
|
];
|
|
});
|
|
}
|
|
|
|
$mailable
|
|
->body($emailBody)
|
|
->subject($emailSubject)
|
|
->sender($sender)
|
|
->recipients([$reviewer]);
|
|
|
|
// Additional template variable
|
|
$mailable->addData([
|
|
'reviewerName' => $mailable->viewData['userFullName'] ?? null,
|
|
'reviewerUserName' => $mailable->viewData['username'] ?? null,
|
|
]);
|
|
|
|
return $mailable;
|
|
}
|
|
}
|
|
|
|
if (!PKP_STRICT_MODE) {
|
|
class_alias('\PKP\submission\action\EditorAction', '\EditorAction');
|
|
}
|