Open Journal Systems  3.3.0
ReviewerForm.inc.php
1 <?php
2 
17 import('lib.pkp.classes.form.Form');
18 
19 class ReviewerForm extends Form {
22 
25 
28 
31 
37  function __construct($submission, $reviewRound) {
38  parent::__construct('controllers/grid/users/reviewer/form/defaultReviewerForm.tpl');
39  $this->setSubmission($submission);
40  $this->setReviewRound($reviewRound);
41 
42  // Validation checks for this form
43  $this->addCheck(new FormValidator($this, 'responseDueDate', 'required', 'editor.review.errorAddingReviewer'));
44  $this->addCheck(new FormValidator($this, 'reviewDueDate', 'required', 'editor.review.errorAddingReviewer'));
45 
46  $this->addCheck(new FormValidatorPost($this));
47  $this->addCheck(new FormValidatorCSRF($this));
48 
49  import('lib.pkp.classes.mail.SubmissionMailTemplate');
50  }
51 
52  //
53  // Getters and Setters
54  //
59  function getSubmissionId() {
60  $submission = $this->getSubmission();
61  return $submission->getId();
62  }
63 
68  function getSubmission() {
69  return $this->_submission;
70  }
71 
76  function getReviewRound() {
77  return $this->_reviewRound;
78  }
79 
84  function setSubmission($submission) {
85  $this->_submission = $submission;
86  }
87 
92  function setReviewRound($reviewRound) {
93  $this->_reviewRound = $reviewRound;
94  }
95 
100  function setReviewerFormAction($action) {
101  $this->_reviewerFormActions[$action->getId()] = $action;
102  }
103 
108  function setUserRoles($userRoles) {
109  $this->_userRoles = $userRoles;
110  }
111 
116  function getUserRoles() {
117  return $this->_userRoles;
118  }
119 
126  }
127  //
128  // Overridden template methods
129  //
133  function initData() {
134  $request = Application::get()->getRequest();
135  $reviewerId = (int) $request->getUserVar('reviewerId');
136  $context = $request->getContext();
137  $reviewRound = $this->getReviewRound();
138  $submission = $this->getSubmission();
139 
140  // The reviewer id has been set
141  if (!empty($reviewerId)) {
142  if ($this->_isValidReviewer($context, $submission, $reviewRound, $reviewerId)) {
143  $userDao = DAORegistry::getDAO('UserDAO'); /* @var $userDao UserDAO */
144  $reviewer = $userDao->getById($reviewerId);
145  $this->setData('userNameString', sprintf('%s (%s)', $reviewer->getFullname(), $reviewer->getUsername()));
146  }
147  }
148 
149  // Get review assignment related data;
150  $reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); /* @var $reviewAssignmentDao ReviewAssignmentDAO */
151  $reviewAssignment = $reviewAssignmentDao->getReviewAssignment($reviewRound->getId(), $reviewerId, $reviewRound->getRound());
152 
153  // Get the review method (open, blind, or double-blind)
154  if (isset($reviewAssignment) && $reviewAssignment->getReviewMethod() != false) {
155  $reviewMethod = $reviewAssignment->getReviewMethod();
156  $reviewFormId = $reviewAssignment->getReviewFormId();
157  } else {
158  // Set default review method.
159  $reviewMethod = $context->getData('defaultReviewMode');
160  if (!$reviewMethod) $reviewMethod = SUBMISSION_REVIEW_METHOD_DOUBLEBLIND;
161 
162  // If there is a section/series and it has a default
163  // review form designated, use it.
164  $sectionDao = Application::getSectionDAO();
165  $section = $sectionDao->getById($submission->getSectionId(), $context->getId());
166  if ($section) $reviewFormId = $section->getReviewFormId();
167  else $reviewFormId = null;
168  }
169 
170  // Get the response/review due dates or else set defaults
171  if (isset($reviewAssignment) && $reviewAssignment->getDueDate() != null) {
172  $reviewDueDate = strtotime($reviewAssignment->getDueDate());
173  } else {
174  $numWeeks = (int) $context->getData('numWeeksPerReview');
175  if ($numWeeks<=0) $numWeeks=4;
176  $reviewDueDate = strtotime('+' . $numWeeks . ' week');
177  }
178  if (isset($reviewAssignment) && $reviewAssignment->getResponseDueDate() != null) {
179  $responseDueDate = strtotime($reviewAssignment->getResponseDueDate());
180  } else {
181  $numWeeks = (int) $context->getData('numWeeksPerResponse');
182  if ($numWeeks<=0) $numWeeks=3;
183  $responseDueDate = strtotime('+' . $numWeeks . ' week');
184  }
185 
186  // Get the currently selected reviewer selection type to show the correct tab if we're re-displaying the form
187  $selectionType = (int) $request->getUserVar('selectionType');
188  $stageId = $reviewRound->getStageId();
189 
190  $this->setData('submissionId', $this->getSubmissionId());
191  $this->setData('stageId', $stageId);
192  $this->setData('reviewMethod', $reviewMethod);
193  $this->setData('reviewFormId', $reviewFormId);
194  $this->setData('reviewRoundId', $reviewRound->getId());
195  $this->setData('reviewerId', $reviewerId);
196 
197  $context = $request->getContext();
198  $templateKey = $this->_getMailTemplateKey($context);
199  $template = new SubmissionMailTemplate($submission, $templateKey, null, null, false);
200  if ($template) {
201  $user = $request->getUser();
202  $dispatcher = $request->getDispatcher();
203  AppLocale::requireComponents(LOCALE_COMPONENT_PKP_REVIEWER); // reviewer.step1.requestBoilerplate
204  $template->assignParams(array(
205  'contextUrl' => $dispatcher->url($request, ROUTE_PAGE, $context->getPath()),
206  'editorialContactSignature' => $user->getContactSignature(),
207  'signatureFullName' => $user->getFullname(),
208  'passwordResetUrl' => $dispatcher->url($request, ROUTE_PAGE, $context->getPath(), 'login', 'lostPassword'),
209  'messageToReviewer' => __('reviewer.step1.requestBoilerplate'),
210  'abstractTermIfEnabled' => ($submission->getLocalizedAbstract() == '' ? '' : __('common.abstract')), // Deprecated; for OJS 2.x templates
211  ));
212  $template->replaceParams();
213  }
214  $this->setData('personalMessage', $template->getBody());
215  $this->setData('responseDueDate', $responseDueDate);
216  $this->setData('reviewDueDate', $reviewDueDate);
217  $this->setData('selectionType', $selectionType);
218  }
219 
223  function fetch($request, $template = null, $display = false) {
224  $context = $request->getContext();
225 
226  // Get the review method options.
227  $reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); /* @var $reviewAssignmentDao ReviewAssignmentDAO */
228  $reviewMethods = $reviewAssignmentDao->getReviewMethodsTranslationKeys();
229  $submission = $this->getSubmission();
230 
231  $templateMgr = TemplateManager::getManager($request);
232  $templateMgr->assign('reviewMethods', $reviewMethods);
233  $templateMgr->assign('reviewerActions', $this->getReviewerFormActions());
234 
235  $reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /* @var $reviewFormDao ReviewFormDAO */
236  $reviewFormsIterator = $reviewFormDao->getActiveByAssocId(Application::getContextAssocType(), $context->getId());
237  $reviewForms = array();
238  while ($reviewForm = $reviewFormsIterator->next()) {
239  $reviewForms[$reviewForm->getId()] = $reviewForm->getLocalizedTitle();
240  }
241 
242  $templateMgr->assign('reviewForms', $reviewForms);
243  $templateMgr->assign('emailVariables', array(
244  'reviewerName' => __('user.name'),
245  'responseDueDate' => __('reviewer.submission.responseDueDate'),
246  'reviewDueDate' => __('reviewer.submission.reviewDueDate'),
247  'submissionReviewUrl' => __('common.url'),
248  'reviewerUserName' => __('user.username'),
249  ));
250  // Allow the default template
251  $templateKeys[] = $this->_getMailTemplateKey($request->getContext());
252 
253  // Determine if the current user can use any custom templates defined.
254  $user = $request->getUser();
255  $roleDao = DAORegistry::getDAO('RoleDAO'); /* @var $roleDao RoleDAO */
256 
257  $userRoles = $roleDao->getByUserId($user->getId(), $submission->getData('contextId'));
258  foreach ($userRoles as $userRole) {
259  if (in_array($userRole->getId(), array(ROLE_ID_MANAGER, ROLE_ID_SUB_EDITOR, ROLE_ID_ASSISTANT))) {
260  $emailTemplatesIterator = Services::get('emailTemplate')->getMany([
261  'contextId' => $submission->getData('contextId'),
262  'isCustom' => true,
263  ]);
264  $customTemplateKeys = [];
265  foreach ($emailTemplatesIterator as $emailTemplate) {
266  $customTemplateKeys[] = $emailTemplate->getData('key');
267  };
268  $templateKeys = array_merge($templateKeys, $customTemplateKeys);
269  break;
270  }
271  }
272 
273  $templates = array();
274  foreach ($templateKeys as $templateKey) {
275  $thisTemplate = new SubmissionMailTemplate($submission, $templateKey, null, null, null, false);
276  $thisTemplate->assignParams(array());
277  $templates[$templateKey] = $thisTemplate->getSubject();
278  }
279 
280  $templateMgr->assign('templates', $templates);
281 
282  // Get the reviewer user groups for the create new reviewer/enroll existing user tabs
283  $context = $request->getContext();
284  $userGroupDao = DAORegistry::getDAO('UserGroupDAO'); /* @var $userGroupDao UserGroupDAO */
285  $reviewRound = $this->getReviewRound();
286  $reviewerUserGroups = $userGroupDao->getUserGroupsByStage($context->getId(), $reviewRound->getStageId(), ROLE_ID_REVIEWER);
287  $userGroups = array();
288  while($userGroup = $reviewerUserGroups->next()) {
289  $userGroups[$userGroup->getId()] = $userGroup->getLocalizedName();
290  }
291 
292  $this->setData('userGroups', $userGroups);
293  return parent::fetch($request, $template, $display);
294  }
295 
300  function readInputData() {
301  $this->readUserVars(array(
302  'selectionType',
303  'submissionId',
304  'template',
305  'personalMessage',
306  'responseDueDate',
307  'reviewDueDate',
308  'reviewMethod',
309  'skipEmail',
310  'keywords',
311  'interests',
312  'reviewRoundId',
313  'stageId',
314  'selectedFiles',
315  'reviewFormId',
316  ));
317  }
318 
322  function execute(...$functionParams) {
323  parent::execute(...$functionParams);
324 
325  $submission = $this->getSubmission();
326  $request = Application::get()->getRequest();
327  $context = $request->getContext();
328 
329  $currentReviewRound = $this->getReviewRound();
330  $stageId = $currentReviewRound->getStageId();
331  $reviewDueDate = $this->getData('reviewDueDate');
332  $responseDueDate = $this->getData('responseDueDate');
333 
334  // Get reviewer id and validate it.
335  $reviewerId = (int) $this->getData('reviewerId');
336 
337  if (!$this->_isValidReviewer($context, $submission, $currentReviewRound, $reviewerId)) {
338  fatalError('Invalid reviewer id.');
339  }
340 
341  $reviewMethod = (int) $this->getData('reviewMethod');
342 
343  import('lib.pkp.classes.submission.action.EditorAction');
344  $editorAction = new EditorAction();
345  $editorAction->addReviewer($request, $submission, $reviewerId, $currentReviewRound, $reviewDueDate, $responseDueDate, $reviewMethod);
346 
347  // Get the reviewAssignment object now that it has been added.
348  $reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); /* @var $reviewAssignmentDao ReviewAssignmentDAO */
349  $reviewAssignment = $reviewAssignmentDao->getReviewAssignment($currentReviewRound->getId(), $reviewerId, $currentReviewRound->getRound(), $stageId);
350  $reviewAssignment->setDateNotified(Core::getCurrentDate());
351  $reviewAssignment->stampModified();
352 
353  // Ensure that the review form ID is valid, if specified
354  $reviewFormId = (int) $this->getData('reviewFormId');
355  $reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /* @var $reviewFormDao ReviewFormDAO */
356  $reviewForm = $reviewFormDao->getById($reviewFormId, Application::getContextAssocType(), $context->getId());
357  $reviewAssignment->setReviewFormId($reviewForm?$reviewFormId:null);
358 
359  $reviewAssignmentDao->updateObject($reviewAssignment);
360 
361  // Grant access for this review to all selected files.
362  $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO'); /* @var $submissionFileDao SubmissionFileDAO */
363  import('lib.pkp.classes.submission.SubmissionFile'); // File constants
364  $submissionFiles = $submissionFileDao->getLatestRevisionsByReviewRound($currentReviewRound, SUBMISSION_FILE_REVIEW_FILE);
365  $selectedFiles = (array) $this->getData('selectedFiles');
366  $reviewFilesDao = DAORegistry::getDAO('ReviewFilesDAO'); /* @var $reviewFilesDao ReviewFilesDAO */
367  foreach ($submissionFiles as $submissionFile) {
368  if (in_array($submissionFile->getFileId(), $selectedFiles)) {
369  $reviewFilesDao->grant($reviewAssignment->getId(), $submissionFile->getFileId());
370  }
371  }
372 
373  // Notify the reviewer via email.
374  import('lib.pkp.classes.mail.SubmissionMailTemplate');
375  $templateKey = $this->getData('template');
376  $mail = new SubmissionMailTemplate($submission, $templateKey, null, null, null, false);
377  $userDao = DAORegistry::getDAO('UserDAO'); /* @var $userDao UserDAO */
378  $reviewer = $userDao->getById($reviewerId);
379 
380  if ($mail->isEnabled() && !$this->getData('skipEmail')) {
381  $user = $request->getUser();
382  $mail->addRecipient($reviewer->getEmail(), $reviewer->getFullName());
383  $mail->setBody($this->getData('personalMessage'));
384  $dispatcher = $request->getDispatcher();
385 
386  // Set the additional arguments for the one click url
387  $reviewUrlArgs = array('submissionId' => $this->getSubmissionId());
388  if ($context->getData('reviewerAccessKeysEnabled')) {
389  import('lib.pkp.classes.security.AccessKeyManager');
390  $accessKeyManager = new AccessKeyManager();
391  $expiryDays = ($context->getData('numWeeksPerReview') + 4) * 7;
392  $accessKey = $accessKeyManager->createKey($context->getId(), $reviewerId, $reviewAssignment->getId(), $expiryDays);
393  $reviewUrlArgs = array_merge($reviewUrlArgs, array('reviewId' => $reviewAssignment->getId(), 'key' => $accessKey));
394  }
395 
396  // Assign the remaining parameters
397  $mail->assignParams(array(
398  'reviewerName' => $reviewer->getFullName(),
399  'responseDueDate' => $responseDueDate,
400  'reviewDueDate' => $reviewDueDate,
401  'reviewerUserName' => $reviewer->getUsername(),
402  'submissionReviewUrl' => $dispatcher->url($request, ROUTE_PAGE, null, 'reviewer', 'submission', null, $reviewUrlArgs)
403  ));
404  if (!$mail->send($request)) {
405  import('classes.notification.NotificationManager');
406  $notificationMgr = new NotificationManager();
407  $notificationMgr->createTrivialNotification($request->getUser()->getId(), NOTIFICATION_TYPE_ERROR, array('contents' => __('email.compose.error')));
408  }
409  }
410 
411  // Insert a trivial notification to indicate the reviewer was added successfully.
412  $currentUser = $request->getUser();
413  $notificationMgr = new NotificationManager();
414  $msgKey = $this->getData('skipEmail') ? 'notification.addedReviewerNoEmail' : 'notification.addedReviewer';
415  $notificationMgr->createTrivialNotification(
416  $currentUser->getId(),
417  NOTIFICATION_TYPE_SUCCESS,
418  array('contents' => __($msgKey, array('reviewerName' => $reviewer->getFullName())))
419  );
420 
421  return $reviewAssignment;
422  }
423 
424 
425  //
426  // Protected methods.
427  //
433  function getAdvancedSearchAction($request) {
434  $reviewRound = $this->getReviewRound();
435  return new LinkAction(
436  'addReviewer',
437  new AjaxAction($request->url(null, null, 'reloadReviewerForm', null, array(
438  'submissionId' => $this->getSubmissionId(),
439  'stageId' => $reviewRound->getStageId(),
440  'reviewRoundId' => $reviewRound->getId(),
441  'selectionType' => REVIEWER_SELECT_ADVANCED_SEARCH,
442  ))),
443  __('editor.submission.backToSearch'),
444  'return'
445  );
446  }
447 
448 
449  //
450  // Private helper methods
451  //
460  function _isValidReviewer($context, $submission, $reviewRound, $reviewerId) {
461  $userDao = DAORegistry::getDAO('UserDAO'); /* @var $userDao UserDAO */
462  $reviewerFactory = $userDao->getReviewersNotAssignedToSubmission($context->getId(), $submission->getId(), $reviewRound);
463  $reviewersArray = $reviewerFactory->toAssociativeArray();
464  if (array_key_exists($reviewerId, $reviewersArray)) {
465  return true;
466  } else {
467  return false;
468  }
469  }
470 
478  function _getMailTemplateKey($context) {
479  $reviewerAccessKeysEnabled = $context->getData('reviewerAccessKeysEnabled');
480  $round = $this->getReviewRound()->getRound();
481 
482  switch(1) {
483  case $reviewerAccessKeysEnabled && $round == 1: return 'REVIEW_REQUEST_ONECLICK';
484  case $reviewerAccessKeysEnabled: return 'REVIEW_REQUEST_ONECLICK_SUBSEQUENT';
485  case $round == 1: return 'REVIEW_REQUEST';
486  default: return 'REVIEW_REQUEST_SUBSEQUENT';
487  }
488  }
489 }
490 
491 
ReviewerForm\__construct
__construct($submission, $reviewRound)
Definition: ReviewerForm.inc.php:37
ReviewerForm\setUserRoles
setUserRoles($userRoles)
Definition: ReviewerForm.inc.php:108
ReviewerForm\$_userRoles
$_userRoles
Definition: ReviewerForm.inc.php:30
ReviewerForm\initData
initData()
Definition: ReviewerForm.inc.php:133
AppLocale\requireComponents
static requireComponents()
Definition: env1/MockAppLocale.inc.php:56
ReviewerForm\getSubmissionId
getSubmissionId()
Definition: ReviewerForm.inc.php:59
ReviewerForm\_getMailTemplateKey
_getMailTemplateKey($context)
Definition: ReviewerForm.inc.php:478
DAORegistry\getDAO
static & getDAO($name, $dbconn=null)
Definition: DAORegistry.inc.php:57
AccessKeyManager
Class defining operations for AccessKey management.
Definition: AccessKeyManager.inc.php:18
SubmissionMailTemplate
Subclass of MailTemplate for sending emails related to submissions.
Definition: SubmissionMailTemplate.inc.php:20
Form\setData
setData($key, $value=null)
Definition: Form.inc.php:229
ReviewerForm\execute
execute(... $functionParams)
Definition: ReviewerForm.inc.php:322
Form\readUserVars
readUserVars($vars)
Definition: Form.inc.php:378
Form\getData
getData($key)
Definition: Form.inc.php:220
FormValidatorPost
Form validation check to make sure the form is POSTed.
Definition: FormValidatorPost.inc.php:18
ReviewerForm\setSubmission
setSubmission($submission)
Definition: ReviewerForm.inc.php:84
AjaxAction
Class defining an AJAX action.
Definition: AjaxAction.inc.php:21
ReviewerForm\setReviewerFormAction
setReviewerFormAction($action)
Definition: ReviewerForm.inc.php:100
ReviewerForm\getAdvancedSearchAction
getAdvancedSearchAction($request)
Definition: ReviewerForm.inc.php:433
ReviewerForm\$_submission
$_submission
Definition: ReviewerForm.inc.php:21
ReviewerForm\_isValidReviewer
_isValidReviewer($context, $submission, $reviewRound, $reviewerId)
Definition: ReviewerForm.inc.php:460
Application\getContextAssocType
static getContextAssocType()
Definition: Application.inc.php:199
ReviewerForm
Base Form for adding a reviewer to a submission. N.B. Requires a subclass to implement the "reviewerI...
Definition: ReviewerForm.inc.php:19
LinkAction
Base class defining an action that can be performed by the user in the user interface.
Definition: LinkAction.inc.php:22
ReviewerForm\$_reviewRound
$_reviewRound
Definition: ReviewerForm.inc.php:24
PKPTemplateManager\getManager
static & getManager($request=null)
Definition: PKPTemplateManager.inc.php:1239
ReviewerForm\fetch
fetch($request, $template=null, $display=false)
Definition: ReviewerForm.inc.php:223
FormValidator
Class to represent a form validation check.
Definition: FormValidator.inc.php:23
ReviewerForm\$_reviewerFormActions
$_reviewerFormActions
Definition: ReviewerForm.inc.php:27
ReviewerForm\getReviewRound
getReviewRound()
Definition: ReviewerForm.inc.php:76
Core\getCurrentDate
static getCurrentDate($ts=null)
Definition: Core.inc.php:63
Form\addCheck
addCheck($formValidator)
Definition: Form.inc.php:395
NotificationManager
Definition: NotificationManager.inc.php:19
FormValidatorCSRF
Form validation check to make sure the CSRF token is correct.
Definition: FormValidatorCSRF.inc.php:18
Form
Class defining basic operations for handling HTML forms.
Definition: Form.inc.php:47
EditorAction
Editor actions.
Definition: EditorAction.inc.php:19
PKPApplication\get
static get()
Definition: PKPApplication.inc.php:235
ReviewerForm\getUserRoles
getUserRoles()
Definition: ReviewerForm.inc.php:116
fatalError
if(!function_exists('import')) fatalError($reason)
Definition: functions.inc.php:32
ReviewerForm\readInputData
readInputData()
Definition: ReviewerForm.inc.php:300
Application\getSectionDAO
static getSectionDAO()
Definition: Application.inc.php:154
ReviewerForm\getReviewerFormActions
getReviewerFormActions()
Definition: ReviewerForm.inc.php:124
ReviewerForm\setReviewRound
setReviewRound($reviewRound)
Definition: ReviewerForm.inc.php:92
PKPServices\get
static get($service)
Definition: PKPServices.inc.php:49
ReviewerForm\getSubmission
getSubmission()
Definition: ReviewerForm.inc.php:68