• Main Page
  • Modules
  • Classes
  • Files
  • File List

classes/submission/seriesEditor/SeriesEditorSubmissionDAO.inc.php

00001 <?php
00002 
00017 import('classes.submission.seriesEditor.SeriesEditorSubmission');
00018 import('classes.monograph.MonographDAO');
00019 
00020 // Bring in editor decision constants
00021 import('classes.submission.reviewer.ReviewerSubmission');
00022 
00023 class SeriesEditorSubmissionDAO extends MonographDAO {
00024    var $authorDao;
00025    var $userDao;
00026    var $reviewAssignmentDao;
00027    var $submissionFileDao;
00028    var $signoffDao;
00029    var $monographEmailLogDao;
00030    var $monographCommentDao;
00031    var $reviewRoundDao;
00032 
00036    function SeriesEditorSubmissionDAO() {
00037       parent::MonographDAO();
00038       $this->authorDao =& DAORegistry::getDAO('AuthorDAO');
00039       $this->userDao =& DAORegistry::getDAO('UserDAO');
00040       $this->reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
00041       $this->submissionFileDao =& DAORegistry::getDAO('SubmissionFileDAO');
00042       $this->signoffDao =& DAORegistry::getDAO('SignoffDAO');
00043       $this->monographEmailLogDao =& DAORegistry::getDAO('MonographEmailLogDAO');
00044       $this->monographCommentDao =& DAORegistry::getDAO('MonographCommentDAO');
00045       $this->reviewRoundDao =& DAORegistry::getDAO('ReviewRoundDAO');
00046    }
00047 
00053    function &getById($monographId) {
00054       $primaryLocale = AppLocale::getPrimaryLocale();
00055       $locale = AppLocale::getLocale();
00056       $result =& $this->retrieve(
00057          'SELECT  m.*,
00058             COALESCE(stl.setting_value, stpl.setting_value) AS series_title,
00059             COALESCE(sal.setting_value, sapl.setting_value) AS series_abbrev
00060          FROM  monographs m
00061             LEFT JOIN series s ON (s.series_id = m.series_id)
00062             LEFT JOIN series_settings stpl ON (s.series_id = stpl.series_id AND stpl.setting_name = ? AND stpl.locale = ?)
00063             LEFT JOIN series_settings stl ON (s.series_id = stl.series_id AND stl.setting_name = ? AND stl.locale = ?)
00064             LEFT JOIN series_settings sapl ON (s.series_id = sapl.series_id AND sapl.setting_name = ? AND sapl.locale = ?)
00065             LEFT JOIN series_settings sal ON (s.series_id = sal.series_id AND sal.setting_name = ? AND sal.locale = ?)
00066          WHERE m.monograph_id = ?',
00067          array(
00068             'title', $primaryLocale, // Series title
00069             'title', $locale, // Series title
00070             'abbrev', $primaryLocale, // Series abbreviation
00071             'abbrev', $locale, // Series abbreviation
00072             (int) $monographId
00073          )
00074       );
00075 
00076       $returner = null;
00077       if ($result->RecordCount() != 0) {
00078          $returner =& $this->_fromRow($result->GetRowAssoc(false));
00079       }
00080 
00081       $result->Close();
00082       unset($result);
00083 
00084       return $returner;
00085    }
00086 
00091    function newDataObject() {
00092       return new SeriesEditorSubmission();
00093    }
00094 
00100    function &_fromRow(&$row) {
00101       // Populate the monograph parts of the object
00102       $seriesEditorSubmission =& parent::_fromRow($row);
00103 
00104       // Editor Decisions
00105       $reviewRounds =& $this->reviewRoundDao->getByMonographId($row['monograph_id']);
00106       while ($reviewRound =& $reviewRounds->next()) {
00107          $stageId = $reviewRound->getStageId();
00108          $round = $reviewRound->getRound();
00109          $seriesEditorSubmission->setDecisions(
00110             $this->getEditorDecisions($row['monograph_id'], $stageId, $round),
00111             $stageId,
00112             $round
00113          );
00114          unset($reviewRound);
00115       }
00116 
00117       // Comments
00118       $seriesEditorSubmission->setMostRecentEditorDecisionComment($this->monographCommentDao->getMostRecentMonographComment($row['monograph_id'], COMMENT_TYPE_EDITOR_DECISION, $row['monograph_id']));
00119       $seriesEditorSubmission->setMostRecentCopyeditComment($this->monographCommentDao->getMostRecentMonographComment($row['monograph_id'], COMMENT_TYPE_COPYEDIT, $row['monograph_id']));
00120       $seriesEditorSubmission->setMostRecentLayoutComment($this->monographCommentDao->getMostRecentMonographComment($row['monograph_id'], COMMENT_TYPE_LAYOUT, $row['monograph_id']));
00121       $seriesEditorSubmission->setMostRecentProofreadComment($this->monographCommentDao->getMostRecentMonographComment($row['monograph_id'], COMMENT_TYPE_PROOFREAD, $row['monograph_id']));
00122 
00123       // Review Assignments
00124       $reviewRounds =& $this->reviewRoundDao->getByMonographId($row['monograph_id']);
00125       while ($reviewRound =& $reviewRounds->next()) {
00126          $stageId = $reviewRound->getStageId();
00127          $round = $reviewRound->getRound();
00128          $seriesEditorSubmission->setReviewAssignments(
00129             $this->reviewAssignmentDao->getBySubmissionId($row['monograph_id'], $reviewRound->getId()),
00130             $stageId,
00131             $round
00132          );
00133          unset($reviewRound);
00134       }
00135 
00136       HookRegistry::call('SeriesEditorSubmissionDAO::_fromRow', array(&$seriesEditorSubmission, &$row));
00137 
00138       return $seriesEditorSubmission;
00139    }
00140 
00145    function updateSeriesEditorSubmission(&$seriesEditorSubmission) {
00146       $monographId = $seriesEditorSubmission->getId();
00147 
00148       // Get all submission editor decisions.
00149       $editorDecisions = $seriesEditorSubmission->getDecisions();
00150 
00151       // Update review stages editor decisions.
00152       $reviewRoundDao =& DAORegistry::getDAO('ReviewRoundDAO'); /* @var $reviewRoundDao ReviewRoundDAO */
00153       $reviewRounds =& $reviewRoundDao->getByMonographId($monographId);
00154 
00155       while ($reviewRound =& $reviewRounds->next()) {
00156          $stageId = $reviewRound->getStageId();
00157          $round = $reviewRound->getRound();
00158          $reviewStageEditorDecisions = array();
00159          if (isset($editorDecisions[$stageId][$round])) {
00160             $reviewStageEditorDecisions = $editorDecisions[$stageId][$round];
00161             unset($editorDecisions[$stageId][$round]);
00162          }
00163          foreach ($reviewStageEditorDecisions as $editorDecision) {
00164             $this->_updateEditorDecision($monographId, $editorDecision, $stageId, $reviewRound);
00165          }
00166          unset($reviewRound);
00167          unset($editorDecision);
00168       }
00169 
00170       // Update the remaining stages editor decisions.
00171       foreach ($editorDecisions as $stageId => $stageEditorDecision) {
00172          if (isset($stageEditorDecision[REVIEW_ROUND_NONE])) {
00173             foreach ($stageEditorDecision[REVIEW_ROUND_NONE] as $editorDecision) {
00174                $this->_updateEditorDecision($monographId, $editorDecision, $stageId);
00175             }
00176          }
00177       }
00178 
00179       // update review assignments
00180       $removedReviewAssignments =& $seriesEditorSubmission->getRemovedReviewAssignments();
00181 
00182       unset($reviewRounds);
00183       $reviewRounds =& $reviewRoundDao->getByMonographId($monographId);
00184 
00185       while ($reviewRound =& $reviewRounds->next()) {
00186          $stageId = $reviewRound->getStageId();
00187          $round = $reviewRound->getRound();
00188          foreach ($seriesEditorSubmission->getReviewAssignments($stageId, $round) as $reviewAssignment) {
00189             if (isset($removedReviewAssignments[$reviewAssignment->getId()])) continue;
00190 
00191             if ($reviewAssignment->getId() > 0) {
00192                $this->reviewAssignmentDao->updateObject($reviewAssignment);
00193             } else {
00194                $this->reviewAssignmentDao->insertObject($reviewAssignment);
00195             }
00196          }
00197          unset($reviewRound);
00198       }
00199 
00200       // Remove deleted review assignments
00201       foreach ($removedReviewAssignments as $removedReviewAssignmentId) {
00202          $this->reviewAssignmentDao->deleteById($removedReviewAssignmentId);
00203       }
00204 
00205       // Update monograph
00206       if ($seriesEditorSubmission->getId()) {
00207          $monograph =& parent::getById($monographId);
00208 
00209          // Only update fields that can actually be edited.
00210          $monograph->setSeriesId($seriesEditorSubmission->getSeriesId());
00211          $monograph->setStatus($seriesEditorSubmission->getStatus());
00212          $monograph->setDateStatusModified($seriesEditorSubmission->getDateStatusModified());
00213          $monograph->setLastModified($seriesEditorSubmission->getLastModified());
00214          $monograph->setCommentsStatus($seriesEditorSubmission->getCommentsStatus());
00215 
00216          parent::updateMonograph($monograph);
00217       }
00218    }
00219 
00226    function _updateEditorDecision($monographId, $editorDecision, $stageId = null, $reviewRound = null) {
00227       if ($editorDecision['editDecisionId'] == null) {
00228 
00229          $this->update(
00230             sprintf(
00231                'INSERT INTO edit_decisions
00232                (monograph_id, review_round_id, stage_id, round, editor_id, decision, date_decided)
00233                VALUES (?, ?, ?, ?, ?, ?, %s)',
00234                $this->datetimeToDB($editorDecision['dateDecided'])
00235             ),
00236             array(
00237                (int) $monographId,
00238                is_a($reviewRound, 'ReviewRound') ? (int) $reviewRound->getId() : 0,
00239                is_a($reviewRound, 'ReviewRound') ? $reviewRound->getStageId() : (int) $stageId,
00240                is_a($reviewRound, 'ReviewRound') ? (int) $reviewRound->getRound() : REVIEW_ROUND_NONE,
00241                (int) $editorDecision['editorId'],
00242                $editorDecision['decision']
00243             )
00244          );
00245       }
00246    }
00247 
00248 
00249    //
00250    // Miscellaneous
00251    //
00257    function deleteDecisionsByMonograph($monographId) {
00258       return $this->update(
00259          'DELETE FROM edit_decisions WHERE monograph_id = ?',
00260          (int) $monographId
00261       );
00262    }
00263 
00269    function deleteReviewRoundsByMonograph($monographId) {
00270       return $this->update(
00271          'DELETE FROM review_rounds WHERE submission_id = ?',
00272          (int) $monographId
00273       );
00274    }
00275 
00283    function getEditorDecisions($monographId, $stageId = null, $round = null) {
00284       $params = array((int) $monographId);
00285       if ($stageId) $params[] = (int) $stageId;
00286       if ($round) $params[] = (int) $round;
00287 
00288       $result =& $this->retrieve(
00289          'SELECT  edit_decision_id, editor_id, decision,
00290             date_decided, review_round_id, stage_id, round
00291          FROM  edit_decisions
00292          WHERE monograph_id = ?
00293             ' . ($stageId?' AND stage_id = ?':'') . '
00294             ' . ($round?' AND round = ?':'') . '
00295          ORDER BY date_decided ASC',
00296          $params
00297       );
00298 
00299       $decisions = array();
00300       while (!$result->EOF) {
00301          $decisions[] = array(
00302             'editDecisionId' => $result->fields['edit_decision_id'],
00303             'reviewRoundId' => $result->fields['review_round_id'],
00304             'stageId' => $result->fields['stage_id'],
00305             'round' => $result->fields['round'],
00306             'editorId' => $result->fields['editor_id'],
00307             'decision' => $result->fields['decision'],
00308             'dateDecided' => $this->datetimeFromDB($result->fields['date_decided'])
00309          );
00310          $result->MoveNext();
00311       }
00312       $result->Close();
00313       unset($result);
00314 
00315       return $decisions;
00316    }
00317 
00325    function reviewerExists($reviewRoundId, $reviewerId) {
00326       $result =& $this->retrieve(
00327          'SELECT COUNT(*)
00328          FROM  review_assignments
00329          WHERE review_round_id = ? AND
00330             reviewer_id = ? AND
00331             cancelled = 0',
00332          array((int) $reviewRoundId, (int) $reviewerId)
00333       );
00334       $returner = isset($result->fields[0]) && $result->fields[0] == 1 ? true : false;
00335 
00336       $result->Close();
00337       unset($result);
00338 
00339       return $returner;
00340    }
00341 
00350    function &getReviewersForMonograph($pressId, $monographId, $round) {
00351       $result =& $this->retrieve(
00352          'SELECT  u.*
00353          FROM  users u
00354             LEFT JOIN user_user_groups uug ON (uug.user_id = u.user_id)
00355             LEFT JOIN user_groups ug ON (ug.user_group_id = uug.user_group_id)
00356             LEFT JOIN review_assignments r ON (r.reviewer_id = u.user_id)
00357          WHERE ug.context_id = ? AND
00358             ug.role_id = ? AND
00359             r.submission_id = ? AND
00360             r.round = ?
00361          ORDER BY last_name, first_name',
00362          array(
00363             (int) $pressId,
00364             ROLE_ID_REVIEWER,
00365             (int) $monographId,
00366             (int) $round
00367          )
00368       );
00369 
00370       $returner = new DAOResultFactory($result, $this, '_returnReviewerUserFromRow');
00371       return $returner;
00372    }
00373 
00379    function &_returnReviewerUserFromRow(&$row) {
00380       $user =& $this->userDao->_returnUserFromRowWithData($row);
00381       if (isset($row['review_id'])) $user->review_id = $row['review_id'];
00382 
00383       HookRegistry::call('SeriesEditorSubmissionDAO::_returnReviewerUserFromRow', array(&$user, &$row));
00384 
00385       return $user;
00386    }
00387 
00397    function &getReviewersNotAssignedToMonograph($pressId, $monographId, &$reviewRound, $name = '') {
00398       $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
00399 
00400       $params = array((int) $pressId, ROLE_ID_REVIEWER, (int) $reviewRound->getStageId(), (int) $monographId, (int) $reviewRound->getId());
00401       if (!empty($name)) $params[] = $params[] = $params[] = $params[] = "%$name%";
00402 
00403       $result =& $this->retrieve(
00404          'SELECT  DISTINCT u.*
00405          FROM  users u
00406             JOIN user_user_groups uug ON (uug.user_id = u.user_id)
00407             JOIN user_groups ug ON (ug.user_group_id = uug.user_group_id AND ug.context_id = ? AND ug.role_id = ?)
00408             JOIN user_group_stage ugs ON (ugs.user_group_id = ug.user_group_id AND ugs.stage_id = ?)
00409             WHERE 0=(SELECT COUNT(r.reviewer_id)
00410                   FROM review_assignments r
00411                      WHERE r.submission_id = ? AND r.reviewer_id = u.user_id AND (r.review_round_id = ? OR' .
00412                      $reviewAssignmentDao->getIncompleteReviewAssignmentsWhereString() . '))' .
00413             (!empty($name)?' AND (first_name LIKE ? OR last_name LIKE ? OR username LIKE ? OR email LIKE ?)':'') .
00414          ' ORDER BY last_name, first_name',
00415          $params
00416       );
00417 
00418       $returner = new DAOResultFactory($result, $this, '_returnReviewerUserFromRow');
00419       return $returner;
00420    }
00421 
00428    function &getAllReviewers($pressId) {
00429       $result =& $this->retrieve(
00430          'SELECT  u.*
00431          FROM  users u
00432             LEFT JOIN user_user_groups uug ON (uug.user_id = u.user_id)
00433             LEFT JOIN user_groups ug ON (ug.user_group_id = uug.user_group_id)
00434          WHERE ug.context_id = ? AND
00435             ug.role_id = ?
00436          ORDER BY last_name, first_name',
00437          array((int) $pressId, ROLE_ID_REVIEWER)
00438       );
00439 
00440       $returner = new DAOResultFactory($result, $this, '_returnReviewerUserFromRow');
00441       return $returner;
00442 
00443    }
00444 
00451    function getAnonymousReviewerStatistics() {
00452       // Setup default array -- Minimum values Will always be set to 0 (to accomodate reviewers that have never reviewed, and thus aren't in review_assignment)
00453       $reviewerValues =  array(
00454          'doneMin' => 0, // Will always be set to 0
00455          'doneMax' => 0,
00456          'avgMin' => 0, // Will always be set to 0
00457          'avgMax' => 0,
00458          'lastMin' => 0, // Will always be set to 0
00459          'lastMax' => 0,
00460          'activeMin' => 0, // Will always be set to 0
00461          'activeMax' => 0
00462       );
00463 
00464       // Get number of reviews completed
00465       $result =& $this->retrieve(
00466          'SELECT  r.reviewer_id, COUNT(*) as completed_count
00467          FROM  review_assignments r
00468          WHERE r.date_completed IS NOT NULL
00469          GROUP BY r.reviewer_id'
00470       );
00471       while (!$result->EOF) {
00472          $row = $result->GetRowAssoc(false);
00473          if ($reviewerValues['doneMax'] < $row['completed_count']) $reviewerValues['doneMax'] = $row['completed_count'];
00474          $result->MoveNext();
00475       }
00476       $result->Close();
00477       unset($result);
00478 
00479       // Get average number of days per review and days since last review
00480       $result =& $this->retrieve(
00481          'SELECT  r.reviewer_id, r.date_completed, r.date_notified
00482          FROM  review_assignments r
00483          WHERE r.date_notified IS NOT NULL AND
00484             r.date_completed IS NOT NULL AND
00485             r.declined = 0'
00486       );
00487       $averageTimeStats = array();
00488       while (!$result->EOF) {
00489          $row = $result->GetRowAssoc(false);
00490          if (!isset($averageTimeStats[$row['reviewer_id']])) $statistics[$row['reviewer_id']] = array();
00491 
00492          $completed = strtotime($this->datetimeFromDB($row['date_completed']));
00493          $notified = strtotime($this->datetimeFromDB($row['date_notified']));
00494          $timeSinceNotified = time() - $notified;
00495          if (isset($averageTimeStats[$row['reviewer_id']]['totalSpan'])) {
00496             $averageTimeStats[$row['reviewer_id']]['totalSpan'] += $completed - $notified;
00497             $averageTimeStats[$row['reviewer_id']]['completedReviewCount'] += 1;
00498          } else {
00499             $averageTimeStats[$row['reviewer_id']]['totalSpan'] = $completed - $notified;
00500             $averageTimeStats[$row['reviewer_id']]['completedReviewCount'] = 1;
00501          }
00502 
00503          // Calculate the average length of review in days.
00504          $averageTimeStats[$row['reviewer_id']]['averageSpan'] = (($averageTimeStats[$row['reviewer_id']]['totalSpan'] / $averageTimeStats[$row['reviewer_id']]['completedReviewCount']) / 86400);
00505 
00506          // This reviewer has the highest average; put in global statistics array
00507          if ($reviewerValues['avgMax'] < $averageTimeStats[$row['reviewer_id']]['averageSpan']) $reviewerValues['avgMax'] = round($averageTimeStats[$row['reviewer_id']]['averageSpan']);
00508          if ($timeSinceNotified > $reviewerValues['lastMax']) $reviewerValues['lastMax'] = $timeSinceNotified;
00509 
00510          $result->MoveNext();
00511       }
00512       $reviewerValues['lastMax'] = round($reviewerValues['lastMax'] / 86400); // Round to nearest day
00513       $result->Close();
00514       unset($result);
00515 
00516       // Get number of currently active reviews
00517       $result =& $this->retrieve(
00518          'SELECT  r.reviewer_id, COUNT(*) AS incomplete
00519          FROM  review_assignments r
00520          WHERE r.date_notified IS NOT NULL AND
00521             r.date_completed IS NULL AND
00522             r.cancelled = 0
00523          GROUP BY r.reviewer_id'
00524       );
00525       while (!$result->EOF) {
00526          $row = $result->GetRowAssoc(false);
00527 
00528          if ($row['incomplete'] > $reviewerValues['activeMax']) $reviewerValues['activeMax'] = $row['incomplete'];
00529          $result->MoveNext();
00530       }
00531       $result->Close();
00532       unset($result);
00533 
00534       return $reviewerValues;
00535    }
00536 
00554    function getFilteredReviewers($pressId, $doneMin, $doneMax, $avgMin, $avgMax, $lastMin, $lastMax, $activeMin, $activeMax, $interests, $monographId = null, $reviewRoundId = null) {
00555       $userDao =& DAORegistry::getDAO('UserDAO'); /* @var $userDao UserDAO */
00556       $interestDao =& DAORegistry::getDAO('InterestDAO'); /* @var $interestDao InterestDAO */
00557       $reviewerStats = $this->getReviewerStatistics($pressId);
00558 
00559       // Get the IDs of the interests searched for
00560       $allInterestIds = array();
00561       if(isset($interests)) {
00562          $key = 0;
00563          foreach ($interests as $interest) {
00564             $interestIds = $interestDao->getUserIdsByInterest($interest);
00565             if (!$interestIds) {
00566                // The interest searched for does not exist -- go to next interest
00567                continue;
00568             }
00569             if ($key == 0) $allInterestIds = $interestIds; // First interest, nothing to intersect with
00570             else $allInterestIds = array_intersect($allInterestIds, $interestIds);
00571             unset($interest);
00572             $key++;
00573          }
00574       }
00575 
00576       // If monographId is set, get the list of available reviewers to the monograph
00577       if($monographId) {
00578          $reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO'); /* @var $reviewAssignmentDao ReviewAssignmentDAO */
00579          $reviewRoundDao =& DAORegistry::getDAO('ReviewRoundDAO');
00580          $reviewRound =& $reviewRoundDao->getReviewRoundById($reviewRoundId);
00581          $availableReviewerFactory =& $this->getReviewersNotAssignedToMonograph($pressId, $monographId, $reviewRound);
00582          $availableReviewers = $availableReviewerFactory->toAssociativeArray();
00583       }
00584 
00585       $filteredReviewers = array();
00586       foreach ($reviewerStats as $userId => $reviewerStat) {
00587          // Get the days since the user was last notified for a review
00588          if(!isset($reviewerStat['last_notified'])) {
00589             $lastNotifiedInDays = 0;
00590          } else {
00591             $lastNotifiedInDays = round((time() - strtotime($reviewerStat['last_notified'])) / 86400);
00592          }
00593 
00594          // If there are interests to check, make sure user is in allInterestIds array
00595          if(!empty($allInterestIds)) {
00596             $interestCheck = in_array($userId, $allInterestIds);
00597          } else $interestCheck = true;
00598 
00599          if ($interestCheck && $reviewerStat['completed_review_count'] <= $doneMax && $reviewerStat['completed_review_count'] >= $doneMin &&
00600             $reviewerStat['average_span'] <= $avgMax && $reviewerStat['average_span'] >= $avgMin && $lastNotifiedInDays <= $lastMax  &&
00601             $lastNotifiedInDays >= $lastMin && $reviewerStat['incomplete'] <= $activeMax && $reviewerStat['incomplete'] >= $activeMin
00602          ) {
00603             if($monographId && !array_key_exists($userId, $availableReviewers)) {
00604                continue;
00605             } else {
00606                $filteredReviewers[] = $userDao->getById($userId);
00607             }
00608          }
00609       }
00610 
00611       return $filteredReviewers;
00612    }
00613 
00620    function getReviewerStatistics($pressId) {
00621       // Build an array of all reviewers and provide a placeholder for all statistics (so even if they don't
00622       //  have a value, it will be filled in as 0
00623       $statistics = array();
00624       $reviewerStatsPlaceholder = array('last_notified' => null, 'incomplete' => 0, 'total_span' => 0, 'completed_review_count' => 0, 'average_span' => 0);
00625 
00626       $allReviewers =& $this->getAllReviewers($pressId);
00627       while($reviewer =& $allReviewers->next()) {
00628             $statistics[$reviewer->getId()] = $reviewerStatsPlaceholder;
00629          unset($reviewer);
00630       }
00631 
00632       // Get counts of completed submissions
00633       $result =& $this->retrieve(
00634          'SELECT  r.reviewer_id, MAX(r.date_notified) AS last_notified
00635          FROM  review_assignments r, monographs m
00636          WHERE r.submission_id = m.monograph_id AND
00637             m.press_id = ?
00638          GROUP BY r.reviewer_id',
00639          (int) $pressId
00640       );
00641       while (!$result->EOF) {
00642          $row = $result->GetRowAssoc(false);
00643          if (!isset($statistics[$row['reviewer_id']])) $statistics[$row['reviewer_id']] = $reviewerStatsPlaceholder;
00644          $statistics[$row['reviewer_id']]['last_notified'] = $this->datetimeFromDB($row['last_notified']);
00645          $result->MoveNext();
00646       }
00647 
00648       $result->Close();
00649       unset($result);
00650 
00651       // Get completion status
00652       $result =& $this->retrieve(
00653          'SELECT  r.reviewer_id, COUNT(*) AS incomplete
00654          FROM  review_assignments r, monographs m
00655          WHERE r.submission_id = m.monograph_id AND
00656             r.date_notified IS NOT NULL AND
00657             r.date_completed IS NULL AND
00658             r.cancelled = 0 AND
00659             m.press_id = ?
00660          GROUP BY r.reviewer_id',
00661          (int) $pressId
00662       );
00663       while (!$result->EOF) {
00664          $row = $result->GetRowAssoc(false);
00665          if (!isset($statistics[$row['reviewer_id']])) $statistics[$row['reviewer_id']] = $reviewerStatsPlaceholder;
00666          $statistics[$row['reviewer_id']]['incomplete'] = $row['incomplete'];
00667          $result->MoveNext();
00668       }
00669 
00670       $result->Close();
00671       unset($result);
00672 
00673       // Calculate time taken for completed reviews
00674       $result =& $this->retrieve(
00675          'SELECT  r.reviewer_id, r.date_notified, r.date_completed
00676          FROM  review_assignments r, monographs m
00677          WHERE r.submission_id = m.monograph_id AND
00678             r.date_notified IS NOT NULL AND
00679             r.date_completed IS NOT NULL AND
00680             r.declined = 0 AND
00681             m.press_id = ?',
00682          (int) $pressId
00683       );
00684       while (!$result->EOF) {
00685          $row = $result->GetRowAssoc(false);
00686          if (!isset($statistics[$row['reviewer_id']])) $statistics[$row['reviewer_id']] = $reviewerStatsPlaceholder;
00687 
00688          $completed = strtotime($this->datetimeFromDB($row['date_completed']));
00689          $notified = strtotime($this->datetimeFromDB($row['date_notified']));
00690          if (isset($statistics[$row['reviewer_id']]['total_span'])) {
00691             $statistics[$row['reviewer_id']]['total_span'] += $completed - $notified;
00692             $statistics[$row['reviewer_id']]['completed_review_count'] += 1;
00693          } else {
00694             $statistics[$row['reviewer_id']]['total_span'] = $completed - $notified;
00695             $statistics[$row['reviewer_id']]['completed_review_count'] = 1;
00696          }
00697 
00698          // Calculate the average length of review in days.
00699          $statistics[$row['reviewer_id']]['average_span'] = round(($statistics[$row['reviewer_id']]['total_span'] / $statistics[$row['reviewer_id']]['completed_review_count']) / 86400);
00700          $result->MoveNext();
00701       }
00702 
00703       $result->Close();
00704       unset($result);
00705 
00706       return $statistics;
00707    }
00708 
00714    function transferEditorDecisions($oldUserId, $newUserId) {
00715       $this->update(
00716          'UPDATE edit_decisions SET editor_id = ? WHERE editor_id = ?',
00717          array($newUserId, $oldUserId)
00718       );
00719    }
00720 }
00721 
00722 ?>

Generated on Mon Sep 17 2012 13:58:55 for Open Monograph Press by  doxygen 1.7.1