| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017 |
- <?php
- /**
- * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
- * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
- *
- * Licensed under The MIT License
- * For full copyright and license information, please see the LICENSE.txt
- * Redistributions of files must retain the above copyright notice.
- *
- * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
- * @link http://cakephp.org CakePHP(tm) Project
- * @since 1.2.0
- * @license http://www.opensource.org/licenses/mit-license.php MIT License
- */
- namespace Cake\View\Helper;
- use Cake\Utility\Inflector;
- use Cake\View\Helper;
- use Cake\View\StringTemplateTrait;
- use Cake\View\View;
- /**
- * Pagination Helper class for easy generation of pagination links.
- *
- * PaginationHelper encloses all methods needed when working with pagination.
- *
- * @property UrlHelper $Url
- * @property NumberHelper $Number
- * @property HtmlHelper $Html
- * @link http://book.cakephp.org/3.0/en/views/helpers/paginator.html
- */
- class PaginatorHelper extends Helper
- {
- use StringTemplateTrait;
- /**
- * List of helpers used by this helper
- *
- * @var array
- */
- public $helpers = ['Url', 'Number', 'Html'];
- /**
- * Default config for this class
- *
- * Options: Holds the default options for pagination links
- *
- * The values that may be specified are:
- *
- * - `url` Url of the action. See Router::url()
- * - `url['sort']` the key that the recordset is sorted.
- * - `url['direction']` Direction of the sorting (default: 'asc').
- * - `url['page']` Page number to use in links.
- * - `model` The name of the model.
- * - `escape` Defines if the title field for the link should be escaped (default: true).
- *
- * Templates: the templates used by this class
- *
- * @var array
- */
- protected $_defaultConfig = [
- 'options' => [],
- 'templates' => [
- 'nextActive' => '<li class="next"><a rel="next" href="{{url}}">{{text}}</a></li>',
- 'nextDisabled' => '<li class="next disabled"><a href="" onclick="return false;">{{text}}</a></li>',
- 'prevActive' => '<li class="prev"><a rel="prev" href="{{url}}">{{text}}</a></li>',
- 'prevDisabled' => '<li class="prev disabled"><a href="" onclick="return false;">{{text}}</a></li>',
- 'counterRange' => '{{start}} - {{end}} of {{count}}',
- 'counterPages' => '{{page}} of {{pages}}',
- 'first' => '<li class="first"><a href="{{url}}">{{text}}</a></li>',
- 'last' => '<li class="last"><a href="{{url}}">{{text}}</a></li>',
- 'number' => '<li><a href="{{url}}">{{text}}</a></li>',
- 'current' => '<li class="active"><a href="">{{text}}</a></li>',
- 'ellipsis' => '<li class="ellipsis">...</li>',
- 'sort' => '<a href="{{url}}">{{text}}</a>',
- 'sortAsc' => '<a class="asc" href="{{url}}">{{text}}</a>',
- 'sortDesc' => '<a class="desc" href="{{url}}">{{text}}</a>',
- 'sortAscLocked' => '<a class="asc locked" href="{{url}}">{{text}}</a>',
- 'sortDescLocked' => '<a class="desc locked" href="{{url}}">{{text}}</a>',
- ]
- ];
- /**
- * Constructor. Overridden to merge passed args with URL options.
- *
- * @param \Cake\View\View $View The View this helper is being attached to.
- * @param array $config Configuration settings for the helper.
- */
- public function __construct(View $View, array $config = [])
- {
- parent::__construct($View, $config);
- $this->config(
- 'options.url',
- array_merge($this->request->params['pass'], $this->request->query)
- );
- }
- /**
- * Gets the current paging parameters from the resultset for the given model
- *
- * @param string|null $model Optional model name. Uses the default if none is specified.
- * @return array The array of paging parameters for the paginated resultset.
- */
- public function params($model = null)
- {
- if (empty($model)) {
- $model = $this->defaultModel();
- }
- if (!isset($this->request->params['paging']) || empty($this->request->params['paging'][$model])) {
- return [];
- }
- return $this->request->params['paging'][$model];
- }
- /**
- * Convenience access to any of the paginator params.
- *
- * @param string $key Key of the paginator params array to retrieve.
- * @param string|null $model Optional model name. Uses the default if none is specified.
- * @return mixed Content of the requested param.
- */
- public function param($key, $model = null)
- {
- $params = $this->params($model);
- if (!isset($params[$key])) {
- return null;
- }
- return $params[$key];
- }
- /**
- * Sets default options for all pagination links
- *
- * @param array $options Default options for pagination links.
- * See PaginatorHelper::$options for list of keys.
- * @return void
- */
- public function options(array $options = [])
- {
- if (!empty($options['paging'])) {
- if (!isset($this->request->params['paging'])) {
- $this->request->params['paging'] = [];
- }
- $this->request->params['paging'] = $options['paging'] + $this->request->params['paging'];
- unset($options['paging']);
- }
- $model = $this->defaultModel();
- if (!empty($options[$model])) {
- if (!isset($this->request->params['paging'][$model])) {
- $this->request->params['paging'][$model] = [];
- }
- $this->request->params['paging'][$model] = $options[$model] + $this->request->params['paging'][$model];
- unset($options[$model]);
- }
- $this->_config['options'] = array_filter($options + $this->_config['options']);
- }
- /**
- * Gets the current page of the recordset for the given model
- *
- * @param string|null $model Optional model name. Uses the default if none is specified.
- * @return int The current page number of the recordset.
- * @link http://book.cakephp.org/3.0/en/views/helpers/paginator.html#checking-the-pagination-state
- */
- public function current($model = null)
- {
- $params = $this->params($model);
- if (isset($params['page'])) {
- return $params['page'];
- }
- return 1;
- }
- /**
- * Gets the current key by which the recordset is sorted
- *
- * @param string|null $model Optional model name. Uses the default if none is specified.
- * @param array $options Options for pagination links. See #options for list of keys.
- * @return string|null The name of the key by which the recordset is being sorted, or
- * null if the results are not currently sorted.
- * @link http://book.cakephp.org/3.0/en/views/helpers/paginator.html#creating-sort-links
- */
- public function sortKey($model = null, array $options = [])
- {
- if (empty($options)) {
- $options = $this->params($model);
- }
- if (!empty($options['sort'])) {
- return $options['sort'];
- }
- return null;
- }
- /**
- * Gets the current direction the recordset is sorted
- *
- * @param string|null $model Optional model name. Uses the default if none is specified.
- * @param array $options Options for pagination links. See #options for list of keys.
- * @return string The direction by which the recordset is being sorted, or
- * null if the results are not currently sorted.
- * @link http://book.cakephp.org/3.0/en/views/helpers/paginator.html#creating-sort-links
- */
- public function sortDir($model = null, array $options = [])
- {
- $dir = null;
- if (empty($options)) {
- $options = $this->params($model);
- }
- if (isset($options['direction'])) {
- $dir = strtolower($options['direction']);
- }
- if ($dir === 'desc') {
- return 'desc';
- }
- return 'asc';
- }
- /**
- * Generate an active/inactive link for next/prev methods.
- *
- * @param string|bool $text The enabled text for the link.
- * @param bool $enabled Whether or not the enabled/disabled version should be created.
- * @param array $options An array of options from the calling method.
- * @param array $templates An array of templates with the 'active' and 'disabled' keys.
- * @return string Generated HTML
- */
- protected function _toggledLink($text, $enabled, $options, $templates)
- {
- $template = $templates['active'];
- if (!$enabled) {
- $text = $options['disabledTitle'];
- $template = $templates['disabled'];
- }
- if (!$enabled && $text === false) {
- return '';
- }
- $text = $options['escape'] ? h($text) : $text;
- if (!$enabled) {
- return $this->templater()->format($template, [
- 'text' => $text,
- ]);
- }
- $paging = $this->params($options['model']);
- $url = array_merge(
- $options['url'],
- ['page' => $paging['page'] + $options['step']]
- );
- $url = $this->generateUrl($url, $options['model']);
- return $this->templater()->format($template, [
- 'url' => $url,
- 'text' => $text,
- ]);
- }
- /**
- * Generates a "previous" link for a set of paged records
- *
- * ### Options:
- *
- * - `disabledTitle` The text to used when the link is disabled. This
- * defaults to the same text at the active link. Setting to false will cause
- * this method to return ''.
- * - `escape` Whether you want the contents html entity encoded, defaults to true
- * - `model` The model to use, defaults to PaginatorHelper::defaultModel()
- * - `url` An array of additional URL options to use for link generation.
- *
- * @param string $title Title for the link. Defaults to '<< Previous'.
- * @param array $options Options for pagination link. See above for list of keys.
- * @return string A "previous" link or a disabled link.
- * @link http://book.cakephp.org/3.0/en/views/helpers/paginator.html#creating-jump-links
- */
- public function prev($title = '<< Previous', array $options = [])
- {
- $defaults = [
- 'url' => [],
- 'model' => $this->defaultModel(),
- 'disabledTitle' => $title,
- 'escape' => true,
- ];
- $options += $defaults;
- $options['step'] = -1;
- $enabled = $this->hasPrev($options['model']);
- $templates = [
- 'active' => 'prevActive',
- 'disabled' => 'prevDisabled'
- ];
- return $this->_toggledLink($title, $enabled, $options, $templates);
- }
- /**
- * Generates a "next" link for a set of paged records
- *
- * ### Options:
- *
- * - `disabledTitle` The text to used when the link is disabled. This
- * defaults to the same text at the active link. Setting to false will cause
- * this method to return ''.
- * - `escape` Whether you want the contents html entity encoded, defaults to true
- * - `model` The model to use, defaults to PaginatorHelper::defaultModel()
- * - `url` An array of additional URL options to use for link generation.
- *
- * @param string $title Title for the link. Defaults to 'Next >>'.
- * @param array $options Options for pagination link. See above for list of keys.
- * @return string A "next" link or $disabledTitle text if the link is disabled.
- * @link http://book.cakephp.org/3.0/en/views/helpers/paginator.html#creating-jump-links
- */
- public function next($title = 'Next >>', array $options = [])
- {
- $defaults = [
- 'url' => [],
- 'model' => $this->defaultModel(),
- 'disabledTitle' => $title,
- 'escape' => true,
- ];
- $options += $defaults;
- $options['step'] = 1;
- $enabled = $this->hasNext($options['model']);
- $templates = [
- 'active' => 'nextActive',
- 'disabled' => 'nextDisabled'
- ];
- return $this->_toggledLink($title, $enabled, $options, $templates);
- }
- /**
- * Generates a sorting link. Sets named parameters for the sort and direction. Handles
- * direction switching automatically.
- *
- * ### Options:
- *
- * - `escape` Whether you want the contents html entity encoded, defaults to true.
- * - `model` The model to use, defaults to PaginatorHelper::defaultModel().
- * - `direction` The default direction to use when this link isn't active.
- * - `lock` Lock direction. Will only use the default direction then, defaults to false.
- *
- * @param string $key The name of the key that the recordset should be sorted.
- * @param string|null $title Title for the link. If $title is null $key will be used
- * for the title and will be generated by inflection.
- * @param array $options Options for sorting link. See above for list of keys.
- * @return string A link sorting default by 'asc'. If the resultset is sorted 'asc' by the specified
- * key the returned link will sort by 'desc'.
- * @link http://book.cakephp.org/3.0/en/views/helpers/paginator.html#creating-sort-links
- */
- public function sort($key, $title = null, array $options = [])
- {
- $options += ['url' => [], 'model' => null, 'escape' => true];
- $url = $options['url'];
- unset($options['url']);
- if (empty($title)) {
- $title = $key;
- if (strpos($title, '.') !== false) {
- $title = str_replace('.', ' ', $title);
- }
- $title = __(Inflector::humanize(preg_replace('/_id$/', '', $title)));
- }
- $defaultDir = isset($options['direction']) ? $options['direction'] : 'asc';
- unset($options['direction']);
- $locked = isset($options['lock']) ? $options['lock'] : false;
- unset($options['lock']);
- $sortKey = $this->sortKey($options['model']);
- $defaultModel = $this->defaultModel();
- $isSorted = (
- $sortKey === $key ||
- $sortKey === $defaultModel . '.' . $key ||
- $key === $defaultModel . '.' . $sortKey
- );
- $template = 'sort';
- $dir = $defaultDir;
- if ($isSorted) {
- if ($locked) {
- $template = $dir === 'asc' ? 'sortDescLocked' : 'sortAscLocked';
- } else {
- $dir = $this->sortDir($options['model']) === 'asc' ? 'desc' : 'asc';
- $template = $dir === 'asc' ? 'sortDesc' : 'sortAsc';
- }
- }
- if (is_array($title) && array_key_exists($dir, $title)) {
- $title = $title[$dir];
- }
- $url = array_merge(
- ['sort' => $key, 'direction' => $dir],
- $url,
- ['order' => null]
- );
- $vars = [
- 'text' => $options['escape'] ? h($title) : $title,
- 'url' => $this->generateUrl($url, $options['model']),
- ];
- return $this->templater()->format($template, $vars);
- }
- /**
- * Merges passed URL options with current pagination state to generate a pagination URL.
- *
- * @param array $options Pagination/URL options array
- * @param string|null $model Which model to paginate on
- * @param bool $full If true, the full base URL will be prepended to the result
- * @return mixed By default, returns a full pagination URL string for use in non-standard contexts (i.e. JavaScript)
- * @link http://book.cakephp.org/3.0/en/views/helpers/paginator.html#generating-pagination-urls
- */
- public function generateUrl(array $options = [], $model = null, $full = false)
- {
- $paging = $this->params($model);
- $paging += ['page' => null, 'sort' => null, 'direction' => null, 'limit' => null];
- $url = [
- 'page' => $paging['page'],
- 'limit' => $paging['limit'],
- 'sort' => $paging['sort'],
- 'direction' => $paging['direction'],
- ];
- if (!empty($this->_config['options']['url'])) {
- $url = array_merge($url, $this->_config['options']['url']);
- }
- $url = array_filter($url, function ($value) {
- return ($value || is_numeric($value));
- });
- $url = array_merge($url, $options);
- if (!empty($url['page']) && $url['page'] == 1) {
- $url['page'] = false;
- }
- if (isset($paging['sortDefault'], $paging['directionDefault'], $url['sort'], $url['direction']) &&
- $url['sort'] === $paging['sortDefault'] &&
- $url['direction'] === $paging['directionDefault']
- ) {
- $url['sort'] = $url['direction'] = null;
- }
- return $this->Url->build($url, $full);
- }
- /**
- * Returns true if the given result set is not at the first page
- *
- * @param string|null $model Optional model name. Uses the default if none is specified.
- * @return bool True if the result set is not at the first page.
- * @link http://book.cakephp.org/3.0/en/views/helpers/paginator.html#checking-the-pagination-state
- */
- public function hasPrev($model = null)
- {
- return $this->_hasPage($model, 'prev');
- }
- /**
- * Returns true if the given result set is not at the last page
- *
- * @param string|null $model Optional model name. Uses the default if none is specified.
- * @return bool True if the result set is not at the last page.
- * @link http://book.cakephp.org/3.0/en/views/helpers/paginator.html#checking-the-pagination-state
- */
- public function hasNext($model = null)
- {
- return $this->_hasPage($model, 'next');
- }
- /**
- * Returns true if the given result set has the page number given by $page
- *
- * @param string $model Optional model name. Uses the default if none is specified.
- * @param int $page The page number - if not set defaults to 1.
- * @return bool True if the given result set has the specified page number.
- * @link http://book.cakephp.org/3.0/en/views/helpers/paginator.html#checking-the-pagination-state
- */
- public function hasPage($model = null, $page = 1)
- {
- if (is_numeric($model)) {
- $page = $model;
- $model = null;
- }
- $paging = $this->params($model);
- if ($paging === []) {
- return false;
- }
- return $page <= $paging['pageCount'];
- }
- /**
- * Does $model have $page in its range?
- *
- * @param string $model Model name to get parameters for.
- * @param int $page Page number you are checking.
- * @return bool Whether model has $page
- */
- protected function _hasPage($model, $page)
- {
- $params = $this->params($model);
- return !empty($params) && $params[$page . 'Page'];
- }
- /**
- * Gets the default model of the paged sets
- *
- * @return string|null Model name or null if the pagination isn't initialized.
- */
- public function defaultModel()
- {
- if ($this->_defaultModel) {
- return $this->_defaultModel;
- }
- if (empty($this->request->params['paging'])) {
- return null;
- }
- list($this->_defaultModel) = array_keys($this->request->params['paging']);
- return $this->_defaultModel;
- }
- /**
- * Returns a counter string for the paged result set
- *
- * ### Options
- *
- * - `model` The model to use, defaults to PaginatorHelper::defaultModel();
- * - `format` The format string you want to use, defaults to 'pages' Which generates output like '1 of 5'
- * set to 'range' to generate output like '1 - 3 of 13'. Can also be set to a custom string, containing
- * the following placeholders `{{page}}`, `{{pages}}`, `{{current}}`, `{{count}}`, `{{model}}`, `{{start}}`, `{{end}}` and any
- * custom content you would like.
- *
- * @param string|array $options Options for the counter string. See #options for list of keys.
- * If string it will be used as format.
- * @return string Counter string.
- * @link http://book.cakephp.org/3.0/en/views/helpers/paginator.html#creating-a-page-counter
- */
- public function counter($options = [])
- {
- if (is_string($options)) {
- $options = ['format' => $options];
- }
- $options += [
- 'model' => $this->defaultModel(),
- 'format' => 'pages',
- ];
- $paging = $this->params($options['model']);
- if (!$paging['pageCount']) {
- $paging['pageCount'] = 1;
- }
- $start = 0;
- if ($paging['count'] >= 1) {
- $start = (($paging['page'] - 1) * $paging['perPage']) + 1;
- }
- $end = $start + $paging['perPage'] - 1;
- if ($paging['count'] < $end) {
- $end = $paging['count'];
- }
- switch ($options['format']) {
- case 'range':
- case 'pages':
- $template = 'counter' . ucfirst($options['format']);
- break;
- default:
- $template = 'counterCustom';
- $this->templater()->add([$template => $options['format']]);
- }
- $map = array_map([$this->Number, 'format'], [
- 'page' => $paging['page'],
- 'pages' => $paging['pageCount'],
- 'current' => $paging['current'],
- 'count' => $paging['count'],
- 'start' => $start,
- 'end' => $end
- ]);
- $map += [
- 'model' => strtolower(Inflector::humanize(Inflector::tableize($options['model'])))
- ];
- return $this->templater()->format($template, $map);
- }
- /**
- * Returns a set of numbers for the paged result set
- * uses a modulus to decide how many numbers to show on each side of the current page (default: 8).
- *
- * ```
- * $this->Paginator->numbers(['first' => 2, 'last' => 2]);
- * ```
- *
- * Using the first and last options you can create links to the beginning and end of the page set.
- *
- * ### Options
- *
- * - `before` Content to be inserted before the numbers, but after the first links.
- * - `after` Content to be inserted after the numbers, but before the last links.
- * - `model` Model to create numbers for, defaults to PaginatorHelper::defaultModel()
- * - `modulus` How many numbers to include on either side of the current page, defaults to 8.
- * Set to `false` to disable and to show all numbers.
- * - `first` Whether you want first links generated, set to an integer to define the number of 'first'
- * links to generate.
- * - `last` Whether you want last links generated, set to an integer to define the number of 'last'
- * links to generate.
- * - `templates` An array of templates, or template file name containing the templates you'd like to
- * use when generating the numbers. The helper's original templates will be restored once
- * numbers() is done.
- * - `url` An array of additional URL options to use for link generation.
- *
- * The generated number links will include the 'ellipsis' template when the `first` and `last` options
- * and the number of pages exceed the modulus. For example if you have 25 pages, and use the first/last
- * options and a modulus of 8, ellipsis content will be inserted after the first and last link sets.
- *
- * @param array $options Options for the numbers.
- * @return string numbers string.
- * @link http://book.cakephp.org/3.0/en/views/helpers/paginator.html#creating-page-number-links
- */
- public function numbers(array $options = [])
- {
- $defaults = [
- 'before' => null, 'after' => null, 'model' => $this->defaultModel(),
- 'modulus' => 8, 'first' => null, 'last' => null, 'url' => []
- ];
- $options += $defaults;
- $params = (array)$this->params($options['model']) + ['page' => 1];
- if ($params['pageCount'] <= 1) {
- return false;
- }
- $templater = $this->templater();
- if (isset($options['templates'])) {
- $templater->push();
- $method = is_string($options['templates']) ? 'load' : 'add';
- $templater->{$method}($options['templates']);
- }
- if ($options['modulus'] !== false && $params['pageCount'] > $options['modulus']) {
- $out = $this->_modulusNumbers($templater, $params, $options);
- } else {
- $out = $this->_numbers($templater, $params, $options);
- }
- if (isset($options['templates'])) {
- $templater->pop();
- }
- return $out;
- }
- /**
- * Calculates the start and end for the pagination numbers.
- *
- * @param array $params Params from the numbers() method.
- * @param array $options Options from the numbers() method.
- * @return array An array with the start and end numbers.
- */
- protected function _getNumbersStartAndEnd($params, $options)
- {
- $half = (int)($options['modulus'] / 2);
- $end = $params['page'] + $half;
- if ($end > $params['pageCount']) {
- $end = $params['pageCount'];
- }
- $start = $params['page'] - ($options['modulus'] - ($end - $params['page']));
- if ($start <= 1) {
- $start = 1;
- $end = $params['page'] + ($options['modulus'] - $params['page']) + 1;
- }
- return [$start, $end];
- }
- /**
- * Formats a number for the paginator number output.
- *
- * @param \Cake\View\StringTemplate $templater StringTemplate instance.
- * @param array $options Options from the numbers() method.
- * @return string
- */
- protected function _formatNumber($templater, $options)
- {
- $url = array_merge($options['url'], ['page' => $options['page']]);
- $vars = [
- 'text' => $options['text'],
- 'url' => $this->generateUrl($url, $options['model']),
- ];
- return $templater->format('number', $vars);
- }
- /**
- * Generates the numbers for the paginator numbers() method.
- *
- * @param \Cake\View\StringTemplate $templater StringTemplate instance.
- * @param array $params Params from the numbers() method.
- * @param array $options Options from the numbers() method.
- * @return string Markup output.
- */
- protected function _modulusNumbers($templater, $params, $options)
- {
- $out = '';
- $ellipsis = $templater->format('ellipsis', []);
- list($start, $end) = $this->_getNumbersStartAndEnd($params, $options);
- $out .= $this->_firstNumber($ellipsis, $params, $start, $options);
- $out .= $options['before'];
- for ($i = $start; $i < $params['page']; $i++) {
- $out .= $this->_formatNumber($templater, [
- 'text' => $i,
- 'page' => $i,
- 'model' => $options['model'],
- 'url' => $options['url'],
- ]);
- }
- $url = array_merge($options['url'], ['page' => $params['page']]);
- $out .= $templater->format('current', [
- 'text' => $params['page'],
- 'url' => $this->generateUrl($url, $options['model']),
- ]);
- $start = $params['page'] + 1;
- for ($i = $start; $i < $end; $i++) {
- $out .= $this->_formatNumber($templater, [
- 'text' => $i,
- 'page' => $i,
- 'model' => $options['model'],
- 'url' => $options['url'],
- ]);
- }
- if ($end != $params['page']) {
- $out .= $this->_formatNumber($templater, [
- 'text' => $i,
- 'page' => $end,
- 'model' => $options['model'],
- 'url' => $options['url'],
- ]);
- }
- $out .= $options['after'];
- $out .= $this->_lastNumber($ellipsis, $params, $end, $options);
- return $out;
- }
- /**
- * Generates the first number for the paginator numbers() method.
- *
- * @param \Cake\View\StringTemplate $ellipsis StringTemplate instance.
- * @param array $params Params from the numbers() method.
- * @param int $start Start number.
- * @param array $options Options from the numbers() method.
- * @return string Markup output.
- */
- protected function _firstNumber($ellipsis, $params, $start, $options)
- {
- $out = '';
- if ($options['first'] && $start > 1) {
- $offset = ($start <= (int)$options['first']) ? $start - 1 : $options['first'];
- $out .= $this->first($offset, $options);
- if ($offset < $start - 1) {
- $out .= $ellipsis;
- }
- }
- return $out;
- }
- /**
- * Generates the last number for the paginator numbers() method.
- *
- * @param \Cake\View\StringTemplate $ellipsis StringTemplate instance.
- * @param array $params Params from the numbers() method.
- * @param int $end End number.
- * @param array $options Options from the numbers() method.
- * @return string Markup output.
- */
- protected function _lastNumber($ellipsis, $params, $end, $options)
- {
- $out = '';
- if ($options['last'] && $end < $params['pageCount']) {
- $offset = ($params['pageCount'] < $end + (int)$options['last']) ? $params['pageCount'] - $end : $options['last'];
- if ($offset <= $options['last'] && $params['pageCount'] - $end > $offset) {
- $out .= $ellipsis;
- }
- $out .= $this->last($offset, $options);
- }
- return $out;
- }
- /**
- * Generates the numbers for the paginator numbers() method.
- *
- * @param \Cake\View\StringTemplate $templater StringTemplate instance.
- * @param array $params Params from the numbers() method.
- * @param array $options Options from the numbers() method.
- * @return string Markup output.
- */
- protected function _numbers($templater, $params, $options)
- {
- $out = '';
- $out .= $options['before'];
- for ($i = 1; $i <= $params['pageCount']; $i++) {
- $url = array_merge($options['url'], ['page' => $i]);
- if ($i == $params['page']) {
- $out .= $templater->format('current', [
- 'text' => $params['page'],
- 'url' => $this->generateUrl($url, $options['model']),
- ]);
- } else {
- $vars = [
- 'text' => $i,
- 'url' => $this->generateUrl($url, $options['model']),
- ];
- $out .= $templater->format('number', $vars);
- }
- }
- $out .= $options['after'];
- return $out;
- }
- /**
- * Returns a first or set of numbers for the first pages.
- *
- * ```
- * echo $this->Paginator->first('< first');
- * ```
- *
- * Creates a single link for the first page. Will output nothing if you are on the first page.
- *
- * ```
- * echo $this->Paginator->first(3);
- * ```
- *
- * Will create links for the first 3 pages, once you get to the third or greater page. Prior to that
- * nothing will be output.
- *
- * ### Options:
- *
- * - `model` The model to use defaults to PaginatorHelper::defaultModel()
- * - `escape` Whether or not to HTML escape the text.
- * - `url` An array of additional URL options to use for link generation.
- *
- * @param string|int $first if string use as label for the link. If numeric, the number of page links
- * you want at the beginning of the range.
- * @param array $options An array of options.
- * @return string numbers string.
- * @link http://book.cakephp.org/3.0/en/views/helpers/paginator.html#creating-jump-links
- */
- public function first($first = '<< first', array $options = [])
- {
- $options += [
- 'url' => [],
- 'model' => $this->defaultModel(),
- 'escape' => true
- ];
- $params = $this->params($options['model']);
- if ($params['pageCount'] <= 1) {
- return false;
- }
- $out = '';
- if (is_int($first) && $params['page'] >= $first) {
- for ($i = 1; $i <= $first; $i++) {
- $url = array_merge($options['url'], ['page' => $i]);
- $out .= $this->templater()->format('number', [
- 'url' => $this->generateUrl($url, $options['model']),
- 'text' => $i
- ]);
- }
- } elseif ($params['page'] > 1 && is_string($first)) {
- $first = $options['escape'] ? h($first) : $first;
- $out .= $this->templater()->format('first', [
- 'url' => $this->generateUrl(['page' => 1], $options['model']),
- 'text' => $first
- ]);
- }
- return $out;
- }
- /**
- * Returns a last or set of numbers for the last pages.
- *
- * ```
- * echo $this->Paginator->last('last >');
- * ```
- *
- * Creates a single link for the last page. Will output nothing if you are on the last page.
- *
- * ```
- * echo $this->Paginator->last(3);
- * ```
- *
- * Will create links for the last 3 pages. Once you enter the page range, no output will be created.
- *
- * ### Options:
- *
- * - `model` The model to use defaults to PaginatorHelper::defaultModel()
- * - `escape` Whether or not to HTML escape the text.
- * - `url` An array of additional URL options to use for link generation.
- *
- * @param string|int $last if string use as label for the link, if numeric print page numbers
- * @param array $options Array of options
- * @return string numbers string.
- * @link http://book.cakephp.org/3.0/en/views/helpers/paginator.html#creating-jump-links
- */
- public function last($last = 'last >>', array $options = [])
- {
- $options += [
- 'model' => $this->defaultModel(),
- 'escape' => true,
- 'url' => []
- ];
- $params = $this->params($options['model']);
- if ($params['pageCount'] <= 1) {
- return false;
- }
- $out = '';
- $lower = $params['pageCount'] - $last + 1;
- if (is_int($last) && $params['page'] <= $lower) {
- for ($i = $lower; $i <= $params['pageCount']; $i++) {
- $url = array_merge($options['url'], ['page' => $i]);
- $out .= $this->templater()->format('number', [
- 'url' => $this->generateUrl($url, $options['model']),
- 'text' => $i
- ]);
- }
- } elseif ($params['page'] < $params['pageCount'] && is_string($last)) {
- $last = $options['escape'] ? h($last) : $last;
- $out .= $this->templater()->format('last', [
- 'url' => $this->generateUrl(['page' => $params['pageCount']], $options['model']),
- 'text' => $last
- ]);
- }
- return $out;
- }
- /**
- * Returns the meta-links for a paginated result set.
- *
- * ```
- * echo $this->Paginator->meta();
- * ```
- *
- * Echos the links directly, will output nothing if there is neither a previous nor next page.
- *
- * ```
- * $this->Paginator->meta(['block' => true]);
- * ```
- *
- * Will append the output of the meta function to the named block - if true is passed the "meta"
- * block is used.
- *
- * ### Options:
- *
- * - `model` The model to use defaults to PaginatorHelper::defaultModel()
- * - `block` The block name to append the output to, or false/absenst to return as a string
- *
- * @param array $options Array of options
- * @return string|null Meta links
- */
- public function meta(array $options = [])
- {
- $model = isset($options['model']) ? $options['model'] : null;
- $params = $this->params($model);
- $links = [];
- if ($this->hasPrev()) {
- $links[] = $this->Html->templater()->format('css', [
- 'rel' => 'prev',
- 'url' => $this->generateUrl(['page' => $params['page'] - 1], null, true)
- ]);
- }
- if ($this->hasNext()) {
- $links[] = $this->Html->templater()->format('css', [
- 'rel' => 'next',
- 'url' => $this->generateUrl(['page' => $params['page'] + 1], null, true)
- ]);
- }
- $out = implode($links);
- if (empty($options['block'])) {
- return $out;
- }
- if ($options['block'] === true) {
- $options['block'] = __FUNCTION__;
- }
- $this->_View->append($options['block'], $out);
- }
- /**
- * Event listeners.
- *
- * @return array
- */
- public function implementedEvents()
- {
- return [];
- }
- }
|