JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-} .
LIBYA CYBER ARMY
Logo of a company Instagram@3g86    Server : Apache
System : Linux uta-edu.server.ly 4.18.0-513.11.1.el8_9.x86_64 #1 SMP Wed Jan 17 02:00:40 EST 2024 x86_64
User : utripoli ( 1001)
PHP Version : 7.4.33
Disable Function : NONE
Directory :  /home/utripoli/public_html/alqalam/lib/pkp/classes/submission/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/utripoli/public_html/alqalam/lib/pkp/classes/submission/Collector.php
<?php
/**
 * @file classes/submission/Collector.php
 *
 * Copyright (c) 2014-2021 Simon Fraser University
 * Copyright (c) 2000-2021 John Willinsky
 * Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
 *
 * @class Collector
 *
 * @brief A helper class to configure a Query Builder to get a collection of submissions
 */

namespace PKP\submission;

use APP\core\Application;
use APP\facades\Repo;
use APP\submission\Collector as AppCollector;
use APP\submission\Submission;
use Exception;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\LazyCollection;
use PKP\core\Core;
use PKP\core\interfaces\CollectorInterface;
use PKP\facades\Locale;
use PKP\identity\Identity;
use PKP\plugins\Hook;
use PKP\search\SubmissionSearch;
use PKP\security\Role;
use PKP\submission\reviewRound\ReviewRound;

/**
 * @template T of Submission
 */
abstract class Collector implements CollectorInterface
{
    public const ORDERBY_DATE_PUBLISHED = 'datePublished';
    public const ORDERBY_DATE_SUBMITTED = 'dateSubmitted';
    public const ORDERBY_LAST_ACTIVITY = 'lastActivity';
    public const ORDERBY_LAST_MODIFIED = 'lastModified';
    public const ORDERBY_SEQUENCE = 'sequence';
    public const ORDERBY_TITLE = 'title';
    public const ORDERBY_SEARCH_RANKING = 'ranking';
    public const ORDER_DIR_ASC = 'ASC';
    public const ORDER_DIR_DESC = 'DESC';

    public const UNASSIGNED = -1;

    public DAO $dao;
    public ?array $categoryIds = null;
    public ?array $contextIds = null;
    public ?int $count = null;
    public ?int $daysInactive = null;
    public bool $isIncomplete = false;
    public bool $isOverdue = false;
    public ?int $offset = null;
    public string $orderBy = self::ORDERBY_DATE_SUBMITTED;
    public string $orderDirection = 'DESC';
    public ?string $searchPhrase = null;
    public ?int $maxSearchKeywords = null;
    public ?array $statuses = null;
    public ?array $stageIds = null;
    public ?array $doiStatuses = null;
    public ?bool $hasDois = null;
    public ?array $excludeIds = null;

    /** @var array Which DOI types should be considered when checking if a submission has DOIs set */
    public array $enabledDoiTypes = [];

    /** @var array|int */
    public $assignedTo = null;

    public function __construct(DAO $dao)
    {
        $this->dao = $dao;
    }

    public function getCount(): int
    {
        return $this->dao->getCount($this);
    }

    /**
     * @return Collection<int,int>
     */
    public function getIds(): Collection
    {
        return $this->dao->getIds($this);
    }

    /**
     * @copydoc DAO::getMany()
     * @return LazyCollection<int,T>
     */
    public function getMany(): LazyCollection
    {
        return $this->dao->getMany($this);
    }

    /**
     * Limit results to submissions in these contexts
     */
    public function filterByContextIds(?array $contextIds): AppCollector
    {
        $this->contextIds = $contextIds;
        return $this;
    }

    /**
     * Limit results by submissions assigned to these categories
     */
    public function filterByCategoryIds(?array $categoryIds): AppCollector
    {
        $this->categoryIds = $categoryIds;
        return $this;
    }

    /**
     * Limit results to submissions that contain any pub objects (e.g. publication and galley) with these statuses
     *
     * @param array|null $statuses One or more of DOI::STATUS_* constants
     *
     */
    public function filterByDoiStatuses(?array $statuses): AppCollector
    {
        $this->doiStatuses = $statuses;

        return $this;
    }

    /**
     * Limit results to submissions that do/don't have any DOIs assign to their sub objects
     *
     * @param array|null $enabledDoiTypes TYPE_* constants to consider when checking submission has DOIs
     */
    public function filterByHasDois(?bool $hasDois, ?array $enabledDoiTypes = null): AppCollector
    {
        $this->hasDois = $hasDois;
        $this->enabledDoiTypes = $enabledDoiTypes === null ? [Repo::doi()::TYPE_PUBLICATION] : $enabledDoiTypes;
        return $this;
    }

    /**
     * Limit results by submissions with these statuses
     *
     * @see \PKP\submissions\PKPSubmission::STATUS_
     */
    public function filterByStatus(?array $statuses): AppCollector
    {
        $this->statuses = $statuses;
        return $this;
    }

    /**
     * Limit results by submissions in these workflow stage ids
     */
    public function filterByStageIds(?array $stageIds): AppCollector
    {
        $this->stageIds = $stageIds;
        return $this;
    }

    /**
     * Limit results to incomplete submissions
     *
     * Submissions are incomplete when the author has begun to enter
     * details about their submission but not yet submitted it.
     */
    public function filterByIncomplete(bool $isIncomplete): AppCollector
    {
        $this->isIncomplete = $isIncomplete;
        return $this;
    }

    /**
     * Limit results to submissions with overdue tasks
     */
    public function filterByOverdue(bool $isOverdue): AppCollector
    {
        $this->isOverdue = $isOverdue;
        return $this;
    }

    /**
     *  Limit results to submission with no activity for X days
     */
    public function filterByDaysInactive(?int $daysInactive): AppCollector
    {
        $this->daysInactive = $daysInactive;
        return $this;
    }

    /**
     * Limit results to submissions assigned to these users
     *
     * @param int|array $assignedTo An array of user IDs
     *  or self::UNASSIGNED to get unassigned submissions
     */
    public function assignedTo($assignedTo): AppCollector
    {
        $this->assignedTo = $assignedTo;
        return $this;
    }

    /**
     * Limit results to submissions matching this search query
     */
    public function searchPhrase(?string $phrase, ?int $maxSearchKeywords = null): AppCollector
    {
        $this->searchPhrase = $phrase;
        $this->maxSearchKeywords = $maxSearchKeywords;
        return $this;
    }

    /**
     * Ensure the given submission IDs are not included
     */
    public function excludeIds(?array $ids): AppCollector
    {
        $this->excludeIds = $ids;
        return $this;
    }

    /**
     * Limit the number of objects retrieved
     */
    public function limit(?int $count): AppCollector
    {
        $this->count = $count;
        return $this;
    }

    /**
     * Offset the number of objects retrieved, for example to
     * retrieve the second page of contents
     */
    public function offset(?int $offset): AppCollector
    {
        $this->offset = $offset;
        return $this;
    }

    /**
     * Order the results
     *
     * The following column values are supported:
     *
     * - lastModified
     * - dateLastActivity
     * - title
     * - seq (sequence)
     * - DAO::ORDERBY_DATE_PUBLISHED
     *
     * Results are ordered by the date submitted by default.
     *
     * @param string $sorter One of the self::ORDERBY_ constants
     * @param string $direction One of the self::ORDER_DIR_ constants
     */
    public function orderBy(string $sorter, string $direction = self::ORDER_DIR_DESC): AppCollector
    {
        $this->orderBy = $sorter;
        $this->orderDirection = $direction;
        return $this;
    }

    /**
     * Add APP-specific filtering methods for submission sub objects DOI statuses
     *
     */
    abstract protected function addDoiStatusFilterToQuery(Builder $q);

    /**
     * Add APP-specific filtering methods for checking if submission sub objects have DOIs assigned
     */
    abstract protected function addHasDoisFilterToQuery(Builder $q);

    /**
     * @copydoc CollectorInterface::getQueryBuilder()
     */
    public function getQueryBuilder(): Builder
    {
        $q = DB::table('submissions AS s')
            ->leftJoin('publications AS po', 's.current_publication_id', '=', 'po.publication_id')
            ->select(['s.*']);

        // Never permit a query without a context_id unless the CONTEXT_ID_ALL wildcard
        // has been set explicitly.
        if (!isset($this->contextIds)) {
            throw new Exception('Submissions can not be retrieved without a context id. Pass the CONTEXT_ID_ALL wildcard to get submissions from any context.');
        } elseif (!in_array(Application::CONTEXT_ID_ALL, $this->contextIds)) {
            $q->whereIn('s.context_id', $this->contextIds);
        }

        // Prepare keywords (allows short and numeric words)
        $keywords = collect(Application::getSubmissionSearchIndex()->filterKeywords($this->searchPhrase, false, true, true))
            ->unique()
            ->take($this->maxSearchKeywords ?? PHP_INT_MAX);

        // Setup the order by
        switch ($this->orderBy) {
            case self::ORDERBY_DATE_PUBLISHED:
                $q->addSelect(['po.date_published']);
                $q->orderBy('po.date_published', $this->orderDirection);
                break;
            case self::ORDERBY_LAST_ACTIVITY:
                $q->orderBy('s.date_last_activity', $this->orderDirection);
                break;
            case self::ORDERBY_LAST_MODIFIED:
                $q->orderBy('s.last_modified', $this->orderDirection);
                break;
            case self::ORDERBY_SEQUENCE:
                $q->addSelect(['po.seq']);
                $q->orderBy('po.seq', $this->orderDirection);
                break;
            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) =>
                        $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) =>
                        $join->on('publication_tlp.publication_id', '=', 'publication_tlpsl.publication_id')
                            ->on('publication_tlpsl.locale', '=', 's.locale')
                            ->where('publication_tlpsl.setting_name', '=', 'title')
                    );
                $coalesceTitles = 'COALESCE(publication_tlps.setting_value, publication_tlpsl.setting_value)';
                $q->addSelect([DB::raw($coalesceTitles)]);
                $q->orderBy(DB::raw($coalesceTitles), $this->orderDirection);
                break;
            case self::ORDERBY_SEARCH_RANKING:
                if (!$keywords->count()) {
                    $q->orderBy('s.date_submitted', $this->orderDirection);
                    break;
                }
                // Retrieves the number of matches for all keywords
                $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)
                        )
                    )
                    ->whereColumn('s.submission_id', '=', 'sso.submission_id')
                    ->selectRaw('COUNT(0)');
                // Retrieves the number of distinct matched keywords
                $orderByDistinctKeyword = (clone $orderByMatchCount)->select(DB::raw('COUNT(DISTINCT sskl.keyword_id)'));
                $q->orderBy($orderByDistinctKeyword, $this->orderDirection)
                    ->orderBy($orderByMatchCount, $this->orderDirection);
                break;
            case self::ORDERBY_DATE_SUBMITTED:
            default:
                $q->orderBy('s.date_submitted', $this->orderDirection);
                break;
        }

        if (isset($this->statuses)) {
            $q->whereIn('s.status', $this->statuses);
        }

        if (isset($this->stageIds)) {
            $q->whereIn('s.stage_id', $this->stageIds);
        }

        if ($this->isIncomplete) {
            $q->where('s.submission_progress', '<>', '');
        }

        if (isset($this->daysInactive)) {
            $q->where('s.date_last_activity', '<', Core::getCurrentDate(strtotime('-' . $this->daysInactive . ' days')));
        }

        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')
                    )
                    ->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->select('s.submission_id')
                    ->from('submissions AS s')
                    ->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) =>
                        $table->on('s.submission_id', '=', 'ra.submission_id')
                            ->where('ra.declined', '=', (int) 0)
                            ->where('ra.cancelled', '=', (int) 0)
                            ->whereIn('ra.reviewer_id', $this->assignedTo)
                    )
                    ->whereNotNull('sa.stage_assignment_id')
                    ->orWhereNotNull('ra.review_id')
            );
        } elseif ($this->assignedTo === self::UNASSIGNED) {
            $sub = DB::table('stage_assignments')
                ->select(DB::raw('count(stage_assignments.stage_assignment_id)'))
                ->leftJoin('user_groups', 'stage_assignments.user_group_id', '=', 'user_groups.user_group_id')
                ->where('stage_assignments.submission_id', '=', DB::raw('s.submission_id'))
                ->whereIn('user_groups.role_id', [Role::ROLE_ID_MANAGER, Role::ROLE_ID_SUB_EDITOR]);

            $q->whereNotNull('s.date_submitted')
                ->mergeBindings($sub)
                ->where(DB::raw('(' . $sub->toSql() . ')'), '=', '0');
        }

        // Search phrase
        if ($keywords->count()) {
            $likePattern = DB::raw("CONCAT('%', LOWER(?), '%')");
            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)
                    ->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)
                            )
                        )
                    )
                    // 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)
                    )
                )
            );
        } elseif (strlen($this->searchPhrase)) {
            // If there's search text, but no keywords could be extracted from it, force the query to return nothing
            $q->whereRaw('1 = 0');
        }

        if (isset($this->categoryIds)) {
            $q->join('publication_categories as pc', 's.current_publication_id', '=', 'pc.publication_id')
                ->whereIn('pc.category_id', $this->categoryIds);
        }

        // Filter by any child pub object's DOI status
        $q->when($this->doiStatuses !== null, fn (Builder $q) => $this->addDoiStatusFilterToQuery($q));

        // Filter by whether any child pub objects have DOIs assigned
        $q->when($this->hasDois !== null, fn (Builder $q) => $this->addHasDoisFilterToQuery($q));

        // Filter out excluded submission IDs
        $q->when($this->excludeIds !== null, fn (Builder $q) => $q->whereNotIn('s.submission_id', $this->excludeIds));

        // Limit and offset results for pagination
        if (isset($this->count)) {
            $q->limit($this->count);
        }
        if (isset($this->offset)) {
            $q->offset($this->offset);
        }

        // Add app-specific query statements
        Hook::call('Submission::Collector', [&$q, $this]);

        return $q;
    }
}

3g86 2022