Вход Регистрация
Файл: concrete5.7.5.6/concrete/src/Page/PageList.php
Строк: 479
<?php
namespace ConcreteCorePage;

use 
ConcreteCoreSearchItemListDatabaseAttributedItemList as DatabaseItemList;
use 
ConcreteCoreSearchPaginationPagination;
use 
ConcreteCoreSearchPaginationPermissionablePagination;
use 
ConcreteCoreSearchPermissionableListItemInterface;
use 
Page as ConcretePage;
use 
PagerfantaAdapterDoctrineDbalAdapter;

/**
 * An object that allows a filtered list of pages to be returned.
 */
class PageList extends DatabaseItemList implements PermissionableListItemInterface
{
    const 
PAGE_VERSION_ACTIVE 1;
    const 
PAGE_VERSION_RECENT 2;

    protected function 
getAttributeKeyClassName()
    {
        return 
'\Concrete\Core\Attribute\Key\CollectionKey';
    }

    
/** @var  Closure | integer | null */
    
protected $permissionsChecker;

    
/**
     * Columns in this array can be sorted via the request.
     *
     * @var array
     */
    
protected $autoSortColumns = array('cv.cvName''cv.cvDatePublic''c.cDateAdded''c.cDateModified');

    
/**
     * Which version to attempt to retrieve.
     *
     * @var int
     */
    
protected $pageVersionToRetrieve self::PAGE_VERSION_ACTIVE;

    
/**
     * Whether this is a search using fulltext.
     */
    
protected $isFulltextSearch false;

    
/**
     * Whether to include system pages (login, etc...) in this query.
     *
     * @var bool
     */
    
protected $includeSystemPages false;

    
/**
     * Whether to include aliases in the result set.
     */
    
protected $includeAliases false;

    
/**
     * Whether to include inactive (deleted) pages in the query.
     *
     * @var bool
     */
    
protected $includeInactivePages false;

    public function 
setPermissionsChecker(Closure $checker)
    {
        
$this->permissionsChecker $checker;
    }

    public function 
ignorePermissions()
    {
        
$this->permissionsChecker = -1;
    }

    public function 
includeAliases()
    {
        
$this->includeAliases true;
    }

    public function 
includeInactivePages()
    {
        
$this->includeInactivePages true;
    }

    public function 
includeSystemPages()
    {
        
$this->includeSystemPages true;
    }

    public function 
isFulltextSearch()
    {
        return 
$this->isFulltextSearch;
    }

    public function 
setPageVersionToRetrieve($pageVersionToRetrieve)
    {
        
$this->pageVersionToRetrieve $pageVersionToRetrieve;
    }

    public function 
createQuery()
    {
        
$this->query->select('p.cID');
    }

    public function 
finalizeQuery(DoctrineDBALQueryQueryBuilder $query)
    {
        if (
$this->includeAliases) {
            
$query->from('Pages''p')
                ->
leftJoin('p''Pages''pa''p.cPointerID = pa.cID')
                ->
leftJoin('p''PagePaths''pp''p.cID = pp.cID and pp.ppIsCanonical = true')
                ->
leftJoin('pa''PageSearchIndex''psi''psi.cID = if(pa.cID is null, p.cID, pa.cID)')
                ->
leftJoin('p''PageTypes''pt''pt.ptID = if(pa.cID is null, p.ptID, pa.ptID)')
                ->
leftJoin('p''CollectionSearchIndexAttributes''csi''csi.cID = if(pa.cID is null, p.cID, pa.cID)')
                ->
innerJoin('p''CollectionVersions''cv''cv.cID = if(pa.cID is null, p.cID, pa.cID)')
                ->
innerJoin('p''Collections''c''p.cID = c.cID')
                ->
andWhere('p.cIsTemplate = 0 or pa.cIsTemplate = 0');
        } else {
            
$query->from('Pages''p')
                ->
leftJoin('p''PagePaths''pp''(p.cID = pp.cID and pp.ppIsCanonical = true)')
                ->
leftJoin('p''PageSearchIndex''psi''p.cID = psi.cID')
                ->
leftJoin('p''PageTypes''pt''p.ptID = pt.ptID')
                ->
leftJoin('c''CollectionSearchIndexAttributes''csi''c.cID = csi.cID')
                ->
innerJoin('p''Collections''c''p.cID = c.cID')
                ->
innerJoin('p''CollectionVersions''cv''p.cID = cv.cID')
                ->
andWhere('p.cPointerID < 1')
                ->
andWhere('p.cIsTemplate = 0');
        }

        if (
$this->pageVersionToRetrieve == self::PAGE_VERSION_RECENT) {
            
$query->andWhere('cvID = (select max(cvID) from CollectionVersions where cID = cv.cID)');
        } else {
            
$query->andWhere('cvIsApproved = 1');
        }

        if (
$this->isFulltextSearch) {
            
$query->addSelect('match(psi.cName, psi.cDescription, psi.content) against (:fulltext) as cIndexScore');
        }

        if (!
$this->includeInactivePages) {
            
$query->andWhere('p.cIsActive = :cIsActive');
            
$query->setParameter('cIsActive'true);
        }
        if (!
$this->includeSystemPages) {
            
$query->andWhere('p.cIsSystemPage = :cIsSystemPage');
            
$query->setParameter('cIsSystemPage'false);
        }

        return 
$query;
    }

    public function 
getTotalResults()
    {
        
$u = new User();
        if (
$this->permissionsChecker === -1) {
            
$query $this->deliverQueryObject();
            
// We add a custom order by here because otherwise, if we've added
            // items to the select parts, and we're ordering by them, we get a SQL error
            // when we get total results, because we're resetting the select
            
return $query->select('count(distinct p.cID)')->orderBy('p.cID''asc')->setMaxResults(1)->execute()->fetchColumn();
        } else {
            return -
1// unknown
        
}
    }

    protected function 
createPaginationObject()
    {
        
$u = new User();
        if (
$this->permissionsChecker === -1) {
            
$adapter = new DoctrineDbalAdapter($this->deliverQueryObject(), function ($query) {
                
// We add a custom order by here because otherwise, if we've added
                // items to the select parts, and we're ordering by them, we get a SQL error
                // when we get total results, because we're resetting the select
                
$query->select('count(distinct p.cID)')->orderBy('p.cID''asc')->setMaxResults(1);
            });
            
$pagination = new Pagination($this$adapter);
        } else {
            
$pagination = new PermissionablePagination($this);
        }

        return 
$pagination;
    }

    
/**
     * @param $queryRow
     *
     * @return ConcreteCoreFileFile
     */
    
public function getResult($queryRow)
    {
        
$c ConcretePage::getByID($queryRow['cID'], 'ACTIVE');
        if (
is_object($c) && $this->checkPermissions($c)) {
            if (
$this->pageVersionToRetrieve == self::PAGE_VERSION_RECENT) {
                
$cp = new Permissions($c);
                if (
$cp->canViewPageVersions() || $this->permissionsChecker === -1) {
                    
$c->loadVersionObject('RECENT');
                }
            }
            if (isset(
$queryRow['cIndexScore'])) {
                
$c->setPageIndexScore($queryRow['cIndexScore']);
            }

            return 
$c;
        }
    }

    public function 
checkPermissions($mixed)
    {
        if (isset(
$this->permissionsChecker)) {
            if (
$this->permissionsChecker === -1) {
                return 
true;
            } else {
                return 
call_user_func_array($this->permissionsChecker, array($mixed));
            }
        }

        
$cp = new Permissions($mixed);

        return 
$cp->canViewPage();
    }

    
/**
     * Filters by type of collection (using the handle field).
     *
     * @param mixed $ptHandle
     */
    
public function filterByPageTypeHandle($ptHandle)
    {
        
$db Database::get();
        if (
is_array($ptHandle)) {
            
$this->query->andWhere(
                
$this->query->expr()->in('ptHandle'array_map(array($db'quote'), $ptHandle))
            );
        } else {
            
$this->query->andWhere('pt.ptHandle = :ptHandle');
            
$this->query->setParameter('ptHandle'$ptHandle);
        }
    }

    
/**
     * Filters by page template.
     *
     * @param mixed $ptHandle
     */
    
public function filterByPageTemplate(Template $template)
    {
        
$this->query->andWhere('cv.pTemplateID = :pTemplateID');
        
$this->query->setParameter('pTemplateID'$template->getPageTemplateID());
    }

    
/**
     * Filters by date added.
     *
     * @param string $date
     */
    
public function filterByDateAdded($date$comparison '=')
    {
        
$this->query->andWhere($this->query->expr()->comparison('c.cDateAdded'$comparison$this->query->createNamedParameter($date)));
    }

    
/**
     * Filter by number of children.
     *
     * @param $number
     * @param string $comparison
     */
    
public function filterByNumberOfChildren($number$comparison '>')
    {
        
$number intval($number);
        if (
$this->includeAliases) {
            
$this->query->andWhere(
                
$this->query->expr()->orX(
                    
$this->query->expr()->comparison('p.cChildren'$comparison':cChildren'),
                    
$this->query->expr()->comparison('pa.cChildren'$comparison':cChildren')
                )
            );
        } else {
            
$this->query->andWhere($this->query->expr()->comparison('p.cChildren'$comparison':cChildren'));
        }
        
$this->query->setParameter('cChildren'$number);
    }

    
/**
     * Filter by last modified date.
     *
     * @param $date
     * @param string $comparison
     */
    
public function filterByDateLastModified($date$comparison '=')
    {
        
$this->query->andWhere($this->query->expr()->comparison('c.cDateModified'$comparison$this->query->createNamedParameter($date)));
    }

    
/**
     * Filters by public date.
     *
     * @param string $date
     */
    
public function filterByPublicDate($date$comparison '=')
    {
        
$this->query->andWhere($this->query->expr()->comparison('cv.cvDatePublic'$comparison$this->query->createNamedParameter($date)));
    }

    
/**
     * Displays only those pages that have style customizations.
     */
    
public function filterByPagesWithCustomStyles()
    {
        
$this->query->innerJoin('cv''CollectionVersionThemeCustomStyles''cvStyles',
            
'cv.cID = cvStyles.cID');
    }

    
/**
     * Filters by user ID).
     *
     * @param mixed $uID
     */
    
public function filterByUserID($uID)
    {
        
$this->query->andWhere('p.uID = :uID');
        
$this->query->setParameter('uID'$uID);
    }

    
/**
     * Filters by page type ID.
     *
     * @param array | integer $cParentID
     */
    
public function filterByPageTypeID($ptID)
    {
        
$db Database::get();
        if (
is_array($ptID)) {
            
$this->query->andWhere(
                
$this->query->expr()->in('pt.ptID'array_map(array($db'quote'), $ptID))
            );
        } else {
            
$this->query->andWhere($this->query->expr()->comparison('pt.ptID''='':ptID'));
            
$this->query->setParameter('ptID'$ptIDPDO::PARAM_INT);
        }
    }

    
/**
     * Filters by parent ID.
     *
     * @param array | integer $cParentID
     */
    
public function filterByParentID($cParentID)
    {
        
$db Database::get();
        if (
is_array($cParentID)) {
            
$this->query->andWhere(
                
$this->query->expr()->in('p.cParentID'array_map(array($db'quote'), $cParentID))
            );
        } else {
            
$this->query->andWhere('p.cParentID = :cParentID');
            
$this->query->setParameter('cParentID'$cParentIDPDO::PARAM_INT);
        }
    }

    
/**
     * Filters a list by page name.
     *
     * @param $name
     * @param bool $exact
     */
    
public function filterByName($name$exact false)
    {
        if (
$exact) {
            
$this->query->andWhere('cv.cvName = :cvName');
            
$this->query->setParameter('cvName'$name);
        } else {
            
$this->query->andWhere(
                
$this->query->expr()->like('cv.cvName'':cvName')
            );
            
$this->query->setParameter('cvName''%' $name '%');
        }
    }

    
/**
     * Filter a list by page path.
     *
     * @param $path
     * @param bool $includeAllChildren
     */
    
public function filterByPath($path$includeAllChildren true)
    {
        if (!
$includeAllChildren) {
            
$this->query->andWhere('pp.cPath = :cPath');
            
$this->query->setParameter('cPath'$path);
        } else {
            
$this->query->andWhere(
                
$this->query->expr()->like('pp.cPath'':cPath')
            );
            
$this->query->setParameter('cPath'$path '/%');
        }
        
$this->query->andWhere('pp.ppIsCanonical = 1');
    }

    
/**
     * Filters keyword fields by keywords (including name, description, content, and attributes.
     *
     * @param $keywords
     */
    
public function filterByKeywords($keywords)
    {
        
$expressions = array(
            
$this->query->expr()->like('psi.cName'':keywords'),
            
$this->query->expr()->like('psi.cDescription'':keywords'),
            
$this->query->expr()->like('psi.content'':keywords'),
        );

        
$keys CollectionAttributeKey::getSearchableIndexedList();
        foreach (
$keys as $ak) {
            
$cnt $ak->getController();
            
$expressions[] = $cnt->searchKeywords($keywords$this->query);
        }
        
$expr $this->query->expr();
        
$this->query->andWhere(call_user_func_array(array($expr'orX'), $expressions));
        
$this->query->setParameter('keywords''%' $keywords '%');
    }

    public function 
filterByFulltextKeywords($keywords)
    {
        
$this->isFulltextSearch true;
        
$this->autoSortColumns[] = 'cIndexScore';
        
$this->query->where('match(psi.cName, psi.cDescription, psi.content) against (:fulltext)');
        
$this->query->orderBy('cIndexScore''desc');
        
$this->query->setParameter('fulltext'$keywords);
    }

    
/**
     * Filters by topic. Doesn't look at specific attributes –instead, actually joins to the topics table.
     */
    
public function filterByTopic($topic)
    {
        if (
is_object($topic)) {
            
$treeNodeID $topic->getTreeNodeID();
        } else {
            
$treeNodeID $topic;
        }
        
$this->query->innerJoin('cv''CollectionAttributeValues''cavTopics',
            
'cv.cID = cavTopics.cID and cv.cvID = cavTopics.cvID');
        
$this->query->innerJoin('cavTopics''atSelectedTopics''atst''cavTopics.avID = atst.avID');
        
$this->query->andWhere('atst.TopicNodeID = :TopicNodeID');
        
$this->query->setParameter('TopicNodeID'$treeNodeID);
    }

    
/**
     * Sorts this list by display order.
     */
    
public function sortByDisplayOrder()
    {
        
$this->query->orderBy('p.cDisplayOrder''asc');
    }

    
/**
     * Sorts this list by display order descending.
     */
    
public function sortByDisplayOrderDescending()
    {
        
$this->query->orderBy('p.cDisplayOrder''desc');
    }

    
/**
     * Sorts by ID in ascending order.
     */
    
public function sortByCollectionIDAscending()
    {
        
$this->query->orderBy('p.cID''asc');
    }

    
/**
     * Sorts this list by public date ascending order.
     */
    
public function sortByPublicDate()
    {
        
$this->query->orderBy('cv.cvDatePublic''asc');
    }

    
/**
     * Sorts by name in ascending order.
     */
    
public function sortByName()
    {
        
$this->query->orderBy('cv.cvName''asc');
    }

    
/**
     * Sorts by name in descending order.
     */
    
public function sortByNameDescending()
    {
        
$this->query->orderBy('cv.cvName''desc');
    }

    
/**
     * Sorts this list by public date descending order.
     */
    
public function sortByPublicDateDescending()
    {
        
$this->query->orderBy('cv.cvDatePublic''desc');
    }

    
/**
     * Sorts by fulltext relevance (requires that the query be fulltext-based.
     */
    
public function sortByRelevance()
    {
        if (
$this->isFulltextSearch) {
            
$this->query->orderBy('cIndexScore''desc');
        }
    }

    
/**
     * @deprecated
     */
    
public function filterByCollectionTypeHandle($ctHandle)
    {
        
$this->filterByPageTypeHandle($ctHandle);
    }

    
/**
     * @deprecated
     */
    
public function filterByCollectionTypeID($ctID)
    {
        
$this->filterByPageTypeID($ctID);
    }

    
/**
     * This does nothing.
     *
     * @deprecated
     */
    
public function ignoreAliases()
    {
        return 
false;
    }

    
/**
     * @deprecated
     */
    
public function displayUnapprovedPages()
    {
        
$this->setPageVersionToRetrieve(self::PAGE_VERSION_RECENT);
    }
}
Онлайн: 1
Реклама