PageRenderTime 34ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/classes/submission/trackDirector/TrackDirectorAction.inc.php

https://github.com/lib-uoguelph-ca/ocs
PHP | 1802 lines | 1197 code | 261 blank | 344 comment | 308 complexity | d1c9edc49549f8693b6f3264c59bf907 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /**
  3. * @file TrackDirectorAction.inc.php
  4. *
  5. * Copyright (c) 2000-2012 John Willinsky
  6. * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
  7. *
  8. * @class TrackDirectorAction
  9. * @ingroup submission
  10. *
  11. * @brief TrackDirectorAction class.
  12. *
  13. */
  14. import('submission.common.Action');
  15. class TrackDirectorAction extends Action {
  16. /**
  17. * Constructor.
  18. */
  19. function TrackDirectorAction() {
  20. parent::Action();
  21. }
  22. /**
  23. * Actions.
  24. */
  25. /**
  26. * Changes the track a paper belongs in.
  27. * @param $trackDirectorSubmission object
  28. * @param $trackId int
  29. */
  30. function changeTrack(&$trackDirectorSubmission, $trackId) {
  31. if (!HookRegistry::call('TrackDirectorAction::changeTrack', array(&$trackDirectorSubmission, $trackId))) {
  32. $trackDirectorSubmissionDao =& DAORegistry::getDAO('TrackDirectorSubmissionDAO');
  33. $trackDirectorSubmission->setTrackId((int) $trackId);
  34. $trackDirectorSubmissionDao->updateTrackDirectorSubmission($trackDirectorSubmission);
  35. }
  36. }
  37. /**
  38. * Changes the session type.
  39. * @param $trackDirectorSubmission object
  40. * @param $sessionType int
  41. */
  42. function changeSessionType(&$trackDirectorSubmission, $sessionType) {
  43. if (!HookRegistry::call('TrackDirectorAction::changeSessionType', array(&$trackDirectorSubmission, $sessionType))) {
  44. $trackDirectorSubmissionDao =& DAORegistry::getDAO('TrackDirectorSubmissionDAO');
  45. $trackDirectorSubmission->setData('sessionType', (int) $sessionType);
  46. $trackDirectorSubmissionDao->updateTrackDirectorSubmission($trackDirectorSubmission);
  47. }
  48. }
  49. /**
  50. * Records a director's submission decision.
  51. * @param $trackDirectorSubmission object
  52. * @param $decision int
  53. * @param $stage int
  54. */
  55. function recordDecision($trackDirectorSubmission, $decision, $stage) {
  56. $editAssignments =& $trackDirectorSubmission->getEditAssignments();
  57. if (empty($editAssignments)) return;
  58. $trackDirectorSubmissionDao =& DAORegistry::getDAO('TrackDirectorSubmissionDAO');
  59. $user =& Request::getUser();
  60. $directorDecision = array(
  61. 'editDecisionId' => null,
  62. 'directorId' => $user->getId(),
  63. 'decision' => $decision,
  64. 'dateDecided' => date(Core::getCurrentDate())
  65. );
  66. if (!HookRegistry::call('TrackDirectorAction::recordDecision', array(&$trackDirectorSubmission, $directorDecision))) {
  67. if ($decision == SUBMISSION_DIRECTOR_DECISION_DECLINE) {
  68. $trackDirectorSubmission->setStatus(STATUS_DECLINED);
  69. $trackDirectorSubmission->stampStatusModified();
  70. } else {
  71. $trackDirectorSubmission->setStatus(STATUS_QUEUED);
  72. $trackDirectorSubmission->stampStatusModified();
  73. }
  74. $trackDirectorSubmission->addDecision($directorDecision, $stage);
  75. $decisions = TrackDirectorSubmission::getDirectorDecisionOptions();
  76. // Add log
  77. import('paper.log.PaperLog');
  78. import('paper.log.PaperEventLogEntry');
  79. AppLocale::requireComponents(array(LOCALE_COMPONENT_APPLICATION_COMMON, LOCALE_COMPONENT_OCS_DIRECTOR));
  80. PaperLog::logEvent(
  81. $trackDirectorSubmission->getPaperId(),
  82. PAPER_LOG_DIRECTOR_DECISION,
  83. LOG_TYPE_DIRECTOR,
  84. $user->getId(),
  85. 'log.director.decision',
  86. array(
  87. 'directorName' => $user->getFullName(),
  88. 'paperId' => $trackDirectorSubmission->getPaperId(),
  89. 'decision' => __($decisions[$decision]),
  90. 'round' => ($stage == REVIEW_STAGE_ABSTRACT?'submission.abstractReview':'submission.paperReview')
  91. )
  92. );
  93. }
  94. if($decision == SUBMISSION_DIRECTOR_DECISION_ACCEPT || $decision == SUBMISSION_DIRECTOR_DECISION_INVITE) {
  95. // completeReview will take care of updating the
  96. // submission with the new decision.
  97. TrackDirectorAction::completeReview($trackDirectorSubmission);
  98. } else {
  99. // Insert the new decision.
  100. $trackDirectorSubmissionDao->updateTrackDirectorSubmission($trackDirectorSubmission);
  101. }
  102. }
  103. /**
  104. * After a decision has been recorded, bumps the paper to the next stage.
  105. * If the submission requires completion, it's sent back to the author.
  106. * If not, review is complete, and the paper can be released.
  107. * @param $schedConf object
  108. * @param $trackDirectorSubmission object
  109. * @param $decision int
  110. */
  111. function completeReview($trackDirectorSubmission) {
  112. $schedConf =& Request::getSchedConf();
  113. if($trackDirectorSubmission->getReviewMode() == REVIEW_MODE_BOTH_SEQUENTIAL) {
  114. // two-stage submission; paper required
  115. // The submission is incomplete, and needs the author to submit
  116. // more materials (potentially for another stage of reviews)
  117. if($trackDirectorSubmission->getCurrentStage() == REVIEW_STAGE_ABSTRACT) {
  118. // We've just completed reviewing the abstract. Prepare for presentation
  119. // review process.
  120. $trackDirectorSubmission->setCurrentStage(REVIEW_STAGE_PRESENTATION);
  121. // The paper itself needs to be collected. Flag it so the author
  122. // may complete it.
  123. $trackDirectorSubmission->setSubmissionProgress(2);
  124. // TODO: notify the author the submission must be completed.
  125. // Q: should the director be given this option explicitly?
  126. // Now, reassign all reviewers that submitted a review for the last
  127. // stage of reviews.
  128. foreach ($trackDirectorSubmission->getReviewAssignments(REVIEW_STAGE_ABSTRACT) as $reviewAssignment) {
  129. if ($reviewAssignment->getRecommendation() !== null && $reviewAssignment->getRecommendation() !== '') {
  130. // This reviewer submitted a review; reassign them
  131. TrackDirectorAction::addReviewer($trackDirectorSubmission, $reviewAssignment->getReviewerId(), REVIEW_STAGE_PRESENTATION);
  132. }
  133. }
  134. }
  135. }
  136. $trackDirectorSubmissionDao =& DAORegistry::getDao('TrackDirectorSubmissionDAO');
  137. $trackDirectorSubmissionDao->updateTrackDirectorSubmission($trackDirectorSubmission);
  138. $trackDirectorSubmission->stampStatusModified();
  139. // Commit the paper changes
  140. $paperDao =& DAORegistry::getDao('PaperDAO');
  141. $paperDao->updatePaper($trackDirectorSubmission);
  142. }
  143. /**
  144. * Assigns a reviewer to a submission.
  145. * @param $trackDirectorSubmission object
  146. * @param $reviewerId int
  147. * @param $stage int
  148. */
  149. function addReviewer($trackDirectorSubmission, $reviewerId, $stage) {
  150. $trackDirectorSubmissionDao =& DAORegistry::getDAO('TrackDirectorSubmissionDAO');
  151. $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
  152. $userDao =& DAORegistry::getDAO('UserDAO');
  153. $user =& Request::getUser();
  154. $reviewer =& $userDao->getUser($reviewerId);
  155. // Check to see if the requested reviewer is not already
  156. // assigned to review this paper.
  157. if ($stage == null) {
  158. $stage = $trackDirectorSubmission->getCurrentStage();
  159. }
  160. $assigned = $trackDirectorSubmissionDao->reviewerExists($trackDirectorSubmission->getPaperId(), $reviewerId, $stage);
  161. // Only add the reviewer if he has not already
  162. // been assigned to review this paper.
  163. if (!$assigned && isset($reviewer) && !HookRegistry::call('TrackDirectorAction::addReviewer', array(&$trackDirectorSubmission, $reviewerId))) {
  164. $reviewAssignment = new ReviewAssignment();
  165. $reviewAssignment->setReviewerId($reviewerId);
  166. $reviewAssignment->setDateAssigned(Core::getCurrentDate());
  167. $reviewAssignment->setStage($stage);
  168. // Assign review form automatically if needed
  169. $schedConfId = $trackDirectorSubmission->getSchedConfId();
  170. $schedConfDao =& DAORegistry::getDAO('SchedConfDAO');
  171. $schedConf =& $schedConfDao->getSchedConf($schedConfId);
  172. $conferenceId = $schedConf->getConferenceId();
  173. $trackDao =& DAORegistry::getDAO('TrackDAO');
  174. $reviewFormDao =& DAORegistry::getDAO('ReviewFormDAO');
  175. $trackId = $trackDirectorSubmission->getTrackId();
  176. $track =& $trackDao->getTrack($trackId, $conferenceId);
  177. if ($track && ($reviewFormId = (int) $track->getReviewFormId())) {
  178. if ($reviewFormDao->reviewFormExists($reviewFormId, ASSOC_TYPE_CONFERENCE, $conferenceId)) {
  179. $reviewAssignment->setReviewFormId($reviewFormId);
  180. }
  181. }
  182. $trackDirectorSubmission->addReviewAssignment($reviewAssignment);
  183. $trackDirectorSubmissionDao->updateTrackDirectorSubmission($trackDirectorSubmission);
  184. $reviewAssignment = $reviewAssignmentDao->getReviewAssignment($trackDirectorSubmission->getPaperId(), $reviewerId, $stage);
  185. $schedConf =& Request::getSchedConf();
  186. if ($schedConf->getSetting('reviewDeadlineType') != null) {
  187. $dueDateSet = true;
  188. if ($schedConf->getSetting('reviewDeadlineType') == REVIEW_DEADLINE_TYPE_ABSOLUTE) {
  189. $reviewDeadlineDate = $schedConf->getSetting('numWeeksPerReviewAbsolute');
  190. $reviewDueDate = strftime(Config::getVar('general', 'date_format_short'), $reviewDeadlineDate);
  191. TrackDirectorAction::setDueDate($trackDirectorSubmission->getPaperId(), $reviewAssignment->getId(), $reviewDueDate, null, false);
  192. } elseif ($schedConf->getSetting('reviewDeadlineType') == REVIEW_DEADLINE_TYPE_RELATIVE) {
  193. TrackDirectorAction::setDueDate($trackDirectorSubmission->getPaperId(), $reviewAssignment->getId(), null, $schedConf->getSetting('numWeeksPerReviewRelative'), false);
  194. } else {
  195. $dueDateSet = false;
  196. }
  197. if ($dueDateSet) {
  198. $reviewAssignment = $reviewAssignmentDao->getReviewAssignment($trackDirectorSubmission->getPaperId(), $reviewerId, $stage);
  199. $trackDirectorSubmission->updateReviewAssignment($reviewAssignment);
  200. $trackDirectorSubmissionDao->updateTrackDirectorSubmission($trackDirectorSubmission);
  201. }
  202. }
  203. // Add log
  204. import('paper.log.PaperLog');
  205. import('paper.log.PaperEventLogEntry');
  206. PaperLog::logEvent($trackDirectorSubmission->getPaperId(), PAPER_LOG_REVIEW_ASSIGN, LOG_TYPE_REVIEW, $reviewAssignment->getId(), 'log.review.reviewerAssigned', array('reviewerName' => $reviewer->getFullName(), 'paperId' => $trackDirectorSubmission->getPaperId(), 'stage' => $stage));
  207. }
  208. }
  209. /**
  210. * Clears a review assignment from a submission.
  211. * @param $trackDirectorSubmission object
  212. * @param $reviewId int
  213. */
  214. function clearReview($trackDirectorSubmission, $reviewId) {
  215. $trackDirectorSubmissionDao =& DAORegistry::getDAO('TrackDirectorSubmissionDAO');
  216. $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
  217. $userDao =& DAORegistry::getDAO('UserDAO');
  218. $user =& Request::getUser();
  219. $reviewAssignment =& $reviewAssignmentDao->getReviewAssignmentById($reviewId);
  220. if (isset($reviewAssignment) && $reviewAssignment->getPaperId() == $trackDirectorSubmission->getPaperId() && !HookRegistry::call('TrackDirectorAction::clearReview', array(&$trackDirectorSubmission, $reviewAssignment))) {
  221. $reviewer =& $userDao->getUser($reviewAssignment->getReviewerId());
  222. if (!isset($reviewer)) return false;
  223. $trackDirectorSubmission->removeReviewAssignment($reviewId);
  224. $trackDirectorSubmissionDao->updateTrackDirectorSubmission($trackDirectorSubmission);
  225. // Add log
  226. import('paper.log.PaperLog');
  227. import('paper.log.PaperEventLogEntry');
  228. PaperLog::logEvent($trackDirectorSubmission->getPaperId(), PAPER_LOG_REVIEW_CLEAR, LOG_TYPE_REVIEW, $reviewAssignment->getId(), 'log.review.reviewCleared', array('reviewerName' => $reviewer->getFullName(), 'paperId' => $trackDirectorSubmission->getPaperId(), 'stage' => $reviewAssignment->getStage()));
  229. }
  230. }
  231. /**
  232. * Notifies a reviewer about a review assignment.
  233. * @param $trackDirectorSubmission object
  234. * @param $reviewId int
  235. * @return boolean true iff ready for redirect
  236. */
  237. function notifyReviewer($trackDirectorSubmission, $reviewId, $send = false) {
  238. $trackDirectorSubmissionDao =& DAORegistry::getDAO('TrackDirectorSubmissionDAO');
  239. $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
  240. $userDao =& DAORegistry::getDAO('UserDAO');
  241. $conference =& Request::getConference();
  242. $schedConf =& Request::getSchedConf();
  243. $user =& Request::getUser();
  244. $reviewAssignment =& $reviewAssignmentDao->getReviewAssignmentById($reviewId);
  245. $reviewerAccessKeysEnabled = $schedConf->getSetting('reviewerAccessKeysEnabled');
  246. // If we're using access keys, disable the address fields
  247. // for this message. (Prevents security issue: track director
  248. // could CC or BCC someone else, or change the reviewer address,
  249. // in order to get the access key.)
  250. $preventAddressChanges = $reviewerAccessKeysEnabled;
  251. import('mail.PaperMailTemplate');
  252. $email = new PaperMailTemplate($trackDirectorSubmission, $reviewerAccessKeysEnabled?'REVIEW_REQUEST_ONECLICK':'REVIEW_REQUEST');
  253. if ($preventAddressChanges) {
  254. $email->setAddressFieldsEnabled(false);
  255. }
  256. if ($reviewAssignment->getPaperId() == $trackDirectorSubmission->getPaperId()) {
  257. $reviewer =& $userDao->getUser($reviewAssignment->getReviewerId());
  258. if (!isset($reviewer)) return true;
  259. if (!$email->isEnabled() || ($send && !$email->hasErrors())) {
  260. HookRegistry::call('TrackDirectorAction::notifyReviewer', array(&$trackDirectorSubmission, &$reviewAssignment, &$email));
  261. if ($email->isEnabled()) {
  262. $email->setAssoc(PAPER_EMAIL_REVIEW_NOTIFY_REVIEWER, PAPER_EMAIL_TYPE_REVIEW, $reviewId);
  263. if ($reviewerAccessKeysEnabled) {
  264. import('security.AccessKeyManager');
  265. import('pages.reviewer.ReviewerHandler');
  266. $accessKeyManager = new AccessKeyManager();
  267. // Key lifetime is the typical review period plus four weeks
  268. if ($schedConf->getSetting('reviewDeadlineType') == REVIEW_DEADLINE_TYPE_ABSOLUTE) {
  269. // Get number of days from now until review deadline date
  270. $reviewDeadlineDate = $schedConf->getSetting('numWeeksPerReviewAbsolute');
  271. $daysDiff = ($reviewDeadlineDate - strtotime(date("Y-m-d"))) / (60 * 60 * 24);
  272. $keyLifetime = (round($daysDiff / 7) + 4) * 7;
  273. } elseif ($schedConf->getSetting('reviewDeadlineType') == REVIEW_DEADLINE_TYPE_RELATIVE) {
  274. $keyLifetime = ((int) $schedConf->getSetting('numWeeksPerReviewRelative') + 4) * 7;
  275. }
  276. $email->addPrivateParam('ACCESS_KEY', $accessKeyManager->createKey('ReviewerContext', $reviewer->getId(), $reviewId, $keyLifetime));
  277. }
  278. if ($preventAddressChanges) {
  279. // Ensure that this messages goes to the reviewer, and the reviewer ONLY.
  280. $email->clearAllRecipients();
  281. $email->addRecipient($reviewer->getEmail(), $reviewer->getFullName());
  282. }
  283. $email->send();
  284. }
  285. $reviewAssignment->setDateNotified(Core::getCurrentDate());
  286. $reviewAssignment->setCancelled(0);
  287. $reviewAssignment->stampModified();
  288. $reviewAssignmentDao->updateReviewAssignment($reviewAssignment);
  289. return true;
  290. } else {
  291. if (!Request::getUserVar('continued')) {
  292. $weekLaterDate = strftime(Config::getVar('general', 'date_format_short'), strtotime('+1 week'));
  293. if ($reviewAssignment->getDateDue() != null) {
  294. $reviewDueDate = strftime(Config::getVar('general', 'date_format_short'), strtotime($reviewAssignment->getDateDue()));
  295. } else {
  296. if ($schedConf->getSetting('reviewDeadlineType') == REVIEW_DEADLINE_TYPE_ABSOLUTE) {
  297. $reviewDeadlineDate = $schedConf->getSetting('numWeeksPerReviewAbsolute');
  298. $reviewDueDate = strftime(Config::getVar('general', 'date_format_short'), $reviewDeadlineDate);
  299. } elseif ($schedConf->getSetting('reviewDeadlineType') == REVIEW_DEADLINE_TYPE_RELATIVE) {
  300. $numWeeks = max((int) $schedConf->getSetting('numWeeksPerReviewRelative'), 2);
  301. $reviewDueDate = strftime(Config::getVar('general', 'date_format_short'), strtotime('+' . $numWeeks . ' week'));
  302. }
  303. }
  304. $submissionUrl = Request::url(null, null, 'reviewer', 'submission', $reviewId, $reviewerAccessKeysEnabled?array('key' => 'ACCESS_KEY'):array());
  305. $paramArray = array(
  306. 'reviewerName' => $reviewer->getFullName(),
  307. 'weekLaterDate' => $weekLaterDate,
  308. 'reviewDueDate' => $reviewDueDate,
  309. 'reviewerUsername' => $reviewer->getUsername(),
  310. 'reviewerPassword' => $reviewer->getPassword(),
  311. 'editorialContactSignature' => $user->getContactSignature(),
  312. 'reviewGuidelines' => $schedConf->getLocalizedSetting('reviewGuidelines'),
  313. 'submissionReviewUrl' => $submissionUrl,
  314. 'passwordResetUrl' => Request::url(null, null, 'login', 'resetPassword', $reviewer->getUsername(), array('confirm' => Validation::generatePasswordResetHash($reviewer->getId())))
  315. );
  316. $email->assignParams($paramArray);
  317. $email->addRecipient($reviewer->getEmail(), $reviewer->getFullName());
  318. }
  319. $email->displayEditForm(Request::url(null, null, null, 'notifyReviewer'), array('reviewId' => $reviewId, 'paperId' => $trackDirectorSubmission->getPaperId()));
  320. return false;
  321. }
  322. }
  323. return true;
  324. }
  325. /**
  326. * Cancels a review.
  327. * @param $trackDirectorSubmission object
  328. * @param $reviewId int
  329. * @return boolean true iff ready for redirect
  330. */
  331. function cancelReview($trackDirectorSubmission, $reviewId, $send = false) {
  332. $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
  333. $trackDirectorSubmissionDao =& DAORegistry::getDAO('TrackDirectorSubmissionDAO');
  334. $userDao =& DAORegistry::getDAO('UserDAO');
  335. $conference =& Request::getConference();
  336. $user =& Request::getUser();
  337. $reviewAssignment =& $reviewAssignmentDao->getReviewAssignmentById($reviewId);
  338. $reviewer =& $userDao->getUser($reviewAssignment->getReviewerId());
  339. if (!isset($reviewer)) return true;
  340. if ($reviewAssignment->getPaperId() == $trackDirectorSubmission->getPaperId()) {
  341. // Only cancel the review if it is currently not cancelled but has previously
  342. // been initiated, and has not been completed.
  343. if ($reviewAssignment->getDateNotified() != null && !$reviewAssignment->getCancelled() && ($reviewAssignment->getDateCompleted() == null || $reviewAssignment->getDeclined())) {
  344. import('mail.PaperMailTemplate');
  345. $email = new PaperMailTemplate($trackDirectorSubmission, 'REVIEW_CANCEL');
  346. if (!$email->isEnabled() || ($send && !$email->hasErrors())) {
  347. HookRegistry::call('TrackDirectorAction::cancelReview', array(&$trackDirectorSubmission, &$reviewAssignment, &$email));
  348. if ($email->isEnabled()) {
  349. $email->setAssoc(PAPER_EMAIL_REVIEW_CANCEL, PAPER_EMAIL_TYPE_REVIEW, $reviewId);
  350. $email->send();
  351. }
  352. $reviewAssignment->setCancelled(1);
  353. $reviewAssignment->setDateCompleted(Core::getCurrentDate());
  354. $reviewAssignment->stampModified();
  355. $reviewAssignmentDao->updateReviewAssignment($reviewAssignment);
  356. // Add log
  357. import('paper.log.PaperLog');
  358. import('paper.log.PaperEventLogEntry');
  359. PaperLog::logEvent($trackDirectorSubmission->getPaperId(), PAPER_LOG_REVIEW_CANCEL, LOG_TYPE_REVIEW, $reviewAssignment->getId(), 'log.review.reviewCancelled', array('reviewerName' => $reviewer->getFullName(), 'paperId' => $trackDirectorSubmission->getPaperId(), 'stage' => $reviewAssignment->getStage()));
  360. } else {
  361. if (!Request::getUserVar('continued')) {
  362. $email->addRecipient($reviewer->getEmail(), $reviewer->getFullName());
  363. $paramArray = array(
  364. 'reviewerName' => $reviewer->getFullName(),
  365. 'reviewerUsername' => $reviewer->getUsername(),
  366. 'reviewerPassword' => $reviewer->getPassword(),
  367. 'editorialContactSignature' => $user->getContactSignature()
  368. );
  369. $email->assignParams($paramArray);
  370. }
  371. $email->displayEditForm(Request::url(null, null, null, 'cancelReview', 'send'), array('reviewId' => $reviewId, 'paperId' => $trackDirectorSubmission->getPaperId()));
  372. return false;
  373. }
  374. }
  375. }
  376. return true;
  377. }
  378. /**
  379. * Reminds a reviewer about a review assignment.
  380. * @param $trackDirectorSubmission object
  381. * @param $reviewId int
  382. * @return boolean true iff no error was encountered
  383. */
  384. function remindReviewer($trackDirectorSubmission, $reviewId, $send = false) {
  385. $trackDirectorSubmissionDao =& DAORegistry::getDAO('TrackDirectorSubmissionDAO');
  386. $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
  387. $userDao =& DAORegistry::getDAO('UserDAO');
  388. $conference =& Request::getConference();
  389. $schedConf =& Request::getSchedConf();
  390. $user =& Request::getUser();
  391. $reviewAssignment =& $reviewAssignmentDao->getReviewAssignmentById($reviewId);
  392. $reviewerAccessKeysEnabled = $schedConf->getSetting('reviewerAccessKeysEnabled');
  393. // If we're using access keys, disable the address fields
  394. // for this message. (Prevents security issue: track director
  395. // could CC or BCC someone else, or change the reviewer address,
  396. // in order to get the access key.)
  397. $preventAddressChanges = $reviewerAccessKeysEnabled;
  398. import('mail.PaperMailTemplate');
  399. $email = new PaperMailTemplate($trackDirectorSubmission, $reviewerAccessKeysEnabled?'REVIEW_REMIND_ONECLICK':'REVIEW_REMIND');
  400. if ($preventAddressChanges) {
  401. $email->setAddressFieldsEnabled(false);
  402. }
  403. if ($send && !$email->hasErrors()) {
  404. HookRegistry::call('TrackDirectorAction::remindReviewer', array(&$trackDirectorSubmission, &$reviewAssignment, &$email));
  405. $email->setAssoc(PAPER_EMAIL_REVIEW_REMIND, PAPER_EMAIL_TYPE_REVIEW, $reviewId);
  406. $reviewer =& $userDao->getUser($reviewAssignment->getReviewerId());
  407. if ($reviewerAccessKeysEnabled) {
  408. import('security.AccessKeyManager');
  409. import('pages.reviewer.ReviewerHandler');
  410. $accessKeyManager = new AccessKeyManager();
  411. // Key lifetime is the typical review period plus four weeks
  412. if ($schedConf->getSetting('reviewDeadlineType') == REVIEW_DEADLINE_TYPE_ABSOLUTE) {
  413. // Get number of days from now until review deadline date
  414. $reviewDeadlineDate = $schedConf->getSetting('numWeeksPerReviewAbsolute');
  415. $daysDiff = ($reviewDeadlineDate - strtotime(date("Y-m-d"))) / (60 * 60 * 24);
  416. $keyLifetime = (round($daysDiff / 7) + 4) * 7;
  417. } elseif ($schedConf->getSetting('reviewDeadlineType') == REVIEW_DEADLINE_TYPE_RELATIVE) {
  418. $keyLifetime = ((int) $schedConf->getSetting('numWeeksPerReviewRelative') + 4) * 7;
  419. }
  420. $email->addPrivateParam('ACCESS_KEY', $accessKeyManager->createKey('ReviewerContext', $reviewer->getId(), $reviewId, $keyLifetime));
  421. }
  422. if ($preventAddressChanges) {
  423. // Ensure that this messages goes to the reviewer, and the reviewer ONLY.
  424. $email->clearAllRecipients();
  425. $email->addRecipient($reviewer->getEmail(), $reviewer->getFullName());
  426. }
  427. $email->send();
  428. $reviewAssignment->setDateReminded(Core::getCurrentDate());
  429. $reviewAssignment->setReminderWasAutomatic(0);
  430. $reviewAssignmentDao->updateReviewAssignment($reviewAssignment);
  431. return true;
  432. } elseif ($reviewAssignment->getPaperId() == $trackDirectorSubmission->getPaperId()) {
  433. $reviewer =& $userDao->getUser($reviewAssignment->getReviewerId());
  434. if (!Request::getUserVar('continued')) {
  435. if (!isset($reviewer)) return true;
  436. $email->addRecipient($reviewer->getEmail(), $reviewer->getFullName());
  437. $submissionUrl = Request::url(null, null, 'reviewer', 'submission', $reviewId, $reviewerAccessKeysEnabled?array('key' => 'ACCESS_KEY'):array());
  438. // Format the review due date
  439. $reviewDueDate = strtotime($reviewAssignment->getDateDue());
  440. $dateFormatShort = Config::getVar('general', 'date_format_short');
  441. if ($reviewDueDate === -1 || $reviewDueDate === false) {
  442. // Use something human-readable if unspecified.
  443. $reviewDueDate = '_____';
  444. } else {
  445. $reviewDueDate = strftime($dateFormatShort, $reviewDueDate);
  446. }
  447. $paramArray = array(
  448. 'reviewerName' => $reviewer->getFullName(),
  449. 'reviewerUsername' => $reviewer->getUsername(),
  450. 'reviewerPassword' => $reviewer->getPassword(),
  451. 'reviewDueDate' => $reviewDueDate,
  452. 'editorialContactSignature' => $user->getContactSignature(),
  453. 'passwordResetUrl' => Request::url(null, null, 'login', 'resetPassword', $reviewer->getUsername(), array('confirm' => Validation::generatePasswordResetHash($reviewer->getId()))),
  454. 'submissionReviewUrl' => $submissionUrl
  455. );
  456. $email->assignParams($paramArray);
  457. }
  458. $email->displayEditForm(
  459. Request::url(null, null, null, 'remindReviewer', 'send'),
  460. array(
  461. 'reviewerId' => $reviewer->getId(),
  462. 'paperId' => $trackDirectorSubmission->getPaperId(),
  463. 'reviewId' => $reviewId
  464. )
  465. );
  466. return false;
  467. }
  468. return true;
  469. }
  470. /**
  471. * Thanks a reviewer for completing a review assignment.
  472. * @param $trackDirectorSubmission object
  473. * @param $reviewId int
  474. * @return boolean true iff ready for redirect
  475. */
  476. function thankReviewer($trackDirectorSubmission, $reviewId, $send = false) {
  477. $trackDirectorSubmissionDao =& DAORegistry::getDAO('TrackDirectorSubmissionDAO');
  478. $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
  479. $userDao =& DAORegistry::getDAO('UserDAO');
  480. $conference =& Request::getConference();
  481. $user =& Request::getUser();
  482. $reviewAssignment =& $reviewAssignmentDao->getReviewAssignmentById($reviewId);
  483. import('mail.PaperMailTemplate');
  484. $email = new PaperMailTemplate($trackDirectorSubmission, 'REVIEW_ACK');
  485. if ($reviewAssignment->getPaperId() == $trackDirectorSubmission->getPaperId()) {
  486. $reviewer =& $userDao->getUser($reviewAssignment->getReviewerId());
  487. if (!isset($reviewer)) return true;
  488. if (!$email->isEnabled() || ($send && !$email->hasErrors())) {
  489. HookRegistry::call('TrackDirectorAction::thankReviewer', array(&$trackDirectorSubmission, &$reviewAssignment, &$email));
  490. if ($email->isEnabled()) {
  491. $email->setAssoc(PAPER_EMAIL_REVIEW_THANK_REVIEWER, PAPER_EMAIL_TYPE_REVIEW, $reviewId);
  492. $email->send();
  493. }
  494. $reviewAssignment->setDateAcknowledged(Core::getCurrentDate());
  495. $reviewAssignment->stampModified();
  496. $reviewAssignmentDao->updateReviewAssignment($reviewAssignment);
  497. } else {
  498. if (!Request::getUserVar('continued')) {
  499. $email->addRecipient($reviewer->getEmail(), $reviewer->getFullName());
  500. $paramArray = array(
  501. 'reviewerName' => $reviewer->getFullName(),
  502. 'editorialContactSignature' => $user->getContactSignature()
  503. );
  504. $email->assignParams($paramArray);
  505. }
  506. $email->displayEditForm(Request::url(null, null, null, 'thankReviewer', 'send'), array('reviewId' => $reviewId, 'paperId' => $trackDirectorSubmission->getPaperId()));
  507. return false;
  508. }
  509. }
  510. return true;
  511. }
  512. /**
  513. * Rates a reviewer for quality of a review.
  514. * @param $paperId int
  515. * @param $reviewId int
  516. * @param $quality int
  517. */
  518. function rateReviewer($paperId, $reviewId, $quality = null) {
  519. $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
  520. $userDao =& DAORegistry::getDAO('UserDAO');
  521. $user =& Request::getUser();
  522. $reviewAssignment =& $reviewAssignmentDao->getReviewAssignmentById($reviewId);
  523. $reviewer =& $userDao->getUser($reviewAssignment->getReviewerId());
  524. if (!isset($reviewer)) return false;
  525. if ($reviewAssignment->getPaperId() == $paperId && !HookRegistry::call('TrackDirectorAction::rateReviewer', array(&$reviewAssignment, &$reviewer, &$quality))) {
  526. // Ensure that the value for quality
  527. // is between 1 and 5.
  528. if ($quality != null && ($quality >= 1 && $quality <= 5)) {
  529. $reviewAssignment->setQuality($quality);
  530. }
  531. $reviewAssignment->setDateRated(Core::getCurrentDate());
  532. $reviewAssignment->stampModified();
  533. $reviewAssignmentDao->updateReviewAssignment($reviewAssignment);
  534. // Add log
  535. import('paper.log.PaperLog');
  536. import('paper.log.PaperEventLogEntry');
  537. PaperLog::logEvent($paperId, PAPER_LOG_REVIEW_RATE, LOG_TYPE_REVIEW, $reviewAssignment->getId(), 'log.review.reviewerRated', array('reviewerName' => $reviewer->getFullName(), 'paperId' => $paperId, 'stage' => $reviewAssignment->getStage()));
  538. }
  539. }
  540. /**
  541. * Makes a reviewer's annotated version of a paper available to the author.
  542. * @param $paperId int
  543. * @param $reviewId int
  544. * @param $viewable boolean
  545. */
  546. function makeReviewerFileViewable($paperId, $reviewId, $fileId, $revision, $viewable = false) {
  547. $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
  548. $paperFileDao =& DAORegistry::getDAO('PaperFileDAO');
  549. $reviewAssignment =& $reviewAssignmentDao->getReviewAssignmentById($reviewId);
  550. $paperFile =& $paperFileDao->getPaperFile($fileId, $revision);
  551. if ($reviewAssignment->getPaperId() == $paperId && $reviewAssignment->getReviewerFileId() == $fileId && !HookRegistry::call('TrackDirectorAction::makeReviewerFileViewable', array(&$reviewAssignment, &$paperFile, &$viewable))) {
  552. $paperFile->setViewable($viewable);
  553. $paperFileDao->updatePaperFile($paperFile);
  554. }
  555. }
  556. /**
  557. * Sets the due date for a review assignment.
  558. * @param $paperId int
  559. * @param $reviewId int
  560. * @param $dueDate string
  561. * @param $numWeeks int
  562. * @param $logChange boolean
  563. */
  564. function setDueDate($paperId, $reviewId, $dueDate = null, $numWeeks = null, $logChange = true) {
  565. $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
  566. $userDao =& DAORegistry::getDAO('UserDAO');
  567. $user =& Request::getUser();
  568. $reviewAssignment =& $reviewAssignmentDao->getReviewAssignmentById($reviewId);
  569. $reviewer =& $userDao->getUser($reviewAssignment->getReviewerId());
  570. if (!isset($reviewer)) return false;
  571. if ($reviewAssignment->getPaperId() == $paperId && !HookRegistry::call('TrackDirectorAction::setDueDate', array(&$reviewAssignment, &$reviewer, &$dueDate, &$numWeeks))) {
  572. $today = getDate();
  573. $todayTimestamp = mktime(0, 0, 0, $today['mon'], $today['mday'], $today['year']);
  574. if ($dueDate != null) {
  575. $dueDateParts = explode('-', $dueDate);
  576. // Ensure that the specified due date is today or after today's date.
  577. if ($todayTimestamp <= strtotime($dueDate)) {
  578. $reviewAssignment->setDateDue(date('Y-m-d H:i:s', mktime(0, 0, 0, $dueDateParts[1], $dueDateParts[2], $dueDateParts[0])));
  579. } else {
  580. $reviewAssignment->setDateDue(date('Y-m-d H:i:s', $todayTimestamp));
  581. }
  582. } else {
  583. // Add the equivilant of $numWeeks weeks, measured in seconds, to $todaysTimestamp.
  584. $newDueDateTimestamp = $todayTimestamp + ($numWeeks * 7 * 24 * 60 * 60);
  585. $reviewAssignment->setDateDue(date('Y-m-d H:i:s', $newDueDateTimestamp));
  586. }
  587. $reviewAssignment->stampModified();
  588. $reviewAssignmentDao->updateReviewAssignment($reviewAssignment);
  589. if ($logChange) {
  590. // Add log
  591. import('paper.log.PaperLog');
  592. import('paper.log.PaperEventLogEntry');
  593. PaperLog::logEvent(
  594. $paperId,
  595. PAPER_LOG_REVIEW_SET_DUE_DATE,
  596. LOG_TYPE_REVIEW,
  597. $reviewAssignment->getId(),
  598. 'log.review.reviewDueDateSet',
  599. array(
  600. 'reviewerName' => $reviewer->getFullName(),
  601. 'dueDate' => strftime(Config::getVar('general', 'date_format_short'), strtotime($reviewAssignment->getDateDue())),
  602. 'paperId' => $paperId,
  603. 'stage' => $reviewAssignment->getStage()
  604. )
  605. );
  606. } // $logChange
  607. }
  608. }
  609. /**
  610. * Notifies an author that a submission was unsuitable.
  611. * @param $trackDirectorSubmission object
  612. * @return boolean true iff ready for redirect
  613. */
  614. function unsuitableSubmission($trackDirectorSubmission, $send = false) {
  615. $trackDirectorSubmissionDao =& DAORegistry::getDAO('TrackDirectorSubmissionDAO');
  616. $userDao =& DAORegistry::getDAO('UserDAO');
  617. $conference =& Request::getConference();
  618. $schedConf =& Request::getSchedConf();
  619. $user =& Request::getUser();
  620. $author =& $userDao->getUser($trackDirectorSubmission->getUserId());
  621. if (!isset($author)) return true;
  622. import('mail.PaperMailTemplate');
  623. $email = new PaperMailTemplate($trackDirectorSubmission, 'SUBMISSION_UNSUITABLE');
  624. if (!$email->isEnabled() || ($send && !$email->hasErrors())) {
  625. HookRegistry::call('TrackDirectorAction::unsuitableSubmission', array(&$trackDirectorSubmission, &$author, &$email));
  626. if ($email->isEnabled()) {
  627. $email->setAssoc(PAPER_EMAIL_DIRECTOR_NOTIFY_AUTHOR_UNSUITABLE, PAPER_EMAIL_TYPE_DIRECTOR, $user->getId());
  628. $email->send();
  629. }
  630. TrackDirectorAction::archiveSubmission($trackDirectorSubmission);
  631. return true;
  632. } else {
  633. if (!Request::getUserVar('continued')) {
  634. $paramArray = array(
  635. 'editorialContactSignature' => $user->getContactSignature(),
  636. 'authorName' => $author->getFullName(),
  637. 'locationCity' => $schedConf->getSetting('locationCity')
  638. );
  639. $email->assignParams($paramArray);
  640. $email->addRecipient($author->getEmail(), $author->getFullName());
  641. }
  642. $email->displayEditForm(Request::url(null, null, null, 'unsuitableSubmission'), array('paperId' => $trackDirectorSubmission->getPaperId()));
  643. return false;
  644. }
  645. }
  646. /**
  647. * Sets the reviewer recommendation for a review assignment.
  648. * Also concatenates the reviewer and director comments from Peer Review and adds them to Director Review.
  649. * @param $paperId int
  650. * @param $reviewId int
  651. * @param $recommendation int
  652. */
  653. function setReviewerRecommendation($paperId, $reviewId, $recommendation, $acceptOption) {
  654. $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
  655. $userDao =& DAORegistry::getDAO('UserDAO');
  656. $user =& Request::getUser();
  657. $reviewAssignment =& $reviewAssignmentDao->getReviewAssignmentById($reviewId);
  658. $reviewer =& $userDao->getUser($reviewAssignment->getReviewerId(), true);
  659. if ($reviewAssignment->getPaperId() == $paperId && !HookRegistry::call('TrackDirectorAction::setReviewerRecommendation', array(&$reviewAssignment, &$reviewer, &$recommendation, &$acceptOption))) {
  660. $reviewAssignment->setRecommendation($recommendation);
  661. $nowDate = Core::getCurrentDate();
  662. if (!$reviewAssignment->getDateConfirmed()) {
  663. $reviewAssignment->setDateConfirmed($nowDate);
  664. }
  665. $reviewAssignment->setDateCompleted($nowDate);
  666. $reviewAssignment->stampModified();
  667. $reviewAssignmentDao->updateReviewAssignment($reviewAssignment);
  668. // Add log
  669. import('paper.log.PaperLog');
  670. import('paper.log.PaperEventLogEntry');
  671. PaperLog::logEvent($paperId, PAPER_LOG_REVIEW_RECOMMENDATION_BY_PROXY, LOG_TYPE_REVIEW, $reviewAssignment->getId(), 'log.review.reviewRecommendationSetByProxy', array('directorName' => $user->getFullName(), 'reviewerName' => $reviewer->getFullName(), 'paperId' => $paperId, 'stage' => $reviewAssignment->getStage()));
  672. }
  673. }
  674. /**
  675. * Clear a review form
  676. * @param $trackDirectorSubmission object
  677. * @param $reviewId int
  678. */
  679. function clearReviewForm($trackDirectorSubmission, $reviewId) {
  680. $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
  681. $reviewAssignment =& $reviewAssignmentDao->getReviewAssignmentById($reviewId);
  682. if (HookRegistry::call('TrackDirectorAction::clearReviewForm', array(&$trackDirectorSubmission, &$reviewAssignment, &$reviewId))) return $reviewId;
  683. if (isset($reviewAssignment) && $reviewAssignment->getPaperId() == $trackDirectorSubmission->getPaperId()) {
  684. $reviewFormResponseDao =& DAORegistry::getDAO('ReviewFormResponseDAO');
  685. $responses = $reviewFormResponseDao->getReviewReviewFormResponseValues($reviewId);
  686. if (!empty($responses)) {
  687. $reviewFormResponseDao->deleteByReviewId($reviewId);
  688. }
  689. $reviewAssignment->setReviewFormId(null);
  690. $reviewAssignmentDao->updateReviewAssignment($reviewAssignment);
  691. }
  692. }
  693. /**
  694. * Assigns a review form to a review.
  695. * @param $trackDirectorSubmission object
  696. * @param $reviewId int
  697. * @param $reviewFormId int
  698. */
  699. function addReviewForm($trackDirectorSubmission, $reviewId, $reviewFormId) {
  700. $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
  701. $reviewAssignment =& $reviewAssignmentDao->getReviewAssignmentById($reviewId);
  702. if (HookRegistry::call('TrackDirectorAction::addReviewForm', array(&$trackDirectorSubmission, &$reviewAssignment, &$reviewId, &$reviewFormId))) return $reviewFormId;
  703. if (isset($reviewAssignment) && $reviewAssignment->getPaperId() == $trackDirectorSubmission->getPaperId()) {
  704. // Only add the review form if it has not already
  705. // been assigned to the review.
  706. if ($reviewAssignment->getReviewFormId() != $reviewFormId) {
  707. $reviewFormResponseDao =& DAORegistry::getDAO('ReviewFormResponseDAO');
  708. $responses = $reviewFormResponseDao->getReviewReviewFormResponseValues($reviewId);
  709. if (!empty($responses)) {
  710. $reviewFormResponseDao->deleteByReviewId($reviewId);
  711. }
  712. $reviewAssignment->setReviewFormId($reviewFormId);
  713. $reviewAssignmentDao->updateReviewAssignment($reviewAssignment);
  714. }
  715. }
  716. }
  717. /**
  718. * View review form response.
  719. * @param $trackDirectorSubmission object
  720. * @param $reviewId int
  721. */
  722. function viewReviewFormResponse($trackDirectorSubmission, $reviewId) {
  723. $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
  724. $reviewAssignment =& $reviewAssignmentDao->getReviewAssignmentById($reviewId);
  725. if (HookRegistry::call('TrackDirectorAction::viewReviewFormResponse', array(&$trackDirectorSubmission, &$reviewAssignment, &$reviewId))) return $reviewId;
  726. if (isset($reviewAssignment) && $reviewAssignment->getPaperId() == $trackDirectorSubmission->getPaperId()) {
  727. $reviewFormId = $reviewAssignment->getReviewFormId();
  728. if ($reviewFormId != null) {
  729. import('submission.form.ReviewFormResponseForm');
  730. $reviewForm = new ReviewFormResponseForm($reviewId, $reviewFormId);
  731. $reviewForm->initData();
  732. $reviewForm->display();
  733. }
  734. }
  735. }
  736. /**
  737. * Set the file to use as the default editing file.
  738. * @param $trackDirectorSubmission object
  739. * @param $fileId int
  740. * @param $revision int
  741. * @param $createGalley boolean
  742. * TODO: SECURITY!
  743. */
  744. function setEditingFile($trackDirectorSubmission, $fileId, $revision, $createGalley = false) {
  745. import('file.PaperFileManager');
  746. $paperFileManager = new PaperFileManager($trackDirectorSubmission->getPaperId());
  747. $trackDirectorSubmissionDao =& DAORegistry::getDAO('TrackDirectorSubmissionDAO');
  748. $paperFileDao =& DAORegistry::getDAO('PaperFileDAO');
  749. $user =& Request::getUser();
  750. if (!HookRegistry::call('TrackDirectorAction::setEditingFile', array(&$trackDirectorSubmission, &$fileId, &$revision))) {
  751. // Copy the file from the director decision file folder to the layout folder
  752. $newFileId = $paperFileManager->copyToLayoutFile($fileId, $revision);
  753. $trackDirectorSubmission->setLayoutFileId($newFileId);
  754. $trackDirectorSubmissionDao->updateTrackDirectorSubmission($trackDirectorSubmission);
  755. if ($createGalley) {
  756. $paperGalleyDao =& DAORegistry::getDAO('PaperGalleyDAO');
  757. $galleys =& $paperGalleyDao->getGalleysByPaper($trackDirectorSubmission->getPaperId());
  758. if (empty($galleys)) {
  759. $layoutFile =& $paperFileDao->getPaperFile($newFileId, $revision);
  760. $fileType = $layoutFile->getFileType();
  761. $fileId = $paperFileManager->copyPublicFile($layoutFile->getFilePath(), $fileType);
  762. if (strstr($fileType, 'html')) {
  763. $galley = new PaperHTMLGalley();
  764. } else {
  765. $galley = new PaperGalley();
  766. }
  767. $galley->setPaperId($trackDirectorSubmission->getPaperId());
  768. $galley->setLocale(AppLocale::getLocale());
  769. $galley->setFileId($fileId);
  770. if ($galley->isHTMLGalley()) {
  771. $galley->setLabel('HTML');
  772. } elseif (strstr($fileType, 'pdf')) {
  773. $galley->setLabel('PDF');
  774. } else if (strstr($fileType, 'postscript')) {
  775. $galley->setLabel('Postscript');
  776. } else if (strstr($fileType, 'xml')) {
  777. $galley->setLabel('XML');
  778. } else {
  779. $galley->setLabel(__('common.untitled'));
  780. }
  781. $paperGalleyDao->insertGalley($galley);
  782. }
  783. }
  784. // Add log
  785. import('paper.log.PaperLog');
  786. import('paper.log.PaperEventLogEntry');
  787. PaperLog::logEvent($trackDirectorSubmission->getPaperId(), PAPER_LOG_LAYOUT_SET_FILE, LOG_TYPE_FILE, $trackDirectorSubmission->getLayoutFileId(), 'log.layout.layoutFileSet', array('directorName' => $user->getFullName(), 'paperId' => $trackDirectorSubmission->getPaperId()));
  788. }
  789. }
  790. /**
  791. * Upload the review version of a paper.
  792. * @param $trackDirectorSubmission object
  793. */
  794. function uploadReviewVersion($trackDirectorSubmission) {
  795. import('file.PaperFileManager');
  796. $paperFileManager = new PaperFileManager($trackDirectorSubmission->getPaperId());
  797. $trackDirectorSubmissionDao =& DAORegistry::getDAO('TrackDirectorSubmissionDAO');
  798. $fileName = 'upload';
  799. if ($paperFileManager->uploadError($fileName)) return false;
  800. if (!$paperFileManager->uploadedFileExists($fileName)) return false;
  801. if (HookRegistry::call('TrackDirectorAction::uploadReviewVersion', array(&$trackDirectorSubmission))) return true;
  802. if ($trackDirectorSubmission->getReviewFileId() != null) {
  803. $reviewFileId = $paperFileManager->uploadReviewFile($fileName, $trackDirectorSubmission->getReviewFileId());
  804. // Increment the review revision.
  805. $trackDirectorSubmission->setReviewRevision($trackDirectorSubmission->getReviewRevision()+1);
  806. } else {
  807. $reviewFileId = $paperFileManager->uploadReviewFile($fileName);
  808. $trackDirectorSubmission->setReviewRevision(1);
  809. }
  810. $directorFileId = $paperFileManager->copyToDirectorFile($reviewFileId, $trackDirectorSubmission->getReviewRevision(), $trackDirectorSubmission->getDirectorFileId());
  811. if ($reviewFileId != 0 && isset($directorFileId) && $directorFileId != 0) {
  812. $trackDirectorSubmission->setReviewFileId($reviewFileId);
  813. $trackDirectorSubmission->setDirectorFileId($directorFileId);
  814. $trackDirectorSubmissionDao->updateTrackDirectorSubmission($trackDirectorSubmission);
  815. }
  816. return true;
  817. }
  818. /**
  819. * Upload the post-review version of a paper.
  820. * @param $trackDirectorSubmission object
  821. */
  822. function uploadDirectorVersion($trackDirectorSubmission) {
  823. import('file.PaperFileManager');
  824. $paperFileManager = new PaperFileManager($trackDirectorSubmission->getPaperId());
  825. $trackDirectorSubmissionDao =& DAORegistry::getDAO('TrackDirectorSubmissionDAO');
  826. $user =& Request::getUser();
  827. $fileName = 'upload';
  828. if ($paperFileManager->uploadError($fileName)) return false;
  829. if ($paperFileManager->uploadedFileExists($fileName) && !HookRegistry::call('TrackDirectorAction::uploadDirectorVersion', array(&$trackDirectorSubmission))) {
  830. if ($trackDirectorSubmission->getDirectorFileId() != null) {
  831. $fileId = $paperFileManager->uploadDirectorDecisionFile($fileName, $trackDirectorSubmission->getDirectorFileId());
  832. } else {
  833. $fileId = $paperFileManager->uploadDirectorDecisionFile($fileName);
  834. }
  835. }
  836. if (isset($fileId) && $fileId != 0) {
  837. $trackDirectorSubmission->setDirectorFileId($fileId);
  838. $trackDirectorSubmissionDao->updateTrackDirectorSubmission($trackDirectorSubmission);
  839. // Add log
  840. import('paper.log.PaperLog');
  841. import('paper.log.PaperEventLogEntry');
  842. PaperLog::logEvent($trackDirectorSubmission->getPaperId(), PAPER_LOG_DIRECTOR_FILE, LOG_TYPE_DIRECTOR, $trackDirectorSubmission->getDirectorFileId(), 'log.director.directorFile');
  843. }
  844. }
  845. /**
  846. * Mark a paper as published or move a previously published paper
  847. * back into the queue.
  848. * @param $trackDirectorSubmission object
  849. * @param $complete boolean If true, complete the submission. If false,
  850. * return it to the queue (unpublish it).
  851. */
  852. function completePaper($trackDirectorSubmission, $complete) {
  853. import('file.PaperFileManager');
  854. $paperFileManager = new PaperFileManager($trackDirectorSubmission->getPaperId());
  855. $trackDirectorSubmissionDao =& DAORegistry::getDAO('TrackDirectorSubmissionDAO');
  856. $user =& Request::getUser();
  857. import('paper.log.PaperLog');
  858. import('paper.log.PaperEventLogEntry');
  859. if ($complete) { // Publish the paper.
  860. $trackDirectorSubmission->setStatus(STATUS_PUBLISHED);
  861. $trackDirectorSubmissionDao->updateTrackDirectorSubmission($trackDirectorSubmission);
  862. // Add a published paper object
  863. $publishedPaperDao =& DAORegistry::getDAO('PublishedPaperDAO');
  864. if(($publishedPaper = $publishedPaperDao->getPublishedPaperByPaperId($trackDirectorSubmission->getPaperId())) == null) {
  865. $schedConfId = $trackDirectorSubmission->getSchedConfId();
  866. $publishedPaper = new PublishedPaper();
  867. $publishedPaper->setPaperId($trackDirectorSubmission->getPaperId());
  868. $publishedPaper->setSchedConfId($schedConfId);
  869. $publishedPaper->setDatePublished(Core::getCurrentDate());
  870. $publishedPaper->setSeq(REALLY_BIG_NUMBER);
  871. $publishedPaper->setViews(0);
  872. $publishedPaperDao->insertPublishedPaper($publishedPaper);
  873. // Resequence the published papers.
  874. $publishedPaperDao->resequencePublishedPapers($trackDirectorSubmission->getTrackId(), $schedConfId);
  875. }
  876. // Add log
  877. PaperLog::logEvent($trackDirectorSubmission->getPaperId(), PAPER_LOG_DIRECTOR_PUBLISH, LOG_TYPE_DIRECTOR, $trackDirectorSubmission->getDirectorFileId(), 'log.director.publish');
  878. } else { // Un-publish the paper.
  879. $trackDirectorSubmission->setStatus(STATUS_QUEUED);
  880. $trackDirectorSubmissionDao->updateTrackDirectorSubmission($trackDirectorSubmission);
  881. // Add log
  882. PaperLog::logEvent($trackDirectorSubmission->getPaperId(), PAPER_LOG_DIRECTOR_UNPUBLISH, LOG_TYPE_DIRECTOR, $trackDirectorSubmission->getDirectorFileId(), 'log.director.unpublish');
  883. }
  884. }
  885. /**
  886. * Archive a submission.
  887. * @param $trackDirectorSubmission object
  888. */
  889. function archiveSubmission($trackDirectorSubmission) {
  890. $trackDirectorSubmissionDao =& DAORegistry::getDAO('TrackDirectorSubmissionDAO');
  891. $user =& Request::getUser();
  892. if (HookRegistry::call('TrackDirectorAction::archiveSubmission', array(&$trackDirectorSubmission))) return;
  893. $trackDirectorSubmission->setStatus(STATUS_ARCHIVED);
  894. $trackDirectorSubmission->stampStatusModified();
  895. $trackDirectorSubmission->stampDateToArchive();
  896. $trackDirectorSubmissionDao->updateTrackDirectorSubmission($trackDirectorSubmission);
  897. // Add log
  898. import('paper.log.PaperLog');
  899. import('paper.log.PaperEventLogEntry');
  900. PaperLog::logEvent($trackDirectorSubmission->getPaperId(), PAPER_LOG_DIRECTOR_ARCHIVE, LOG_TYPE_DIRECTOR, $trackDirectorSubmission->getPaperId(), 'log.director.archived', array('paperId' => $trackDirectorSubmission->getPaperId()));
  901. }
  902. /**
  903. * Restores a submission to the queue.
  904. * @param $trackDirectorSubmission object
  905. */
  906. function restoreToQueue($trackDirectorSubmission) {
  907. if (HookRegistry::call('TrackDirectorAction::restoreToQueue', array(&$trackDirectorSubmission))) return;
  908. $trackDirectorSubmissionDao =& DAORegistry::getDAO('TrackDirectorSubmissionDAO');
  909. // Determine which queue to return the paper to: the
  910. // scheduling queue or the editing queue.
  911. $publishedPaperDao =& DAORegistry::getDAO('PublishedPaperDAO');
  912. $publishedPaper =& $publishedPaperDao->getPublishedPaperByPaperId($trackDirectorSubmission->getPaperId());
  913. if ($publishedPaper) {
  914. $trackDirectorSubmission->setStatus(STATUS_PUBLISHED);
  915. } else {
  916. $trackDirectorSubmission->setStatus(STATUS_QUEUED);
  917. }
  918. unset($publishedPaper);
  919. $trackDirectorSubmission->stampStatusModified();
  920. $trackDirectorSubmissionDao->updateTrackDirectorSubmission($trackDirectorSubmission);
  921. // Add log
  922. import('paper.log.PaperLog');
  923. import('paper.log.PaperEventLogEntry');
  924. PaperLog::logEvent($trackDirectorSubmission->getPaperId(), PAPER_LOG_DIRECTOR_RESTORE, LOG_TYPE_DIRECTOR, $trackDirectorSubmission->getPaperId(), 'log.director.restored', array('paperId' => $trackDirectorSubmission->getPaperId()));
  925. }
  926. //
  927. // Layout Editing
  928. //
  929. /**
  930. * Change the sequence order of a galley.
  931. * @param $paper object
  932. * @param $galleyId int
  933. * @param $direction char u = up, d = down
  934. */
  935. function orderGalley($paper, $galleyId, $direction) {
  936. $galleyDao =& DAORegistry::getDAO('PaperGalleyDAO');
  937. $galley =& $galleyDao->getGalley($galleyId, $paper->getId());
  938. if (isset($galley)) {
  939. $galley->setSequence($galley->getSequence() + ($direction == 'u' ? -1.5 : 1.5));
  940. $galleyDao->updateGalley($galley);
  941. $galleyDao->resequenceGalleys($paper->getId());
  942. }
  943. }
  944. /**
  945. * Delete a galley.
  946. * @param $paper object
  947. * @param $galleyId int
  948. */
  949. function deleteGalley($paper, $galleyId) {
  950. import('file.PaperFileManager');
  951. $galleyDao =& DAORegistry::getDAO('PaperGalleyDAO');
  952. $galley =& $galleyDao->getGalley($galleyId, $paper->getId());
  953. if (isset($galley) && !HookRegistry::call('TrackDirectorAction::deleteGalley', array(&$paper, &$galley))) {
  954. $paperFileManager = new PaperFileManager($paper->getId());
  955. if ($galley->getFileId()) {
  956. $paperFileManager->deleteFile($galley->getFileId());
  957. import('search.PaperSearchIndex');
  958. PaperSearchIndex::deleteTextIndex($paper->getId(), PAPER_SEARCH_GALLEY_FILE, $galley->getFileId());
  959. }
  960. if ($galley->isHTMLGalley()) {
  961. if ($galley->getStyleFileId()) {
  962. $paperFileManager->deleteFile($galley->getStyleFileId());
  963. }
  964. foreach ($galley->getImageFiles() as $image) {
  965. $paperFileManager->deleteFile($image->getFileId());
  966. }
  967. }
  968. $galleyDao->deleteGalley($galley);
  969. }
  970. }
  971. /**
  972. * Change the sequence order of a supplementary file.
  973. * @param $paper object
  974. * @param $suppFileId int
  975. * @param $direction char u = up, d = down
  976. */
  977. function orderSuppFile($paper, $suppFileId, $direction) {
  978. $suppFileDao =& DAORegistry::getDAO('SuppFileDAO');
  979. $suppFile =& $suppFileDao->getSuppFile($suppFileId, $paper->getId());
  980. if (isset($suppFile)) {
  981. $suppFile->setSequence($suppFile->getSequence() + ($direction == 'u' ? -1.5 : 1.5));
  982. $suppFileDao->updateSuppFile($suppFile);
  983. $suppFileDao->resequenceSuppFiles($paper->getId());
  984. }
  985. }
  986. /**
  987. * Delete a supplementary file.
  988. * @param $paper object
  989. * @param $suppFileId int
  990. */
  991. function deleteSuppFile($paper, $suppFileId) {
  992. import('file.PaperFileManager');
  993. $suppFileDao =& DAORegistry::getDAO('SuppFileDAO');
  994. $suppFile =& $suppFileDao->getSuppFile($suppFileId, $paper->getId());
  995. if (isset($suppFile) && !HookRegistry::call('TrackDirectorAction::deleteSuppFile', array(&$paper, &$suppFile))) {
  996. if ($suppFile->getFileId()) {
  997. $paperFileManager = new PaperFileManager($paper->getId());
  998. $paperFileManager->deleteFile($suppFile->getFileId());
  999. import('search.PaperSearchIndex');
  1000. PaperSearchIndex::deleteTextIndex($paper->getId(), PAPER_SEARCH_SUPPLEMENTARY_FILE, $suppFile->getFileId());
  1001. }
  1002. $suppFileDao->deleteSuppFile($suppFile);
  1003. }
  1004. }
  1005. /**
  1006. * Delete a file from a paper.
  1007. * @param $submission object
  1008. * @param $fileId int
  1009. * @param $revision int (optional)
  1010. */
  1011. function deletePaperFile($submission, $fileId, $revision) {
  1012. import('file.PaperFileManager');
  1013. $file =& $submission->getDirectorFile();
  1014. if (isset($file) && $file->getFileId() == $fileId && !HookRegistry::call('TrackDirectorAction::deletePaperFile', array(&$submission, &$fileId, &$revision))) {
  1015. $paperFileManager = new PaperFileManager($submission->getPaperId());
  1016. $paperFileManager->deleteFile($fileId, $revision);
  1017. }
  1018. }
  1019. /**
  1020. * Delete an image from a paper galley.
  1021. * @param $submission object
  1022. * @param $fileId int
  1023. * @param $revision int (optional)
  1024. */
  1025. function deletePaperImage($submission, $fileId, $revision) {
  1026. import('file.PaperFileManager');
  1027. $paperGalleyDao =& DAORegistry::getDAO('PaperGalleyDAO');
  1028. if (HookRegistry::call('TrackDirectorAction::deletePaperImage', array(&$submission, &$fileId, &$revision))) return;
  1029. foreach ($submission->getGalleys() as $galley) {
  1030. $images =& $paperGalleyDao->getGalleyImages($galley->getId());
  1031. foreach ($images as $imageFile) {
  1032. if ($imageFile->getPaperId() == $submission->getPaperId() && $fileId == $imageFile->getFileId() && $imageFile->getRevision() == $revision) {
  1033. $paperFileManager = new PaperFileManager($submission->getPaperId());
  1034. $paperFileManager->deleteFile($imageFile->getFileId(), $imageFile->getRevision());
  1035. }
  1036. }
  1037. unset($images);
  1038. }
  1039. }
  1040. /**
  1041. * Add Submission Note
  1042. * @param $paperId int
  1043. */
  1044. function addSubmissionNote($paperId) {
  1045. import('file.PaperFileManager');
  1046. $paperNoteDao =& DAORegistry::getDAO('PaperNoteDAO');
  1047. $user =& Request::getUser();
  1048. $paperNote = new PaperNote();
  1049. $paperNote->setPaperId($paperId);
  1050. $paperNote->setUserId($user->getId());
  1051. $paperNote->setDateCreated(Core::getCurrentDate());
  1052. $paperNote->setDateModified(Core::getCurrentDate());
  1053. $paperNote->setTitle(Request::getUserVar('title'));
  1054. $paperNote->setNote(Request::getUserVar('note'));
  1055. if (!HookRegistry::call('TrackDirectorAction::addSubmissionNote', array(&$paperId, &$paperNote))) {
  1056. $paperFileManager = new PaperFileManager($paperId);
  1057. if ($paperFileManager->uploadedFileExists('upload')) {
  1058. if ($paperFileManager->uploadError('upload')) return false;
  1059. $fileId = $paperFileManager->uploadSubmissionNoteFile('upload');
  1060. } else {
  1061. $fileId = 0;
  1062. }
  1063. $paperNote->setFileId($fileId);
  1064. $paperNoteDao->insertPaperNote($paperNote);
  1065. }
  1066. }
  1067. /**
  1068. * Remove Submission Note
  1069. * @param $paperId int
  1070. */
  1071. function removeSubmissionNote($paperId) {
  1072. $noteId = Request::getUserVar('noteId');
  1073. $fileId = Request::getUserVar('fileId');
  1074. if (HookRegistry::call('TrackDirectorAction::removeSubmissionNote', array(&$paperId, &$noteId, &$fileId))) return;
  1075. // if there is an attached file, remove it as well
  1076. if ($fileId) {
  1077. import('file.PaperFileManager');
  1078. $paperFileManager = new PaperFileManager($paperId);
  1079. $paperFileManager->deleteFile($fileId);
  1080. }
  1081. $paperNoteDao =& DAORegistry::getDAO('PaperNoteDAO');
  1082. $paperNoteDao->deletePaperNoteById($noteId);
  1083. }
  1084. /**
  1085. * Updates Submission Note
  1086. * @param $paperId int
  1087. */
  1088. function updateSubmissionNote($paperId) {
  1089. import('file.PaperFileManager');
  1090. $paperNoteDao =& DAORegistry::getDAO('PaperNoteDAO');
  1091. $user =& Request::getUser();
  1092. $paperNote = new PaperNote();
  1093. $paperNote->setNoteId(Request::getUserVar('noteId'));
  1094. $paperNote->setPaperId($paperId);
  1095. $paperNote->setUserId($user->getId());
  1096. $paperNote->setDateModified(Core::getCurrentDate());
  1097. $paperNote->setTitle(Request::getUserVar('title'));
  1098. $paperNote->setNote(Request::getUserVar('note'));
  1099. $paperNote->setFileId(Request::getUserVar('fileId'));
  1100. if (HookRegistry::call('TrackDirectorAction::updateSubmissionNote', array(&$paperId, &$paperNote))) return;
  1101. $paperFileManager = new PaperFileManager($paperId);
  1102. if ($paperFileManager->uploadError('upload')) return false;
  1103. // if there is a new file being uploaded
  1104. if ($paperFileManager->uploadedFileExists('upload')) {
  1105. // Attach the new file to the note, overwriting existing file if necessary
  1106. $fileId = $paperFileManager->uploadSubmissionNoteFile('upload', $paperNote->getFileId(), true);
  1107. $paperNote->setFileId($fileId);
  1108. } else {
  1109. if (Request::getUserVar('removeUploadedFile')) {
  1110. $paperFileManager = new PaperFileManager($paperId);
  1111. $paperFileManager->deleteFile($paperNote->getFileId());
  1112. $paperNote->setFileId(0);
  1113. }
  1114. }
  1115. $paperNoteDao->updatePaperNote($paperNote);
  1116. }
  1117. /**
  1118. * Clear All Submission Notes
  1119. * @param $paperId int
  1120. */
  1121. function clearAllSubmissionNotes($paperId) {
  1122. if (HookRegistry::call('TrackDirectorAction::clearAllSubmissionNotes', array(&$paperId))) return;
  1123. import('file.PaperFileManager');
  1124. $paperNoteDao =& DAORegistry::getDAO('PaperNoteDAO');
  1125. $fileIds = $paperNoteDao->getAllPaperNoteFileIds($paperId);
  1126. if (!empty($fileIds)) {
  1127. $paperFileDao =& DAORegistry::getDAO('PaperFileDAO');
  1128. $paperFileManager = new PaperFileManager($paperId);
  1129. foreach ($fileIds as $fileId) {
  1130. $paperFileManager->deleteFile($fileId);
  1131. }
  1132. }
  1133. $paperNoteDao->clearAllPaperNotes($paperId);
  1134. }
  1135. //
  1136. // Comments
  1137. //
  1138. /**
  1139. * View reviewer comments.
  1140. * @param $paper object
  1141. * @param $reviewId int
  1142. */
  1143. function viewPeerReviewComments(&$paper, $reviewId) {
  1144. if (HookRegistry::call('TrackDirectorAction::viewPeerReviewComments', array(&$paper, &$reviewId))) return;
  1145. import('submission.form.comment.PeerReviewCommentForm');
  1146. $commentForm = new PeerReviewCommentForm($paper, $reviewId, Validation::isDirector()?ROLE_ID_DIRECTOR:ROLE_ID_TRACK_DIRECTOR);
  1147. $commentForm->initData();
  1148. $commentForm->display();
  1149. }
  1150. /**
  1151. * Post reviewer comments.
  1152. * @param $paper object
  1153. * @param $reviewId int
  1154. * @param $emailComment boolean
  1155. */
  1156. function postPeerReviewComment(&$paper, $reviewId, $emailComment) {
  1157. if (HookRegistry::call('TrackDirectorAction::postPeerReviewComment', array(&$paper, &$reviewId, &$emailComment))) return;
  1158. import('submission.form.comment.PeerReviewCommentForm');
  1159. $commentForm = new PeerReviewCommentForm($paper, $reviewId, Validation::isDirector()?ROLE_ID_DIRECTOR:ROLE_ID_TRACK_DIRECTOR);
  1160. $commentForm->readInputData();
  1161. if ($commentForm->validate()) {
  1162. $commentForm->execute();
  1163. // Send a notification to associated users
  1164. import('notification.NotificationManager');
  1165. $notificationManager = new NotificationManager();
  1166. $notificationUsers = $paper->getAssociatedUserIds();
  1167. foreach ($notificationUsers as $userRole) {
  1168. $url = Request::url(null, null, $userRole['role'], 'submissionReview', $paper->getId(), null, 'peerReview');
  1169. $notificationManager->createNotification(
  1170. $userRole['id'], 'notification.type.reviewerComment',
  1171. $paper->getLocalizedTitle(), $url, 1, NOTIFICATION_TYPE_REVIEWER_COMMENT
  1172. );
  1173. }
  1174. if ($emailComment) {
  1175. $commentForm->email();
  1176. }
  1177. } else {
  1178. $commentForm->display();
  1179. return false;
  1180. }
  1181. return true;
  1182. }
  1183. /**
  1184. * View director decision comments.
  1185. * @param $paper object
  1186. */
  1187. function viewDirectorDecisionComments($paper) {
  1188. if (HookRegistry::call('TrackDirectorAction::viewDirectorDecisionComments', array(&$paper))) return;
  1189. import('submission.form.comment.DirectorDecisionCommentForm');
  1190. $commentForm = new DirectorDecisionCommentForm($paper, Validation::isDirector()?ROLE_ID_DIRECTOR:ROLE_ID_TRACK_DIRECTOR);
  1191. $commentForm->initData();
  1192. $commentForm->display();
  1193. }
  1194. /**
  1195. * Post director decision comment.
  1196. * @param $paper int
  1197. * @param $emailComment boolean
  1198. */
  1199. function postDirectorDecisionComment($paper, $emailComment) {
  1200. if (HookRegistry::call('TrackDirectorAction::postDirectorDecisionComment', array(&$paper, &$emailComment))) return;
  1201. import('submission.form.comment.DirectorDecisionCommentForm');
  1202. $commentForm = new DirectorDecisionCommentForm($paper, Validation::isDirector()?ROLE_ID_DIRECTOR:ROLE_ID_TRACK_DIRECTOR);
  1203. $commentForm->readInputData();
  1204. if ($commentForm->validate()) {
  1205. $commentForm->execute();
  1206. // Send a notification to associated users
  1207. import('notification.NotificationManager');
  1208. $notificationManager = new NotificationManager();
  1209. $notificationUsers = $paper->getAssociatedUserIds(true, false);
  1210. foreach ($notificationUsers as $userRole) {
  1211. $url = Request::url(null, null, $userRole['role'], 'submissionReview', $paper->getId(), null, 'directorDecision');
  1212. $notificationManager->createNotification(
  1213. $userRole['id'], 'notification.type.directorDecisionComment',
  1214. $paper->getLocalizedTitle(), $url, 1, NOTIFICATION_TYPE_DIRECTOR_DECISION_COMMENT
  1215. );
  1216. }
  1217. if ($emailComment) {
  1218. $commentForm->email();
  1219. }
  1220. } else {
  1221. $commentForm->display();
  1222. return false;
  1223. }
  1224. return true;
  1225. }
  1226. /**
  1227. * Email director decision comment.
  1228. * @param $trackDirectorSubmission object
  1229. * @param $send boolean
  1230. */
  1231. function emailDirectorDecisionComment($trackDirectorSubmission, $send) {
  1232. $userDao =& DAORegistry::getDAO('UserDAO');
  1233. $paperCommentDao =& DAORegistry::getDAO('PaperCommentDAO');
  1234. $conference =& Request::getConference();
  1235. $schedConf =& Request::getSchedConf();
  1236. $templateName = null;
  1237. $reviewMode = $trackDirectorSubmission->getReviewMode();
  1238. $stages = $trackDirectorSubmission->getDecisions();
  1239. if (is_array($stages)) {
  1240. $isAbstract = array_pop(array_keys($stages)) == REVIEW_STAGE_ABSTRACT;
  1241. }
  1242. if (isset($stages) && is_array($stages)) {
  1243. $decisions = array_pop($stages);
  1244. // If this round has no decision, revert to prior round
  1245. if (empty($decisions)) $decisions = array_pop($stages);
  1246. }
  1247. if (isset($decisions) && is_array($decisions)) $lastDecision = array_pop($decisions);
  1248. if (isset($lastDecision) && is_array($lastDecision)) switch ($lastDecision['decision']) {
  1249. case SUBMISSION_DIRECTOR_DECISION_INVITE:
  1250. $templateName = ($reviewMode==REVIEW_MODE_BOTH_SEQUENTIAL?'SUBMISSION_PAPER_INVITE':'SUBMISSION_ABSTRACT_ACCEPT');
  1251. break;
  1252. case SUBMISSION_DIRECTOR_DECISION_ACCEPT:
  1253. $templateName = 'SUBMISSION_PAPER_ACCEPT';
  1254. break;
  1255. case SUBMISSION_DIRECTOR_DECISION_PENDING_REVISIONS:
  1256. $templateName = $isAbstract?'SUBMISSION_ABSTRACT_REVISE':'SUBMISSION_PAPER_REVISE';
  1257. break;
  1258. case SUBMISSION_DIRECTOR_DECISION_DECLINE:
  1259. $templateName = $isAbstract?'SUBMISSION_ABSTRACT_DECLINE':'SUBMISSION_PAPER_DECLINE';
  1260. break;
  1261. }
  1262. $user =& Request::getUser();
  1263. import('mail.PaperMailTemplate');
  1264. $email = new PaperMailTemplate($trackDirectorSubmission, $templateName);
  1265. if ($send && !$email->hasErrors()) {
  1266. HookRegistry::call('TrackDirectorAction::emailDirectorDecisionComment', array(&$trackDirectorSubmission, &$send));
  1267. $email->send();
  1268. $paperComment = new PaperComment();
  1269. $paperComment->setCommentType(COMMENT_TYPE_DIRECTOR_DECISION);
  1270. $paperComment->setRoleId(Validation::isDirector()?ROLE_ID_DIRECTOR:ROLE_ID_TRACK_DIRECTOR);
  1271. $paperComment->setPaperId($trackDirectorSubmission->getPaperId());
  1272. $paperComment->setAuthorId($trackDirectorSubmission->getUserId());
  1273. $paperComment->setCommentTitle($email->getSubject());
  1274. $paperComment->setComments($email->getBody());
  1275. $paperComment->setDatePosted(Core::getCurrentDate());
  1276. $paperComment->setViewable(true);
  1277. $paperComment->setAssocId($trackDirectorSubmission->getPaperId());
  1278. $paperCommentDao->insertPaperComment($paperComment);
  1279. return true;
  1280. } else {
  1281. if (!Request::getUserVar('continued')) {
  1282. $authorUser =& $userDao->getUser($trackDirectorSubmission->getUserId());
  1283. $authorEmail = $authorUser->getEmail();
  1284. $email->addRecipient($authorEmail, $authorUser->getFullName());
  1285. if ($schedConf->getSetting('notifyAllAuthorsOnDecision')) foreach ($trackDirectorSubmission->getAuthors() as $author) {
  1286. if ($author->getEmail() != $authorEmail) {
  1287. $email->addCc ($author->getEmail(), $author->getFullName());
  1288. }
  1289. }
  1290. $email->assignParams(array(
  1291. 'conferenceDate' => strftime(Config::getVar('general', 'date_format_short'), $schedConf->getSetting('startDate')),
  1292. 'authorName' => $authorUser->getFullName(),
  1293. 'conferenceTitle' => $conference->getConferenceTitle(),
  1294. 'editorialContactSignature' => $user->getContactSignature(),
  1295. 'locationCity' => $schedConf->getSetting('locationCity'),
  1296. 'paperTitle' => $trackDirectorSubmission->getLocalizedTitle()
  1297. ));
  1298. } elseif (Request::getUserVar('importPeerReviews')) {
  1299. $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
  1300. $hasBody = false;
  1301. for ($stage = $trackDirectorSubmission->getCurrentStage(); $stage == REVIEW_STAGE_ABSTRACT || $stage == REVIEW_STAGE_PRESENTATION; $stage--) {
  1302. $reviewAssignments =& $reviewAssignmentDao->getReviewAssignmentsByPaperId($trackDirectorSubmission->getPaperId(), $stage);
  1303. $reviewIndexes =& $reviewAssignmentDao->getReviewIndexesForStage($trackDirectorSubmission->getPaperId(), $stage);
  1304. $body = '';
  1305. foreach ($reviewAssignments as $reviewAssignment) {
  1306. // If the reviewer has completed the assignment, then import the review.
  1307. if ($reviewAssignment->getDateCompleted() != null && !$reviewAssignment->getCancelled()) {
  1308. // Get the comments associated with this review assignment
  1309. $paperComments =& $paperCommentDao->getPaperComments($trackDirectorSubmission->getPaperId(), COMMENT_TYPE_PEER_REVIEW, $reviewAssignment->getId());
  1310. if ($paperComments) {
  1311. $body .= "------------------------------------------------------\n";
  1312. $body .= __('submission.comments.importPeerReviews.reviewerLetter', array('reviewerLetter' => chr(ord('A') + $reviewIndexes[$reviewAssignment->getId()]))) . "\n";
  1313. if (is_array($paperComments)) {
  1314. foreach ($paperComments as $comment) {
  1315. // If the comment is viewable by the author, then add the comment.
  1316. if ($comment->getViewable()) {
  1317. $body .= String::html2utf(
  1318. strip_tags(
  1319. str_replace(array('<p>', '<br>', '<br/>'), array("\n", "\n", "\n"), $comment->getComments())
  1320. )
  1321. ) . "\n\n";
  1322. $hasBody = true;
  1323. }
  1324. }
  1325. }
  1326. $body .= "------------------------------------------------------\n\n";
  1327. }
  1328. if ($reviewFormId = $reviewAssignment->getReviewFormId()){
  1329. $reviewId = $reviewAssignment->getId();
  1330. $reviewFormResponseDao =& DAORegistry::getDAO('ReviewFormResponseDAO');
  1331. $reviewFormElementDao =& DAORegistry::getDAO('ReviewFormElementDAO');
  1332. $reviewFormElements =& $reviewFormElementDao->getReviewFormElements($reviewFormId);
  1333. if (!$paperComments) {
  1334. $body .= "------------------------------------------------------\n";
  1335. $body .= __('submission.comments.importPeerReviews.reviewerLetter', array('reviewerLetter' => chr(ord('A') + $reviewIndexes[$reviewAssignment->getId()]))) . "\n\n";
  1336. }
  1337. foreach ($reviewFormElements as $reviewFormElement) if ($reviewFormElement->getIncluded()) {
  1338. $body .= strip_tags($reviewFormElement->getLocalizedQuestion()) . ": \n";
  1339. $reviewFormResponse = $reviewFormResponseDao->getReviewFormResponse($reviewId, $reviewFormElement->getId());
  1340. if ($reviewFormResponse) {
  1341. $possibleResponses = $reviewFormElement->getLocalizedPossibleResponses();
  1342. if (in_array($reviewFormElement->getElementType(), $reviewFormElement->getMultipleResponsesElementTypes())) {
  1343. if ($reviewFormElement->getElementType() == REVIEW_FORM_ELEMENT_TYPE_CHECKBOXES) {
  1344. foreach ($reviewFormResponse->getValue() as $value) {
  1345. $body .= "\t" . String::html2utf(strip_tags($possibleResponses[$value-1]['content'])) . "\n";
  1346. }
  1347. } else {
  1348. $body .= "\t" . String::html2utf(strip_tags($possibleResponses[$reviewFormResponse->getValue()-1]['content'])) . "\n";
  1349. }
  1350. $body .= "\n";
  1351. } else {
  1352. $body .= "\t" . String::html2utf(strip_tags($reviewFormResponse->getValue())) . "\n\n";
  1353. }
  1354. }
  1355. }
  1356. $body .= "------------------------------------------------------\n\n";
  1357. $hasBody = true;
  1358. }
  1359. } // if
  1360. } // foreach
  1361. if ($hasBody) {
  1362. $oldBody = $email->getBody();
  1363. if (!empty($oldBody)) $oldBody .= "\n";
  1364. $email->setBody($oldBody . $body);
  1365. break;
  1366. }
  1367. } // foreach
  1368. }
  1369. $email->displayEditForm(Request::url(null, null, null, 'emailDirectorDecisionComment', 'send'), array('paperId' => $trackDirectorSubmission->getPaperId()), 'submission/comment/directorDecisionEmail.tpl', array('isADirector' => true));
  1370. return false;
  1371. }
  1372. }
  1373. /**
  1374. * Blind CC the reviews to reviewers.
  1375. * @param $paper object
  1376. * @param $send boolean
  1377. * @param $inhibitExistingEmail boolean
  1378. * @return boolean true iff ready for redirect
  1379. */
  1380. function blindCcReviewsToReviewers($paper, $send = false, $inhibitExistingEmail = false) {
  1381. $commentDao =& DAORegistry::getDAO('PaperCommentDAO');
  1382. $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
  1383. $userDao =& DAORegistry::getDAO('UserDAO');
  1384. $conference =& Request::getConference();
  1385. $comments =& $commentDao->getPaperComments($paper->getId(), COMMENT_TYPE_DIRECTOR_DECISION);
  1386. $reviewAssignments =& $reviewAssignmentDao->getReviewAssignmentsByPaperId($paper->getId(), $paper->getCurrentStage());
  1387. $commentsText = "";
  1388. foreach ($comments as $comment) {
  1389. $commentsText .= String::html2utf(strip_tags($comment->getComments())) . "\n\n";
  1390. }
  1391. $user =& Request::getUser();
  1392. import('mail.PaperMailTemplate');
  1393. $email = new PaperMailTemplate($paper, 'SUBMISSION_DECISION_REVIEWERS', null, null, null, null, true, true);
  1394. if ($send && !$email->hasErrors() && !$inhibitExistingEmail) {
  1395. HookRegistry::call('TrackDirectorAction::blindCcReviewsToReviewers', array(&$paper, &$reviewAssignments, &$email));
  1396. $email->send();
  1397. return true;
  1398. } else {
  1399. if ($inhibitExistingEmail || !Request::getUserVar('continued')) {
  1400. $email->clearRecipients();
  1401. foreach ($reviewAssignments as $reviewAssignment) {
  1402. if ($reviewAssignment->getDateCompleted() != null && !$reviewAssignment->getCancelled()) {
  1403. $reviewer =& $userDao->getUser($reviewAssignment->getReviewerId());
  1404. if (isset($reviewer)) $email->addBcc($reviewer->getEmail(), $reviewer->getFullName());
  1405. }
  1406. }
  1407. $paramArray = array(
  1408. 'comments' => $commentsText,
  1409. 'editorialContactSignature' => $user->getContactSignature()
  1410. );
  1411. $email->assignParams($paramArray);
  1412. }
  1413. $email->displayEditForm(Request::url(null, null, null, 'blindCcReviewsToReviewers'), array('paperId' => $paper->getId()));
  1414. return false;
  1415. }
  1416. }
  1417. /**
  1418. * Accepts the review assignment on behalf of its reviewer.
  1419. * @param $reviewId int
  1420. */
  1421. function confirmReviewForReviewer($reviewId) {
  1422. $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
  1423. $userDao =& DAORegistry::getDAO('UserDAO');
  1424. $user =& Request::getUser();
  1425. $reviewAssignment =& $reviewAssignmentDao->getReviewAssignmentById($reviewId);
  1426. $reviewer =& $userDao->getUser($reviewAssignment->getReviewerId(), true);
  1427. if (HookRegistry::call('TrackDirectorAction::confirmReviewForReviewer', array(&$reviewAssignment, &$reviewer))) return;
  1428. // Only confirm the review for the reviewer if
  1429. // he has not previously done so.
  1430. if ($reviewAssignment->getDateConfirmed() == null) {
  1431. $reviewAssignment->setDeclined(0);
  1432. $reviewAssignment->setDateConfirmed(Core::getCurrentDate());
  1433. $reviewAssignment->stampModified();
  1434. $reviewAssignmentDao->updateReviewAssignment($reviewAssignment);
  1435. // Add log
  1436. import('paper.log.PaperLog');
  1437. import('paper.log.PaperEventLogEntry');
  1438. $entry = new PaperEventLogEntry();
  1439. $entry->setPaperId($reviewAssignment->getPaperId());
  1440. $entry->setUserId($user->getId());
  1441. $entry->setDateLogged(Core::getCurrentDate());
  1442. $entry->setEventType(PAPER_LOG_REVIEW_ACCEPT_BY_PROXY);
  1443. $entry->setLogMessage('log.review.reviewAcceptedByProxy', array('reviewerName' => $reviewer->getFullName(), 'paperId' => $reviewAssignment->getPaperId(), 'stage' => $reviewAssignment->getStage(), 'userName' => $user->getFullName()));
  1444. $entry->setAssocType(LOG_TYPE_REVIEW);
  1445. $entry->setAssocId($reviewAssignment->getId());
  1446. PaperLog::logEventEntry($reviewAssignment->getPaperId(), $entry);
  1447. }
  1448. }
  1449. /**
  1450. * Upload a review on behalf of its reviewer.
  1451. * @param $reviewId int
  1452. */
  1453. function uploadReviewForReviewer($reviewId) {
  1454. $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
  1455. $userDao =& DAORegistry::getDAO('UserDAO');
  1456. $user =& Request::getUser();
  1457. $reviewAssignment =& $reviewAssignmentDao->getReviewAssignmentById($reviewId);
  1458. $reviewer =& $userDao->getUser($reviewAssignment->getReviewerId(), true);
  1459. if (HookRegistry::call('TrackDirectorAction::uploadReviewForReviewer', array(&$reviewAssignment, &$reviewer))) return;
  1460. // Upload the review file.
  1461. import('file.PaperFileManager');
  1462. $paperFileManager = new PaperFileManager($reviewAssignment->getPaperId());
  1463. // Only upload the file if the reviewer has yet to submit a recommendation
  1464. if (($reviewAssignment->getRecommendation() === null || $reviewAssignment->getRecommendation() === '') && !$reviewAssignment->getCancelled()) {
  1465. $fileName = 'upload';
  1466. if ($paperFileManager->uploadError($fileName)) return false;
  1467. if ($paperFileManager->uploadedFileExists($fileName)) {
  1468. if ($reviewAssignment->getReviewerFileId() != null) {
  1469. $fileId = $paperFileManager->uploadReviewFile($fileName, $reviewAssignment->getReviewerFileId());
  1470. } else {
  1471. $fileId = $paperFileManager->uploadReviewFile($fileName);
  1472. }
  1473. }
  1474. }
  1475. if (isset($fileId) && $fileId != 0) {
  1476. // Only confirm the review for the reviewer if
  1477. // he has not previously done so.
  1478. if ($reviewAssignment->getDateConfirmed() == null) {
  1479. $reviewAssignment->setDeclined(0);
  1480. $reviewAssignment->setDateConfirmed(Core::getCurrentDate());
  1481. }
  1482. $reviewAssignment->setReviewerFileId($fileId);
  1483. $reviewAssignment->stampModified();
  1484. $reviewAssignmentDao->updateReviewAssignment($reviewAssignment);
  1485. // Add log
  1486. import('paper.log.PaperLog');
  1487. import('paper.log.PaperEventLogEntry');
  1488. $entry = new PaperEventLogEntry();
  1489. $entry->setPaperId($reviewAssignment->getPaperId());
  1490. $entry->setUserId($user->getId());
  1491. $entry->setDateLogged(Core::getCurrentDate());
  1492. $entry->setEventType(PAPER_LOG_REVIEW_FILE_BY_PROXY);
  1493. $entry->setLogMessage('log.review.reviewFileByProxy', array('reviewerName' => $reviewer->getFullName(), 'paperId' => $reviewAssignment->getPaperId(), 'stage' => $reviewAssignment->getStage(), 'userName' => $user->getFullName()));
  1494. $entry->setAssocType(LOG_TYPE_REVIEW);
  1495. $entry->setAssocId($reviewAssignment->getId());
  1496. PaperLog::logEventEntry($reviewAssignment->getPaperId(), $entry);
  1497. }
  1498. }
  1499. /**
  1500. * Changes the submission RT comments status.
  1501. * @param $submission object
  1502. * @param $commentsStatus int
  1503. */
  1504. function updateCommentsStatus($submission, $commentsStatus) {
  1505. if (HookRegistry::call('TrackDirectorAction::updateCommentsStatus', array(&$submission, &$commentsStatus))) return;
  1506. $submissionDao =& DAORegistry::getDAO('TrackDirectorSubmissionDAO');
  1507. $submission->setCommentsStatus($commentsStatus); // FIXME validate this?
  1508. $submissionDao->updateTrackDirectorSubmission($submission);
  1509. }
  1510. /**
  1511. * Helper method for building submission breadcrumb
  1512. * @param $paperId
  1513. * @param $parentPage name of submission component
  1514. * @return array
  1515. */
  1516. function submissionBreadcrumb($paperId, $parentPage, $track) {
  1517. $breadcrumb = array();
  1518. if ($paperId) {
  1519. $breadcrumb[] = array(Request::url(null, null, $track, 'submission', $paperId), "#$paperId", true);
  1520. }
  1521. if ($parentPage) {
  1522. switch($parentPage) {
  1523. case 'summary':
  1524. $parent = array(Request::url(null, null, $track, 'submission', $paperId), 'submission.summary');
  1525. break;
  1526. case 'review':
  1527. $parent = array(Request::url(null, null, $track, 'submissionReview', $paperId), 'submission.review');
  1528. break;
  1529. case 'history':
  1530. $parent = array(Request::url(null, null, $track, 'submissionHistory', $paperId), 'submission.history');
  1531. break;
  1532. }
  1533. if ($track != 'director' && $track != 'trackDirector') {
  1534. $parent[0] = Request::url(null, null, $track, 'submission', $paperId);
  1535. }
  1536. if (isset($parent)) $breadcrumb[] = $parent;
  1537. }
  1538. return $breadcrumb;
  1539. }
  1540. }
  1541. ?>