00001 <?php
00002
00015
00016 import('lib.pkp.classes.controllers.grid.GridHandler');
00017
00018
00019 import('controllers.grid.users.reviewer.ReviewerGridCellProvider');
00020 import('controllers.grid.users.reviewer.ReviewerGridRow');
00021
00022
00023 define('REVIEWER_SELECT_SEARCH_BY_NAME', 0x00000001);
00024 define('REVIEWER_SELECT_ADVANCED_SEARCH', 0x00000002);
00025 define('REVIEWER_SELECT_CREATE', 0x00000003);
00026 define('REVIEWER_SELECT_ENROLL_EXISTING', 0x00000004);
00027
00028 class ReviewerGridHandler extends GridHandler {
00029
00031 var $_monograph;
00032
00034 var $_stageId;
00035
00036
00040 function ReviewerGridHandler() {
00041 parent::GridHandler();
00042
00043 $allOperations = array_merge($this->_getReviewAssignmentOps(), $this->_getReviewRoundOps());
00044
00045 $this->addRoleAssignment(
00046 array(ROLE_ID_PRESS_MANAGER),
00047 $allOperations
00048 );
00049
00050
00051 $nonPressManagerOperations = array_flip($allOperations);
00052 unset($nonPressManagerOperations['createReviewer']);
00053 unset($nonPressManagerOperations['enrollReviewer']);
00054 $nonPressManagerOperations = array_flip($nonPressManagerOperations);
00055
00056 $this->addRoleAssignment(
00057 array(ROLE_ID_SERIES_EDITOR, ROLE_ID_PRESS_ASSISTANT),
00058 $nonPressManagerOperations
00059 );
00060 }
00061
00062
00063
00064
00065
00070 function &getMonograph() {
00071 return $this->getAuthorizedContextObject(ASSOC_TYPE_MONOGRAPH);
00072 }
00073
00078 function getStageId() {
00079 return $this->_stageId;
00080 }
00081
00086 function &getReviewRound() {
00087 $reviewRound =& $this->getAuthorizedContextObject(ASSOC_TYPE_REVIEW_ROUND);
00088 if (is_a($reviewRound, 'ReviewRound')) {
00089 return $reviewRound;
00090 } else {
00091 $reviewAssignment =& $this->getAuthorizedContextObject(ASSOC_TYPE_REVIEW_ASSIGNMENT);
00092 $reviewRoundId = $reviewAssignment->getReviewRoundId();
00093 $reviewRoundDao =& DAORegistry::getDAO('ReviewRoundDAO');
00094 return $reviewRoundDao->getReviewRoundById($reviewRoundId);
00095 }
00096 }
00097
00098
00099
00100
00101
00108 function authorize(&$request, $args, $roleAssignments) {
00109 $stageId = $request->getUserVar('stageId');
00110
00111
00112 $this->_stageId = (int)$stageId;
00113
00114
00115 import('classes.security.authorization.OmpWorkflowStageAccessPolicy');
00116 $ompWorkflowStageAccessPolicy = new OmpWorkflowStageAccessPolicy($request, $args, $roleAssignments, 'monographId', $stageId);
00117
00118
00119 import('classes.security.authorization.internal.ReviewRoundRequiredPolicy');
00120 $ompWorkflowStageAccessPolicy->addPolicy(new ReviewRoundRequiredPolicy($request, $args, 'reviewRoundId', $this->_getReviewRoundOps()));
00121
00122
00123 import('classes.security.authorization.internal.ReviewAssignmentRequiredPolicy');
00124 $ompWorkflowStageAccessPolicy->addPolicy(new ReviewAssignmentRequiredPolicy($request, $args, 'reviewAssignmentId', $this->_getReviewAssignmentOps()));
00125 $this->addPolicy($ompWorkflowStageAccessPolicy);
00126
00127 return parent::authorize($request, $args, $roleAssignments);
00128 }
00129
00130
00131
00132
00133
00134 function initialize(&$request) {
00135 parent::initialize($request);
00136
00137
00138 AppLocale::requireComponents(
00139 LOCALE_COMPONENT_PKP_SUBMISSION,
00140 LOCALE_COMPONENT_PKP_MANAGER,
00141 LOCALE_COMPONENT_PKP_USER,
00142 LOCALE_COMPONENT_OMP_EDITOR
00143 );
00144
00145 $this->setTitle('user.role.reviewers');
00146 $this->setInstructions('editor.monograph.review.reviewersDescription');
00147
00148
00149 import('lib.pkp.classes.linkAction.request.AjaxModal');
00150 $router =& $request->getRouter();
00151 $actionArgs = array_merge($this->getRequestArgs(), array('selectionType' => REVIEWER_SELECT_SEARCH_BY_NAME));
00152 $this->addAction(
00153 new LinkAction(
00154 'addReviewer',
00155 new AjaxModal(
00156 $router->url($request, null, null, 'showReviewerForm', null, $actionArgs),
00157 __('editor.monograph.addReviewer'),
00158 'modal_add_user'
00159 ),
00160 __('editor.monograph.addReviewer'),
00161 'add_user'
00162 )
00163 );
00164
00165
00166 $cellProvider = new ReviewerGridCellProvider();
00167 $this->addColumn(
00168 new GridColumn(
00169 'name',
00170 'user.name',
00171 null,
00172 'controllers/grid/gridCell.tpl',
00173 $cellProvider,
00174 array('width' => 60)
00175 )
00176 );
00177
00178
00179 $this->addColumn(
00180 new GridColumn(
00181 'considered',
00182 'common.considered',
00183 null,
00184 'controllers/grid/common/cell/statusCell.tpl',
00185 $cellProvider,
00186 array('hoverTitle' => true)
00187 )
00188 );
00189 }
00190
00191
00192
00193
00194
00199 function &getRowInstance() {
00200 $row = new ReviewerGridRow();
00201 return $row;
00202 }
00203
00207 function getRequestArgs() {
00208 $monograph =& $this->getMonograph();
00209 $reviewRound =& $this->getReviewRound();
00210 return array(
00211 'monographId' => $monograph->getId(),
00212 'stageId' => $this->getStageId(),
00213 'reviewRoundId' => $reviewRound->getId()
00214 );
00215 }
00216
00220 function loadData($request, $filter) {
00221
00222 $monograph =& $this->getMonograph();
00223 $reviewRound =& $this->getReviewRound();
00224 return $monograph->getReviewAssignments($this->getStageId(), $reviewRound->getRound());
00225 }
00226
00227
00228
00229
00230
00237 function showReviewerForm($args, &$request) {
00238 $json = new JSONMessage(true, $this->_fetchReviewerForm($args, $request));
00239 return $json->getString();
00240 }
00241
00248 function reloadReviewerForm($args, &$request) {
00249 $json = new JSONMessage(true);
00250 $json->setEvent('refreshForm', $this->_fetchReviewerForm($args, $request));
00251 return $json->getString();
00252 }
00253
00260 function createReviewer($args, &$request) {
00261 return $this->updateReviewer($args, $request);
00262 }
00263
00270 function enrollReviewer($args, &$request) {
00271 return $this->updateReviewer($args, $request);
00272 }
00273
00280 function updateReviewer($args, &$request) {
00281 $selectionType = $request->getUserVar('selectionType');
00282 $formClassName = $this->_getReviewerFormClassName($selectionType);
00283
00284
00285 import('controllers.grid.users.reviewer.form.' . $formClassName );
00286 $reviewerForm = new $formClassName($this->getMonograph(), $this->getReviewRound());
00287 $reviewerForm->readInputData();
00288 if ($reviewerForm->validate()) {
00289 $reviewAssignment =& $reviewerForm->execute($args, $request);
00290
00291 return DAO::getDataChangedEvent($reviewAssignment->getId());
00292 } else {
00293
00294 $json = new JSONMessage(true, $reviewerForm->fetch($request));
00295 }
00296 return $json->getString();
00297 }
00298
00305 function deleteReviewer($args, &$request) {
00306
00307
00308
00309
00310 $monograph =& $this->getMonograph();
00311 $reviewAssignment =& $this->getAuthorizedContextObject(ASSOC_TYPE_REVIEW_ASSIGNMENT);
00312 import('classes.submission.seriesEditor.SeriesEditorAction');
00313 $seriesEditorAction = new SeriesEditorAction();
00314 $result = $seriesEditorAction->clearReview($request, $monograph->getId(), $reviewAssignment->getId());
00315
00316
00317 if ($result) {
00318 return DAO::getDataChangedEvent($reviewAssignment->getId());
00319 } else {
00320 $json = new JSONMessage(false, __('editor.review.errorDeletingReviewer'));
00321 return $json->getString();
00322 }
00323 }
00324
00325
00332 function getReviewersNotAssignedToMonograph($args, &$request) {
00333 $press =& $request->getPress();
00334 $monograph =& $this->getMonograph();
00335 $stageId = $this->getAuthorizedContextObject(ASSOC_TYPE_WORKFLOW_STAGE);
00336 $reviewRound =& $this->getReviewRound();
00337 $round = $reviewRound->getRound();
00338 $term = $request->getUserVar('term');
00339
00340 $seriesEditorSubmissionDao =& DAORegistry::getDAO('SeriesEditorSubmissionDAO');
00341 $reviewers =& $seriesEditorSubmissionDao->getReviewersNotAssignedToMonograph($press->getId(), $monograph->getId(), $reviewRound, $term);
00342
00343 $reviewerList = array();
00344 while($reviewer =& $reviewers->next()) {
00345 $reviewerList[] = array('label' => $reviewer->getFullName(), 'value' => $reviewer->getId());
00346 unset($reviewer);
00347 }
00348
00349 if (count($reviewerList) == 0) {
00350 $reviewerList[] = array('label' => __('common.noMatches'), 'value' => '');
00351 }
00352
00353 $json = new JSONMessage(true, $reviewerList);
00354 return $json->getString();
00355 }
00356
00363 function getUsersNotAssignedAsReviewers($args, &$request) {
00364 $press =& $request->getPress();
00365 $term = $request->getUserVar('term');
00366
00367 $userGroupDao =& DAORegistry::getDAO('UserGroupDAO');
00368 $monograph =& $this->getMonograph();
00369
00370 $users =& $userGroupDao->getUsersNotInRole(ROLE_ID_REVIEWER, $press->getId(), $term);
00371
00372 $userList = array();
00373 while ($user =& $users->next()) {
00374 $userList[] = array('label' => $user->getFullName(), 'value' => $user->getId());
00375 unset($user);
00376 }
00377
00378 if (count($userList) == 0) {
00379 return $this->noAutocompleteResults();
00380 }
00381
00382 $json = new JSONMessage(true, $userList);
00383 return $json->getString();
00384 }
00385
00393 function readReview($args, &$request) {
00394 $templateMgr =& TemplateManager::getManager();
00395
00396
00397 $templateMgr->assign_by_ref('monograph', $this->getMonograph());
00398
00399
00400 $reviewAssignment =& $this->getAuthorizedContextObject(ASSOC_TYPE_REVIEW_ASSIGNMENT);
00401 $templateMgr->assign_by_ref('reviewAssignment', $reviewAssignment);
00402
00403
00404 $monographCommentDao =& DAORegistry::getDAO('MonographCommentDAO');
00405 $monographComments =& $monographCommentDao->getReviewerCommentsByReviewerId($reviewAssignment->getReviewerId(), $reviewAssignment->getSubmissionId(), $reviewAssignment->getId());
00406 $templateMgr->assign_by_ref('reviewerComment', $monographComments->next());
00407
00408
00409 return $templateMgr->fetchJson('controllers/grid/users/reviewer/readReview.tpl');
00410 }
00411
00418 function unconsiderReview($args, &$request) {
00419
00420
00421 $monograph =& $this->getMonograph();
00422 $user =& $request->getUser();
00423 $reviewAssignment =& $this->getAuthorizedContextObject(ASSOC_TYPE_REVIEW_ASSIGNMENT);
00424 $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
00425
00426 $reviewAssignment->setUnconsidered(REVIEW_ASSIGNMENT_UNCONSIDERED);
00427 $result = $reviewAssignmentDao->updateReviewAssignment($reviewAssignment);
00428 $this->_updateReviewRoundStatus($reviewAssignment);
00429
00430
00431 import('classes.log.MonographLog');
00432 import('classes.log.MonographEventLogEntry');
00433
00434 $entry = new MonographEventLogEntry();
00435 $entry->setMonographId($reviewAssignment->getSubmissionId());
00436 $entry->setUserId($user->getId());
00437 $entry->setDateLogged(Core::getCurrentDate());
00438 $entry->setEventType(MONOGRAPH_LOG_REVIEW_UNCONSIDERED);
00439
00440 MonographLog::logEvent(
00441 $request,
00442 $monograph,
00443 MONOGRAPH_LOG_REVIEW_UNCONSIDERED,
00444 'log.review.reviewUnconsidered',
00445 array(
00446 'editorName' => $user->getFullName(),
00447 'monographId' => $monograph->getId(),
00448 'round' => $reviewAssignment->getRound(),
00449 )
00450 );
00451
00452
00453 if ($result) {
00454 return DAO::getDataChangedEvent($reviewAssignment->getId());
00455 } else {
00456 $json = new JSONMessage(false, __('editor.review.errorUnconsideringReview'));
00457 return $json->getString();
00458 }
00459 }
00460
00467 function reviewRead($args, &$request) {
00468
00469 $reviewAssignment =& $this->getAuthorizedContextObject(ASSOC_TYPE_REVIEW_ASSIGNMENT);
00470
00471
00472 $user =& $request->getUser();
00473 $viewsDao =& DAORegistry::getDAO('ViewsDAO');
00474 $viewsDao->recordView(ASSOC_TYPE_REVIEW_RESPONSE, $reviewAssignment->getId(), $user->getId());
00475
00476
00477 if ($reviewAssignment->getUnconsidered() == REVIEW_ASSIGNMENT_UNCONSIDERED) {
00478 $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
00479 $reviewAssignment->setUnconsidered(REVIEW_ASSIGNMENT_UNCONSIDERED_READ);
00480 $reviewAssignmentDao->updateReviewAssignment($reviewAssignment);
00481 }
00482
00483 $this->_updateReviewRoundStatus($reviewAssignment);
00484
00485 return DAO::getDataChangedEvent($reviewAssignment->getId());
00486 }
00487
00494 function editThankReviewer($args, &$request) {
00495
00496 $reviewAssignment =& $this->getAuthorizedContextObject(ASSOC_TYPE_REVIEW_ASSIGNMENT);
00497
00498
00499 import('controllers.grid.users.reviewer.form.ThankReviewerForm');
00500 $thankReviewerForm = new ThankReviewerForm($reviewAssignment);
00501 $thankReviewerForm->initData($args, $request);
00502
00503
00504 $json = new JSONMessage(true, $thankReviewerForm->fetch($request));
00505 return $json->getString();
00506 }
00507
00514 function thankReviewer($args, &$request) {
00515
00516 $reviewAssignment =& $this->getAuthorizedContextObject(ASSOC_TYPE_REVIEW_ASSIGNMENT);
00517
00518
00519 import('controllers.grid.users.reviewer.form.ThankReviewerForm');
00520 $thankReviewerForm = new ThankReviewerForm($reviewAssignment);
00521 $thankReviewerForm->readInputData();
00522 if ($thankReviewerForm->validate()) {
00523 $thankReviewerForm->execute($args, $request);
00524 $json = new JSONMessage(true);
00525
00526 $currentUser =& $request->getUser();
00527 $notificationMgr = new NotificationManager();
00528 $messageKey = $thankReviewerForm->getData('skipEmail') ? __('notification.reviewAcknowledged') : __('notification.sentNotification');
00529 $notificationMgr->createTrivialNotification($currentUser->getId(), NOTIFICATION_TYPE_SUCCESS, array('contents' => $messageKey));
00530 } else {
00531 $json = new JSONMessage(false, __('editor.review.thankReviewerError'));
00532 }
00533
00534 $this->_updateReviewRoundStatus($reviewAssignment);
00535 return DAO::getDataChangedEvent($reviewAssignment->getId());
00536 }
00537
00544 function editReminder($args, &$request) {
00545
00546 $reviewAssignment =& $this->getAuthorizedContextObject(ASSOC_TYPE_REVIEW_ASSIGNMENT);
00547
00548
00549 import('controllers.grid.users.reviewer.form.ReviewReminderForm');
00550 $reviewReminderForm = new ReviewReminderForm($reviewAssignment);
00551 $reviewReminderForm->initData($args, $request);
00552
00553
00554 $json = new JSONMessage(true, $reviewReminderForm->fetch($request));
00555 return $json->getString();
00556 }
00557
00564 function sendReminder($args, &$request) {
00565 $reviewAssignment =& $this->getAuthorizedContextObject(ASSOC_TYPE_REVIEW_ASSIGNMENT);
00566
00567
00568 import('controllers.grid.users.reviewer.form.ReviewReminderForm');
00569 $reviewReminderForm = new ReviewReminderForm($reviewAssignment);
00570 $reviewReminderForm->readInputData();
00571 if ($reviewReminderForm->validate()) {
00572 $reviewReminderForm->execute($args, $request);
00573 $json = new JSONMessage(true);
00574
00575 $currentUser =& $request->getUser();
00576 $notificationMgr = new NotificationManager();
00577 $notificationMgr->createTrivialNotification($currentUser->getId(), NOTIFICATION_TYPE_SUCCESS, array('contents' => __('notification.sentNotification')));
00578 } else {
00579 $json = new JSONMessage(false, __('editor.review.reminderError'));
00580 }
00581 return $json->getString();
00582 }
00583
00590 function sendEmail($args, &$request) {
00591 $user =& $request->getUser();
00592
00593 $reviewAssignment =& $this->getAuthorizedContextObject(ASSOC_TYPE_REVIEW_ASSIGNMENT);
00594
00595
00596 import('controllers.grid.settings.user.form.UserEmailForm');
00597 $userEmailForm = new UserEmailForm($reviewAssignment->getReviewerId());
00598 $userEmailForm->initData($args, $request);
00599
00600 $json = new JSONMessage(true, $userEmailForm->display($args, $request));
00601 return $json->getString();
00602 }
00603
00604
00611 function reviewHistory($args, &$request) {
00612 $user =& $request->getUser();
00613
00614 $reviewAssignment =& $this->getAuthorizedContextObject(ASSOC_TYPE_REVIEW_ASSIGNMENT);
00615
00616 $templateMgr =& TemplateManager::getManager();
00617 $templateMgr->assign_by_ref('reviewAssignment', $reviewAssignment);
00618
00619
00620 return $templateMgr->fetchJson('workflow/reviewHistory.tpl');
00621 }
00622
00623
00624
00625
00626
00633 function _fetchReviewerForm($args, &$request) {
00634 $selectionType = $request->getUserVar('selectionType');
00635 assert(!empty($selectionType));
00636 $formClassName = $this->_getReviewerFormClassName($selectionType);
00637 $userRoles = $this->getAuthorizedContextObject(ASSOC_TYPE_USER_ROLES);
00638
00639
00640 import('controllers.grid.users.reviewer.form.' . $formClassName );
00641 $reviewerForm = new $formClassName($this->getMonograph(), $this->getReviewRound());
00642 $reviewerForm->initData($args, $request);
00643 $reviewerForm->setUserRoles($userRoles);
00644
00645 return $reviewerForm->fetch($request);
00646 }
00647
00653 function _getReviewerFormClassName($selectionType) {
00654 switch ($selectionType) {
00655 case REVIEWER_SELECT_SEARCH_BY_NAME:
00656 return 'SearchByNameReviewerForm';
00657 case REVIEWER_SELECT_ADVANCED_SEARCH:
00658 return 'AdvancedSearchReviewerForm';
00659 case REVIEWER_SELECT_CREATE:
00660 return 'CreateReviewerForm';
00661 case REVIEWER_SELECT_ENROLL_EXISTING:
00662 return 'EnrollExistingReviewerForm';
00663 }
00664 }
00665
00670 function _getReviewAssignmentOps() {
00671
00672 return array('readReview', 'reviewHistory', 'reviewRead', 'editThankReviewer', 'thankReviewer', 'editReminder', 'sendReminder', 'deleteReviewer', 'sendEmail', 'unconsiderReview');
00673
00674 }
00675
00680 function _getReviewRoundOps() {
00681
00682 return array('fetchGrid', 'fetchRow', 'showReviewerForm', 'reloadReviewerForm', 'createReviewer', 'enrollReviewer', 'updateReviewer',
00683 'getReviewersNotAssignedToMonograph', 'getUsersNotAssignedAsReviewers');
00684 }
00685
00689 function _updateReviewRoundStatus($reviewAssignment) {
00690
00691 $reviewRoundDao =& DAORegistry::getDAO('ReviewRoundDAO');
00692 $reviewRound =& $reviewRoundDao->getReviewRoundById($reviewAssignment->getReviewRoundId());
00693 $seriesEditorSubmission =& $this->getMonograph();
00694 $seriesEditorSubmission->updateReviewAssignment($reviewAssignment);
00695 $reviewAssignments = $seriesEditorSubmission->getReviewAssignments($reviewRound->getStageId(), $reviewRound->getRound());
00696 $reviewRoundDao->updateStatus($reviewRound, $reviewAssignments);
00697 }
00698 }
00699
00700 ?>