PagerSelectExtender.php

Same filename in this branch
  1. 11.x core/tests/fixtures/database_drivers/module/core_fake/src/Driver/Database/CoreFakeWithAllCustomClasses/PagerSelectExtender.php
Same filename and directory in other branches
  1. 9 core/tests/fixtures/database_drivers/module/corefake/src/Driver/Database/corefakeWithAllCustomClasses/PagerSelectExtender.php
  2. 9 core/lib/Drupal/Core/Database/Query/PagerSelectExtender.php
  3. 8.9.x core/lib/Drupal/Core/Database/Query/PagerSelectExtender.php
  4. 10 core/tests/fixtures/database_drivers/module/core_fake/src/Driver/Database/CoreFakeWithAllCustomClasses/PagerSelectExtender.php
  5. 10 core/lib/Drupal/Core/Database/Query/PagerSelectExtender.php

Namespace

Drupal\Core\Database\Query

File

core/lib/Drupal/Core/Database/Query/PagerSelectExtender.php

View source
<?php

namespace Drupal\Core\Database\Query;

use Drupal\Core\Database\Connection;

/**
 * Query extender for pager queries.
 *
 * This is the "default" pager mechanism.  It creates a paged query with a fixed
 * number of entries per page.
 *
 * When adding this extender along with other extenders, be sure to add
 * PagerSelectExtender last, so that its range and count are based on the full
 * query.
 */
class PagerSelectExtender extends SelectExtender {
    
    /**
     * The number of elements per page to allow.
     *
     * @var int
     */
    protected $limit = 10;
    
    /**
     * The unique ID of this pager on this page.
     *
     * @var int
     */
    protected $element = NULL;
    
    /**
     * The count query that will be used for this pager.
     *
     * @var \Drupal\Core\Database\Query\SelectInterface
     */
    protected $customCountQuery = FALSE;
    
    /**
     * Constructs a PagerSelectExtender object.
     *
     * @param \Drupal\Core\Database\Query\SelectInterface $query
     *   Select query object.
     * @param \Drupal\Core\Database\Connection $connection
     *   Database connection object.
     */
    public function __construct(SelectInterface $query, Connection $connection) {
        parent::__construct($query, $connection);
        // Add pager tag. Do this here to ensure that it is always added before
        // preExecute() is called.
        $this->addTag('pager');
    }
    
    /**
     * Override the execute method.
     *
     * Before we run the query, we need to add pager-based range() instructions
     * to it.
     */
    public function execute() {
        // By calling preExecute() here, we force it to preprocess the extender
        // object rather than just the base query object. That means
        // hook_query_alter() gets access to the extended object.
        if (!$this->preExecute($this)) {
            return NULL;
        }
        // A NULL limit is the "kill switch" for pager queries.
        if (empty($this->limit)) {
            return;
        }
        $this->ensureElement();
        $total_items = $this->getCountQuery()
            ->execute()
            ->fetchField();
        $pager = $this->connection
            ->getPagerManager()
            ->createPager($total_items, $this->limit, $this->element);
        $this->range($pager->getCurrentPage() * $this->limit, $this->limit);
        // Now that we've added our pager-based range instructions, run the query normally.
        return $this->query
            ->execute();
    }
    
    /**
     * Ensure that there is an element associated with this query.
     *
     * After running this method, access $this->element to get the element for this
     * query.
     */
    protected function ensureElement() {
        if (!isset($this->element)) {
            $this->element($this->connection
                ->getPagerManager()
                ->getMaxPagerElementId() + 1);
        }
    }
    
    /**
     * Specify the count query object to use for this pager.
     *
     * You will rarely need to specify a count query directly.  If not specified,
     * one is generated off of the pager query itself.
     *
     * @param \Drupal\Core\Database\Query\SelectInterface $query
     *   The count query object.  It must return a single row with a single column,
     *   which is the total number of records.
     */
    public function setCountQuery(SelectInterface $query) {
        $this->customCountQuery = $query;
    }
    
    /**
     * Retrieve the count query for this pager.
     *
     * The count query may be specified manually or, by default, taken from the
     * query we are extending.
     *
     * @return \Drupal\Core\Database\Query\SelectInterface
     *   A count query object.
     */
    public function getCountQuery() {
        if ($this->customCountQuery) {
            return $this->customCountQuery;
        }
        else {
            return $this->query
                ->countQuery();
        }
    }
    
    /**
     * Specify the maximum number of elements per page for this query.
     *
     * The default if not specified is 10 items per page.
     *
     * @param int|false $limit
     *   An integer specifying the number of elements per page. If passed a false
     *   value (FALSE, 0, NULL), the pager is disabled.
     */
    public function limit($limit = 10) {
        $this->limit = $limit;
        return $this;
    }
    
    /**
     * Specify the element ID for this pager query.
     *
     * The element is used to differentiate different pager queries on the same
     * page so that they may be operated independently.  If you do not specify an
     * element, every pager query on the page will get a unique element.  If for
     * whatever reason you want to explicitly define an element for a given query,
     * you may do so here.
     *
     * Note that no collision detection is done when setting an element ID
     * explicitly, so it is possible for two pagers to end up using the same ID
     * if both are set explicitly.
     *
     * @param $element
     *   Element ID that is used to differentiate different pager queries.
     */
    public function element($element) {
        $this->element = $element;
        $this->connection
            ->getPagerManager()
            ->reservePagerElementId($this->element);
        return $this;
    }
    
    /**
     * Gets the element ID for this pager query.
     *
     * The element is used to differentiate different pager queries on the same
     * page so that they may be operated independently.
     *
     * @return int
     *   Element ID that is used to differentiate between different pager
     *   queries.
     */
    public function getElement() : int {
        $this->ensureElement();
        return $this->element;
    }

}

Classes

Title Deprecated Summary
PagerSelectExtender Query extender for pager queries.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.