Open Journal Systems  2.4.4
 All Classes Namespaces Functions Variables Groups Pages
SectionEditorSubmissionDAO.inc.php
1 <?php
2 
17 import('classes.submission.sectionEditor.SectionEditorSubmission');
18 
19 // Bring in editor decision constants
20 import('classes.submission.author.AuthorSubmission');
21 import('classes.submission.common.Action');
22 import('classes.submission.reviewer.ReviewerSubmission');
23 
25  var $articleDao;
26  var $authorDao;
27  var $userDao;
28  var $editAssignmentDao;
29  var $reviewAssignmentDao;
30  var $copyeditorSubmissionDao;
31  var $articleFileDao;
32  var $suppFileDao;
33  var $signoffDao;
34  var $galleyDao;
35  var $articleEmailLogDao;
36  var $articleCommentDao;
37 
42  parent::DAO();
43  $this->articleDao =& DAORegistry::getDAO('ArticleDAO');
44  $this->authorDao =& DAORegistry::getDAO('AuthorDAO');
45  $this->userDao =& DAORegistry::getDAO('UserDAO');
46  $this->editAssignmentDao =& DAORegistry::getDAO('EditAssignmentDAO');
47  $this->reviewAssignmentDao =& DAORegistry::getDAO('ReviewAssignmentDAO');
48  $this->copyeditorSubmissionDao =& DAORegistry::getDAO('CopyeditorSubmissionDAO');
49  $this->articleFileDao =& DAORegistry::getDAO('ArticleFileDAO');
50  $this->suppFileDao =& DAORegistry::getDAO('SuppFileDAO');
51  $this->signoffDao =& DAORegistry::getDAO('SignoffDAO');
52  $this->galleyDao =& DAORegistry::getDAO('ArticleGalleyDAO');
53  $this->articleEmailLogDao =& DAORegistry::getDAO('ArticleEmailLogDAO');
54  $this->articleCommentDao =& DAORegistry::getDAO('ArticleCommentDAO');
55  }
56 
62  function &getSectionEditorSubmission($articleId) {
63  $primaryLocale = AppLocale::getPrimaryLocale();
64  $locale = AppLocale::getLocale();
65  $result =& $this->retrieve(
66  'SELECT a.*,
67  COALESCE(stl.setting_value, stpl.setting_value) AS section_title,
68  COALESCE(sal.setting_value, sapl.setting_value) AS section_abbrev,
69  r2.review_revision
70  FROM articles a
71  LEFT JOIN sections s ON (s.section_id = a.section_id)
72  LEFT JOIN review_rounds r2 ON (a.article_id = r2.submission_id AND a.current_round = r2.round)
73  LEFT JOIN section_settings stpl ON (s.section_id = stpl.section_id AND stpl.setting_name = ? AND stpl.locale = ?)
74  LEFT JOIN section_settings stl ON (s.section_id = stl.section_id AND stl.setting_name = ? AND stl.locale = ?)
75  LEFT JOIN section_settings sapl ON (s.section_id = sapl.section_id AND sapl.setting_name = ? AND sapl.locale = ?)
76  LEFT JOIN section_settings sal ON (s.section_id = sal.section_id AND sal.setting_name = ? AND sal.locale = ?)
77  WHERE a.article_id = ?',
78  array(
79  'title',
80  $primaryLocale,
81  'title',
82  $locale,
83  'abbrev',
84  $primaryLocale,
85  'abbrev',
86  $locale,
87  $articleId
88  )
89  );
90 
91  $returner = null;
92  if ($result->RecordCount() != 0) {
93  $returner =& $this->_returnSectionEditorSubmissionFromRow($result->GetRowAssoc(false));
94  }
95 
96  $result->Close();
97  unset($result);
98 
99  return $returner;
100  }
101 
108  $sectionEditorSubmission = new SectionEditorSubmission();
109 
110  // Article attributes
111  $this->articleDao->_articleFromRow($sectionEditorSubmission, $row);
112 
113  // Editor Assignment
114  $editAssignments =& $this->editAssignmentDao->getEditAssignmentsByArticleId($row['article_id']);
115  $sectionEditorSubmission->setEditAssignments($editAssignments->toArray());
116 
117  // Editor Decisions
118  for ($i = 1; $i <= $row['current_round']; $i++) {
119  $sectionEditorSubmission->setDecisions($this->getEditorDecisions($row['article_id'], $i), $i);
120  }
121 
122  // Comments
123  $sectionEditorSubmission->setMostRecentEditorDecisionComment($this->articleCommentDao->getMostRecentArticleComment($row['article_id'], COMMENT_TYPE_EDITOR_DECISION, $row['article_id']));
124  $sectionEditorSubmission->setMostRecentCopyeditComment($this->articleCommentDao->getMostRecentArticleComment($row['article_id'], COMMENT_TYPE_COPYEDIT, $row['article_id']));
125  $sectionEditorSubmission->setMostRecentLayoutComment($this->articleCommentDao->getMostRecentArticleComment($row['article_id'], COMMENT_TYPE_LAYOUT, $row['article_id']));
126  $sectionEditorSubmission->setMostRecentProofreadComment($this->articleCommentDao->getMostRecentArticleComment($row['article_id'], COMMENT_TYPE_PROOFREAD, $row['article_id']));
127 
128  // Files
129  $sectionEditorSubmission->setSubmissionFile($this->articleFileDao->getArticleFile($row['submission_file_id']));
130  $sectionEditorSubmission->setRevisedFile($this->articleFileDao->getArticleFile($row['revised_file_id']));
131  $sectionEditorSubmission->setReviewFile($this->articleFileDao->getArticleFile($row['review_file_id']));
132  $sectionEditorSubmission->setSuppFiles($this->suppFileDao->getSuppFilesByArticle($row['article_id']));
133  $sectionEditorSubmission->setEditorFile($this->articleFileDao->getArticleFile($row['editor_file_id']));
134 
135 
136  for ($i = 1; $i <= $row['current_round']; $i++) {
137  $sectionEditorSubmission->setEditorFileRevisions($this->articleFileDao->getArticleFileRevisions($row['editor_file_id'], $i), $i);
138  $sectionEditorSubmission->setAuthorFileRevisions($this->articleFileDao->getArticleFileRevisions($row['revised_file_id'], $i), $i);
139  }
140 
141  // Review Rounds
142  $sectionEditorSubmission->setReviewRevision($row['review_revision']);
143 
144  // Review Assignments
145  for ($i = 1; $i <= $row['current_round']; $i++) {
146  $sectionEditorSubmission->setReviewAssignments($this->reviewAssignmentDao->getBySubmissionId($row['article_id'], $i), $i);
147  }
148 
149  // Layout Editing
150  $sectionEditorSubmission->setGalleys($this->galleyDao->getGalleysByArticle($row['article_id']));
151 
152  // Proof Assignment
153  HookRegistry::call('SectionEditorSubmissionDAO::_returnSectionEditorSubmissionFromRow', array(&$sectionEditorSubmission, &$row));
154 
155  return $sectionEditorSubmission;
156  }
157 
162  function updateSectionEditorSubmission(&$sectionEditorSubmission) {
163  // update edit assignment
164  $editAssignments =& $sectionEditorSubmission->getEditAssignments();
165  foreach ($editAssignments as $editAssignment) {
166  if ($editAssignment->getEditId() > 0) {
167  $this->editAssignmentDao->updateEditAssignment($editAssignment);
168  } else {
169  $this->editAssignmentDao->insertEditAssignment($editAssignment);
170  }
171  }
172 
173  // Update editor decisions
174  for ($i = 1; $i <= $sectionEditorSubmission->getCurrentRound(); $i++) {
175  $editorDecisions =& $sectionEditorSubmission->getDecisions($i);
176  if (is_array($editorDecisions)) {
177  foreach ($editorDecisions as $key => $editorDecision) {
178  if ($editorDecision['editDecisionId'] == null) {
179  $this->update(
180  sprintf('INSERT INTO edit_decisions
181  (article_id, round, editor_id, decision, date_decided)
182  VALUES (?, ?, ?, ?, %s)',
183  $this->datetimeToDB($editorDecision['dateDecided'])),
184  array($sectionEditorSubmission->getId(), $sectionEditorSubmission->getCurrentRound(), $editorDecision['editorId'], $editorDecision['decision'])
185  );
186  $editorDecisions[$key]['editDecisionId'] = $this->getInsertId('edit_decisions', 'edit_decision_id');
187  }
188  }
189  }
190  unset($editorDecisions);
191  }
192  if ($this->reviewRoundExists($sectionEditorSubmission->getId(), $sectionEditorSubmission->getCurrentRound())) {
193  $this->update(
194  'UPDATE review_rounds
195  SET
196  review_revision = ?
197  WHERE submission_id = ? AND round = ?',
198  array(
199  $sectionEditorSubmission->getReviewRevision(),
200  $sectionEditorSubmission->getId(),
201  $sectionEditorSubmission->getCurrentRound()
202  )
203  );
204  } elseif ($sectionEditorSubmission->getReviewRevision()!=null) {
205  $this->createReviewRound(
206  $sectionEditorSubmission->getId(),
207  $sectionEditorSubmission->getCurrentRound() === null ? 1 : $sectionEditorSubmission->getCurrentRound(),
208  $sectionEditorSubmission->getReviewRevision()
209  );
210  }
211 
212  // Update copyeditor assignment
213  $copyeditSignoff = $this->signoffDao->getBySymbolic('SIGNOFF_COPYEDITING_INITIAL', ASSOC_TYPE_ARTICLE, $sectionEditorSubmission->getId());
214  if ($copyeditSignoff) {
215  $copyeditorSubmission =& $this->copyeditorSubmissionDao->getCopyeditorSubmission($sectionEditorSubmission->getId());
216  } else {
217  $copyeditorSubmission = new CopyeditorSubmission();
218  }
219 
220  // Only update the fields that an editor can modify.
221  $copyeditorSubmission->setId($sectionEditorSubmission->getId());
222  $copyeditorSubmission->setDateStatusModified($sectionEditorSubmission->getDateStatusModified());
223  $copyeditorSubmission->setLastModified($sectionEditorSubmission->getLastModified());
224 
225  // update review assignments
226  foreach ($sectionEditorSubmission->getReviewAssignments() as $roundReviewAssignments) {
227  foreach ($roundReviewAssignments as $reviewAssignment) {
228  if ($reviewAssignment->getId() > 0) {
229  $this->reviewAssignmentDao->updateReviewAssignment($reviewAssignment);
230  } else {
231  $this->reviewAssignmentDao->insertObject($reviewAssignment);
232  }
233  }
234  }
235 
236  // Remove deleted review assignments
237  $removedReviewAssignments = $sectionEditorSubmission->getRemovedReviewAssignments();
238  for ($i=0, $count=count($removedReviewAssignments); $i < $count; $i++) {
239  $this->reviewAssignmentDao->deleteReviewAssignmentById($removedReviewAssignments[$i]);
240  }
241 
242  // Update article
243  if ($sectionEditorSubmission->getId()) {
244 
245  $article =& $this->articleDao->getArticle($sectionEditorSubmission->getId());
246 
247  // Only update fields that can actually be edited.
248  $article->setSectionId($sectionEditorSubmission->getSectionId());
249  $article->setCurrentRound($sectionEditorSubmission->getCurrentRound());
250  $article->setReviewFileId($sectionEditorSubmission->getReviewFileId());
251  $article->setEditorFileId($sectionEditorSubmission->getEditorFileId());
252  $article->setStatus($sectionEditorSubmission->getStatus());
253  $article->setDateStatusModified($sectionEditorSubmission->getDateStatusModified());
254  $article->setLastModified($sectionEditorSubmission->getLastModified());
255  $article->setCommentsStatus($sectionEditorSubmission->getCommentsStatus());
256 
257  $this->articleDao->updateArticle($article);
258  }
259 
260  }
261 
262  function createReviewRound($articleId, $round, $reviewRevision) {
263  $this->update(
264  'INSERT INTO review_rounds
265  (submission_id, round, review_revision)
266  VALUES
267  (?, ?, ?)',
268  array($articleId, $round, $reviewRevision)
269  );
270  }
271 
278  function &getSectionEditorSubmissions($sectionEditorId, $journalId, $status = true) {
279  $primaryLocale = AppLocale::getPrimaryLocale();
280  $locale = AppLocale::getLocale();
281 
282  $sectionEditorSubmissions = array();
283 
284  $result =& $this->retrieve(
285  'SELECT a.*,
286  COALESCE(stl.setting_value, stpl.setting_value) AS section_title,
287  COALESCE(sal.setting_value, sapl.setting_value) AS section_abbrev,
288  r2.review_revision
289  FROM articles a
290  LEFT JOIN edit_assignments e ON (e.article_id = a.article_id)
291  LEFT JOIN sections s ON (s.section_id = a.section_id)
292  LEFT JOIN review_rounds r2 ON (a.article_id = r2.submission_id AND a.current_round = r2.round)
293  LEFT JOIN section_settings stpl ON (s.section_id = stpl.section_id AND stpl.setting_name = ? AND stpl.locale = ?)
294  LEFT JOIN section_settings stl ON (s.section_id = stl.section_id AND stl.setting_name = ? AND stl.locale = ?)
295  LEFT JOIN section_settings sapl ON (s.section_id = sapl.section_id AND sapl.setting_name = ? AND sapl.locale = ?)
296  LEFT JOIN section_settings sal ON (s.section_id = sal.section_id AND sal.setting_name = ? AND sal.locale = ?)
297  WHERE a.journal_id = ?
298  AND e.editor_id = ?
299  AND a.status = ?',
300  array(
301  'title',
302  $primaryLocale,
303  'title',
304  $locale,
305  'abbrev',
306  $primaryLocale,
307  'abbrev',
308  $locale,
309  $journalId,
310  $sectionEditorId,
311  $status
312  )
313  );
314 
315  while (!$result->EOF) {
316  $sectionEditorSubmissions[] =& $this->_returnSectionEditorSubmissionFromRow($result->GetRowAssoc(false));
317  $result->MoveNext();
318  }
319 
320  $result->Close();
321  unset($result);
322 
323  return $sectionEditorSubmissions;
324  }
325 
329  function &_getUnfilteredSectionEditorSubmissions($sectionEditorId, $journalId, $sectionId = 0, $searchField = null, $searchMatch = null, $search = null, $dateField = null, $dateFrom = null, $dateTo = null, $additionalWhereSql = '', $rangeInfo = null, $sortBy = null, $sortDirection = SORT_DIRECTION_ASC) {
330  $primaryLocale = AppLocale::getPrimaryLocale();
331  $locale = AppLocale::getLocale();
332 
333  $params = array(
334  ASSOC_TYPE_ARTICLE,
335  'SIGNOFF_COPYEDITING_FINAL',
336  ASSOC_TYPE_ARTICLE,
337  'SIGNOFF_PROOFREADING_PROOFREADER',
338  ASSOC_TYPE_ARTICLE,
339  'SIGNOFF_LAYOUT',
340  'title', // Section title
341  $primaryLocale,
342  'title',
343  $locale,
344  'abbrev', // Section abbrev
345  $primaryLocale,
346  'abbrev',
347  $locale,
348  'cleanTitle', // Article title
349  'cleanTitle',
350  $locale,
351  $journalId,
352  $sectionEditorId
353  );
354 
355  $searchSql = '';
356 
357  if (!empty($search)) switch ($searchField) {
358  case SUBMISSION_FIELD_ID:
359  $params[] = (int) $search;
360  $searchSql = ' AND a.article_id = ?';
361  break;
362  case SUBMISSION_FIELD_TITLE:
363  if ($searchMatch === 'is') {
364  $searchSql = ' AND LOWER(atl.setting_value) = LOWER(?)';
365  } elseif ($searchMatch === 'contains') {
366  $searchSql = ' AND LOWER(atl.setting_value) LIKE LOWER(?)';
367  $search = '%' . $search . '%';
368  } else { // $searchMatch === 'startsWith'
369  $searchSql = ' AND LOWER(atl.setting_value) LIKE LOWER(?)';
370  $search = '%' . $search . '%';
371  }
372  $params[] = $search;
373  break;
374  case SUBMISSION_FIELD_AUTHOR:
375  $searchSql = $this->_generateUserNameSearchSQL($search, $searchMatch, 'aa.', $params);
376  break;
377  case SUBMISSION_FIELD_EDITOR:
378  $searchSql = $this->_generateUserNameSearchSQL($search, $searchMatch, 'ed.', $params);
379  break;
380  }
381 
382  if (!empty($dateFrom) || !empty($dateTo)) switch($dateField) {
383  case SUBMISSION_FIELD_DATE_SUBMITTED:
384  if (!empty($dateFrom)) {
385  $searchSql .= ' AND a.date_submitted >= ' . $this->datetimeToDB($dateFrom);
386  }
387  if (!empty($dateTo)) {
388  $searchSql .= ' AND a.date_submitted <= ' . $this->datetimeToDB($dateTo);
389  }
390  break;
391  case SUBMISSION_FIELD_DATE_COPYEDIT_COMPLETE:
392  if (!empty($dateFrom)) {
393  $searchSql .= ' AND c.date_final_completed >= ' . $this->datetimeToDB($dateFrom);
394  }
395  if (!empty($dateTo)) {
396  $searchSql .= ' AND c.date_final_completed <= ' . $this->datetimeToDB($dateTo);
397  }
398  break;
399  case SUBMISSION_FIELD_DATE_LAYOUT_COMPLETE:
400  if (!empty($dateFrom)) {
401  $searchSql .= ' AND l.date_completed >= ' . $this->datetimeToDB($dateFrom);
402  }
403  if (!empty($dateTo)) {
404  $searchSql .= ' AND l.date_completed <= ' . $this->datetimeToDB($dateTo);
405  }
406  break;
407  case SUBMISSION_FIELD_DATE_PROOFREADING_COMPLETE:
408  if (!empty($dateFrom)) {
409  $searchSql .= ' AND p.date_proofreader_completed >= ' . $this->datetimeToDB($dateFrom);
410  }
411  if (!empty($dateTo)) {
412  $searchSql .= ' AND p.date_proofreader_completed <= ' . $this->datetimeToDB($dateTo);
413  }
414  break;
415  }
416 
417  $sql = 'SELECT DISTINCT
418  a.*,
419  scf.date_completed as copyedit_completed,
420  spr.date_completed as proofread_completed,
421  sle.date_completed as layout_completed,
422  SUBSTRING(COALESCE(atl.setting_value, atpl.setting_value) FROM 1 FOR 255) AS submission_title,
423  aap.last_name AS author_name,
424  e.can_review AS can_review,
425  e.can_edit AS can_edit,
426  SUBSTRING(COALESCE(stl.setting_value, stpl.setting_value) FROM 1 FOR 255) AS section_title,
427  SUBSTRING(COALESCE(sal.setting_value, sapl.setting_value) FROM 1 FOR 255) AS section_abbrev,
428  r2.review_revision
429  FROM articles a
430  LEFT JOIN authors aa ON (aa.submission_id = a.article_id)
431  LEFT JOIN authors aap ON (aap.submission_id = a.article_id AND aap.primary_contact = 1)
432  LEFT JOIN edit_assignments e ON (e.article_id = a.article_id)
433  LEFT JOIN users ed ON (e.editor_id = ed.user_id)
434  LEFT JOIN sections s ON (s.section_id = a.section_id)
435  LEFT JOIN signoffs scf ON (a.article_id = scf.assoc_id AND scf.assoc_type = ? AND scf.symbolic = ?)
436  LEFT JOIN users ce ON (scf.user_id = ce.user_id)
437  LEFT JOIN signoffs spr ON (a.article_id = spr.assoc_id AND spr.assoc_type = ? AND spr.symbolic = ?)
438  LEFT JOIN users pe ON (pe.user_id = spr.user_id)
439  LEFT JOIN review_rounds r2 ON (a.article_id = r2.submission_id and a.current_round = r2.round)
440  LEFT JOIN signoffs sle ON (a.article_id = sle.assoc_id AND sle.assoc_type = ? AND sle.symbolic = ?) LEFT JOIN users le ON (le.user_id = sle.user_id)
441  LEFT JOIN section_settings stpl ON (s.section_id = stpl.section_id AND stpl.setting_name = ? AND stpl.locale = ?)
442  LEFT JOIN section_settings stl ON (s.section_id = stl.section_id AND stl.setting_name = ? AND stl.locale = ?)
443  LEFT JOIN section_settings sapl ON (s.section_id = sapl.section_id AND sapl.setting_name = ? AND sapl.locale = ?)
444  LEFT JOIN section_settings sal ON (s.section_id = sal.section_id AND sal.setting_name = ? AND sal.locale = ?)
445  LEFT JOIN article_settings atpl ON (atpl.article_id = a.article_id AND atpl.setting_name = ? AND atpl.locale = a.locale)
446  LEFT JOIN article_settings atl ON (a.article_id = atl.article_id AND atl.setting_name = ? AND atl.locale = ?)
447  LEFT JOIN edit_decisions edec ON (a.article_id = edec.article_id)
448  LEFT JOIN edit_decisions edec2 ON (a.article_id = edec2.article_id AND edec.edit_decision_id < edec2.edit_decision_id)
449  WHERE a.journal_id = ?
450  AND e.editor_id = ?
451  AND a.submission_progress = 0' . (!empty($additionalWhereSql)?" AND ($additionalWhereSql)":'') . '
452  AND edec2.edit_decision_id IS NULL';
453 
454  if ($sectionId) {
455  $params[] = $sectionId;
456  $searchSql .= ' AND a.section_id = ?';
457  }
458 
459  $result =& $this->retrieveRange($sql . ' ' . $searchSql . ($sortBy?(' ORDER BY ' . $this->getSortMapping($sortBy) . ' ' . $this->getDirectionMapping($sortDirection)) : ''),
460  $params,
461  $rangeInfo
462  );
463 
464  return $result;
465  }
466 
470  function _generateUserNameSearchSQL($search, $searchMatch, $prefix, &$params) {
471  $first_last = $this->concat($prefix.'first_name', '\' \'', $prefix.'last_name');
472  $first_middle_last = $this->concat($prefix.'first_name', '\' \'', $prefix.'middle_name', '\' \'', $prefix.'last_name');
473  $last_comma_first = $this->concat($prefix.'last_name', '\', \'', $prefix.'first_name');
474  $last_comma_first_middle = $this->concat($prefix.'last_name', '\', \'', $prefix.'first_name', '\' \'', $prefix.'middle_name');
475  if ($searchMatch === 'is') {
476  $searchSql = " AND (LOWER({$prefix}last_name) = LOWER(?) OR LOWER($first_last) = LOWER(?) OR LOWER($first_middle_last) = LOWER(?) OR LOWER($last_comma_first) = LOWER(?) OR LOWER($last_comma_first_middle) = LOWER(?))";
477  } elseif ($searchMatch === 'contains') {
478  $searchSql = " AND (LOWER({$prefix}last_name) LIKE LOWER(?) OR LOWER($first_last) LIKE LOWER(?) OR LOWER($first_middle_last) LIKE LOWER(?) OR LOWER($last_comma_first) LIKE LOWER(?) OR LOWER($last_comma_first_middle) LIKE LOWER(?))";
479  $search = '%' . $search . '%';
480  } else { // $searchMatch === 'startsWith'
481  $searchSql = " AND (LOWER({$prefix}last_name) LIKE LOWER(?) OR LOWER($first_last) LIKE LOWER(?) OR LOWER($first_middle_last) LIKE LOWER(?) OR LOWER($last_comma_first) LIKE LOWER(?) OR LOWER($last_comma_first_middle) LIKE LOWER(?))";
482  $search = $search . '%';
483  }
484  $params[] = $params[] = $params[] = $params[] = $params[] = $search;
485  return $searchSql;
486  }
487 
501  function &getSectionEditorSubmissionsInReview($sectionEditorId, $journalId, $sectionId, $searchField = null, $searchMatch = null, $search = null, $dateField = null, $dateFrom = null, $dateTo = null, $rangeInfo = null, $sortBy = null, $sortDirection = SORT_DIRECTION_ASC) {
502  $result =& $this->_getUnfilteredSectionEditorSubmissions(
503  $sectionEditorId, $journalId, $sectionId,
504  $searchField, $searchMatch, $search,
505  $dateField, $dateFrom, $dateTo,
506  'a.status = ' . STATUS_QUEUED . ' AND e.can_review = 1 AND (edec.decision IS NULL OR edec.decision <> ' . SUBMISSION_EDITOR_DECISION_ACCEPT . ')',
507  $rangeInfo, $sortBy, $sortDirection
508  );
509  $returner = new DAOResultFactory($result, $this, '_returnSectionEditorSubmissionFromRow');
510  return $returner;
511  }
512 
526  function &getSectionEditorSubmissionsInEditing($sectionEditorId, $journalId, $sectionId, $searchField = null, $searchMatch = null, $search = null, $dateField = null, $dateFrom = null, $dateTo = null, $rangeInfo = null, $sortBy = null, $sortDirection = SORT_DIRECTION_ASC) {
527  $result =& $this->_getUnfilteredSectionEditorSubmissions(
528  $sectionEditorId, $journalId, $sectionId,
529  $searchField, $searchMatch, $search,
530  $dateField, $dateFrom, $dateTo,
531  'a.status = ' . STATUS_QUEUED . ' AND e.can_edit = 1 AND edec.decision = ' . SUBMISSION_EDITOR_DECISION_ACCEPT,
532  $rangeInfo, $sortBy, $sortDirection
533  );
534  $returner = new DAOResultFactory($result, $this, '_returnSectionEditorSubmissionFromRow');
535  return $returner;
536  }
537 
551  function &getSectionEditorSubmissionsArchives($sectionEditorId, $journalId, $sectionId, $searchField = null, $searchMatch = null, $search = null, $dateField = null, $dateFrom = null, $dateTo = null, $rangeInfo = null, $sortBy = null, $sortDirection = SORT_DIRECTION_ASC) {
553  $sectionEditorId, $journalId, $sectionId,
554  $searchField, $searchMatch, $search,
555  $dateField, $dateFrom, $dateTo,
556  'a.status <> ' . STATUS_QUEUED,
557  $rangeInfo, $sortBy, $sortDirection
558  );
559  $returner = new DAOResultFactory($result, $this, '_returnSectionEditorSubmissionFromRow');
560  return $returner;
561  }
562 
566  function &getSectionEditorSubmissionsCount($sectionEditorId, $journalId) {
567  $submissionsCount = array();
568  for($i = 0; $i < 2; $i++) {
569  $submissionsCount[$i] = 0;
570  }
571 
572  // Fetch a count of submissions in review.
573  // "d2" and "d" are used to fetch the single most recent
574  // editor decision.
575  $result =& $this->retrieve(
576  'SELECT COUNT(*) AS review_count
577  FROM articles a
578  LEFT JOIN edit_assignments e ON (a.article_id = e.article_id)
579  LEFT JOIN edit_decisions d ON (a.article_id = d.article_id)
580  LEFT JOIN edit_decisions d2 ON (a.article_id = d2.article_id AND d.edit_decision_id < d2.edit_decision_id)
581  WHERE a.journal_id = ?
582  AND e.editor_id = ?
583  AND a.submission_progress = 0
584  AND a.status = ' . STATUS_QUEUED . '
585  AND d2.edit_decision_id IS NULL
586  AND (d.decision IS NULL OR d.decision <> ' . SUBMISSION_EDITOR_DECISION_ACCEPT . ')',
587  array((int) $journalId, (int) $sectionEditorId)
588  );
589  $submissionsCount[0] = $result->Fields('review_count');
590  $result->Close();
591 
592  // Fetch a count of submissions in editing.
593  // "d2" and "d" are used to fetch the single most recent
594  // editor decision.
595  $result =& $this->retrieve(
596  'SELECT COUNT(*) AS editing_count
597  FROM articles a
598  LEFT JOIN edit_assignments e ON (a.article_id = e.article_id)
599  LEFT JOIN edit_decisions d ON (a.article_id = d.article_id)
600  LEFT JOIN edit_decisions d2 ON (a.article_id = d2.article_id AND d.edit_decision_id < d2.edit_decision_id)
601  WHERE a.journal_id = ?
602  AND e.editor_id = ?
603  AND a.submission_progress = 0
604  AND a.status = ' . STATUS_QUEUED . '
605  AND d2.edit_decision_id IS NULL
606  AND d.decision = ' . SUBMISSION_EDITOR_DECISION_ACCEPT,
607  array((int) $journalId, (int) $sectionEditorId)
608  );
609  $submissionsCount[1] = $result->Fields('editing_count');
610  $result->Close();
611  return $submissionsCount;
612  }
613 
614  //
615  // Miscellaneous
616  //
617 
622  function deleteDecisionsByArticle($articleId) {
623  return $this->update(
624  'DELETE FROM edit_decisions WHERE article_id = ?',
625  $articleId
626  );
627  }
628 
633  function deleteReviewRoundsByArticle($articleId) {
634  return $this->update(
635  'DELETE FROM review_rounds WHERE submission_id = ?',
636  $articleId
637  );
638  }
639 
645  function getEditorDecisions($articleId, $round = null) {
646  $decisions = array();
647 
648  if ($round == null) {
649  $result =& $this->retrieve(
650  'SELECT edit_decision_id, editor_id, decision, date_decided FROM edit_decisions WHERE article_id = ? ORDER BY edit_decision_id ASC', $articleId
651  );
652  } else {
653  $result =& $this->retrieve(
654  'SELECT edit_decision_id, editor_id, decision, date_decided FROM edit_decisions WHERE article_id = ? AND round = ? ORDER BY edit_decision_id ASC',
655  array($articleId, $round)
656  );
657  }
658 
659  while (!$result->EOF) {
660  $decisions[] = array(
661  'editDecisionId' => $result->fields['edit_decision_id'],
662  'editorId' => $result->fields['editor_id'],
663  'decision' => $result->fields['decision'],
664  'dateDecided' => $this->datetimeFromDB($result->fields['date_decided'])
665  );
666  $result->moveNext();
667  }
668  $result->Close();
669  unset($result);
670 
671  return $decisions;
672  }
673 
679  function getMaxReviewRound($articleId) {
680  $result =& $this->retrieve(
681  'SELECT MAX(round) FROM review_rounds WHERE submission_id = ?', $articleId
682  );
683  $returner = isset($result->fields[0]) ? $result->fields[0] : 0;
684 
685  $result->Close();
686  unset($result);
687 
688  return $returner;
689  }
690 
697  function reviewRoundExists($articleId, $round) {
698  $result =& $this->retrieve(
699  'SELECT COUNT(*) FROM review_rounds WHERE submission_id = ? AND round = ?', array($articleId, $round)
700  );
701  $returner = isset($result->fields[0]) && $result->fields[0] == 1 ? true : false;
702 
703  $result->Close();
704  unset($result);
705 
706  return $returner;
707  }
708 
715  function reviewerExists($articleId, $reviewerId, $round) {
716  $result =& $this->retrieve(
717  'SELECT COUNT(*) FROM review_assignments WHERE submission_id = ? AND reviewer_id = ? AND round = ? AND cancelled = 0', array((int) $articleId, (int) $reviewerId, (int) $round)
718  );
719  $returner = isset($result->fields[0]) && $result->fields[0] == 1 ? true : false;
720 
721  $result->Close();
722  unset($result);
723 
724  return $returner;
725  }
726 
738  function &getReviewersForArticle($journalId, $articleId, $round, $searchType = null, $search = null, $searchMatch = null, $rangeInfo = null, $sortBy = null, $sortDirection = SORT_DIRECTION_ASC) {
739  // Convert the field being searched for to a DB element to select on
740  $searchTypeMap = array(
741  USER_FIELD_FIRSTNAME => 'u.first_name',
742  USER_FIELD_LASTNAME => 'u.last_name',
743  USER_FIELD_USERNAME => 'u.username',
744  USER_FIELD_EMAIL => 'u.email',
745  USER_FIELD_INTERESTS => 'cves.setting_value'
746  );
747 
748  // Generate the SQL used to filter the results based on what the user is searching for
749  $paramArray = array((int) $articleId, (int) $round);
750  $joinInterests = false;
751  if($searchType == USER_FIELD_INTERESTS) {
752  $joinInterests = true;
753  }
754 
755  // Push some extra default parameters to the SQL parameter array
756  $paramArray[] = (int) $journalId;
757  $paramArray[] = ROLE_ID_REVIEWER;
758 
759  $searchSql = '';
760  if (isset($search) && isset($searchTypeMap[$searchType])) {
761  $fieldName = $searchTypeMap[$searchType];
762  switch ($searchMatch) {
763  case 'is':
764  $searchSql = "AND LOWER($fieldName) = LOWER(?)";
765  $paramArray[] = $search;
766  break;
767  case 'contains':
768  $searchSql = "AND LOWER($fieldName) LIKE LOWER(?)";
769  $paramArray[] = '%' . $search . '%';
770  break;
771  case 'startsWith':
772  $searchSql = "AND LOWER($fieldName) LIKE LOWER(?)";
773  $paramArray[] = $search . '%';
774  break;
775  }
776  } elseif (isset($search)) switch ($searchType) {
777  case USER_FIELD_USERID:
778  $searchSql = 'AND user_id=?';
779  $paramArray[] = $search;
780  break;
781  case USER_FIELD_INITIAL:
782  $searchSql = 'AND (LOWER(last_name) LIKE LOWER(?) OR LOWER(username) LIKE LOWER(?))';
783  $paramArray[] = $search . '%';
784  $paramArray[] = $search . '%';
785  break;
786  }
787 
788  $interestJoinSql = ($joinInterests ? '
789  LEFT JOIN user_interests ui ON (ui.user_id = u.user_id)
790  LEFT JOIN controlled_vocab_entry_settings cves ON (cves.controlled_vocab_entry_id = ui.controlled_vocab_entry_id) ':'');
791 
792  $result =& $this->retrieveRange(
793  'SELECT DISTINCT
794  u.user_id,
795  u.last_name,
796  ar.review_id,
797  (SELECT AVG(ra.quality) FROM review_assignments ra WHERE ra.reviewer_id = u.user_id) AS average_quality,
798  (SELECT COUNT(ac.review_id) FROM review_assignments ac WHERE ac.reviewer_id = u.user_id AND ac.date_completed IS NOT NULL) AS completed,
799  (SELECT COUNT(ac.review_id) FROM review_assignments ac, articles a WHERE
800  ac.reviewer_id = u.user_id AND
801  ac.submission_id = a.article_id AND
802  ac.date_notified IS NOT NULL AND
803  ac.date_completed IS NULL AND
804  ac.cancelled = 0 AND
805  ac.declined = 0 AND
806  a.status <> '.STATUS_QUEUED.') AS incomplete,
807  (SELECT MAX(ac.date_notified) FROM review_assignments ac WHERE ac.reviewer_id = u.user_id AND ac.date_completed IS NOT NULL) AS latest,
808  (SELECT AVG(ac.date_completed-ac.date_notified) FROM review_assignments ac WHERE ac.reviewer_id = u.user_id AND ac.date_completed IS NOT NULL) AS average
809  FROM users u
810  LEFT JOIN review_assignments ra ON (ra.reviewer_id = u.user_id)
811  LEFT JOIN review_assignments ar ON (ar.reviewer_id = u.user_id AND ar.cancelled = 0 AND ar.submission_id = ? AND ar.round = ?)
812  LEFT JOIN roles r ON (r.user_id = u.user_id)
813  LEFT JOIN articles a ON (ra.submission_id = a.article_id)
814  '.$interestJoinSql.'
815  WHERE u.user_id = r.user_id AND
816  r.journal_id = ? AND
817  r.role_id = ? ' . $searchSql . 'GROUP BY u.user_id, u.last_name, ar.review_id' .
818  ($sortBy?(' ORDER BY ' . $this->getSortMapping($sortBy) . ' ' . $this->getDirectionMapping($sortDirection)) : ''),
819  $paramArray, $rangeInfo
820  );
821 
822  $returner = new DAOResultFactory($result, $this, '_returnReviewerUserFromRow');
823  return $returner;
824  }
825 
826  function &_returnReviewerUserFromRow(&$row) { // FIXME
827  $user =& $this->userDao->getUser($row['user_id']);
828  $user->review_id = $row['review_id'];
829  $user->declined = $row['declined'];
830 
831  HookRegistry::call('SectionEditorSubmissionDAO::_returnReviewerUserFromRow', array(&$user, &$row));
832 
833  return $user;
834  }
835 
842  function &getReviewersNotAssignedToArticle($journalId, $articleId) {
843  $users = array();
844 
845  $result =& $this->retrieve(
846  'SELECT u.*
847  FROM users u
848  LEFT JOIN roles r ON (r.user_id = u.user_id)
849  LEFT JOIN review_assignments a ON (a.reviewer_id = u.user_id AND a.article_id = ?)
850  WHERE r.journal_id = ? AND
851  r.role_id = ? AND
852  a.article_id IS NULL
853  ORDER BY last_name, first_name',
854  array($articleId, $journalId, RoleDAO::getRoleIdFromPath('reviewer'))
855  );
856 
857  while (!$result->EOF) {
858  $users[] =& $this->userDao->_returnUserFromRowWithData($result->GetRowAssoc(false));
859  $result->moveNext();
860  }
861 
862  $result->Close();
863  unset($result);
864 
865  return $users;
866  }
867 
874  function copyeditorExists($articleId, $copyeditorId) {
875  $result =& $this->retrieve(
876  'SELECT COUNT(*) FROM signoffs WHERE assoc_id = ? AND assoc_type = ? AND user_id = ? AND symbolic = ?', array($articleId, ASSOC_TYPE_ARTICLE, $copyeditorId, 'SIGNOFF_COPYEDITING_INITIAL')
877  );
878  return isset($result->fields[0]) && $result->fields[0] == 1 ? true : false;
879  }
880 
885  function getLayoutEditorStatistics($journalId) {
886  $statistics = Array();
887 
888  // Get counts of completed submissions
889  $result =& $this->retrieve('SELECT sl.user_id AS editor_id, COUNT(sl.assoc_id) AS complete FROM signoffs sl, articles a INNER JOIN signoffs sp ON (sp.assoc_id = a.article_id) WHERE sl.assoc_id = a.article_id AND (sl.date_completed IS NOT NULL AND sp.date_completed IS NOT NULL) AND sl.date_notified IS NOT NULL AND a.journal_id = ? AND sl.symbolic = ? AND sp.symbolic = ? AND sl.assoc_type = ? AND sp.assoc_type = ? GROUP BY sl.user_id', array($journalId, 'SIGNOFF_LAYOUT', 'SIGNOFF_PROOFREADING_LAYOUT', ASSOC_TYPE_ARTICLE, ASSOC_TYPE_ARTICLE));
890  while (!$result->EOF) {
891  $row = $result->GetRowAssoc(false);
892  if (!isset($statistics[$row['editor_id']])) $statistics[$row['editor_id']] = array();
893  $statistics[$row['editor_id']]['complete'] = $row['complete'];
894  $result->MoveNext();
895  }
896 
897  $result->Close();
898  unset($result);
899 
900  // Get counts of incomplete submissions
901  $result =& $this->retrieve('SELECT sl.user_id AS editor_id, COUNT(sl.assoc_id) AS complete FROM signoffs sl, articles a INNER JOIN signoffs sp ON (sp.assoc_id = a.article_id) WHERE sl.assoc_id = a.article_id AND (sl.date_completed IS NULL AND sp.date_completed IS NULL) AND sl.date_notified IS NOT NULL AND a.journal_id = ? AND sl.symbolic = ? AND sp.symbolic = ? AND sl.assoc_type = ? AND sp.assoc_type = ? GROUP BY sl.user_id', array($journalId, 'SIGNOFF_LAYOUT', 'SIGNOFF_PROOFREADING_LAYOUT', ASSOC_TYPE_ARTICLE, ASSOC_TYPE_ARTICLE));
902  while (!$result->EOF) {
903  $row = $result->GetRowAssoc(false);
904  if (!isset($statistics[$row['editor_id']])) $statistics[$row['editor_id']] = array();
905  $statistics[$row['editor_id']]['incomplete'] = $row['incomplete'];
906  $result->MoveNext();
907  }
908 
909  $result->Close();
910  unset($result);
911 
912  // Get last assignment date
913  $result =& $this->retrieve('SELECT sl.user_id AS editor_id, MAX(sl.date_notified) AS last_assigned FROM signoffs sl, articles a WHERE sl.assoc_id=a.article_id AND a.journal_id=? AND sl.symbolic = ? AND sl.assoc_type = ? GROUP BY sl.user_id', array($journalId, 'SIGNOFF_LAYOUT', ASSOC_TYPE_ARTICLE));
914  while (!$result->EOF) {
915  $row = $result->GetRowAssoc(false);
916  if (!isset($statistics[$row['editor_id']])) $statistics[$row['editor_id']] = array();
917  $statistics[$row['editor_id']]['last_assigned'] = $this->datetimeFromDB($row['last_assigned']);
918  $result->MoveNext();
919  }
920 
921  $result->Close();
922  unset($result);
923 
924  return $statistics;
925  }
926 
931  function getReviewerStatistics($journalId) {
932  $statistics = Array();
933 
934  // Get latest review request date
935  $result =& $this->retrieve(
936  'SELECT r.reviewer_id, MAX(r.date_notified) AS last_notified
937  FROM review_assignments r,
938  articles a
939  WHERE r.submission_id = a.article_id AND
940  a.journal_id = ?
941  GROUP BY r.reviewer_id',
942  (int) $journalId
943  );
944  while (!$result->EOF) {
945  $row = $result->GetRowAssoc(false);
946  if (!isset($statistics[$row['reviewer_id']])) $statistics[$row['reviewer_id']] = array();
947  $statistics[$row['reviewer_id']]['last_notified'] = $this->datetimeFromDB($row['last_notified']);
948  $result->MoveNext();
949  }
950 
951  $result->Close();
952  unset($result);
953 
954  // Get completion status
955  $result =& $this->retrieve(
956  'SELECT r.reviewer_id, COUNT(*) AS incomplete
957  FROM review_assignments r,
958  articles a
959  WHERE r.submission_id = a.article_id AND
960  r.date_notified IS NOT NULL AND
961  r.date_completed IS NULL AND
962  r.cancelled = 0 AND
963  r.declined = 0 AND
964  a.status != '.STATUS_QUEUED.' AND
965  a.journal_id = ?
966  GROUP BY r.reviewer_id',
967  (int) $journalId
968  );
969  while (!$result->EOF) {
970  $row = $result->GetRowAssoc(false);
971  if (!isset($statistics[$row['reviewer_id']])) $statistics[$row['reviewer_id']] = array();
972  $statistics[$row['reviewer_id']]['incomplete'] = $row['incomplete'];
973  $result->MoveNext();
974  }
975 
976  $result->Close();
977  unset($result);
978 
979  // Calculate time taken for completed reviews
980  $result =& $this->retrieve(
981  'SELECT r.reviewer_id, r.date_notified, r.date_completed
982  FROM review_assignments r,
983  articles a
984  WHERE r.submission_id = a.article_id AND
985  r.date_notified IS NOT NULL AND
986  r.date_completed IS NOT NULL AND
987  r.declined = 0 AND
988  a.journal_id = ?',
989  (int) $journalId
990  );
991  while (!$result->EOF) {
992  $row = $result->GetRowAssoc(false);
993  if (!isset($statistics[$row['reviewer_id']])) $statistics[$row['reviewer_id']] = array();
994 
995  $completed = strtotime($this->datetimeFromDB($row['date_completed']));
996  $notified = strtotime($this->datetimeFromDB($row['date_notified']));
997  if (isset($statistics[$row['reviewer_id']]['total_span'])) {
998  $statistics[$row['reviewer_id']]['total_span'] += $completed - $notified;
999  $statistics[$row['reviewer_id']]['completed_review_count'] += 1;
1000  } else {
1001  $statistics[$row['reviewer_id']]['total_span'] = $completed - $notified;
1002  $statistics[$row['reviewer_id']]['completed_review_count'] = 1;
1003  }
1004 
1005  // Calculate the average length of review in weeks.
1006  $statistics[$row['reviewer_id']]['average_span'] = (($statistics[$row['reviewer_id']]['total_span'] / $statistics[$row['reviewer_id']]['completed_review_count']) / 60 / 60 / 24 / 7);
1007  $result->MoveNext();
1008  }
1009 
1010  $result->Close();
1011  unset($result);
1012 
1013  return $statistics;
1014  }
1015 
1020  function getCopyeditorStatistics($journalId) {
1021  $statistics = Array();
1022 
1023  // Get counts of completed submissions
1024  $result =& $this->retrieve('SELECT sc.user_id AS editor_id, COUNT(sc.assoc_id) AS complete FROM signoffs sc, articles a WHERE sc.assoc_id = a.article_id AND sc.date_completed IS NOT NULL AND a.journal_id = ? AND sc.symbolic = ? AND sc.assoc_type = ? GROUP BY sc.user_id', array($journalId, 'SIGNOFF_COPYEDITING_FINAL', ASSOC_TYPE_ARTICLE));
1025  while (!$result->EOF) {
1026  $row = $result->GetRowAssoc(false);
1027  if (!isset($statistics[$row['editor_id']])) $statistics[$row['editor_id']] = array();
1028  $statistics[$row['editor_id']]['complete'] = $row['complete'];
1029  $result->MoveNext();
1030  }
1031 
1032  $result->Close();
1033  unset($result);
1034 
1035  // Get counts of incomplete submissions
1036  $result =& $this->retrieve('SELECT sc.user_id AS editor_id, COUNT(sc.assoc_id) AS incomplete FROM signoffs sc, articles a WHERE sc.assoc_id = a.article_id AND sc.date_completed IS NULL AND a.journal_id = ? AND sc.symbolic = ? AND sc.assoc_type = ? GROUP BY sc.user_id', array($journalId, 'SIGNOFF_COPYEDITING_FINAL', ASSOC_TYPE_ARTICLE));
1037  while (!$result->EOF) {
1038  $row = $result->GetRowAssoc(false);
1039  if (!isset($statistics[$row['editor_id']])) $statistics[$row['editor_id']] = array();
1040  $statistics[$row['editor_id']]['incomplete'] = $row['incomplete'];
1041  $result->MoveNext();
1042  }
1043 
1044  $result->Close();
1045  unset($result);
1046 
1047  // Get last assignment date
1048  $result =& $this->retrieve('SELECT sc.user_id AS editor_id, MAX(sc.date_notified) AS last_assigned FROM signoffs sc, articles a WHERE sc.assoc_id = a.article_id AND a.journal_id = ? AND sc.symbolic = ? AND sc.assoc_type = ? GROUP BY sc.user_id', array($journalId, 'SIGNOFF_COPYEDITING_INITIAL', ASSOC_TYPE_ARTICLE));
1049  while (!$result->EOF) {
1050  $row = $result->GetRowAssoc(false);
1051  if (!isset($statistics[$row['editor_id']])) $statistics[$row['editor_id']] = array();
1052  $statistics[$row['editor_id']]['last_assigned'] = $this->datetimeFromDB($row['last_assigned']);
1053  $result->MoveNext();
1054  }
1055 
1056  $result->Close();
1057  unset($result);
1058 
1059  return $statistics;
1060  }
1061 
1066  function getProofreaderStatistics($journalId) {
1067  $statistics = Array();
1068 
1069  // Get counts of completed submissions
1070  $result =& $this->retrieve('SELECT sp.user_id AS editor_id, COUNT(sp.assoc_id) AS complete FROM signoffs sp, articles a WHERE sp.assoc_id = a.article_id AND sp.date_completed IS NOT NULL AND a.journal_id = ? AND sp.symbolic = ? AND sp.assoc_type = ? GROUP BY sp.user_id', array($journalId, 'SIGNOFF_PROOFREADING_PROOFREADER', ASSOC_TYPE_ARTICLE));
1071  while (!$result->EOF) {
1072  $row = $result->GetRowAssoc(false);
1073  if (!isset($statistics[$row['editor_id']])) $statistics[$row['editor_id']] = array();
1074  $statistics[$row['editor_id']]['complete'] = $row['complete'];
1075  $result->MoveNext();
1076  }
1077 
1078  $result->Close();
1079  unset($result);
1080 
1081  // Get counts of incomplete submissions
1082  $result =& $this->retrieve('SELECT sp.user_id AS editor_id, COUNT(sp.assoc_id) AS incomplete FROM signoffs sp, articles a WHERE sp.assoc_id = a.article_id AND sp.date_completed IS NULL AND a.journal_id = ? AND sp.symbolic = ? AND sp.assoc_type = ? GROUP BY sp.user_id', array($journalId, 'SIGNOFF_PROOFREADING_PROOFREADER', ASSOC_TYPE_ARTICLE));
1083  while (!$result->EOF) {
1084  $row = $result->GetRowAssoc(false);
1085  if (!isset($statistics[$row['editor_id']])) $statistics[$row['editor_id']] = array();
1086  $statistics[$row['editor_id']]['incomplete'] = $row['incomplete'];
1087  $result->MoveNext();
1088  }
1089 
1090  $result->Close();
1091  unset($result);
1092 
1093  // Get last assignment date
1094  $result =& $this->retrieve('SELECT sp.user_id AS editor_id, MAX(sp.date_notified) AS last_assigned FROM signoffs sp, articles a WHERE sp.assoc_id = a.article_id AND a.journal_id = ? AND sp.symbolic = ? AND sp.assoc_type = ? GROUP BY sp.user_id', array($journalId, 'SIGNOFF_PROOFREADING_PROOFREADER', ASSOC_TYPE_ARTICLE));
1095  while (!$result->EOF) {
1096  $row = $result->GetRowAssoc(false);
1097  if (!isset($statistics[$row['editor_id']])) $statistics[$row['editor_id']] = array();
1098  $statistics[$row['editor_id']]['last_assigned'] = $this->datetimeFromDB($row['last_assigned']);
1099  $result->MoveNext();
1100  }
1101  $result->Close();
1102  unset($result);
1103 
1104  return $statistics;
1105  }
1106 
1112  function getSortMapping($heading) {
1113  switch ($heading) {
1114  case 'id': return 'a.article_id';
1115  case 'submitDate': return 'a.date_submitted';
1116  case 'section': return 'section_abbrev';
1117  case 'authors': return 'author_name';
1118  case 'title': return 'submission_title';
1119  case 'active': return 'incomplete';
1120  case 'subCopyedit': return 'copyedit_completed';
1121  case 'subLayout': return 'layout_completed';
1122  case 'subProof': return 'proofread_completed';
1123  case 'reviewerName': return 'u.last_name';
1124  case 'quality': return 'average_quality';
1125  case 'done': return 'completed';
1126  case 'latest': return 'latest';
1127  case 'active': return 'active';
1128  case 'average': return 'average';
1129  case 'name': return 'u.last_name';
1130  default: return null;
1131  }
1132  }
1133 }
1134 
1135 ?>
Operations for retrieving and modifying objects from a database.
Definition: DAO.inc.php:29
& getReviewersNotAssignedToArticle($journalId, $articleId)
copyeditorExists($articleId, $copyeditorId)
& retrieve($sql, $params=false, $callHooks=true)
Definition: DAO.inc.php:83
& getSectionEditorSubmissionsCount($sectionEditorId, $journalId)
getInsertId($table= '', $id= '', $callHooks=true)
Definition: DAO.inc.php:252
CopyeditorSubmission class.
getRoleIdFromPath($rolePath)
& getSectionEditorSubmissionsInEditing($sectionEditorId, $journalId, $sectionId, $searchField=null, $searchMatch=null, $search=null, $dateField=null, $dateFrom=null, $dateTo=null, $rangeInfo=null, $sortBy=null, $sortDirection=SORT_DIRECTION_ASC)
reviewerExists($articleId, $reviewerId, $round)
& retrieveRange($sql, $params=false, $dbResultRange=null, $callHooks=true)
Definition: DAO.inc.php:176
updateSectionEditorSubmission(&$sectionEditorSubmission)
& getReviewersForArticle($journalId, $articleId, $round, $searchType=null, $search=null, $searchMatch=null, $rangeInfo=null, $sortBy=null, $sortDirection=SORT_DIRECTION_ASC)
concat()
Definition: DAO.inc.php:52
datetimeFromDB($dt)
Definition: DAO.inc.php:316
& _getUnfilteredSectionEditorSubmissions($sectionEditorId, $journalId, $sectionId=0, $searchField=null, $searchMatch=null, $search=null, $dateField=null, $dateFrom=null, $dateTo=null, $additionalWhereSql= '', $rangeInfo=null, $sortBy=null, $sortDirection=SORT_DIRECTION_ASC)
Wrapper around ADORecordSet providing &quot;factory&quot; features for generating objects from DAOs...
& getSectionEditorSubmissionsInReview($sectionEditorId, $journalId, $sectionId, $searchField=null, $searchMatch=null, $search=null, $dateField=null, $dateFrom=null, $dateTo=null, $rangeInfo=null, $sortBy=null, $sortDirection=SORT_DIRECTION_ASC)
Operations for retrieving and modifying SectionEditorSubmission objects.
& getDAO($name, $dbconn=null)
call($hookName, $args=null)
_generateUserNameSearchSQL($search, $searchMatch, $prefix, &$params)
SectionEditorSubmission class.
datetimeToDB($dt)
Definition: DAO.inc.php:296
update($sql, $params=false, $callHooks=true, $dieOnError=true)
Definition: DAO.inc.php:211
getDirectionMapping($direction)
Definition: DAO.inc.php:588
& getSectionEditorSubmissionsArchives($sectionEditorId, $journalId, $sectionId, $searchField=null, $searchMatch=null, $search=null, $dateField=null, $dateFrom=null, $dateTo=null, $rangeInfo=null, $sortBy=null, $sortDirection=SORT_DIRECTION_ASC)
& getSectionEditorSubmissions($sectionEditorId, $journalId, $status=true)