CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Reporting Security Issues
    • Privacy Policy
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Get Involved
    • Issues (GitHub)
    • Bakery
    • Featured Resources
    • Training
    • Meetups
    • My CakePHP
    • CakeFest
    • Newsletter
    • Linkedin
    • YouTube
    • Facebook
    • Twitter
    • Mastodon
    • Help & Support
    • Forum
    • Stack Overflow
    • Slack
    • Paid Support
CakePHP

C CakePHP 2.10 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.10
      • 4.2
      • 4.1
      • 4.0
      • 3.9
      • 3.8
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Packages

  • Cake
    • Cache
      • Engine
    • Configure
    • Console
      • Command
        • Task
    • Controller
      • Component
        • Acl
        • Auth
    • Core
    • Error
    • Event
    • I18n
    • Log
      • Engine
    • Model
      • Behavior
      • Datasource
        • Database
        • Session
      • Validator
    • Network
      • Email
      • Http
    • Routing
      • Filter
      • Route
    • TestSuite
      • Coverage
      • Fixture
      • Reporter
    • Utility
    • View
      • Helper
  • None

Classes

  • CacheHelper
  • FlashHelper
  • FormHelper
  • HtmlHelper
  • JqueryEngineHelper
  • JsBaseEngineHelper
  • JsHelper
  • MootoolsEngineHelper
  • NumberHelper
  • PaginatorHelper
  • PrototypeEngineHelper
  • RssHelper
  • SessionHelper
  • TextHelper
  • TimeHelper
   1: <?php
   2: /**
   3:  * Pagination Helper class file.
   4:  *
   5:  * Generates pagination links
   6:  *
   7:  * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
   8:  * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
   9:  *
  10:  * Licensed under The MIT License
  11:  * For full copyright and license information, please see the LICENSE.txt
  12:  * Redistributions of files must retain the above copyright notice.
  13:  *
  14:  * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  15:  * @link          https://cakephp.org CakePHP(tm) Project
  16:  * @package       Cake.View.Helper
  17:  * @since         CakePHP(tm) v 1.2.0
  18:  * @license       https://opensource.org/licenses/mit-license.php MIT License
  19:  */
  20: 
  21: App::uses('AppHelper', 'View/Helper');
  22: 
  23: /**
  24:  * Pagination Helper class for easy generation of pagination links.
  25:  *
  26:  * PaginationHelper encloses all methods needed when working with pagination.
  27:  *
  28:  * @package       Cake.View.Helper
  29:  * @property      HtmlHelper $Html
  30:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html
  31:  */
  32: class PaginatorHelper extends AppHelper {
  33: 
  34: /**
  35:  * Helper dependencies
  36:  *
  37:  * @var array
  38:  */
  39:     public $helpers = array('Html');
  40: 
  41: /**
  42:  * The class used for 'Ajax' pagination links. Defaults to JsHelper. You should make sure
  43:  * that JsHelper is defined as a helper before PaginatorHelper, if you want to customize the JsHelper.
  44:  *
  45:  * @var string
  46:  */
  47:     protected $_ajaxHelperClass = 'Js';
  48: 
  49: /**
  50:  * Holds the default options for pagination links
  51:  *
  52:  * The values that may be specified are:
  53:  *
  54:  * - `format` Format of the counter. Supported formats are 'range' and 'pages'
  55:  *    and custom (default). In the default mode the supplied string is parsed and constants are replaced
  56:  *    by their actual values.
  57:  *    placeholders: %page%, %pages%, %current%, %count%, %start%, %end% .
  58:  * - `separator` The separator of the actual page and number of pages (default: ' of ').
  59:  * - `url` Url of the action. See Router::url()
  60:  * - `url['sort']`  the key that the recordset is sorted.
  61:  * - `url['direction']` Direction of the sorting (default: 'asc').
  62:  * - `url['page']` Page number to use in links.
  63:  * - `model` The name of the model.
  64:  * - `escape` Defines if the title field for the link should be escaped (default: true).
  65:  * - `update` DOM id of the element updated with the results of the AJAX call.
  66:  *     If this key isn't specified Paginator will use plain HTML links.
  67:  * - `paging['paramType']` The type of parameters to use when creating links. Valid options are
  68:  *     'querystring' and 'named'. See PaginatorComponent::$settings for more information.
  69:  * - `convertKeys` - A list of keys in URL arrays that should be converted to querysting params
  70:  *    if paramType == 'querystring'.
  71:  *
  72:  * @var array
  73:  */
  74:     public $options = array(
  75:         'convertKeys' => array('page', 'limit', 'sort', 'direction')
  76:     );
  77: 
  78: /**
  79:  * Constructor for the helper. Sets up the helper that is used for creating 'AJAX' links.
  80:  *
  81:  * Use `public $helpers = array('Paginator' => array('ajax' => 'CustomHelper'));` to set a custom Helper
  82:  * or choose a non JsHelper Helper. If you want to use a specific library with JsHelper declare JsHelper and its
  83:  * adapter before including PaginatorHelper in your helpers array.
  84:  *
  85:  * The chosen custom helper must implement a `link()` method.
  86:  *
  87:  * @param View $View the view object the helper is attached to.
  88:  * @param array $settings Array of settings.
  89:  * @throws CakeException When the AjaxProvider helper does not implement a link method.
  90:  */
  91:     public function __construct(View $View, $settings = array()) {
  92:         $ajaxProvider = isset($settings['ajax']) ? $settings['ajax'] : 'Js';
  93:         $this->helpers[] = $ajaxProvider;
  94:         $this->_ajaxHelperClass = $ajaxProvider;
  95:         App::uses($ajaxProvider . 'Helper', 'View/Helper');
  96:         $classname = $ajaxProvider . 'Helper';
  97:         if (!class_exists($classname) || !method_exists($classname, 'link')) {
  98:             throw new CakeException(
  99:                 __d('cake_dev', '%s does not implement a %s method, it is incompatible with %s', $classname, 'link()', 'PaginatorHelper')
 100:             );
 101:         }
 102:         parent::__construct($View, $settings);
 103:     }
 104: 
 105: /**
 106:  * Before render callback. Overridden to merge passed args with URL options.
 107:  *
 108:  * @param string $viewFile View file name.
 109:  * @return void
 110:  */
 111:     public function beforeRender($viewFile) {
 112:         $this->options['url'] = array_merge($this->request->params['pass'], $this->request->params['named']);
 113:         if (!empty($this->request->query)) {
 114:             $this->options['url']['?'] = $this->request->query;
 115:         }
 116:         parent::beforeRender($viewFile);
 117:     }
 118: 
 119: /**
 120:  * Gets the current paging parameters from the resultset for the given model
 121:  *
 122:  * @param string $model Optional model name. Uses the default if none is specified.
 123:  * @return array The array of paging parameters for the paginated resultset.
 124:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::params
 125:  */
 126:     public function params($model = null) {
 127:         if (empty($model)) {
 128:             $model = $this->defaultModel();
 129:         }
 130:         if (!isset($this->request->params['paging']) || empty($this->request->params['paging'][$model])) {
 131:             return array(
 132:                 'prevPage' => false,
 133:                 'nextPage' => true,
 134:                 'paramType' => 'named',
 135:                 'pageCount' => 1,
 136:                 'options' => array(),
 137:                 'page' => 1
 138:             );
 139:         }
 140:         return $this->request->params['paging'][$model];
 141:     }
 142: 
 143: /**
 144:  * Convenience access to any of the paginator params.
 145:  *
 146:  * @param string $key Key of the paginator params array to retrieve.
 147:  * @param string $model Optional model name. Uses the default if none is specified.
 148:  * @return mixed Content of the requested param.
 149:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::params
 150:  */
 151:     public function param($key, $model = null) {
 152:         $params = $this->params($model);
 153:         if (!isset($params[$key])) {
 154:             return null;
 155:         }
 156:         return $params[$key];
 157:     }
 158: 
 159: /**
 160:  * Sets default options for all pagination links
 161:  *
 162:  * @param array|string $options Default options for pagination links. If a string is supplied - it
 163:  *   is used as the DOM id element to update. See PaginatorHelper::$options for list of keys.
 164:  * @return void
 165:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::options
 166:  */
 167:     public function options($options = array()) {
 168:         if (is_string($options)) {
 169:             $options = array('update' => $options);
 170:         }
 171: 
 172:         if (!empty($options['paging'])) {
 173:             if (!isset($this->request->params['paging'])) {
 174:                 $this->request->params['paging'] = array();
 175:             }
 176:             $this->request->params['paging'] = array_merge($this->request->params['paging'], $options['paging']);
 177:             unset($options['paging']);
 178:         }
 179:         $model = $this->defaultModel();
 180: 
 181:         if (!empty($options[$model])) {
 182:             if (!isset($this->request->params['paging'][$model])) {
 183:                 $this->request->params['paging'][$model] = array();
 184:             }
 185:             $this->request->params['paging'][$model] = array_merge(
 186:                 $this->request->params['paging'][$model], $options[$model]
 187:             );
 188:             unset($options[$model]);
 189:         }
 190:         if (!empty($options['convertKeys'])) {
 191:             $options['convertKeys'] = array_merge($this->options['convertKeys'], $options['convertKeys']);
 192:         }
 193:         $this->options = array_filter(array_merge($this->options, $options));
 194:         if (!empty($this->options['model'])) {
 195:             $this->defaultModel($this->options['model']);
 196:         }
 197:     }
 198: 
 199: /**
 200:  * Gets the current page of the recordset for the given model
 201:  *
 202:  * @param string $model Optional model name. Uses the default if none is specified.
 203:  * @return string The current page number of the recordset.
 204:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::current
 205:  */
 206:     public function current($model = null) {
 207:         $params = $this->params($model);
 208: 
 209:         if (isset($params['page'])) {
 210:             return $params['page'];
 211:         }
 212:         return 1;
 213:     }
 214: 
 215: /**
 216:  * Gets the current key by which the recordset is sorted
 217:  *
 218:  * @param string $model Optional model name. Uses the default if none is specified.
 219:  * @param array $options Options for pagination links. See #options for list of keys.
 220:  * @return string|null The name of the key by which the recordset is being sorted, or
 221:  *  null if the results are not currently sorted.
 222:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::sortKey
 223:  */
 224:     public function sortKey($model = null, $options = array()) {
 225:         if (empty($options)) {
 226:             $params = $this->params($model);
 227:             $options = $params['options'];
 228:         }
 229:         if (isset($options['sort']) && !empty($options['sort'])) {
 230:             return $options['sort'];
 231:         }
 232:         if (isset($options['order'])) {
 233:             return is_array($options['order']) ? key($options['order']) : $options['order'];
 234:         }
 235:         if (isset($params['order'])) {
 236:             return is_array($params['order']) ? key($params['order']) : $params['order'];
 237:         }
 238:         return null;
 239:     }
 240: 
 241: /**
 242:  * Gets the current direction the recordset is sorted
 243:  *
 244:  * @param string $model Optional model name. Uses the default if none is specified.
 245:  * @param array $options Options for pagination links. See #options for list of keys.
 246:  * @return string The direction by which the recordset is being sorted, or
 247:  *  null if the results are not currently sorted.
 248:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::sortDir
 249:  */
 250:     public function sortDir($model = null, $options = array()) {
 251:         $dir = null;
 252: 
 253:         if (empty($options)) {
 254:             $params = $this->params($model);
 255:             $options = $params['options'];
 256:         }
 257: 
 258:         if (isset($options['direction'])) {
 259:             $dir = strtolower($options['direction']);
 260:         } elseif (isset($options['order']) && is_array($options['order'])) {
 261:             $dir = strtolower(current($options['order']));
 262:         } elseif (isset($params['order']) && is_array($params['order'])) {
 263:             $dir = strtolower(current($params['order']));
 264:         }
 265: 
 266:         if ($dir === 'desc') {
 267:             return 'desc';
 268:         }
 269:         return 'asc';
 270:     }
 271: 
 272: /**
 273:  * Generates a "previous" link for a set of paged records
 274:  *
 275:  * ### Options:
 276:  *
 277:  * - `url` Allows sending routing parameters such as controllers, actions or passed arguments.
 278:  * - `tag` The tag wrapping tag you want to use, defaults to 'span'. Set this to false to disable this option
 279:  * - `escape` Whether you want the contents html entity encoded, defaults to true
 280:  * - `model` The model to use, defaults to PaginatorHelper::defaultModel()
 281:  * - `disabledTag` Tag to use instead of A tag when there is no previous page
 282:  *
 283:  * @param string $title Title for the link. Defaults to '<< Previous'.
 284:  * @param array $options Options for pagination link. See #options for list of keys.
 285:  * @param string $disabledTitle Title when the link is disabled.
 286:  * @param array $disabledOptions Options for the disabled pagination link. See #options for list of keys.
 287:  * @return string A "previous" link or $disabledTitle text if the link is disabled.
 288:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::prev
 289:  */
 290:     public function prev($title = '<< Previous', $options = array(), $disabledTitle = null, $disabledOptions = array()) {
 291:         $defaults = array(
 292:             'rel' => 'prev'
 293:         );
 294:         $options = (array)$options + $defaults;
 295:         return $this->_pagingLink('Prev', $title, $options, $disabledTitle, $disabledOptions);
 296:     }
 297: 
 298: /**
 299:  * Generates a "next" link for a set of paged records
 300:  *
 301:  * ### Options:
 302:  *
 303:  * - `url` Allows sending routing parameters such as controllers, actions or passed arguments.
 304:  * - `tag` The tag wrapping tag you want to use, defaults to 'span'. Set this to false to disable this option
 305:  * - `escape` Whether you want the contents html entity encoded, defaults to true
 306:  * - `model` The model to use, defaults to PaginatorHelper::defaultModel()
 307:  * - `disabledTag` Tag to use instead of A tag when there is no next page
 308:  *
 309:  * @param string $title Title for the link. Defaults to 'Next >>'.
 310:  * @param array $options Options for pagination link. See above for list of keys.
 311:  * @param string $disabledTitle Title when the link is disabled.
 312:  * @param array $disabledOptions Options for the disabled pagination link. See above for list of keys.
 313:  * @return string A "next" link or $disabledTitle text if the link is disabled.
 314:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::next
 315:  */
 316:     public function next($title = 'Next >>', $options = array(), $disabledTitle = null, $disabledOptions = array()) {
 317:         $defaults = array(
 318:             'rel' => 'next'
 319:         );
 320:         $options = (array)$options + $defaults;
 321:         return $this->_pagingLink('Next', $title, $options, $disabledTitle, $disabledOptions);
 322:     }
 323: 
 324: /**
 325:  * Generates a sorting link. Sets named parameters for the sort and direction. Handles
 326:  * direction switching automatically.
 327:  *
 328:  * ### Options:
 329:  *
 330:  * - `escape` Whether you want the contents html entity encoded, defaults to true.
 331:  * - `model` The model to use, defaults to PaginatorHelper::defaultModel().
 332:  * - `direction` The default direction to use when this link isn't active.
 333:  * - `lock` Lock direction. Will only use the default direction then, defaults to false.
 334:  *
 335:  * @param string $key The name of the key that the recordset should be sorted.
 336:  * @param string $title Title for the link. If $title is null $key will be used
 337:  *      for the title and will be generated by inflection.
 338:  * @param array $options Options for sorting link. See above for list of keys.
 339:  * @return string A link sorting default by 'asc'. If the resultset is sorted 'asc' by the specified
 340:  *  key the returned link will sort by 'desc'.
 341:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::sort
 342:  */
 343:     public function sort($key, $title = null, $options = array()) {
 344:         $options += array('url' => array(), 'model' => null);
 345:         $url = $options['url'];
 346:         unset($options['url']);
 347: 
 348:         if (empty($title)) {
 349:             $title = $key;
 350: 
 351:             if (strpos($title, '.') !== false) {
 352:                 $title = str_replace('.', ' ', $title);
 353:             }
 354: 
 355:             $title = __(Inflector::humanize(preg_replace('/_id$/', '', $title)));
 356:         }
 357:         $defaultDir = isset($options['direction']) ? strtolower($options['direction']) : 'asc';
 358:         unset($options['direction']);
 359: 
 360:         $locked = isset($options['lock']) ? $options['lock'] : false;
 361:         unset($options['lock']);
 362: 
 363:         $sortKey = $this->sortKey($options['model']);
 364:         $defaultModel = $this->defaultModel();
 365:         $model = $options['model'] ?: $defaultModel;
 366:         list($table, $field) = explode('.', $key . '.');
 367:         if (!$field) {
 368:             $field = $table;
 369:             $table = $model;
 370:         }
 371:         $isSorted = (
 372:             $sortKey === $table . '.' . $field ||
 373:             $sortKey === $defaultModel . '.' . $key ||
 374:             $table . '.' . $field === $defaultModel . '.' . $sortKey
 375:         );
 376: 
 377:         $dir = $defaultDir;
 378:         if ($isSorted) {
 379:             $dir = $this->sortDir($options['model']) === 'asc' ? 'desc' : 'asc';
 380:             $class = $dir === 'asc' ? 'desc' : 'asc';
 381:             if (!empty($options['class'])) {
 382:                 $options['class'] .= ' ' . $class;
 383:             } else {
 384:                 $options['class'] = $class;
 385:             }
 386:             if ($locked) {
 387:                 $dir = $defaultDir;
 388:                 $options['class'] .= ' locked';
 389:             }
 390:         }
 391:         if (is_array($title) && array_key_exists($dir, $title)) {
 392:             $title = $title[$dir];
 393:         }
 394: 
 395:         $url = array_merge(array('sort' => $key, 'direction' => $dir), $url, array('order' => null));
 396:         return $this->link($title, $url, $options);
 397:     }
 398: 
 399: /**
 400:  * Generates a plain or Ajax link with pagination parameters
 401:  *
 402:  * ### Options
 403:  *
 404:  * - `update` The Id of the DOM element you wish to update. Creates Ajax enabled links
 405:  *    with the AjaxHelper.
 406:  * - `escape` Whether you want the contents html entity encoded, defaults to true
 407:  * - `model` The model to use, defaults to PaginatorHelper::defaultModel()
 408:  *
 409:  * @param string $title Title for the link.
 410:  * @param string|array $url URL for the action. See Router::url()
 411:  * @param array $options Options for the link. See #options for list of keys.
 412:  * @return string A link with pagination parameters.
 413:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::link
 414:  */
 415:     public function link($title, $url = array(), $options = array()) {
 416:         $options += array('model' => null, 'escape' => true);
 417:         $model = $options['model'];
 418:         unset($options['model']);
 419: 
 420:         if (!empty($this->options)) {
 421:             $options += $this->options;
 422:         }
 423:         if (isset($options['url'])) {
 424:             $url = array_merge((array)$options['url'], (array)$url);
 425:             unset($options['url']);
 426:         }
 427:         unset($options['convertKeys']);
 428: 
 429:         $url = $this->url($url, true, $model);
 430: 
 431:         $obj = isset($options['update']) ? $this->_ajaxHelperClass : 'Html';
 432:         return $this->{$obj}->link($title, $url, $options);
 433:     }
 434: 
 435: /**
 436:  * Merges passed URL options with current pagination state to generate a pagination URL.
 437:  *
 438:  * @param array $options Pagination/URL options array
 439:  * @param bool $asArray Return the URL as an array, or a URI string
 440:  * @param string $model Which model to paginate on
 441:  * @return mixed By default, returns a full pagination URL string for use in non-standard contexts (i.e. JavaScript)
 442:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::url
 443:  */
 444:     public function url($options = array(), $asArray = false, $model = null) {
 445:         $paging = $this->params($model);
 446:         $url = array_merge(array_filter($paging['options']), $options);
 447: 
 448:         if (isset($url['order'])) {
 449:             $sort = $direction = null;
 450:             if (is_array($url['order'])) {
 451:                 list($sort, $direction) = array($this->sortKey($model, $url), current($url['order']));
 452:             }
 453:             unset($url['order']);
 454:             $url = array_merge($url, compact('sort', 'direction'));
 455:         }
 456:         $url = $this->_convertUrlKeys($url, $paging['paramType']);
 457:         if (!empty($url['page']) && $url['page'] == 1) {
 458:             $url['page'] = null;
 459:         }
 460:         if (!empty($url['?']['page']) && $url['?']['page'] == 1) {
 461:             unset($url['?']['page']);
 462:         }
 463:         if (!empty($paging['queryScope'])) {
 464:             $url = array($paging['queryScope'] => $url);
 465:             if (empty($url[$paging['queryScope']]['page'])) {
 466:                 unset($url[$paging['queryScope']]['page']);
 467:             }
 468:         }
 469: 
 470:         if ($asArray) {
 471:             return $url;
 472:         }
 473:         return parent::url($url);
 474:     }
 475: 
 476: /**
 477:  * Converts the keys being used into the format set by options.paramType
 478:  *
 479:  * @param array $url Array of URL params to convert
 480:  * @param string $type Keys type.
 481:  * @return array converted URL params.
 482:  */
 483:     protected function _convertUrlKeys($url, $type) {
 484:         if ($type === 'named') {
 485:             return $url;
 486:         }
 487:         if (!isset($url['?'])) {
 488:             $url['?'] = array();
 489:         }
 490:         foreach ($this->options['convertKeys'] as $key) {
 491:             if (isset($url[$key])) {
 492:                 $url['?'][$key] = $url[$key];
 493:                 unset($url[$key]);
 494:             }
 495:         }
 496:         return $url;
 497:     }
 498: 
 499: /**
 500:  * Protected method for generating prev/next links
 501:  *
 502:  * @param string $which Link type: 'Prev', 'Next'.
 503:  * @param string $title Link title.
 504:  * @param array $options Options list.
 505:  * @param string $disabledTitle Disabled link title.
 506:  * @param array $disabledOptions Disabled link options.
 507:  * @return string
 508:  */
 509:     protected function _pagingLink($which, $title = null, $options = array(), $disabledTitle = null, $disabledOptions = array()) {
 510:         $check = 'has' . $which;
 511:         $_defaults = array(
 512:             'url' => array(), 'step' => 1, 'escape' => true, 'model' => null,
 513:             'tag' => 'span', 'class' => strtolower($which), 'disabledTag' => null
 514:         );
 515:         $options = (array)$options + $_defaults;
 516:         $paging = $this->params($options['model']);
 517:         if (empty($disabledOptions)) {
 518:             $disabledOptions = $options;
 519:         }
 520: 
 521:         if (!$this->{$check}($options['model']) && (!empty($disabledTitle) || !empty($disabledOptions))) {
 522:             if (!empty($disabledTitle) && $disabledTitle !== true) {
 523:                 $title = $disabledTitle;
 524:             }
 525:             $options = (array)$disabledOptions + array_intersect_key($options, $_defaults) + $_defaults;
 526:         } elseif (!$this->{$check}($options['model'])) {
 527:             return '';
 528:         }
 529: 
 530:         foreach (array_keys($_defaults) as $key) {
 531:             ${$key} = $options[$key];
 532:             unset($options[$key]);
 533:         }
 534: 
 535:         if ($this->{$check}($model)) {
 536:             $url = array_merge(
 537:                 array('page' => $paging['page'] + ($which === 'Prev' ? $step * -1 : $step)),
 538:                 $url
 539:             );
 540:             if ($tag === false) {
 541:                 return $this->link(
 542:                     $title,
 543:                     $url,
 544:                     compact('escape', 'model', 'class') + $options
 545:                 );
 546:             }
 547:             $link = $this->link($title, $url, compact('escape', 'model') + $options);
 548:             return $this->Html->tag($tag, $link, compact('class'));
 549:         }
 550:         unset($options['rel']);
 551:         if (!$tag) {
 552:             if ($disabledTag) {
 553:                 $tag = $disabledTag;
 554:                 $disabledTag = null;
 555:             } else {
 556:                 $tag = $_defaults['tag'];
 557:             }
 558:         }
 559:         if ($disabledTag) {
 560:             $title = $this->Html->tag($disabledTag, $title, compact('escape') + $options);
 561:             return $this->Html->tag($tag, $title, compact('class'));
 562:         }
 563:         return $this->Html->tag($tag, $title, compact('escape', 'class') + $options);
 564:     }
 565: 
 566: /**
 567:  * Returns true if the given result set is not at the first page
 568:  *
 569:  * @param string $model Optional model name. Uses the default if none is specified.
 570:  * @return bool True if the result set is not at the first page.
 571:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::hasPrev
 572:  */
 573:     public function hasPrev($model = null) {
 574:         return $this->_hasPage($model, 'prev');
 575:     }
 576: 
 577: /**
 578:  * Returns true if the given result set is not at the last page
 579:  *
 580:  * @param string $model Optional model name. Uses the default if none is specified.
 581:  * @return bool True if the result set is not at the last page.
 582:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::hasNext
 583:  */
 584:     public function hasNext($model = null) {
 585:         return $this->_hasPage($model, 'next');
 586:     }
 587: 
 588: /**
 589:  * Returns true if the given result set has the page number given by $page
 590:  *
 591:  * @param string $model Optional model name. Uses the default if none is specified.
 592:  * @param int $page The page number - if not set defaults to 1.
 593:  * @return bool True if the given result set has the specified page number.
 594:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::hasPage
 595:  */
 596:     public function hasPage($model = null, $page = 1) {
 597:         if (is_numeric($model)) {
 598:             $page = $model;
 599:             $model = null;
 600:         }
 601:         $paging = $this->params($model);
 602:         return $page <= $paging['pageCount'];
 603:     }
 604: 
 605: /**
 606:  * Does $model have $page in its range?
 607:  *
 608:  * @param string $model Model name to get parameters for.
 609:  * @param int $page Page number you are checking.
 610:  * @return bool Whether model has $page
 611:  */
 612:     protected function _hasPage($model, $page) {
 613:         $params = $this->params($model);
 614:         return !empty($params) && $params[$page . 'Page'];
 615:     }
 616: 
 617: /**
 618:  * Gets or sets the default model of the paged sets
 619:  *
 620:  * @param string|null $model Model name to set
 621:  * @return string|null Model name or null if the pagination isn't initialized.
 622:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::defaultModel
 623:  */
 624:     public function defaultModel($model = null) {
 625:         if ($model !== null) {
 626:             $this->_defaultModel = $model;
 627:         }
 628:         if ($this->_defaultModel) {
 629:             return $this->_defaultModel;
 630:         }
 631:         if (empty($this->request->params['paging'])) {
 632:             return null;
 633:         }
 634:         list($this->_defaultModel) = array_keys($this->request->params['paging']);
 635:         return $this->_defaultModel;
 636:     }
 637: 
 638: /**
 639:  * Returns a counter string for the paged result set
 640:  *
 641:  * ### Options
 642:  *
 643:  * - `model` The model to use, defaults to PaginatorHelper::defaultModel();
 644:  * - `format` The format string you want to use, defaults to 'pages' Which generates output like '1 of 5'
 645:  *    set to 'range' to generate output like '1 - 3 of 13'. Can also be set to a custom string, containing
 646:  *    the following placeholders `{:page}`, `{:pages}`, `{:current}`, `{:count}`, `{:model}`, `{:start}`, `{:end}` and any
 647:  *    custom content you would like.
 648:  * - `separator` The separator string to use, default to ' of '
 649:  *
 650:  * The `%page%` style placeholders also work, but are deprecated and will be removed in a future version.
 651:  *
 652:  * @param array $options Options for the counter string. See #options for list of keys.
 653:  * @return string Counter string.
 654:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::counter
 655:  */
 656:     public function counter($options = array()) {
 657:         if (is_string($options)) {
 658:             $options = array('format' => $options);
 659:         }
 660: 
 661:         $options += array(
 662:             'model' => $this->defaultModel(),
 663:             'format' => 'pages',
 664:             'separator' => __d('cake', ' of ')
 665:         );
 666: 
 667:         $paging = $this->params($options['model']);
 668:         if (!$paging['pageCount']) {
 669:             $paging['pageCount'] = 1;
 670:         }
 671:         $start = 0;
 672:         if ($paging['count'] >= 1) {
 673:             $start = (($paging['page'] - 1) * $paging['limit']) + 1;
 674:         }
 675:         $end = $start + $paging['limit'] - 1;
 676:         if ($paging['count'] < $end) {
 677:             $end = $paging['count'];
 678:         }
 679: 
 680:         switch ($options['format']) {
 681:             case 'range':
 682:                 if (!is_array($options['separator'])) {
 683:                     $options['separator'] = array(' - ', $options['separator']);
 684:                 }
 685:                 $out = $start . $options['separator'][0] . $end . $options['separator'][1];
 686:                 $out .= $paging['count'];
 687:                 break;
 688:             case 'pages':
 689:                 $out = $paging['page'] . $options['separator'] . $paging['pageCount'];
 690:                 break;
 691:             default:
 692:                 $map = array(
 693:                     '%page%' => $paging['page'],
 694:                     '%pages%' => $paging['pageCount'],
 695:                     '%current%' => $paging['current'],
 696:                     '%count%' => $paging['count'],
 697:                     '%start%' => $start,
 698:                     '%end%' => $end,
 699:                     '%model%' => strtolower(Inflector::humanize(Inflector::tableize($options['model'])))
 700:                 );
 701:                 $out = str_replace(array_keys($map), array_values($map), $options['format']);
 702: 
 703:                 $newKeys = array(
 704:                     '{:page}', '{:pages}', '{:current}', '{:count}', '{:start}', '{:end}', '{:model}'
 705:                 );
 706:                 $out = str_replace($newKeys, array_values($map), $out);
 707:         }
 708:         return $out;
 709:     }
 710: 
 711: /**
 712:  * Returns a set of numbers for the paged result set
 713:  * uses a modulus to decide how many numbers to show on each side of the current page (default: 8).
 714:  *
 715:  * `$this->Paginator->numbers(array('first' => 2, 'last' => 2));`
 716:  *
 717:  * Using the first and last options you can create links to the beginning and end of the page set.
 718:  *
 719:  * ### Options
 720:  *
 721:  * - `before` Content to be inserted before the numbers
 722:  * - `after` Content to be inserted after the numbers
 723:  * - `model` Model to create numbers for, defaults to PaginatorHelper::defaultModel()
 724:  * - `modulus` how many numbers to include on either side of the current page, defaults to 8.
 725:  * - `separator` Separator content defaults to ' | '
 726:  * - `tag` The tag to wrap links in, defaults to 'span'
 727:  * - `first` Whether you want first links generated, set to an integer to define the number of 'first'
 728:  *    links to generate. If a string is set a link to the first page will be generated with the value
 729:  *    as the title.
 730:  * - `last` Whether you want last links generated, set to an integer to define the number of 'last'
 731:  *    links to generate. If a string is set a link to the last page will be generated with the value
 732:  *    as the title.
 733:  * - `ellipsis` Ellipsis content, defaults to '...'
 734:  * - `class` Class for wrapper tag
 735:  * - `currentClass` Class for wrapper tag on current active page, defaults to 'current'
 736:  * - `currentTag` Tag to use for current page number, defaults to null
 737:  *
 738:  * @param array|bool $options Options for the numbers, (before, after, model, modulus, separator)
 739:  * @return string Numbers string.
 740:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::numbers
 741:  */
 742:     public function numbers($options = array()) {
 743:         if ($options === true) {
 744:             $options = array(
 745:                 'before' => ' | ', 'after' => ' | ', 'first' => 'first', 'last' => 'last'
 746:             );
 747:         }
 748: 
 749:         $defaults = array(
 750:             'tag' => 'span', 'before' => null, 'after' => null, 'model' => $this->defaultModel(), 'class' => null,
 751:             'modulus' => '8', 'separator' => ' | ', 'first' => null, 'last' => null, 'ellipsis' => '...',
 752:             'currentClass' => 'current', 'currentTag' => null
 753:         );
 754:         $options += $defaults;
 755: 
 756:         $params = (array)$this->params($options['model']) + array('page' => 1);
 757:         unset($options['model']);
 758: 
 759:         if (empty($params['pageCount']) || $params['pageCount'] <= 1) {
 760:             return '';
 761:         }
 762: 
 763:         extract($options);
 764:         unset($options['tag'], $options['before'], $options['after'], $options['model'],
 765:             $options['modulus'], $options['separator'], $options['first'], $options['last'],
 766:             $options['ellipsis'], $options['class'], $options['currentClass'], $options['currentTag']
 767:         );
 768:         $out = '';
 769: 
 770:         if ($modulus && $params['pageCount'] > $modulus) {
 771:             $half = (int)($modulus / 2);
 772:             $end = $params['page'] + $half;
 773: 
 774:             if ($end > $params['pageCount']) {
 775:                 $end = $params['pageCount'];
 776:             }
 777:             $start = $params['page'] - ($modulus - ($end - $params['page']));
 778:             if ($start <= 1) {
 779:                 $start = 1;
 780:                 $end = $params['page'] + ($modulus - $params['page']) + 1;
 781:             }
 782: 
 783:             $firstPage = is_int($first) ? $first : 0;
 784:             if ($first && $start > 1) {
 785:                 $offset = ($start <= $firstPage) ? $start - 1 : $first;
 786:                 if ($firstPage < $start - 1) {
 787:                     $out .= $this->first($offset, compact('tag', 'separator', 'ellipsis', 'class'));
 788:                 } else {
 789:                     $out .= $this->first($offset, compact('tag', 'separator', 'class', 'ellipsis') + array('after' => $separator));
 790:                 }
 791:             }
 792: 
 793:             $out .= $before;
 794: 
 795:             for ($i = $start; $i < $params['page']; $i++) {
 796:                 $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class')) . $separator;
 797:             }
 798: 
 799:             if ($class) {
 800:                 $currentClass .= ' ' . $class;
 801:             }
 802:             if ($currentTag) {
 803:                 $out .= $this->Html->tag($tag, $this->Html->tag($currentTag, $params['page']), array('class' => $currentClass));
 804:             } else {
 805:                 $out .= $this->Html->tag($tag, $params['page'], array('class' => $currentClass));
 806:             }
 807:             if ($i != $params['pageCount']) {
 808:                 $out .= $separator;
 809:             }
 810: 
 811:             $start = $params['page'] + 1;
 812:             for ($i = $start; $i < $end; $i++) {
 813:                 $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class')) . $separator;
 814:             }
 815: 
 816:             if ($end != $params['page']) {
 817:                 $out .= $this->Html->tag($tag, $this->link($i, array('page' => $end), $options), compact('class'));
 818:             }
 819: 
 820:             $out .= $after;
 821: 
 822:             if ($last && $end < $params['pageCount']) {
 823:                 $lastPage = is_int($last) ? $last : 0;
 824:                 $offset = ($params['pageCount'] < $end + $lastPage) ? $params['pageCount'] - $end : $last;
 825:                 if ($offset <= $lastPage && $params['pageCount'] - $end > $lastPage) {
 826:                     $out .= $this->last($offset, compact('tag', 'separator', 'ellipsis', 'class'));
 827:                 } else {
 828:                     $out .= $this->last($offset, compact('tag', 'separator', 'class', 'ellipsis') + array('before' => $separator));
 829:                 }
 830:             }
 831: 
 832:         } else {
 833:             $out .= $before;
 834: 
 835:             for ($i = 1; $i <= $params['pageCount']; $i++) {
 836:                 if ($i == $params['page']) {
 837:                     if ($class) {
 838:                         $currentClass .= ' ' . $class;
 839:                     }
 840:                     if ($currentTag) {
 841:                         $out .= $this->Html->tag($tag, $this->Html->tag($currentTag, $i), array('class' => $currentClass));
 842:                     } else {
 843:                         $out .= $this->Html->tag($tag, $i, array('class' => $currentClass));
 844:                     }
 845:                 } else {
 846:                     $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class'));
 847:                 }
 848:                 if ($i != $params['pageCount']) {
 849:                     $out .= $separator;
 850:                 }
 851:             }
 852: 
 853:             $out .= $after;
 854:         }
 855: 
 856:         return $out;
 857:     }
 858: 
 859: /**
 860:  * Returns a first or set of numbers for the first pages.
 861:  *
 862:  * `echo $this->Paginator->first('< first');`
 863:  *
 864:  * Creates a single link for the first page. Will output nothing if you are on the first page.
 865:  *
 866:  * `echo $this->Paginator->first(3);`
 867:  *
 868:  * Will create links for the first 3 pages, once you get to the third or greater page. Prior to that
 869:  * nothing will be output.
 870:  *
 871:  * ### Options:
 872:  *
 873:  * - `tag` The tag wrapping tag you want to use, defaults to 'span'
 874:  * - `after` Content to insert after the link/tag
 875:  * - `model` The model to use defaults to PaginatorHelper::defaultModel()
 876:  * - `separator` Content between the generated links, defaults to ' | '
 877:  * - `ellipsis` Content for ellipsis, defaults to '...'
 878:  *
 879:  * @param string|int $first if string use as label for the link. If numeric, the number of page links
 880:  *   you want at the beginning of the range.
 881:  * @param array $options An array of options.
 882:  * @return string Numbers string.
 883:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::first
 884:  */
 885:     public function first($first = '<< first', $options = array()) {
 886:         $options = (array)$options + array(
 887:             'tag' => 'span',
 888:             'after' => null,
 889:             'model' => $this->defaultModel(),
 890:             'separator' => ' | ',
 891:             'ellipsis' => '...',
 892:             'class' => null
 893:         );
 894: 
 895:         $params = array_merge(array('page' => 1), (array)$this->params($options['model']));
 896:         unset($options['model']);
 897: 
 898:         if ($params['pageCount'] <= 1) {
 899:             return '';
 900:         }
 901:         extract($options);
 902:         unset($options['tag'], $options['after'], $options['model'], $options['separator'], $options['ellipsis'], $options['class']);
 903: 
 904:         $out = '';
 905: 
 906:         if ((is_int($first) || ctype_digit($first)) && $params['page'] >= $first) {
 907:             if ($after === null) {
 908:                 $after = $ellipsis;
 909:             }
 910:             for ($i = 1; $i <= $first; $i++) {
 911:                 $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class'));
 912:                 if ($i != $first) {
 913:                     $out .= $separator;
 914:                 }
 915:             }
 916:             $out .= $after;
 917:         } elseif ($params['page'] > 1 && is_string($first)) {
 918:             $options += array('rel' => 'first');
 919:             $out = $this->Html->tag($tag, $this->link($first, array('page' => 1), $options), compact('class')) . $after;
 920:         }
 921:         return $out;
 922:     }
 923: 
 924: /**
 925:  * Returns a last or set of numbers for the last pages.
 926:  *
 927:  * `echo $this->Paginator->last('last >');`
 928:  *
 929:  * Creates a single link for the last page. Will output nothing if you are on the last page.
 930:  *
 931:  * `echo $this->Paginator->last(3);`
 932:  *
 933:  * Will create links for the last 3 pages. Once you enter the page range, no output will be created.
 934:  *
 935:  * ### Options:
 936:  *
 937:  * - `tag` The tag wrapping tag you want to use, defaults to 'span'
 938:  * - `before` Content to insert before the link/tag
 939:  * - `model` The model to use defaults to PaginatorHelper::defaultModel()
 940:  * - `separator` Content between the generated links, defaults to ' | '
 941:  * - `ellipsis` Content for ellipsis, defaults to '...'
 942:  *
 943:  * @param string|int $last if string use as label for the link, if numeric print page numbers
 944:  * @param array $options Array of options
 945:  * @return string Numbers string.
 946:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::last
 947:  */
 948:     public function last($last = 'last >>', $options = array()) {
 949:         $options = (array)$options + array(
 950:             'tag' => 'span',
 951:             'before' => null,
 952:             'model' => $this->defaultModel(),
 953:             'separator' => ' | ',
 954:             'ellipsis' => '...',
 955:             'class' => null
 956:         );
 957: 
 958:         $params = array_merge(array('page' => 1), (array)$this->params($options['model']));
 959:         unset($options['model']);
 960: 
 961:         if ($params['pageCount'] <= 1) {
 962:             return '';
 963:         }
 964: 
 965:         extract($options);
 966:         unset($options['tag'], $options['before'], $options['model'], $options['separator'], $options['ellipsis'], $options['class']);
 967: 
 968:         $out = '';
 969:         $lower = $params['pageCount'] - (int)$last + 1;
 970: 
 971:         if ((is_int($last) || ctype_digit($last)) && $params['page'] <= $lower) {
 972:             if ($before === null) {
 973:                 $before = $ellipsis;
 974:             }
 975:             for ($i = $lower; $i <= $params['pageCount']; $i++) {
 976:                 $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class'));
 977:                 if ($i != $params['pageCount']) {
 978:                     $out .= $separator;
 979:                 }
 980:             }
 981:             $out = $before . $out;
 982:         } elseif ($params['page'] < $params['pageCount'] && is_string($last)) {
 983:             $options += array('rel' => 'last');
 984:             $out = $before . $this->Html->tag(
 985:                 $tag, $this->link($last, array('page' => $params['pageCount']), $options), compact('class')
 986:             );
 987:         }
 988:         return $out;
 989:     }
 990: 
 991: /**
 992:  * Returns the meta-links for a paginated result set.
 993:  *
 994:  * `echo $this->Paginator->meta();`
 995:  *
 996:  * Echos the links directly, will output nothing if there is neither a previous nor next page.
 997:  *
 998:  * `$this->Paginator->meta(array('block' => true));`
 999:  *
1000:  * Will append the output of the meta function to the named block - if true is passed the "meta"
1001:  * block is used.
1002:  *
1003:  * ### Options:
1004:  *
1005:  * - `model` The model to use defaults to PaginatorHelper::defaultModel()
1006:  * - `block` The block name to append the output to, or false/absent to return as a string
1007:  *
1008:  * @param array $options Array of options.
1009:  * @return string|null Meta links.
1010:  */
1011:     public function meta($options = array()) {
1012:         $model = isset($options['model']) ? $options['model'] : null;
1013:         $params = $this->params($model);
1014:         $urlOptions = isset($this->options['url']) ? $this->options['url'] : array();
1015:         $links = array();
1016:         if ($this->hasPrev()) {
1017:             $links[] = $this->Html->meta(array(
1018:                 'rel' => 'prev',
1019:                 'link' => $this->url(array_merge($urlOptions, array('page' => $params['page'] - 1)), true)
1020:             ));
1021:         }
1022:         if ($this->hasNext()) {
1023:             $links[] = $this->Html->meta(array(
1024:                 'rel' => 'next',
1025:                 'link' => $this->url(array_merge($urlOptions, array('page' => $params['page'] + 1)), true)
1026:             ));
1027:         }
1028:         $out = implode($links);
1029:         if (empty($options['block'])) {
1030:             return $out;
1031:         }
1032:         if ($options['block'] === true) {
1033:             $options['block'] = __FUNCTION__;
1034:         }
1035:         $this->_View->append($options['block'], $out);
1036:     }
1037: 
1038: }
1039: 
OpenHub
Rackspace
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Reporting Security Issues
  • Privacy Policy
  • Logos & Trademarks
  • Community
  • Get Involved
  • Issues (GitHub)
  • Bakery
  • Featured Resources
  • Training
  • Meetups
  • My CakePHP
  • CakeFest
  • Newsletter
  • Linkedin
  • YouTube
  • Facebook
  • Twitter
  • Mastodon
  • Help & Support
  • Forum
  • Stack Overflow
  • Slack
  • Paid Support

Generated using CakePHP API Docs