Skip to content

Commit

Permalink
#10662 Fix isOverdue query
Browse files Browse the repository at this point in the history
  • Loading branch information
taslangraham committed Jan 15, 2025
1 parent 1399d09 commit 82203af
Showing 1 changed file with 130 additions and 89 deletions.
219 changes: 130 additions & 89 deletions classes/submission/Collector.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

/**
* @file classes/submission/Collector.php
*
Expand Down Expand Up @@ -93,6 +94,7 @@ public function getIds(): Collection

/**
* @copydoc DAO::getMany()
*
* @return LazyCollection<int,T>
*/
public function getMany(): LazyCollection
Expand Down Expand Up @@ -318,14 +320,18 @@ public function getQueryBuilder(): Builder
case self::ORDERBY_TITLE:
$locale = Locale::getLocale();
$q->leftJoin('publications as publication_tlp', 's.current_publication_id', '=', 'publication_tlp.publication_id')
->leftJoin('publication_settings as publication_tlps', fn (JoinClause $join) =>
->leftJoin(
'publication_settings as publication_tlps',
fn (JoinClause $join) =>
$join->on('publication_tlp.publication_id', '=', 'publication_tlps.publication_id')
->where('publication_tlps.setting_name', '=', 'title')
->where('publication_tlps.setting_value', '!=', '')
->where('publication_tlps.locale', '=', $locale)
);
$q->leftJoin('publications as publication_tlpl', 's.current_publication_id', '=', 'publication_tlpl.publication_id')
->leftJoin('publication_settings as publication_tlpsl', fn (JoinClause $join) =>
->leftJoin(
'publication_settings as publication_tlpsl',
fn (JoinClause $join) =>
$join->on('publication_tlp.publication_id', '=', 'publication_tlpsl.publication_id')
->on('publication_tlpsl.locale', '=', 's.locale')
->where('publication_tlpsl.setting_name', '=', 'title')
Expand All @@ -343,10 +349,12 @@ public function getQueryBuilder(): Builder
$orderByMatchCount = DB::table('submission_search_objects', 'sso')
->join('submission_search_object_keywords AS ssok', 'ssok.object_id', '=', 'sso.object_id')
->join('submission_search_keyword_list AS sskl', 'sskl.keyword_id', '=', 'ssok.keyword_id')
->where(fn (Builder $q) =>
$keywords->map(fn (string $keyword) => $q
->orWhere('sskl.keyword_text', '=', DB::raw('LOWER(?)'))
->addBinding($keyword)
->where(
fn (Builder $q) =>
$keywords->map(
fn (string $keyword) => $q
->orWhere('sskl.keyword_text', '=', DB::raw('LOWER(?)'))
->addBinding($keyword)
)
)
->whereColumn('s.submission_id', '=', 'sso.submission_id')
Expand Down Expand Up @@ -379,41 +387,57 @@ public function getQueryBuilder(): Builder
}

if ($this->isOverdue) {
$q->leftJoin('review_assignments as raod', 'raod.submission_id', '=', 's.submission_id')
->leftJoin('review_rounds as rr', fn (Builder $table) =>
$table->on('rr.submission_id', '=', 's.submission_id')
->on('raod.review_round_id', '=', 'rr.review_round_id')
);
// Only get overdue assignments on active review rounds
$q->whereNotIn('rr.status', [
ReviewRound::REVIEW_ROUND_STATUS_RESUBMIT_FOR_REVIEW,
ReviewRound::REVIEW_ROUND_STATUS_SENT_TO_EXTERNAL,
ReviewRound::REVIEW_ROUND_STATUS_ACCEPTED,
ReviewRound::REVIEW_ROUND_STATUS_DECLINED,
]);
$q->where(fn (Builder $q) =>
$q->where('raod.declined', '<>', 1)
->where('raod.cancelled', '<>', 1)
->where(fn (Builder $q) =>
$q->where('raod.date_due', '<', Core::getCurrentDate(strtotime('tomorrow')))
->whereNull('raod.date_completed')
$q->whereIn(
's.submission_id',
fn (Builder $q) =>
$q->select('s.submission_id')
->from('submissions AS s')
->leftJoin('review_assignments as raod', 'raod.submission_id', '=', 's.submission_id')
->leftJoin(
'review_rounds as rr',
fn (Builder $table) =>
$table->on('rr.submission_id', '=', 's.submission_id')
->on('raod.review_round_id', '=', 'rr.review_round_id')
)
->orWhere(fn (Builder $q) =>
$q->where('raod.date_response_due', '<', Core::getCurrentDate(strtotime('tomorrow')))
->whereNull('raod.date_confirmed')
->whereNotIn('rr.status', [
ReviewRound::REVIEW_ROUND_STATUS_RESUBMIT_FOR_REVIEW,
ReviewRound::REVIEW_ROUND_STATUS_SENT_TO_EXTERNAL,
ReviewRound::REVIEW_ROUND_STATUS_ACCEPTED,
ReviewRound::REVIEW_ROUND_STATUS_DECLINED,
])
->where(
fn (Builder $q) =>
$q->where('raod.declined', '<>', 1)
->where('raod.cancelled', '<>', 1)
->where(
fn (Builder $q) =>
$q->where('raod.date_due', '<', Core::getCurrentDate(strtotime('tomorrow')))
->whereNull('raod.date_completed')
)
->orWhere(
fn (Builder $q) =>
$q->where('raod.date_response_due', '<', Core::getCurrentDate(strtotime('tomorrow')))
->whereNull('raod.date_confirmed')
)
)
);
}

if (is_array($this->assignedTo)) {
$q->whereIn('s.submission_id', fn (Builder $q) =>
$q->whereIn(
's.submission_id',
fn (Builder $q) =>
$q->select('s.submission_id')
->from('submissions AS s')
->leftJoin('stage_assignments as sa', fn (Builder $q) =>
->leftJoin(
'stage_assignments as sa',
fn (Builder $q) =>
$q->on('s.submission_id', '=', 'sa.submission_id')
->whereIn('sa.user_id', $this->assignedTo)
)
->leftJoin('review_assignments as ra', fn (Builder $table) =>
->leftJoin(
'review_assignments as ra',
fn (Builder $table) =>
$table->on('s.submission_id', '=', 'ra.submission_id')
->where('ra.declined', '=', (int) 0)
->where('ra.cancelled', '=', (int) 0)
Expand All @@ -437,72 +461,89 @@ public function getQueryBuilder(): Builder
// Search phrase
if ($keywords->count()) {
$likePattern = DB::raw("CONCAT('%', LOWER(?), '%')");
if(!empty($this->assignedTo)) {
if (!empty($this->assignedTo)) {
// Holds a single random row to check whether we have any assignment
$q->leftJoinSub(fn (Builder $q) => $q
->from('review_assignments', 'ra')
->whereIn('ra.reviewer_id', $this->assignedTo == self::UNASSIGNED ? [] : (array) $this->assignedTo)
->select(DB::raw('1 AS value'))
->limit(1),
'any_assignment', 'any_assignment.value', '=', DB::raw('1')
$q->leftJoinSub(
fn (Builder $q) => $q
->from('review_assignments', 'ra')
->whereIn('ra.reviewer_id', $this->assignedTo == self::UNASSIGNED ? [] : (array) $this->assignedTo)
->select(DB::raw('1 AS value'))
->limit(1),
'any_assignment',
'any_assignment.value',
'=',
DB::raw('1')
);
}
// Builds the filters
$q->where(fn (Builder $q) => $keywords
->map(fn (string $keyword) => $q
// Look for matches on the indexed data
->orWhereExists(fn (Builder $query) => $query
->from('submission_search_objects', 'sso')
->join('submission_search_object_keywords AS ssok', 'sso.object_id', '=', 'ssok.object_id')
->join('submission_search_keyword_list AS sskl', 'sskl.keyword_id', '=', 'ssok.keyword_id')
->where('sskl.keyword_text', '=', DB::raw('LOWER(?)'))->addBinding($keyword)
->whereColumn('s.submission_id', '=', 'sso.submission_id')
// Don't permit reviewers to search on author names
->when(!empty($this->assignedTo), fn (Builder $q) => $q
->where(fn (Builder $q) => $q
->whereNull('any_assignment.value')
->orWhere('sso.type', '!=', SubmissionSearch::SUBMISSION_SEARCH_AUTHOR)
$q->where(
fn (Builder $q) => $keywords
->map(
fn (string $keyword) => $q
// Look for matches on the indexed data
->orWhereExists(
fn (Builder $query) => $query
->from('submission_search_objects', 'sso')
->join('submission_search_object_keywords AS ssok', 'sso.object_id', '=', 'ssok.object_id')
->join('submission_search_keyword_list AS sskl', 'sskl.keyword_id', '=', 'ssok.keyword_id')
->where('sskl.keyword_text', '=', DB::raw('LOWER(?)'))->addBinding($keyword)
->whereColumn('s.submission_id', '=', 'sso.submission_id')
// Don't permit reviewers to search on author names
->when(
!empty($this->assignedTo),
fn (Builder $q) => $q
->where(
fn (Builder $q) => $q
->whereNull('any_assignment.value')
->orWhere('sso.type', '!=', SubmissionSearch::SUBMISSION_SEARCH_AUTHOR)
)
)
)
)
)
// Search on the publication title
->orWhereIn('s.submission_id', fn (Builder $query) => $query
->select('p.submission_id')->from('publications AS p')
->join('publication_settings AS ps', 'p.publication_id', '=', 'ps.publication_id')
->where('ps.setting_name', '=', 'title')
->where(DB::raw('LOWER(ps.setting_value)'), 'LIKE', $likePattern)
->addBinding($keyword)
)
// Search on the author name and ORCID
->orWhereIn('s.submission_id', fn (Builder $query) => $query
->select('p.submission_id')
->from('publications AS p')
->join('authors AS au', 'au.publication_id', '=', 'p.publication_id')
->join('author_settings AS aus', 'aus.author_id', '=', 'au.author_id')
->whereIn('aus.setting_name', [
Identity::IDENTITY_SETTING_GIVENNAME,
Identity::IDENTITY_SETTING_FAMILYNAME,
'orcid'
])
// Don't permit reviewers to search on author names
->when(!empty($this->assignedTo), fn (Builder $q) => $q
->where(fn (Builder $q) => $q
->whereNull('any_assignment.value')
->orWhereNotIn('aus.setting_name', [
Identity::IDENTITY_SETTING_GIVENNAME,
Identity::IDENTITY_SETTING_FAMILYNAME
])
// Search on the publication title
->orWhereIn(
's.submission_id',
fn (Builder $query) => $query
->select('p.submission_id')->from('publications AS p')
->join('publication_settings AS ps', 'p.publication_id', '=', 'ps.publication_id')
->where('ps.setting_name', '=', 'title')
->where(DB::raw('LOWER(ps.setting_value)'), 'LIKE', $likePattern)
->addBinding($keyword)
)
// Search on the author name and ORCID
->orWhereIn(
's.submission_id',
fn (Builder $query) => $query
->select('p.submission_id')
->from('publications AS p')
->join('authors AS au', 'au.publication_id', '=', 'p.publication_id')
->join('author_settings AS aus', 'aus.author_id', '=', 'au.author_id')
->whereIn('aus.setting_name', [
Identity::IDENTITY_SETTING_GIVENNAME,
Identity::IDENTITY_SETTING_FAMILYNAME,
'orcid'
])
// Don't permit reviewers to search on author names
->when(
!empty($this->assignedTo),
fn (Builder $q) => $q
->where(
fn (Builder $q) => $q
->whereNull('any_assignment.value')
->orWhereNotIn('aus.setting_name', [
Identity::IDENTITY_SETTING_GIVENNAME,
Identity::IDENTITY_SETTING_FAMILYNAME
])
)
)
->where(DB::raw('LOWER(aus.setting_value)'), 'LIKE', $likePattern)
->addBinding($keyword)
)
// Search for the exact submission ID
->when(
($numericWords = $keywords->filter(fn (string $keyword) => ctype_digit($keyword)))->count(),
fn (Builder $query) => $query->orWhereIn('s.submission_id', $numericWords)
)
)
->where(DB::raw('LOWER(aus.setting_value)'), 'LIKE', $likePattern)
->addBinding($keyword)
)
// Search for the exact submission ID
->when(
($numericWords = $keywords->filter(fn (string $keyword) => ctype_digit($keyword)))->count(),
fn (Builder $query) => $query->orWhereIn('s.submission_id', $numericWords)
)
)
);
} elseif (strlen($this->searchPhrase ?? '')) {
// If there's search text, but no keywords could be extracted from it, force the query to return nothing
Expand Down

0 comments on commit 82203af

Please sign in to comment.