/** * @copydoc Form::execute() */ function execute($args, $request) { // Retrieve the submission. $submission = $this->getSubmission(); // Get this form decision actions labels. $actionLabels = EditorDecisionActionsManager::getActionLabels($this->_getDecisions()); // Record the decision. $reviewRound = $this->getReviewRound(); $decision = $this->getDecision(); $stageId = $this->getStageId(); import('lib.pkp.classes.submission.action.EditorAction'); $editorAction = new EditorAction(); $editorAction->recordDecision($request, $submission, $decision, $actionLabels, $reviewRound, $stageId); // Identify email key and status of round. switch ($decision) { case SUBMISSION_EDITOR_DECISION_PENDING_REVISIONS: $emailKey = 'EDITOR_DECISION_REVISIONS'; $status = REVIEW_ROUND_STATUS_REVISIONS_REQUESTED; break; case SUBMISSION_EDITOR_DECISION_RESUBMIT: $emailKey = 'EDITOR_DECISION_RESUBMIT'; $status = REVIEW_ROUND_STATUS_RESUBMITTED; break; case SUBMISSION_EDITOR_DECISION_DECLINE: $emailKey = 'SUBMISSION_UNSUITABLE'; $status = REVIEW_ROUND_STATUS_DECLINED; break; default: fatalError('Unsupported decision!'); } $this->_updateReviewRoundStatus($submission, $status, $reviewRound); // Send email to the author. $this->_sendReviewMailToAuthor($submission, $emailKey, $request); }
/** * Fetch information for the author on the specified review round * @param $args array * @param $request Request * @return JSONMessage JSON object */ function fetchReviewRoundInfo($args, $request) { $this->setupTemplate($request); $templateMgr = TemplateManager::getManager($request); $stageId = $this->getAuthorizedContextObject(ASSOC_TYPE_WORKFLOW_STAGE); if ($stageId !== WORKFLOW_STAGE_ID_INTERNAL_REVIEW && $stageId !== WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) { fatalError('Invalid Stage Id'); } $templateMgr->assign('stageId', $stageId); $reviewRound = $this->getAuthorizedContextObject(ASSOC_TYPE_REVIEW_ROUND); $templateMgr->assign('reviewRoundId', $reviewRound->getId()); $submission = $this->getAuthorizedContextObject(ASSOC_TYPE_SUBMISSION); $templateMgr->assign('submission', $submission); // Review round request notification options. $notificationRequestOptions = array(NOTIFICATION_LEVEL_NORMAL => array(NOTIFICATION_TYPE_REVIEW_ROUND_STATUS => array(ASSOC_TYPE_REVIEW_ROUND, $reviewRound->getId())), NOTIFICATION_LEVEL_TRIVIAL => array()); $templateMgr->assign('reviewRoundNotificationRequestOptions', $notificationRequestOptions); // Editor has taken an action and sent an email; Display the email import('classes.workflow.EditorDecisionActionsManager'); if (EditorDecisionActionsManager::getEditorTakenActionInReviewRound($reviewRound)) { $submissionEmailLogDao = DAORegistry::getDAO('SubmissionEmailLogDAO'); $user = $request->getUser(); $submissionEmailFactory = $submissionEmailLogDao->getByEventType($submission->getId(), SUBMISSION_EMAIL_EDITOR_NOTIFY_AUTHOR, $user->getId()); $templateMgr->assign('submissionEmails', $submissionEmailFactory); $templateMgr->assign('showReviewAttachments', true); } return $templateMgr->fetchJson('authorDashboard/reviewRoundInfo.tpl'); }
/** * @see AuthorizationPolicy::effect() */ function effect() { $request = $this->getRequest(); $reviewRoundDao = DAORegistry::getDAO('ReviewRoundDAO'); /* @var $reviewRoundDao ReviewRoundDAO */ // Get the submission file. $submissionFile = $this->getSubmissionFile($request); if (!is_a($submissionFile, 'SubmissionFile')) { return AUTHORIZATION_DENY; } // Make sure the file belongs to the submission in request. $submission = $this->getAuthorizedContextObject(ASSOC_TYPE_SUBMISSION); if (!is_a($submission, 'Submission')) { return AUTHORIZATION_DENY; } if ($submission->getId() != $submissionFile->getSubmissionId()) { return AUTHORIZATION_DENY; } // Make sure the file is part of a review round // with a requested revision decision. $reviewRound = $reviewRoundDao->getBySubmissionFileId($submissionFile->getFileId()); if (!is_a($reviewRound, 'ReviewRound')) { return AUTHORIZATION_DENY; } import('classes.workflow.EditorDecisionActionsManager'); if (!EditorDecisionActionsManager::getEditorTakenActionInReviewRound($reviewRound, array(SUBMISSION_EDITOR_DECISION_PENDING_REVISIONS))) { return AUTHORIZATION_DENY; } // Make sure that it's in the review stage. $reviewRound = $reviewRoundDao->getBySubmissionFileId($submissionFile->getFileId()); if (!is_a($reviewRound, 'ReviewRound')) { return AUTHORIZATION_DENY; } // Make sure review round stage is the same of the current stage in request. $stageId = $this->getAuthorizedContextObject(ASSOC_TYPE_WORKFLOW_STAGE); if ($reviewRound->getStageId() != $stageId) { return AUTHORIZATION_DENY; } $reviewRoundDao = DAORegistry::getDAO('ReviewRoundDAO'); /* @var $reviewRoundDao ReviewRoundDAO */ // Make sure that the last review round editor decision is request revisions. $editDecisionDao = DAORegistry::getDAO('EditDecisionDAO'); /* @var $editDecisionDao EditDecisionDAO */ $reviewRoundDecisions = $editDecisionDao->getEditorDecisions($submissionFile->getSubmissionId(), $reviewRound->getStageId(), $reviewRound->getRound()); if (empty($reviewRoundDecisions)) { return AUTHORIZATION_DENY; } $lastEditorDecision = array_pop($reviewRoundDecisions); if ($lastEditorDecision['decision'] != SUBMISSION_EDITOR_DECISION_PENDING_REVISIONS) { return AUTHORIZATION_DENY; } // Made it through -- permit access. return AUTHORIZATION_PERMIT; // Made it through -- permit access. return AUTHORIZATION_PERMIT; }
/** * @copydoc Form::execute() */ function execute($args, $request) { // Retrieve the submission. $submission = $this->getSubmission(); // Record the decision. import('classes.workflow.EditorDecisionActionsManager'); $actionLabels = EditorDecisionActionsManager::getActionLabels(array($this->_decision)); import('lib.pkp.classes.submission.action.EditorAction'); $editorAction = new EditorAction(); $editorAction->recordDecision($request, $submission, $this->_decision, $actionLabels); // Move to the internal review stage. $editorAction->incrementWorkflowStage($submission, WORKFLOW_STAGE_ID_EXTERNAL_REVIEW, $request); // Create an initial internal review round. $this->_initiateReviewRound($submission, WORKFLOW_STAGE_ID_EXTERNAL_REVIEW, $request, REVIEW_ROUND_STATUS_PENDING_REVIEWERS); }
/** * @copydoc Form::execute() * @return integer The new review round number */ function execute($args, $request) { // Retrieve the submission. $submission = $this->getSubmission(); // Get this form decision actions labels. $actionLabels = EditorDecisionActionsManager::getActionLabels($this->_getDecisions()); // Record the decision. $reviewRound = $this->getReviewRound(); import('lib.pkp.classes.submission.action.EditorAction'); $editorAction = new EditorAction(); $editorAction->recordDecision($request, $submission, SUBMISSION_EDITOR_DECISION_RESUBMIT, $actionLabels, $reviewRound); // Update the review round status. $reviewRoundDao = DAORegistry::getDAO('ReviewRoundDAO'); $reviewRoundDao->updateStatus($reviewRound, null, REVIEW_ROUND_STATUS_RESUBMITTED); // Create a new review round. $newRound = $this->_initiateReviewRound($submission, $submission->getStageId(), $request, REVIEW_ROUND_STATUS_PENDING_REVIEWERS); return $newRound; }
/** * @see Form::fetch() */ function fetch($request) { $submission = $this->getSubmission(); $reviewRound = $this->getReviewRound(); if (is_a($reviewRound, 'ReviewRound')) { $this->setData('reviewRoundId', $reviewRound->getId()); } $this->setData('stageId', $this->getStageId()); $templateMgr = TemplateManager::getManager($request); $stageDecisions = EditorDecisionActionsManager::getStageDecisions($this->getStageId()); $templateMgr->assign(array('decisionData' => $stageDecisions[$this->getDecision()], 'submissionId' => $submission->getId(), 'submission' => $submission)); return parent::fetch($request); }
/** * Fetch JSON-encoded editor decision options. * @param $args array * @param $request Request * @return JSONMessage JSON object */ function editorDecisionActions($args, $request) { AppLocale::requireComponents(LOCALE_COMPONENT_APP_EDITOR); $reviewRoundId = (int) $request->getUserVar('reviewRoundId'); // Prepare the action arguments. $submission = $this->getAuthorizedContextObject(ASSOC_TYPE_SUBMISSION); $stageId = $this->getAuthorizedContextObject(ASSOC_TYPE_WORKFLOW_STAGE); $actionArgs = array('submissionId' => $submission->getId(), 'stageId' => (int) $stageId); // If a review round was specified, include it in the args; // must also check that this is the last round or decisions // cannot be recorded. if ($reviewRoundId) { $actionArgs['reviewRoundId'] = $reviewRoundId; $reviewRoundDao = DAORegistry::getDAO('ReviewRoundDAO'); $lastReviewRound = $reviewRoundDao->getLastReviewRoundBySubmissionId($submission->getId(), $stageId); } // If a review round was specified, // If there is an editor assigned, retrieve stage decisions. $stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); if ($stageAssignmentDao->editorAssignedToStage($submission->getId(), $stageId) && (!$reviewRoundId || $reviewRoundId == $lastReviewRound->getId())) { import('classes.workflow.EditorDecisionActionsManager'); $decisions = EditorDecisionActionsManager::getStageDecisions($stageId); } else { $decisions = array(); // None available } // Iterate through the editor decisions and create a link action for each decision. $editorActions = array(); // If we're in Submission stage and could expedite, show action. import('lib.pkp.classes.workflow.linkAction.ExpediteSubmissionLinkAction'); if ($stageId == WORKFLOW_STAGE_ID_SUBMISSION && ExpediteSubmissionLinkAction::canExpedite($request->getUser(), $request->getContext())) { $editorActions[] = new ExpediteSubmissionLinkAction($request, $submission->getId()); } $dispatcher = $request->getDispatcher(); import('lib.pkp.classes.linkAction.request.AjaxModal'); foreach ($decisions as $decision => $action) { $actionArgs['decision'] = $decision; $editorActions[] = new LinkAction($action['name'], new AjaxModal($dispatcher->url($request, ROUTE_COMPONENT, null, 'modals.editorDecision.EditorDecisionHandler', $action['operation'], null, $actionArgs), __($action['title']), $action['titleIcon']), __($action['title'])); } // Assign the actions to the template. $templateMgr = TemplateManager::getManager($request); $templateMgr->assign('editorActions', $editorActions); $templateMgr->assign('stageId', $stageId); return $templateMgr->fetchJson('workflow/editorialLinkActions.tpl'); }
/** * Delete the participant from the user groups * @param $args * @param $request * @return JSONMessage JSON object */ function deleteParticipant($args, $request) { $submission = $this->getSubmission(); $stageId = $this->getStageId(); $assignmentId = (int) $request->getUserVar('assignmentId'); $stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); /* @var $stageAssignmentDao StageAssignmentDAO */ $stageAssignment = $stageAssignmentDao->getById($assignmentId); if (!$stageAssignment || $stageAssignment->getSubmissionId() != $submission->getId()) { fatalError('Invalid Assignment'); } // Delete the assignment $stageAssignmentDao->deleteObject($stageAssignment); // FIXME: perhaps we can just insert the notification on page load // instead of having it there all the time? $stages = Application::getApplicationStages(); foreach ($stages as $workingStageId) { // remove user's assignment from this user group from all the stages // (no need to check if user group is assigned, since nothing will be deleted if there isn't) $stageAssignmentDao->deleteByAll($submission->getId(), $workingStageId, $stageAssignment->getUserGroupId(), $stageAssignment->getUserId()); } $notificationMgr = new NotificationManager(); import('classes.workflow.EditorDecisionActionsManager'); $notificationMgr->updateNotification($request, EditorDecisionActionsManager::getStageNotifications(), null, ASSOC_TYPE_SUBMISSION, $submission->getId()); // Log removal. $userDao = DAORegistry::getDAO('UserDAO'); $assignedUser = $userDao->getById($userId); $userGroupDao = DAORegistry::getDAO('UserGroupDAO'); $userGroup = $userGroupDao->getById($stageAssignment->getUserGroupId()); import('lib.pkp.classes.log.SubmissionLog'); SubmissionLog::logEvent($request, $submission, SUBMISSION_LOG_REMOVE_PARTICIPANT, 'submission.event.participantRemoved', array('name' => $assignedUser->getFullName(), 'username' => $assignedUser->getUsername(), 'userGroupName' => $userGroup->getLocalizedName())); // Redraw the category return DAO::getDataChangedEvent($stageAssignment->getUserGroupId()); }
/** * @copydoc Form::execute() */ function execute($args, $request) { // Retrieve the submission. $submission = $this->getSubmission(); // Get this form decision actions labels. $actionLabels = EditorDecisionActionsManager::getActionLabels($this->_getDecisions()); // Record the decision. $reviewRound = $this->getReviewRound(); $decision = $this->getDecision(); import('lib.pkp.classes.submission.action.EditorAction'); $editorAction = new EditorAction(); $editorAction->recordDecision($request, $submission, $decision, $actionLabels, $reviewRound); // Identify email key and status of round. import('lib.pkp.classes.file.SubmissionFileManager'); $submissionFileManager = new SubmissionFileManager($submission->getContextId(), $submission->getId()); switch ($decision) { case SUBMISSION_EDITOR_DECISION_ACCEPT: $emailKey = 'EDITOR_DECISION_ACCEPT'; $status = REVIEW_ROUND_STATUS_ACCEPTED; $this->_updateReviewRoundStatus($submission, $status, $reviewRound); // Move to the editing stage. $editorAction->incrementWorkflowStage($submission, WORKFLOW_STAGE_ID_EDITING, $request); // Bring in the SUBMISSION_FILE_* constants. import('lib.pkp.classes.submission.SubmissionFile'); // Bring in the Manager (we need it). import('lib.pkp.classes.file.SubmissionFileManager'); $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO'); /* @var $submissionFileDao SubmissionFileDAO */ $selectedFiles = $this->getData('selectedFiles'); if (is_array($selectedFiles)) { foreach ($selectedFiles as $fileId) { $revisionNumber = $submissionFileDao->getLatestRevisionNumber($fileId); $submissionFileManager->copyFileToFileStage($fileId, $revisionNumber, SUBMISSION_FILE_FINAL, null, true); } } // Send email to the author. $this->_sendReviewMailToAuthor($submission, $emailKey, $request); break; case SUBMISSION_EDITOR_DECISION_EXTERNAL_REVIEW: $emailKey = 'EDITOR_DECISION_SEND_TO_EXTERNAL'; $status = REVIEW_ROUND_STATUS_SENT_TO_EXTERNAL; $this->_updateReviewRoundStatus($submission, $status, $reviewRound); // Move to the external review stage. $editorAction->incrementWorkflowStage($submission, WORKFLOW_STAGE_ID_EXTERNAL_REVIEW, $request); // Create an initial external review round. $this->_initiateReviewRound($submission, WORKFLOW_STAGE_ID_EXTERNAL_REVIEW, $request, REVIEW_ROUND_STATUS_PENDING_REVIEWERS); // Send email to the author. $this->_sendReviewMailToAuthor($submission, $emailKey, $request); break; case SUBMISSION_EDITOR_DECISION_SEND_TO_PRODUCTION: $emailKey = 'EDITOR_DECISION_SEND_TO_PRODUCTION'; // FIXME: this is copy-pasted from above, save the FILE_GALLEY. // Move to the editing stage. $editorAction->incrementWorkflowStage($submission, WORKFLOW_STAGE_ID_PRODUCTION, $request); // Bring in the SUBMISSION_FILE_* constants. import('lib.pkp.classes.submission.SubmissionFile'); // Bring in the Manager (we need it). import('lib.pkp.classes.file.SubmissionFileManager'); // Move the revisions to the next stage $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO'); /* @var $submissionFileDao SubmissionFileDAO */ $selectedFiles = $this->getData('selectedFiles'); if (is_array($selectedFiles)) { foreach ($selectedFiles as $fileId) { $revisionNumber = $submissionFileDao->getLatestRevisionNumber($fileId); $submissionFileManager->copyFileToFileStage($fileId, $revisionNumber, SUBMISSION_FILE_PRODUCTION_READY); } } // Send email to the author. $this->_sendReviewMailToAuthor($submission, $emailKey, $request); break; default: fatalError('Unsupported decision!'); } }
/** * Delete the participant from the user groups * @param $args * @param $request * @return JSONMessage JSON object */ function deleteParticipant($args, $request) { $submission = $this->getSubmission(); $stageId = $this->getStageId(); $assignmentId = (int) $request->getUserVar('assignmentId'); $stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); /* @var $stageAssignmentDao StageAssignmentDAO */ $stageAssignment = $stageAssignmentDao->getById($assignmentId); if (!$request->checkCSRF() || !$stageAssignment || $stageAssignment->getSubmissionId() != $submission->getId()) { return new JSONMessage(false); } // Delete the assignment $stageAssignmentDao->deleteObject($stageAssignment); // FIXME: perhaps we can just insert the notification on page load // instead of having it there all the time? $notificationMgr = new NotificationManager(); import('classes.workflow.EditorDecisionActionsManager'); $notificationMgr->updateNotification($request, EditorDecisionActionsManager::getStageNotifications(), null, ASSOC_TYPE_SUBMISSION, $submission->getId()); // Update submission notifications $notificationMgr->updateNotification($request, array(NOTIFICATION_TYPE_ASSIGN_COPYEDITOR, NOTIFICATION_TYPE_AWAITING_COPYEDITS, NOTIFICATION_TYPE_ASSIGN_PRODUCTIONUSER, NOTIFICATION_TYPE_AWAITING_REPRESENTATIONS), null, ASSOC_TYPE_SUBMISSION, $submission->getId()); // Log removal. $userDao = DAORegistry::getDAO('UserDAO'); $assignedUser = $userDao->getById($stageAssignment->getUserId()); $userGroupDao = DAORegistry::getDAO('UserGroupDAO'); $userGroup = $userGroupDao->getById($stageAssignment->getUserGroupId()); import('lib.pkp.classes.log.SubmissionLog'); SubmissionLog::logEvent($request, $submission, SUBMISSION_LOG_REMOVE_PARTICIPANT, 'submission.event.participantRemoved', array('name' => $assignedUser->getFullName(), 'username' => $assignedUser->getUsername(), 'userGroupName' => $userGroup->getLocalizedName())); // Redraw the category return DAO::getDataChangedEvent($stageAssignment->getUserGroupId()); }
/** * Save changes to submission. * @param $args array * @param $request PKPRequest * @return int the submission ID */ function execute($args, $request) { $submissionDao = Application::getSubmissionDAO(); // Set other submission data. if ($this->submission->getSubmissionProgress() <= $this->step) { $this->submission->setDateSubmitted(Core::getCurrentDate()); $this->submission->stampStatusModified(); $this->submission->setSubmissionProgress(0); } parent::execute($this->submission); // Save the submission. $submissionDao->updateObject($this->submission); // Assign the default stage participants. $userGroupDao = DAORegistry::getDAO('UserGroupDAO'); // Assistant roles -- For each assistant role user group assigned to this // stage in setup, iff there is only one user for the group, // automatically assign the user to the stage // But skip authors and reviewers, since these are very submission specific $stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); $submissionStageGroups = $userGroupDao->getUserGroupsByStage($this->submission->getContextId(), WORKFLOW_STAGE_ID_SUBMISSION, true, true); $managerFound = false; while ($userGroup = $submissionStageGroups->next()) { $users = $userGroupDao->getUsersById($userGroup->getId(), $this->submission->getContextId()); if ($users->getCount() == 1) { $user = $users->next(); $stageAssignmentDao->build($this->submission->getId(), $userGroup->getId(), $user->getId()); if ($userGroup->getRoleId() == ROLE_ID_MANAGER) { $managerFound = true; } } } // Author roles // Assign only the submitter in whatever ROLE_ID_AUTHOR capacity they were assigned previously $user = $request->getUser(); $submitterAssignments = $stageAssignmentDao->getBySubmissionAndStageId($this->submission->getId(), null, null, $user->getId()); while ($assignment = $submitterAssignments->next()) { $userGroup = $userGroupDao->getById($assignment->getUserGroupId()); if ($userGroup->getRoleId() == ROLE_ID_AUTHOR) { $stageAssignmentDao->build($this->submission->getId(), $userGroup->getId(), $assignment->getUserId()); // Only assign them once, since otherwise we'll one assignment for each previous stage. // And as long as they are assigned once, they will get access to their submission. break; } } $notificationManager = new NotificationManager(); // Assign sub editors for that section $submissionSubEditorFound = false; $subEditorsDao = DAORegistry::getDAO('SubEditorsDAO'); $subEditors = $subEditorsDao->getBySectionId($this->submission->getSectionId(), $this->submission->getContextId()); foreach ($subEditors as $subEditor) { $userGroups = $userGroupDao->getByUserId($subEditor->getId(), $this->submission->getContextId()); while ($userGroup = $userGroups->next()) { if ($userGroup->getRoleId() != ROLE_ID_SUB_EDITOR) { continue; } $stageAssignmentDao->build($this->submission->getId(), $userGroup->getId(), $subEditor->getId()); // If we assign a stage assignment in the Submission stage to a sub editor, make note. if ($userGroupDao->userGroupAssignedToStage($userGroup->getId(), WORKFLOW_STAGE_ID_SUBMISSION)) { $submissionSubEditorFound = true; } } } // Update assignment notifications import('classes.workflow.EditorDecisionActionsManager'); $notificationManager->updateNotification($request, EditorDecisionActionsManager::getStageNotifications(), null, ASSOC_TYPE_SUBMISSION, $this->submission->getId()); // Send a notification to associated users if an editor needs assigning if (!$managerFound && !$submissionSubEditorFound) { $roleDao = DAORegistry::getDAO('RoleDAO'); /* @var $roleDao RoleDAO */ // Get the managers. $managers = $roleDao->getUsersByRoleId(ROLE_ID_MANAGER, $this->submission->getContextId()); $managersArray = $managers->toAssociativeArray(); $allUserIds = array_keys($managersArray); foreach ($allUserIds as $userId) { $notificationManager->createNotification($request, $userId, NOTIFICATION_TYPE_SUBMISSION_SUBMITTED, $this->submission->getContextId(), ASSOC_TYPE_SUBMISSION, $this->submission->getId()); // Add TASK notification indicating that a submission is unassigned $notificationManager->createNotification($request, $userId, NOTIFICATION_TYPE_EDITOR_ASSIGNMENT_REQUIRED, $this->submission->getContextId(), ASSOC_TYPE_SUBMISSION, $this->submission->getId(), NOTIFICATION_LEVEL_TASK); } } $notificationManager->updateNotification($request, array(NOTIFICATION_TYPE_APPROVE_SUBMISSION), null, ASSOC_TYPE_SUBMISSION, $this->submission->getId()); return $this->submissionId; }