Вход Регистрация
Файл: 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', $ptID, PDO::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', $cParentID, PDO::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);
    }
}
Онлайн: 3
Реклама