Issue #2044435 by mondrake, kim.pepper, Mile23, andypost, martin107, daffie, jibran, beejeebus, alexpott, larowlan, dawehner, catch, pwolanin: Convert pager.inc to a service

merge-requests/2419/head
Francesco Placella 2019-10-12 00:41:42 +02:00
parent 55a2b4076f
commit 38741fcbd8
21 changed files with 1082 additions and 139 deletions

View File

@ -106,7 +106,7 @@ services:
- { name: cache.context }
cache_context.url.query_args.pagers:
class: Drupal\Core\Cache\Context\PagersCacheContext
arguments: ['@request_stack']
arguments: ['@pager.parameters']
tags:
- { name: cache.context }
@ -1742,3 +1742,9 @@ services:
arguments: ['@keyvalue.expirable', '@lock', '@request_stack', '%tempstore.expire%']
tags:
- { name: backend_overridable }
pager.manager:
class: Drupal\Core\Pager\PagerManager
arguments: ['@pager.parameters']
pager.parameters:
class: Drupal\Core\Pager\PagerParameters
arguments: ['@request_stack']

View File

@ -5,6 +5,8 @@
* These are the global variables that Drupal uses.
*/
use Drupal\Component\Utility\DeprecatedArray;
/**
* The insecure base URL of the Drupal installation.
*
@ -81,33 +83,53 @@ global $install_state;
*
* The array index is the pager element index (0 by default).
*
* @see pager_default_initialize()
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Do not
* directly set or get values from this array. Use the pager.manager service
* instead.
*
* @see https://www.drupal.org/node/2779457
* @see \Drupal\Core\Pager\PagerManagerInterface
*/
global $pager_limits;
$GLOBALS['pager_limits'] = new DeprecatedArray([], 'Global variable $pager_limits is deprecated in drupal:8.8.0 and is removed in drupal:9.0.0. Use \Drupal\Core\Pager\PagerManagerInterface instead. See https://www.drupal.org/node/2779457');
/**
* Array of current page numbers for each pager.
*
* The array index is the pager element index (0 by default).
*
* @see pager_default_initialize()
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Do not
* directly set or get values from this array. Use the pager.manager service
* instead.
*
* @see https://www.drupal.org/node/2779457
* @see \Drupal\Core\Pager\PagerManagerInterface
*/
global $pager_page_array;
$GLOBALS['pager_page_array'] = new DeprecatedArray([], 'Global variable $pager_page_array is deprecated in drupal:8.8.0 and is removed in drupal:9.0.0. Use \Drupal\Core\Pager\PagerManagerInterface instead. See https://www.drupal.org/node/2779457');
/**
* Array of the total number of pages for each pager.
*
* The array index is the pager element index (0 by default).
*
* @see pager_default_initialize()
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Do not
* directly set or get values from this array. Use the pager.manager service
* instead.
*
* @see https://www.drupal.org/node/2779457
* @see \Drupal\Core\Pager\PagerManagerInterface
*/
global $pager_total;
$GLOBALS['pager_total'] = new DeprecatedArray([], 'Global variable $pager_total is deprecated in drupal:8.8.0 and is removed in drupal:9.0.0. Use \Drupal\Core\Pager\PagerManagerInterface instead. See https://www.drupal.org/node/2779457');
/**
* Array of the total number of items for each pager.
*
* The array index is the pager element index (0 by default).
*
* @see pager_default_initialize()
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Do not
* directly set or get values from this array. Use the pager.manager service
* instead.
*
* @see https://www.drupal.org/node/2779457
* @see \Drupal\Core\Pager\PagerManagerInterface
*/
global $pager_total_items;
$GLOBALS['pager_total_items'] = new DeprecatedArray([], 'Global variable $pager_total_items is deprecated in drupal:8.8.0 and is removed in drupal:9.0.0. Use \Drupal\Core\Pager\PagerManagerInterface instead. See https://www.drupal.org/node/2779457');

View File

@ -7,7 +7,6 @@
use Drupal\Core\Template\Attribute;
use Drupal\Core\Url;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Component\Utility\Html;
/**
@ -26,15 +25,17 @@ use Drupal\Component\Utility\Html;
* even though the default pager implementation adjusts for this and still
* displays the third page of search results at that URL.
*
* @see pager_default_initialize()
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
* \Drupal\Core\Pager\RequestPagerInterface->findPage() instead.
*
* @see https://www.drupal.org/node/2779457
* @see \Drupal\Core\Pager\PagerParametersInterface::findPage()
*/
function pager_find_page($element = 0) {
$page = \Drupal::request()->query->get('page', '');
$page_array = explode(',', $page);
if (!isset($page_array[$element])) {
$page_array[$element] = 0;
}
return (int) $page_array[$element];
@trigger_error(__FUNCTION__ . ' is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Pager\RequestPagerInterface->findPage() instead. See https://www.drupal.org/node/2779457', E_USER_DEPRECATED);
/* @var $pager_parameters \Drupal\Core\Pager\PagerParametersInterface */
$pager_parameters = \Drupal::service('pager.parameters');
return $pager_parameters->findPage($element);
}
/**
@ -126,18 +127,19 @@ function pager_find_page($element = 0) {
* that does not correspond to the actual range of the result set was
* requested, this function will return the closest page actually within the
* result set.
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
* \Drupal\Core\Pager\PagerManagerInterface->defaultInitialize() instead.
*
* @see https://www.drupal.org/node/2779457
* @see \Drupal\Core\Pager\PagerManagerInterface::createPager()
*/
function pager_default_initialize($total, $limit, $element = 0) {
global $pager_page_array, $pager_total, $pager_total_items, $pager_limits;
$page = pager_find_page($element);
// We calculate the total of pages as ceil(items / limit).
$pager_total_items[$element] = $total;
$pager_total[$element] = ceil($pager_total_items[$element] / $limit);
$pager_page_array[$element] = max(0, min($page, ((int) $pager_total[$element]) - 1));
$pager_limits[$element] = $limit;
return $pager_page_array[$element];
@trigger_error(__FUNCTION__ . ' is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Pager\PagerManagerInterface->createPager() instead. See https://www.drupal.org/node/2779457', E_USER_DEPRECATED);
/* @var $pager_manager \Drupal\Core\Pager\PagerManagerInterface */
$pager_manager = \Drupal::service('pager.manager');
$pager = $pager_manager->createPager($total, $limit, $element);
return $pager->getCurrentPage();
}
/**
@ -146,13 +148,18 @@ function pager_default_initialize($total, $limit, $element = 0) {
* @return array
* A URL query parameter array that consists of all components of the current
* page request except for those pertaining to paging.
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
* \Drupal\Core\Pager\RequestPagerInterface->getQueryParameters() instead.
*
* @see https://www.drupal.org/node/2779457
* @see \Drupal\Core\Pager\PagerParametersInterface::getQueryParameters()
*/
function pager_get_query_parameters() {
$query = &drupal_static(__FUNCTION__);
if (!isset($query)) {
$query = UrlHelper::filterQueryParameters(\Drupal::request()->query->all(), ['page']);
}
return $query;
@trigger_error(__FUNCTION__ . ' is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Pager\RequestPagerInterface->getQueryParameters() instead. See https://www.drupal.org/node/2779457', E_USER_DEPRECATED);
/* @var $pager_params \Drupal\Core\Pager\PagerParametersInterface */
$pager_params = \Drupal::service('pager.parameters');
return $pager_params->getQueryParameters();
}
/**
@ -181,10 +188,21 @@ function template_preprocess_pager(&$variables) {
$quantity = $variables['pager']['#quantity'];
$route_name = $variables['pager']['#route_name'];
$route_parameters = isset($variables['pager']['#route_parameters']) ? $variables['pager']['#route_parameters'] : [];
global $pager_page_array, $pager_total;
/* @var $pager_manager \Drupal\Core\Pager\PagerManagerInterface */
$pager_manager = \Drupal::service('pager.manager');
$pager = $pager_manager->getPager($element);
// Nothing to do if there is no pager.
if (!isset($pager)) {
return;
}
$pager_max = $pager->getTotalPages();
// Nothing to do if there is only one page.
if ($pager_total[$element] <= 1) {
if ($pager_max <= 1) {
return;
}
@ -193,14 +211,13 @@ function template_preprocess_pager(&$variables) {
// Calculate various markers within this pager piece:
// Middle is used to "center" pages around the current page.
$pager_middle = ceil($quantity / 2);
// current is the page we are currently paged to.
$pager_current = $pager_page_array[$element] + 1;
// first is the first page listed by this pager piece (re quantity).
$current_page = $pager->getCurrentPage();
// The current pager is the page we are currently paged to.
$pager_current = $current_page + 1;
// The first pager is the first page listed by this pager piece (re quantity).
$pager_first = $pager_current - $pager_middle + 1;
// last is the last page listed by this pager piece (re quantity).
// The last is the last page listed by this pager piece (re quantity).
$pager_last = $pager_current + $quantity - $pager_middle;
// max is the maximum page number.
$pager_max = $pager_total[$element];
// End of marker calculations.
// Prepare for generation loop.
@ -218,11 +235,11 @@ function template_preprocess_pager(&$variables) {
// End of generation loop preparation.
// Create the "first" and "previous" links if we are not on the first page.
if ($pager_page_array[$element] > 0) {
if ($current_page > 0) {
$items['first'] = [];
$items['first']['attributes'] = new Attribute();
$options = [
'query' => pager_query_add_page($parameters, $element, 0),
'query' => $pager_manager->getUpdatedParameters($parameters, $element, 0),
];
$items['first']['href'] = Url::fromRoute($route_name, $route_parameters, $options)->toString();
if (isset($tags[0])) {
@ -232,7 +249,7 @@ function template_preprocess_pager(&$variables) {
$items['previous'] = [];
$items['previous']['attributes'] = new Attribute();
$options = [
'query' => pager_query_add_page($parameters, $element, $pager_page_array[$element] - 1),
'query' => $pager_manager->getUpdatedParameters($parameters, $element, $current_page - 1),
];
$items['previous']['href'] = Url::fromRoute($route_name, $route_parameters, $options)->toString();
if (isset($tags[1])) {
@ -248,7 +265,7 @@ function template_preprocess_pager(&$variables) {
// Now generate the actual pager piece.
for (; $i <= $pager_last && $i <= $pager_max; $i++) {
$options = [
'query' => pager_query_add_page($parameters, $element, $i - 1),
'query' => $pager_manager->getUpdatedParameters($parameters, $element, $i - 1),
];
$items['pages'][$i]['href'] = Url::fromRoute($route_name, $route_parameters, $options)->toString();
$items['pages'][$i]['attributes'] = new Attribute();
@ -263,11 +280,11 @@ function template_preprocess_pager(&$variables) {
}
// Create the "next" and "last" links if we are not on the last page.
if ($pager_page_array[$element] < ($pager_max - 1)) {
if ($current_page < ($pager_max - 1)) {
$items['next'] = [];
$items['next']['attributes'] = new Attribute();
$options = [
'query' => pager_query_add_page($parameters, $element, $pager_page_array[$element] + 1),
'query' => $pager_manager->getUpdatedParameters($parameters, $element, $current_page + 1),
];
$items['next']['href'] = Url::fromRoute($route_name, $route_parameters, $options)->toString();
if (isset($tags[3])) {
@ -277,7 +294,7 @@ function template_preprocess_pager(&$variables) {
$items['last'] = [];
$items['last']['attributes'] = new Attribute();
$options = [
'query' => pager_query_add_page($parameters, $element, $pager_max - 1),
'query' => $pager_manager->getUpdatedParameters($parameters, $element, $pager_max - 1),
];
$items['last']['href'] = Url::fromRoute($route_name, $route_parameters, $options)->toString();
if (isset($tags[4])) {
@ -316,25 +333,16 @@ function template_preprocess_pager(&$variables) {
*
* @return array
* The altered $query parameter array.
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
* \Drupal\Core\Pager\PagerManagerInterface->queryAddPage() instead.
*
* @see https://www.drupal.org/node/2779457
* @see \Drupal\Core\Pager\PagerManagerInterface::getUpdatedParameters()
*/
function pager_query_add_page(array $query, $element, $index) {
global $pager_page_array;
// Build the 'page' query parameter. This is built based on the current
// page of each pager element (or NULL if the pager is not set), with the
// exception of the requested page index for the current element.
$max_element = max(array_keys($pager_page_array));
$element_pages = [];
for ($i = 0; $i <= $max_element; $i++) {
$element_pages[] = ($i == $element) ? $index : (isset($pager_page_array[$i]) ? $pager_page_array[$i] : NULL);
}
$query['page'] = implode(',', $element_pages);
// Merge the query parameters passed to this function with the parameters
// from the current request. In case of collision, the parameters passed into
// this function take precedence.
if ($current_request_query = pager_get_query_parameters()) {
$query = array_merge($current_request_query, $query);
}
return $query;
@trigger_error(__FUNCTION__ . ' is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Pager\PagerManagerInterface->queryAddPage() instead. See https://www.drupal.org/node/2779457', E_USER_DEPRECATED);
/* @var $pager_manager \Drupal\Core\Pager\PagerManagerInterface */
$pager_manager = \Drupal::service('pager.manager');
return $pager_manager->getUpdatedParameters($query, $element, $index);
}

View File

@ -0,0 +1,69 @@
<?php
namespace Drupal\Component\Utility;
/**
* An array that triggers a deprecation warning when accessed.
*/
class DeprecatedArray implements \ArrayAccess {
/**
* The array values.
*
* @var array
*/
protected $values = [];
/**
* The deprecation message.
*
* @var string
*/
protected $message;
/**
* DeprecatedArray constructor.
*
* @param array $values
* The array values.
* @param $message
* The deprecation message.
*/
public function __construct(array $values, $message) {
$this->values = $values;
$this->message = $message;
}
/**
* {@inheritdoc}
*/
public function offsetExists($offset) {
@trigger_error($this->message, E_USER_DEPRECATED);
return isset($this->values[$offset]);
}
/**
* {@inheritdoc}
*/
public function offsetGet($offset) {
@trigger_error($this->message, E_USER_DEPRECATED);
return $this->values[$offset] ?? NULL;
}
/**
* {@inheritdoc}
*/
public function offsetSet($offset, $value) {
@trigger_error($this->message, E_USER_DEPRECATED);
return $this->values[$offset] = $value;
}
/**
* {@inheritdoc}
*/
public function offsetUnset($offset) {
@trigger_error($this->message, E_USER_DEPRECATED);
unset($this->values[$offset]);
}
}

View File

@ -3,6 +3,8 @@
namespace Drupal\Core\Cache\Context;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\DependencyInjection\DeprecatedServicePropertyTrait;
use Drupal\Core\Pager\PagerParametersInterface;
/**
* Defines a cache context for "per page in a pager" caching.
@ -11,7 +13,35 @@ use Drupal\Core\Cache\CacheableMetadata;
* Calculated cache context ID: 'url.query_args.pagers:%pager_id', e.g.
* 'url.query_args.pagers:1' (to vary by the pager with ID 1).
*/
class PagersCacheContext extends RequestStackCacheContextBase implements CalculatedCacheContextInterface {
class PagersCacheContext implements CalculatedCacheContextInterface {
use DeprecatedServicePropertyTrait;
/**
* {@inheritdoc}
*/
protected $deprecatedProperties = ['requestStack' => 'request_stack'];
/**
* The pager parameters.
*
* @var \Drupal\Core\Pager\PagerParametersInterface
*/
protected $pagerParams;
/**
* Constructs a new PagersCacheContext object.
*
* @param \Drupal\Core\Pager\PagerParametersInterface $pager_params
* The pager parameters.
*/
public function __construct($pager_params) {
if (!($pager_params instanceof PagerParametersInterface)) {
@trigger_error('Calling ' . __METHOD__ . ' with a $pager_params argument that does not implement \Drupal\Core\Pager\PagerParametersInterface is deprecated in drupal:8.8.0 and is required in drupal:9.0.0. See https://www.drupal.org/node/2779457', E_USER_DEPRECATED);
$pager_params = \Drupal::service('pager.parameters');
}
$this->pagerParams = $pager_params;
}
/**
* {@inheritdoc}
@ -23,16 +53,16 @@ class PagersCacheContext extends RequestStackCacheContextBase implements Calcula
/**
* {@inheritdoc}
*
* @see pager_find_page()
* @see \Drupal\Core\Pager\PagerParametersInterface::findPage()
*/
public function getContext($pager_id = NULL) {
// The value of the 'page' query argument contains the information that
// controls *all* pagers.
if ($pager_id === NULL) {
return $this->requestStack->getCurrentRequest()->query->get('page', '');
return $this->pagerParams->getPagerParameter();
}
return $pager_id . '.' . pager_find_page($pager_id);
return $pager_id . '.' . $this->pagerParams->findPage($pager_id);
}
/**

View File

@ -73,8 +73,10 @@ class PagerSelectExtender extends SelectExtender {
$this->ensureElement();
$total_items = $this->getCountQuery()->execute()->fetchField();
$current_page = pager_default_initialize($total_items, $this->limit, $this->element);
$this->range($current_page * $this->limit, $this->limit);
/** @var \Drupal\Core\Pager\PagerManagerInterface $pager_manager */
$pager_manager = \Drupal::service('pager.manager');
$pager = $pager_manager->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();

View File

@ -310,11 +310,11 @@ abstract class QueryBase implements QueryInterface {
*/
protected function initializePager() {
if ($this->pager && !empty($this->pager['limit']) && !$this->count) {
$page = pager_find_page($this->pager['element']);
$page = \Drupal::service('pager.parameters')->findPage($this->pager['element']);
$count_query = clone $this;
$this->pager['total'] = $count_query->count()->execute();
$this->pager['start'] = $page * $this->pager['limit'];
pager_default_initialize($this->pager['total'], $this->pager['limit'], $this->pager['element']);
\Drupal::service('pager.manager')->createPager($this->pager['total'], $this->pager['limit'], $this->pager['element']);
$this->range($this->pager['start'], $this->pager['limit']);
}
}

View File

@ -0,0 +1,121 @@
<?php
namespace Drupal\Core\Pager;
/**
* A value object that represents a pager.
*/
class Pager {
/**
* The total number of items .
*
* @var int
*/
protected $totalItems;
/**
* The total number of pages.
*
* @var int
*/
protected $totalPages;
/**
* The current page of the pager.
*
* @var int
*/
protected $currentPage;
/**
* The maximum number of items per page.
*
* @var int
*/
protected $limit;
/**
* Pager constructor.
*
* @param int $totalItems
* The total number of items.
* @param int $limit
* The maximum number of items per page.
* @param int $currentPage
* The current page.
*/
public function __construct($totalItems, $limit, $currentPage = 0) {
$this->totalItems = $totalItems;
$this->limit = $limit;
$this->setTotalPages($totalItems, $limit);
$this->setCurrentPage($currentPage);
}
/**
* Sets the current page to a valid value within range.
*
* If a page that does not correspond to the actual range of the result set
* was provided, this function will set the closest page actually within
* the result set.
*
* @param int $currentPage
* (optional) The current page.
*/
protected function setCurrentPage($currentPage = 0) {
$this->currentPage = max(0, min($currentPage, $this->getTotalPages() - 1));
}
/**
* Sets the total number of pages.
*
* @param int $totalItems
* The total number of items.
* @param int $limit
* The maximum number of items per page.
*/
protected function setTotalPages($totalItems, $limit) {
$this->totalPages = (int) ceil($totalItems / $limit);
}
/**
* Gets the total number of items.
*
* @return int
* The total number of items.
*/
public function getTotalItems() {
return $this->totalItems;
}
/**
* Gets the total number of pages.
*
* @return int
* The total number of pages.
*/
public function getTotalPages() {
return $this->totalPages;
}
/**
* Gets the current page.
*
* @return int
* The current page.
*/
public function getCurrentPage() {
return $this->currentPage;
}
/**
* Gets the maximum number of items per page.
*
* @return int
* The the maximum number of items per page.
*/
public function getLimit() {
return $this->limit;
}
}

View File

@ -0,0 +1,132 @@
<?php
namespace Drupal\Core\Pager;
use Drupal\Component\Utility\DeprecatedArray;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
/**
* Provides a manager for pagers.
*
* Pagers are cached, and can be retrieved when rendering.
*/
class PagerManager implements PagerManagerInterface {
use DependencySerializationTrait;
/**
* The pager parameters.
*
* @var \Drupal\Core\Pager\PagerParametersInterface
*/
protected $pagerParams;
/**
* An associative array of pagers.
*
* Implemented as an array consisting of:
* - key: the element id integer.
* - value: a \Drupal\Core\Pager\Pager.
*
* @var array
*/
protected $pagers;
/**
* Construct a PagerManager object.
*
* @param \Drupal\Core\Pager\PagerParametersInterface $pager_params
* The pager parameters.
*/
public function __construct(PagerParametersInterface $pager_params) {
$this->pagerParams = $pager_params;
}
/**
* {@inheritdoc}
*/
public function createPager($total, $limit, $element = 0) {
$currentPage = $this->pagerParams->findPage($element);
$pager = new Pager($total, $limit, $currentPage);
$this->setPager($pager, $element);
return $pager;
}
/**
* {@inheritdoc}
*/
public function getPager($element = 0) {
return isset($this->pagers[$element]) ? $this->pagers[$element] : NULL;
}
/**
* {@inheritdoc}
*/
public function getUpdatedParameters(array $query, $element, $index) {
// Build the 'page' query parameter. This is built based on the current
// page of each pager element (or NULL if the pager is not set), with the
// exception of the requested page index for the current element.
$element_pages = [];
$max = $this->getMaxPagerElementId();
for ($i = 0; $i <= $max; $i++) {
$currentPage = ($pager = $this->getPager($i)) ? $pager->getCurrentPage() : NULL;
$element_pages[] = ($i == $element) ? $index : $currentPage;
}
$query['page'] = implode(',', $element_pages);
// Merge the query parameters passed to this function with the parameters
// from the current request. In case of collision, the parameters passed
// into this function take precedence.
if ($current_query = $this->pagerParams->getQueryParameters()) {
$query = array_merge($current_query, $query);
}
return $query;
}
/**
* Gets the extent of the pager page element IDs.
*
* @return int
* The maximum element ID available, -1 if there are no elements.
*/
protected function getMaxPagerElementId() {
return empty($this->pagers) ? -1 : max(array_keys($this->pagers));
}
/**
* Saves a pager to the static cache.
*
* @param \Drupal\Core\Pager\Pager $pager
* The pager.
* @param int $element
* The pager index.
*/
protected function setPager(Pager $pager, $element = 0) {
$this->pagers[$element] = $pager;
$this->updateGlobals();
}
/**
* Updates global variables with a pager data for backwards compatibility.
*/
protected function updateGlobals() {
$pager_total_items = [];
$pager_total = [];
$pager_page_array = [];
$pager_limits = [];
/** @var $pager \Drupal\Core\Pager\Pager */
foreach ($this->pagers as $pager_id => $pager) {
$pager_total_items[$pager_id] = $pager->getTotalItems();
$pager_total[$pager_id] = $pager->getTotalPages();
$pager_page_array[$pager_id] = $pager->getCurrentPage();
$pager_limits[$pager_id] = $pager->getLimit();
}
$GLOBALS['pager_total_items'] = new DeprecatedArray($pager_total_items, 'Global variable $pager_total_items is deprecated in drupal:8.8.0 and is removed in drupal:9.0.0. Use \Drupal\Core\Pager\PagerManagerInterface instead. See https://www.drupal.org/node/2779457');
$GLOBALS['pager_total'] = new DeprecatedArray($pager_total, 'Global variable $pager_total is deprecated in drupal:8.8.0 and is removed in drupal:9.0.0. Use \Drupal\Core\Pager\PagerManagerInterface instead. See https://www.drupal.org/node/2779457');
$GLOBALS['pager_page_array'] = new DeprecatedArray($pager_page_array, 'Global variable $pager_page_array is deprecated in drupal:8.8.0 and is removed in drupal:9.0.0. Use \Drupal\Core\Pager\PagerManagerInterface instead. See https://www.drupal.org/node/2779457');
$GLOBALS['pager_limits'] = new DeprecatedArray($pager_limits, 'Global variable $pager_limits is deprecated in drupal:8.8.0 and is removed in drupal:9.0.0. Use \Drupal\Core\Pager\PagerManagerInterface instead. See https://www.drupal.org/node/2779457');
}
}

View File

@ -0,0 +1,155 @@
<?php
namespace Drupal\Core\Pager;
/**
* This is a service for pager information.
*
* The pager.manager service manages the pager information which will eventually
* be rendered into pager elements in the response. To gather information
* related to pager information in the request, use the pager.parameters
* service.
*
* Since there can be multiple pagers per requested page, each one is
* represented by an 'element' ID. This is an integer. It represents the index
* of the pager element within the 'page' query. The value of the element is an
* integer telling us the current page number for that pager.
*
* This class generally replaces the functions in core/includes/pager.inc. Those
* functions use globals to store data which they all use. Since we require
* backwards compatibility with this behavior, this class presents a public API
* for using pager information, which is implemented using the same globals as a
* 'backend.'
*
* @see \Drupal\Core\Pager\PagerParametersInterface
*/
interface PagerManagerInterface {
/**
* Initializes a pager.
*
* This function sets up the necessary variables so that the render system
* will correctly process #type 'pager' render arrays to output pagers that
* correspond to the items being displayed.
*
* If the items being displayed result from a database query performed using
* Drupal's database API, and if you have control over the construction of the
* database query, you do not need to call this function directly; instead,
* you can extend the query object with the 'PagerSelectExtender' extender
* before executing it. For example:
* @code
* $query = db_select('some_table')
* ->extend('Drupal\Core\Database\Query\PagerSelectExtender');
* @endcode
*
* However, if you are using a different method for generating the items to be
* paged through, then you should call this service in preparation.
*
* The following example shows how this service can be used in a controller
* that invokes an external datastore with an SQL-like syntax:
* @code
* // First find the total number of items and initialize the pager.
* $where = "status = 1";
* $total = mymodule_select("SELECT COUNT(*) FROM data " . $where)->result();
* $num_per_page = \Drupal::config('mymodule.settings')->get('num_per_page');
* $pager = \Drupal::service('pager.manager')->createPager($total, $num_per_page);
* $page = $pager->getCurrentPage();
*
* // Next, retrieve the items for the current page and put them into a
* // render array.
* $offset = $num_per_page * $page;
* $result = mymodule_select("SELECT * FROM data " . $where . " LIMIT %d, %d", $offset, $num_per_page)->fetchAll();
* $render = [];
* $render[] = [
* '#theme' => 'mymodule_results',
* '#result' => $result,
* ];
*
* // Finally, add the pager to the render array, and return.
* $render[] = ['#type' => 'pager'];
* return $render;
* @endcode
*
* A second example involves a controller that invokes an external search
* service where the total number of matching results is provided as part of
* the returned set (so that we do not need a separate query in order to
* obtain this information). Here, we call PagerManagerInterface->findPage()
* to calculate the desired offset before the search is invoked:
* @code
*
* // Perform the query, using the requested offset from
* // PagerManagerInterface::findPage(). This comes from a URL parameter, so
* // here we are assuming that the URL parameter corresponds to an actual
* // page of results that will exist within the set.
* $pager_parameters = \Drupal::service('pager.parameters');
* $page = $pager_parameters->findPage();
* $num_per_page = \Drupal::config('mymodule.settings')->get('num_per_page');
* $offset = $num_per_page * $page;
* $result = mymodule_remote_search($keywords, $offset, $num_per_page);
*
* // Now that we have the total number of results, initialize the pager.
* $pager_manager = \Drupal::service('pager.manager');
* $pager_manager->createPager($result->total, $num_per_page);
*
* // Create a render array with the search results.
* $render = [];
* $render[] = [
* '#theme' => 'search_results',
* '#results' => $result->data,
* '#type' => 'remote',
* ];
*
* // Finally, add the pager to the render array, and return.
* $render[] = ['#type' => 'pager'];
* return $render;
* @endcode
*
* @param int $total
* The total number of items to be paged.
* @param int $limit
* The number of items the calling code will display per page.
* @param int $element
* (optional) An integer to distinguish between multiple pagers on one page.
*
* @return \Drupal\Core\Pager\Pager
* The pager.
*/
public function createPager($total, $limit, $element = 0);
/**
* Gets a pager from the static cache.
*
* @param int $element
* The pager element index.
*
* @return \Drupal\Core\Pager\Pager|null
* The pager, or null if not found.
*/
public function getPager($element = 0);
/**
* Gets the URL query parameter array of a pager link.
*
* Adds to or adjusts the 'page' URL query parameter so that if you follow the
* link, you'll get page $index for pager $element on the page.
*
* The 'page' URL query parameter is a comma-delimited string, where each
* value is the target content page for the corresponding pager $element. For
* instance, if we have 5 pagers on a single page, and we want to have a link
* to a page that should display the 6th content page for the 3rd pager, and
* the 1st content page for all the other pagers, then the URL query will look
* like this: ?page=0,0,5,0,0 (page numbering starts at zero).
*
* @param array $query
* An associative array of URL query parameters to add to.
* @param int $element
* An integer to distinguish between multiple pagers on one page.
* @param int $index
* The index of the target page, for the given element, in the pager array.
*
* @return array
* The altered $query parameter array.
*/
public function getUpdatedParameters(array $query, $element, $index);
}

View File

@ -0,0 +1,72 @@
<?php
namespace Drupal\Core\Pager;
use Drupal\Component\Utility\UrlHelper;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Provides pager information contained within the current request.
*
* @see \Drupal\Core\Pager\PagerManagerInterface
*/
class PagerParameters implements PagerParametersInterface {
/**
* The HTTP request stack.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
/**
* Construct a PagerManager object.
*
* @param \Symfony\Component\HttpFoundation\RequestStack $stack
* The current HTTP request stack.
*/
public function __construct(RequestStack $stack) {
$this->requestStack = $stack;
}
/**
* {@inheritdoc}
*/
public function getQueryParameters() {
$request = $this->requestStack->getCurrentRequest();
if ($request) {
return UrlHelper::filterQueryParameters(
$request->query->all(), ['page']
);
}
return [];
}
/**
* {@inheritdoc}
*/
public function findPage($pager_id = 0) {
$pages = $this->getPagerQuery();
return (int) ($pages[$pager_id] ?? 0);
}
/**
* {@inheritdoc}
*/
public function getPagerQuery() {
$query = $this->getPagerParameter();
return !empty($query) ? explode(',', $query) : [];
}
/**
* {@inheritdoc}
*/
public function getPagerParameter() {
$request = $this->requestStack->getCurrentRequest();
if ($request) {
return $request->query->get('page', '');
}
return '';
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace Drupal\Core\Pager;
/**
* Interface describing pager information contained within the request.
*
* @see \Drupal\Core\Pager\PagerManagerInterface
*/
interface PagerParametersInterface {
/**
* Gets all request URL query parameters that are unrelated to paging.
*
* @return array
* A URL query parameter array that consists of all components of the
* current page request except for those pertaining to paging.
*/
public function getQueryParameters();
/**
* Returns the current page being requested for display within a pager.
*
* @param int $pager_id
* (optional) An integer to distinguish between multiple pagers on one page.
*
* @return int
* The number of the current requested page, within the pager represented by
* $element. This is determined from the URL query parameter
* \Drupal::request()->query->get('page'), or 0 by default. Note that this
* number may differ from the actual page being displayed. For example, if a
* search for "example text" brings up three pages of results, but a user
* visits search/node/example+text?page=10, this function will return 10,
* even though the default pager implementation adjusts for this and still
* displays the third page of search results at that URL.
*/
public function findPage($pager_id = 0);
/**
* Gets the request query parameter.
*
* @return int[]
* Array of pagers. Keys are integers which are the element ID. Values are
* the zero-based current page from the request. The first page is 0, the
* second page is 1, etc.
*/
public function getPagerQuery();
/**
* Gets the 'page' query parameter for the current request.
*
* @return string
* The 'page' query parameter for the current request. This is a
* comma-delimited string of pager element values. Defaults to empty string
* if the query does not have a 'page' parameter.
*/
public function getPagerParameter();
}

View File

@ -5,10 +5,10 @@ namespace Drupal\Core\Render\Element;
/**
* Provides a render element for a pager.
*
* The pager must be initialized with a call to pager_default_initialize() in
* order to render properly. When used with database queries, this is performed
* for you when you extend a select query with
* \Drupal\Core\Database\Query\PagerSelectExtender.
* The pager must be initialized with a call to
* \Drupal\Core\Pager\PagerManagerInterface::createPager() in order to render
* properly. When used with database queries, this is performed for you when you
* extend a select query with \Drupal\Core\Database\Query\PagerSelectExtender.
*
* Properties:
* - #element: (optional, int) The pager ID, to distinguish between multiple
@ -68,11 +68,12 @@ class Pager extends RenderElement {
*/
public static function preRenderPager(array $pager) {
// Note: the default pager theme process function
// template_preprocess_pager() also calls pager_query_add_page(), which
// maintains the existing query string. Therefore
// template_preprocess_pager() adds the 'url.query_args' cache context,
// which causes the more specific cache context below to be optimized away.
// In other themes, however, that may not be the case.
// template_preprocess_pager() also calls
// \Drupal\Core\Pager\PagerManagerInterface::queryAddPage(), which maintains
// the existing query string. Therefore template_preprocess_pager() adds the
// 'url.query_args' cache context, which causes the more specific cache
// context below to be optimized away. In other themes, however, that may
// not be the case.
$pager['#cache']['contexts'][] = 'url.query_args.pagers:' . $pager['#element'];
return $pager;
}

View File

@ -9,11 +9,12 @@
* Implements hook_preprocess_HOOK().
*/
function pager_test_preprocess_pager(&$variables) {
global $pager_total;
// Nothing to do if there is only one page.
$element = $variables['pager']['#element'];
if ($pager_total[$element] <= 1) {
/** @var \Drupal\Core\Pager\PagerManagerInterface $pager_manager */
$pager_manager = \Drupal::service('pager.manager');
$pager = $pager_manager->getPager($element);
if ($pager->getTotalPages() <= 1) {
return;
}

View File

@ -5,13 +5,39 @@ namespace Drupal\pager_test\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\Query\PagerSelectExtender;
use Drupal\Core\Pager\PagerParametersInterface;
use Drupal\Core\Security\TrustedCallbackInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Controller routine for testing the pager.
*/
class PagerTestController extends ControllerBase implements TrustedCallbackInterface {
/**
* The pager request service.
*
* @var \Drupal\Core\Pager\PagerParametersInterface
*/
protected $pagerParams;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static($container->get('pager.parameters'));
}
/**
* Construct a new PagerTestController object.
*
* @param \Drupal\Core\Pager\PagerParametersInterface $pager_params
* The pager parameters.
*/
public function __construct(PagerParametersInterface $pager_params) {
$this->pagerParams = $pager_params;
}
/**
* Builds a render array for a pageable test table.
*
@ -59,7 +85,7 @@ class PagerTestController extends ControllerBase implements TrustedCallbackInter
$build['pager_table_0'] = $this->buildTestTable(0, 5);
// Counter of calls to the current pager.
$query_params = pager_get_query_parameters();
$query_params = $this->pagerParams->getQueryParameters();
$pager_calls = isset($query_params['pager_calls']) ? ($query_params['pager_calls'] ? $query_params['pager_calls'] : 0) : 0;
$build['l_pager_pager_0'] = ['#markup' => $this->t('Pager calls: @pager_calls', ['@pager_calls' => $pager_calls])];

View File

@ -0,0 +1,43 @@
<?php
namespace Drupal\Tests\system\Kernel\Pager;
use Drupal\KernelTests\KernelTestBase;
/**
* Ensure that deprecated pager functions trigger deprecation errors.
*
* @group Pager
* @group legacy
*/
class PagerDeprecationTest extends KernelTestBase {
/**
* @expectedDeprecation pager_find_page is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Pager\RequestPagerInterface->findPage() instead. See https://www.drupal.org/node/2779457
*/
public function testFindPage() {
$this->assertInternalType('int', pager_find_page());
}
/**
* @expectedDeprecation pager_default_initialize is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Pager\PagerManagerInterface->createPager() instead. See https://www.drupal.org/node/2779457
*/
public function testDefaultInitialize() {
$this->assertInternalType('int', pager_default_initialize(1, 1));
}
/**
* @expectedDeprecation pager_get_query_parameters is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Pager\RequestPagerInterface->getQueryParameters() instead. See https://www.drupal.org/node/2779457
*/
public function testGetQueryParameters() {
$this->assertInternalType('array', pager_get_query_parameters());
}
/**
* @expectedDeprecation pager_query_add_page is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Pager\PagerManagerInterface->queryAddPage() instead. See https://www.drupal.org/node/2779457
*/
public function testQueryAddPage() {
$this->assertArrayHasKey('page', pager_query_add_page([], 1, 1));
}
}

View File

@ -10,6 +10,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Pager\PagerManagerInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Url;
use Drupal\taxonomy\VocabularyInterface;
@ -70,6 +71,13 @@ class OverviewTerms extends FormBase {
*/
protected $entityRepository;
/**
* The pager manager.
*
* @var \Drupal\Core\Pager\PagerManagerInterface
*/
protected $pagerManager;
/**
* Constructs an OverviewTerms object.
*
@ -81,8 +89,10 @@ class OverviewTerms extends FormBase {
* The renderer service.
* @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
* The entity repository.
* @param \Drupal\Core\Pager\PagerManagerInterface|null $pager_manager
* The pager manager.
*/
public function __construct(ModuleHandlerInterface $module_handler, EntityTypeManagerInterface $entity_type_manager, RendererInterface $renderer = NULL, EntityRepositoryInterface $entity_repository = NULL) {
public function __construct(ModuleHandlerInterface $module_handler, EntityTypeManagerInterface $entity_type_manager, RendererInterface $renderer = NULL, EntityRepositoryInterface $entity_repository = NULL, PagerManagerInterface $pager_manager = NULL) {
$this->moduleHandler = $module_handler;
$this->entityTypeManager = $entity_type_manager;
$this->storageController = $entity_type_manager->getStorage('taxonomy_term');
@ -93,6 +103,11 @@ class OverviewTerms extends FormBase {
$entity_repository = \Drupal::service('entity.repository');
}
$this->entityRepository = $entity_repository;
if (!$pager_manager) {
@trigger_error('Calling OverviewTerms::__construct() without the $pager_manager argument is deprecated in drupal:8.8.0 and the $pager_manager argument will be required in drupal:9.0.0. See https://www.drupal.org/node/2779457', E_USER_DEPRECATED);
$pager_manager = \Drupal::service('pager.manager');
}
$this->pagerManager = $pager_manager;
}
/**
@ -103,7 +118,8 @@ class OverviewTerms extends FormBase {
$container->get('module_handler'),
$container->get('entity_type.manager'),
$container->get('renderer'),
$container->get('entity.repository')
$container->get('entity.repository'),
$container->get('pager.manager')
);
}
@ -131,10 +147,6 @@ class OverviewTerms extends FormBase {
* The form structure.
*/
public function buildForm(array $form, FormStateInterface $form_state, VocabularyInterface $taxonomy_vocabulary = NULL) {
// @todo Remove global variables when https://www.drupal.org/node/2044435 is
// in.
global $pager_page_array, $pager_total, $pager_total_items;
$form_state->set(['taxonomy', 'vocabulary'], $taxonomy_vocabulary);
$vocabulary_hierarchy = $this->storageController->getVocabularyHierarchyType($taxonomy_vocabulary->id());
$parent_fields = FALSE;
@ -227,9 +239,7 @@ class OverviewTerms extends FormBase {
// Because we didn't use a pager query, set the necessary pager variables.
$total_entries = $before_entries + $page_entries + $after_entries;
$pager_total_items[0] = $total_entries;
$pager_page_array[0] = $page;
$pager_total[0] = ceil($total_entries / $page_increment);
$this->pagerManager->createPager($total_entries, $page_increment);
// If this form was already submitted once, it's probably hit a validation
// error. Ensure the form is rebuilt in the same order as the user

View File

@ -5,11 +5,77 @@ namespace Drupal\views\Plugin\views\pager;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheableDependencyInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Pager\PagerManagerInterface;
use Drupal\Core\Pager\PagerParameters;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* A common base class for sql based pager.
*/
abstract class SqlBase extends PagerPluginBase implements CacheableDependencyInterface {
abstract class SqlBase extends PagerPluginBase implements CacheableDependencyInterface, ContainerFactoryPluginInterface {
/**
* The pager manager.
*
* @var \Drupal\Core\Pager\PagerManagerInterface
*/
protected $pagerManager;
/**
* The request stack.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
/**
* The pager parameters.
*
* @var \Drupal\Core\Pager\PagerParametersInterface
*/
protected $pagerParameters;
/**
* Constructs a SqlBase object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Pager\PagerManagerInterface $pager_manager
* The pager manager.
* @param \Drupal\Core\Pager\PagerParameters|null $pager_parameters
* The pager parameters.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, PagerManagerInterface $pager_manager = NULL, PagerParameters $pager_parameters = NULL) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
if (!$pager_manager) {
@trigger_error('Calling ' . __METHOD__ . ' without the $pager_manager argument is deprecated in drupal:8.8.0 and is required in drupal:9.0.0. See https://www.drupal.org/node/2779457', E_USER_DEPRECATED);
$pager_manager = \Drupal::service('pager.manager');
}
$this->pagerManager = $pager_manager;
if (!$pager_parameters) {
@trigger_error('Calling ' . __METHOD__ . ' without the $pager_parameters argument is deprecated in drupal:8.8.0 and is required in drupal:9.0.0. See https://www.drupal.org/node/2779457', E_USER_DEPRECATED);
$pager_parameters = \Drupal::service('pager.parameters');
}
$this->pagerParameters = $pager_parameters;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('pager.manager'),
$container->get('pager.parameters')
);
}
protected function defineOptions() {
$options = parent::defineOptions();
@ -242,7 +308,7 @@ abstract class SqlBase extends PagerPluginBase implements CacheableDependencyInt
*
* @param $number
* If provided, the page number will be set to this. If NOT provided,
* the page number will be set from the global page array.
* the page number will be set from the pager manager service.
*/
public function setCurrentPage($number = NULL) {
if (isset($number)) {
@ -250,25 +316,7 @@ abstract class SqlBase extends PagerPluginBase implements CacheableDependencyInt
return;
}
// If the current page number was not specified, extract it from the global
// page array.
global $pager_page_array;
if (empty($pager_page_array)) {
$pager_page_array = [];
}
// Fill in missing values in the global page array, in case the global page
// array hasn't been initialized before.
$page = $this->view->getRequest()->query->get('page');
$page = isset($page) ? explode(',', $page) : [];
for ($i = 0; $i <= $this->options['id'] || $i < count($pager_page_array); $i++) {
$pager_page_array[$i] = empty($page[$i]) ? 0 : $page[$i];
}
// Don't allow the number to be less than zero.
$this->current_page = max(0, intval($pager_page_array[$this->options['id']]));
$this->current_page = max(0, $this->pagerParameters->findPage($this->options['id']));
}
public function getPagerTotal() {
@ -297,24 +345,11 @@ abstract class SqlBase extends PagerPluginBase implements CacheableDependencyInt
// Don't set pager settings for items per page = 0.
$items_per_page = $this->getItemsPerPage();
if (!empty($items_per_page)) {
// Dump information about what we already know into the globals.
global $pager_page_array, $pager_total, $pager_total_items, $pager_limits;
// Set the limit.
$pager_limits[$this->options['id']] = $this->options['items_per_page'];
// Set the item count for the pager.
$pager_total_items[$this->options['id']] = $this->total_items;
// Calculate and set the count of available pages.
$pager_total[$this->options['id']] = $this->getPagerTotal();
$pager = $this->pagerManager->createPager($this->getTotalItems(), $this->options['items_per_page'], $this->options['id']);
// See if the requested page was within range:
if ($this->current_page >= $pager_total[$this->options['id']]) {
// Pages are numbered from 0 so if there are 10 pages, the last page is 9.
$this->setCurrentPage($pager_total[$this->options['id']] - 1);
if ($this->getCurrentPage() >= $pager->getTotalPages()) {
$this->setCurrentPage($pager->getTotalPages() - 1);
}
// Put this number in to guarantee that we do not generate notices when the pager
// goes to look for it later.
$pager_page_array[$this->options['id']] = $this->current_page;
}
}

View File

@ -1000,18 +1000,25 @@ function template_preprocess_views_exposed_form(&$variables) {
* exposed input.
*/
function template_preprocess_views_mini_pager(&$variables) {
global $pager_page_array, $pager_total;
/* @var $pager_manager \Drupal\Core\Pager\PagerManagerInterface */
$pager_manager = \Drupal::service('pager.manager');
$tags = &$variables['tags'];
$element = $variables['element'];
$parameters = $variables['parameters'];
$pager = $pager_manager->getPager($element);
if (!$pager) {
return;
}
$current = $pager->getCurrentPage();
$total = $pager->getTotalPages();
// Current is the page we are currently paged to.
$variables['items']['current'] = $pager_page_array[$element] + 1;
$variables['items']['current'] = $current + 1;
if ($pager_total[$element] > 1 && $pager_page_array[$element] > 0) {
if ($total > 1 && $current > 0) {
$options = [
'query' => pager_query_add_page($parameters, $element, $pager_page_array[$element] - 1),
'query' => $pager_manager->getUpdatedParameters($parameters, $element, $current - 1),
];
$variables['items']['previous']['href'] = Url::fromRoute('<current>', [], $options)->toString();
if (isset($tags[1])) {
@ -1020,9 +1027,9 @@ function template_preprocess_views_mini_pager(&$variables) {
$variables['items']['previous']['attributes'] = new Attribute();
}
if ($pager_page_array[$element] < ($pager_total[$element] - 1)) {
if ($current < ($total - 1)) {
$options = [
'query' => pager_query_add_page($parameters, $element, $pager_page_array[$element] + 1),
'query' => $pager_manager->getUpdatedParameters($parameters, $element, $current + 1),
];
$variables['items']['next']['href'] = Url::fromRoute('<current>', [], $options)->toString();
if (isset($tags[3])) {

View File

@ -0,0 +1,95 @@
<?php
namespace Drupal\KernelTests\Core\Pager;
use Drupal\KernelTests\KernelTestBase;
use Symfony\Component\HttpFoundation\Request;
/**
* @group Pager
*
* @coversDefaultClass \Drupal\Core\Pager\PagerManager
*/
class PagerManagerTest extends KernelTestBase {
/**
* @covers ::createPager
*/
public function testDefaultInitializeGlobals() {
$pager_globals = [
'pager_page_array',
'pager_total_items',
'pager_total',
'pager_limits',
];
foreach ($pager_globals as $pager_global) {
$this->assertFalse(isset($GLOBALS[$pager_global]));
}
/* @var $pager_manager \Drupal\Core\Pager\PagerManagerInterface */
$pager_manager = $this->container->get('pager.manager');
$pager_manager->createPager(5, 1);
foreach ($pager_globals as $pager_global) {
$this->assertTrue(isset($GLOBALS[$pager_global]));
}
}
/**
* @covers ::getUpdatedParameters
*/
public function testQueryAddPage() {
$element = 2;
$index = 5;
$test_parameters = [
'other' => 'arbitrary',
];
$request = Request::create('http://example.com', 'GET', $test_parameters);
/* @var $request_stack \Symfony\Component\HttpFoundation\RequestStack */
$request_stack = $this->container->get('request_stack');
$request_stack->push($request);
/* @var $pager_manager \Drupal\Core\Pager\PagerManagerInterface */
$pager_manager = $this->container->get('pager.manager');
$pager_manager->createPager(30, 10, $element);
$query = $pager_manager->getUpdatedParameters($request->query->all(), $element, $index);
$this->assertArrayHasKey('other', $query);
$this->assertEquals(",,$index", $query['page']);
}
/**
* @group legacy
* @expectedDeprecation Global variable $pager_page_array is deprecated in drupal:8.8.0 and is removed in drupal:9.0.0. Use \Drupal\Core\Pager\PagerManagerInterface instead. See https://www.drupal.org/node/2779457
* @expectedDeprecation Global variable $pager_total_items is deprecated in drupal:8.8.0 and is removed in drupal:9.0.0. Use \Drupal\Core\Pager\PagerManagerInterface instead. See https://www.drupal.org/node/2779457
* @expectedDeprecation Global variable $pager_total is deprecated in drupal:8.8.0 and is removed in drupal:9.0.0. Use \Drupal\Core\Pager\PagerManagerInterface instead. See https://www.drupal.org/node/2779457
* @expectedDeprecation Global variable $pager_limits is deprecated in drupal:8.8.0 and is removed in drupal:9.0.0. Use \Drupal\Core\Pager\PagerManagerInterface instead. See https://www.drupal.org/node/2779457
*/
public function testGlobalsSafety() {
/* @var $pager_manager \Drupal\Core\Pager\PagerManagerInterface */
$pager_manager = $this->container->get('pager.manager');
$pager_manager->createPager(30, 10);
$pager_globals = [
'pager_page_array',
'pager_total_items',
'pager_total',
'pager_limits',
];
// Check globals were set.
foreach ($pager_globals as $pager_global) {
$this->assertTrue(isset($GLOBALS[$pager_global]));
}
$this->assertEquals(0, $GLOBALS['pager_page_array'][0]);
$this->assertEquals(30, $GLOBALS['pager_total_items'][0]);
$this->assertEquals(3, $GLOBALS['pager_total'][0]);
$this->assertEquals(10, $GLOBALS['pager_limits'][0]);
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace Drupal\KernelTests\Core\Pager;
use Drupal\KernelTests\KernelTestBase;
use Symfony\Component\HttpFoundation\Request;
/**
* @group Pager
*
* @coversDefaultClass \Drupal\Core\Pager\PagerParameters
*/
class RequestPagerTest extends KernelTestBase {
/**
* @covers ::findPage
*/
public function testFindPage() {
$request = Request::create('http://example.com', 'GET', ['page' => '0,10']);
/* @var $request_stack \Symfony\Component\HttpFoundation\RequestStack */
$request_stack = $this->container->get('request_stack');
$request_stack->push($request);
$pager_params = $this->container->get('pager.parameters');
$this->assertEquals(10, $pager_params->findPage(1));
}
/**
* @covers ::getQueryParameters
*/
public function testGetQueryParameters() {
$test_parameters = [
'other' => 'arbitrary',
];
$request = Request::create('http://example.com', 'GET', array_merge(['page' => '0,10'], $test_parameters));
/* @var $request_stack \Symfony\Component\HttpFoundation\RequestStack */
$request_stack = $this->container->get('request_stack');
$request_stack->push($request);
$pager_params = $this->container->get('pager.parameters');
$this->assertEquals($test_parameters, $pager_params->getQueryParameters());
$this->assertEquals(0, $pager_params->findPage());
}
}