pictcode / lib / Cake / View / Helper / PaginatorHelper.php @ 48ae03cf
履歴 | 表示 | アノテート | ダウンロード (35.357 KB)
| 1 | 635eef61 | spyder1211 | <?php
|
|---|---|---|---|
| 2 | /**
|
||
| 3 | * Pagination Helper class file.
|
||
| 4 | *
|
||
| 5 | * Generates pagination links
|
||
| 6 | *
|
||
| 7 | * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||
| 8 | * Copyright (c) Cake Software Foundation, Inc. (http://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. (http://cakefoundation.org)
|
||
| 15 | * @link http://cakephp.org CakePHP(tm) Project
|
||
| 16 | * @package Cake.View.Helper
|
||
| 17 | * @since CakePHP(tm) v 1.2.0
|
||
| 18 | * @license http://www.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 http://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 http://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 http://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 http://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 | } |
||
| 195 | |||
| 196 | /**
|
||
| 197 | * Gets the current page of the recordset for the given model
|
||
| 198 | *
|
||
| 199 | * @param string $model Optional model name. Uses the default if none is specified.
|
||
| 200 | * @return string The current page number of the recordset.
|
||
| 201 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::current
|
||
| 202 | */
|
||
| 203 | public function current($model = null) { |
||
| 204 | $params = $this->params($model); |
||
| 205 | |||
| 206 | if (isset($params['page'])) { |
||
| 207 | return $params['page']; |
||
| 208 | } |
||
| 209 | return 1; |
||
| 210 | } |
||
| 211 | |||
| 212 | /**
|
||
| 213 | * Gets the current key by which the recordset is sorted
|
||
| 214 | *
|
||
| 215 | * @param string $model Optional model name. Uses the default if none is specified.
|
||
| 216 | * @param array $options Options for pagination links. See #options for list of keys.
|
||
| 217 | * @return string|null The name of the key by which the recordset is being sorted, or
|
||
| 218 | * null if the results are not currently sorted.
|
||
| 219 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::sortKey
|
||
| 220 | */
|
||
| 221 | public function sortKey($model = null, $options = array()) { |
||
| 222 | if (empty($options)) { |
||
| 223 | $params = $this->params($model); |
||
| 224 | $options = $params['options']; |
||
| 225 | } |
||
| 226 | if (isset($options['sort']) && !empty($options['sort'])) { |
||
| 227 | return $options['sort']; |
||
| 228 | } |
||
| 229 | if (isset($options['order'])) { |
||
| 230 | return is_array($options['order']) ? key($options['order']) : $options['order']; |
||
| 231 | } |
||
| 232 | if (isset($params['order'])) { |
||
| 233 | return is_array($params['order']) ? key($params['order']) : $params['order']; |
||
| 234 | } |
||
| 235 | return null; |
||
| 236 | } |
||
| 237 | |||
| 238 | /**
|
||
| 239 | * Gets the current direction the recordset is sorted
|
||
| 240 | *
|
||
| 241 | * @param string $model Optional model name. Uses the default if none is specified.
|
||
| 242 | * @param array $options Options for pagination links. See #options for list of keys.
|
||
| 243 | * @return string The direction by which the recordset is being sorted, or
|
||
| 244 | * null if the results are not currently sorted.
|
||
| 245 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::sortDir
|
||
| 246 | */
|
||
| 247 | public function sortDir($model = null, $options = array()) { |
||
| 248 | $dir = null; |
||
| 249 | |||
| 250 | if (empty($options)) { |
||
| 251 | $params = $this->params($model); |
||
| 252 | $options = $params['options']; |
||
| 253 | } |
||
| 254 | |||
| 255 | if (isset($options['direction'])) { |
||
| 256 | $dir = strtolower($options['direction']); |
||
| 257 | } elseif (isset($options['order']) && is_array($options['order'])) { |
||
| 258 | $dir = strtolower(current($options['order'])); |
||
| 259 | } elseif (isset($params['order']) && is_array($params['order'])) { |
||
| 260 | $dir = strtolower(current($params['order'])); |
||
| 261 | } |
||
| 262 | |||
| 263 | if ($dir === 'desc') { |
||
| 264 | return 'desc'; |
||
| 265 | } |
||
| 266 | return 'asc'; |
||
| 267 | } |
||
| 268 | |||
| 269 | /**
|
||
| 270 | * Generates a "previous" link for a set of paged records
|
||
| 271 | *
|
||
| 272 | * ### Options:
|
||
| 273 | *
|
||
| 274 | * - `url` Allows sending routing parameters such as controllers, actions or passed arguments.
|
||
| 275 | * - `tag` The tag wrapping tag you want to use, defaults to 'span'. Set this to false to disable this option
|
||
| 276 | * - `escape` Whether you want the contents html entity encoded, defaults to true
|
||
| 277 | * - `model` The model to use, defaults to PaginatorHelper::defaultModel()
|
||
| 278 | * - `disabledTag` Tag to use instead of A tag when there is no previous page
|
||
| 279 | *
|
||
| 280 | * @param string $title Title for the link. Defaults to '<< Previous'.
|
||
| 281 | * @param array $options Options for pagination link. See #options for list of keys.
|
||
| 282 | * @param string $disabledTitle Title when the link is disabled.
|
||
| 283 | * @param array $disabledOptions Options for the disabled pagination link. See #options for list of keys.
|
||
| 284 | * @return string A "previous" link or $disabledTitle text if the link is disabled.
|
||
| 285 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::prev
|
||
| 286 | */
|
||
| 287 | public function prev($title = '<< Previous', $options = array(), $disabledTitle = null, $disabledOptions = array()) { |
||
| 288 | $defaults = array( |
||
| 289 | 'rel' => 'prev' |
||
| 290 | ); |
||
| 291 | $options = (array)$options + $defaults; |
||
| 292 | return $this->_pagingLink('Prev', $title, $options, $disabledTitle, $disabledOptions); |
||
| 293 | } |
||
| 294 | |||
| 295 | /**
|
||
| 296 | * Generates a "next" link for a set of paged records
|
||
| 297 | *
|
||
| 298 | * ### Options:
|
||
| 299 | *
|
||
| 300 | * - `url` Allows sending routing parameters such as controllers, actions or passed arguments.
|
||
| 301 | * - `tag` The tag wrapping tag you want to use, defaults to 'span'. Set this to false to disable this option
|
||
| 302 | * - `escape` Whether you want the contents html entity encoded, defaults to true
|
||
| 303 | * - `model` The model to use, defaults to PaginatorHelper::defaultModel()
|
||
| 304 | * - `disabledTag` Tag to use instead of A tag when there is no next page
|
||
| 305 | *
|
||
| 306 | * @param string $title Title for the link. Defaults to 'Next >>'.
|
||
| 307 | * @param array $options Options for pagination link. See above for list of keys.
|
||
| 308 | * @param string $disabledTitle Title when the link is disabled.
|
||
| 309 | * @param array $disabledOptions Options for the disabled pagination link. See above for list of keys.
|
||
| 310 | * @return string A "next" link or $disabledTitle text if the link is disabled.
|
||
| 311 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::next
|
||
| 312 | */
|
||
| 313 | public function next($title = 'Next >>', $options = array(), $disabledTitle = null, $disabledOptions = array()) { |
||
| 314 | $defaults = array( |
||
| 315 | 'rel' => 'next' |
||
| 316 | ); |
||
| 317 | $options = (array)$options + $defaults; |
||
| 318 | return $this->_pagingLink('Next', $title, $options, $disabledTitle, $disabledOptions); |
||
| 319 | } |
||
| 320 | |||
| 321 | /**
|
||
| 322 | * Generates a sorting link. Sets named parameters for the sort and direction. Handles
|
||
| 323 | * direction switching automatically.
|
||
| 324 | *
|
||
| 325 | * ### Options:
|
||
| 326 | *
|
||
| 327 | * - `escape` Whether you want the contents html entity encoded, defaults to true.
|
||
| 328 | * - `model` The model to use, defaults to PaginatorHelper::defaultModel().
|
||
| 329 | * - `direction` The default direction to use when this link isn't active.
|
||
| 330 | * - `lock` Lock direction. Will only use the default direction then, defaults to false.
|
||
| 331 | *
|
||
| 332 | * @param string $key The name of the key that the recordset should be sorted.
|
||
| 333 | * @param string $title Title for the link. If $title is null $key will be used
|
||
| 334 | * for the title and will be generated by inflection.
|
||
| 335 | * @param array $options Options for sorting link. See above for list of keys.
|
||
| 336 | * @return string A link sorting default by 'asc'. If the resultset is sorted 'asc' by the specified
|
||
| 337 | * key the returned link will sort by 'desc'.
|
||
| 338 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::sort
|
||
| 339 | */
|
||
| 340 | public function sort($key, $title = null, $options = array()) { |
||
| 341 | $options += array('url' => array(), 'model' => null); |
||
| 342 | $url = $options['url']; |
||
| 343 | unset($options['url']); |
||
| 344 | |||
| 345 | if (empty($title)) { |
||
| 346 | $title = $key; |
||
| 347 | |||
| 348 | if (strpos($title, '.') !== false) { |
||
| 349 | $title = str_replace('.', ' ', $title); |
||
| 350 | } |
||
| 351 | |||
| 352 | $title = __(Inflector::humanize(preg_replace('/_id$/', '', $title))); |
||
| 353 | } |
||
| 354 | $defaultDir = isset($options['direction']) ? $options['direction'] : 'asc'; |
||
| 355 | unset($options['direction']); |
||
| 356 | |||
| 357 | $locked = isset($options['lock']) ? $options['lock'] : false; |
||
| 358 | unset($options['lock']); |
||
| 359 | |||
| 360 | $sortKey = $this->sortKey($options['model']); |
||
| 361 | $defaultModel = $this->defaultModel(); |
||
| 362 | $isSorted = (
|
||
| 363 | $sortKey === $key || |
||
| 364 | $sortKey === $defaultModel . '.' . $key || |
||
| 365 | $key === $defaultModel . '.' . $sortKey |
||
| 366 | ); |
||
| 367 | |||
| 368 | $dir = $defaultDir; |
||
| 369 | if ($isSorted) { |
||
| 370 | $dir = $this->sortDir($options['model']) === 'asc' ? 'desc' : 'asc'; |
||
| 371 | $class = $dir === 'asc' ? 'desc' : 'asc'; |
||
| 372 | if (!empty($options['class'])) { |
||
| 373 | $options['class'] .= ' ' . $class; |
||
| 374 | } else {
|
||
| 375 | $options['class'] = $class; |
||
| 376 | } |
||
| 377 | if ($locked) { |
||
| 378 | $dir = $defaultDir; |
||
| 379 | $options['class'] .= ' locked'; |
||
| 380 | } |
||
| 381 | } |
||
| 382 | if (is_array($title) && array_key_exists($dir, $title)) { |
||
| 383 | $title = $title[$dir]; |
||
| 384 | } |
||
| 385 | |||
| 386 | $url = array_merge(array('sort' => $key, 'direction' => $dir), $url, array('order' => null)); |
||
| 387 | return $this->link($title, $url, $options); |
||
| 388 | } |
||
| 389 | |||
| 390 | /**
|
||
| 391 | * Generates a plain or Ajax link with pagination parameters
|
||
| 392 | *
|
||
| 393 | * ### Options
|
||
| 394 | *
|
||
| 395 | * - `update` The Id of the DOM element you wish to update. Creates Ajax enabled links
|
||
| 396 | * with the AjaxHelper.
|
||
| 397 | * - `escape` Whether you want the contents html entity encoded, defaults to true
|
||
| 398 | * - `model` The model to use, defaults to PaginatorHelper::defaultModel()
|
||
| 399 | *
|
||
| 400 | * @param string $title Title for the link.
|
||
| 401 | * @param string|array $url URL for the action. See Router::url()
|
||
| 402 | * @param array $options Options for the link. See #options for list of keys.
|
||
| 403 | * @return string A link with pagination parameters.
|
||
| 404 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::link
|
||
| 405 | */
|
||
| 406 | public function link($title, $url = array(), $options = array()) { |
||
| 407 | $options += array('model' => null, 'escape' => true); |
||
| 408 | $model = $options['model']; |
||
| 409 | unset($options['model']); |
||
| 410 | |||
| 411 | if (!empty($this->options)) { |
||
| 412 | $options += $this->options; |
||
| 413 | } |
||
| 414 | if (isset($options['url'])) { |
||
| 415 | $url = array_merge((array)$options['url'], (array)$url); |
||
| 416 | unset($options['url']); |
||
| 417 | } |
||
| 418 | unset($options['convertKeys']); |
||
| 419 | |||
| 420 | $url = $this->url($url, true, $model); |
||
| 421 | |||
| 422 | $obj = isset($options['update']) ? $this->_ajaxHelperClass : 'Html'; |
||
| 423 | return $this->{$obj}->link($title, $url, $options); |
||
| 424 | } |
||
| 425 | |||
| 426 | /**
|
||
| 427 | * Merges passed URL options with current pagination state to generate a pagination URL.
|
||
| 428 | *
|
||
| 429 | * @param array $options Pagination/URL options array
|
||
| 430 | * @param bool $asArray Return the URL as an array, or a URI string
|
||
| 431 | * @param string $model Which model to paginate on
|
||
| 432 | * @return mixed By default, returns a full pagination URL string for use in non-standard contexts (i.e. JavaScript)
|
||
| 433 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::url
|
||
| 434 | */
|
||
| 435 | public function url($options = array(), $asArray = false, $model = null) { |
||
| 436 | $paging = $this->params($model); |
||
| 437 | $url = array_merge(array_filter($paging['options']), $options); |
||
| 438 | |||
| 439 | if (isset($url['order'])) { |
||
| 440 | $sort = $direction = null; |
||
| 441 | if (is_array($url['order'])) { |
||
| 442 | list($sort, $direction) = array($this->sortKey($model, $url), current($url['order'])); |
||
| 443 | } |
||
| 444 | unset($url['order']); |
||
| 445 | $url = array_merge($url, compact('sort', 'direction')); |
||
| 446 | } |
||
| 447 | $url = $this->_convertUrlKeys($url, $paging['paramType']); |
||
| 448 | if (!empty($url['page']) && $url['page'] == 1) { |
||
| 449 | $url['page'] = null; |
||
| 450 | } |
||
| 451 | if (!empty($url['?']['page']) && $url['?']['page'] == 1) { |
||
| 452 | unset($url['?']['page']); |
||
| 453 | } |
||
| 454 | if ($asArray) { |
||
| 455 | return $url; |
||
| 456 | } |
||
| 457 | return parent::url($url); |
||
| 458 | } |
||
| 459 | |||
| 460 | /**
|
||
| 461 | * Converts the keys being used into the format set by options.paramType
|
||
| 462 | *
|
||
| 463 | * @param array $url Array of URL params to convert
|
||
| 464 | * @param string $type Keys type.
|
||
| 465 | * @return array converted URL params.
|
||
| 466 | */
|
||
| 467 | protected function _convertUrlKeys($url, $type) { |
||
| 468 | if ($type === 'named') { |
||
| 469 | return $url; |
||
| 470 | } |
||
| 471 | if (!isset($url['?'])) { |
||
| 472 | $url['?'] = array(); |
||
| 473 | } |
||
| 474 | foreach ($this->options['convertKeys'] as $key) { |
||
| 475 | if (isset($url[$key])) { |
||
| 476 | $url['?'][$key] = $url[$key]; |
||
| 477 | unset($url[$key]); |
||
| 478 | } |
||
| 479 | } |
||
| 480 | return $url; |
||
| 481 | } |
||
| 482 | |||
| 483 | /**
|
||
| 484 | * Protected method for generating prev/next links
|
||
| 485 | *
|
||
| 486 | * @param string $which Link type: 'Prev', 'Next'.
|
||
| 487 | * @param string $title Link title.
|
||
| 488 | * @param array $options Options list.
|
||
| 489 | * @param string $disabledTitle Disabled link title.
|
||
| 490 | * @param array $disabledOptions Disabled link options.
|
||
| 491 | * @return string
|
||
| 492 | */
|
||
| 493 | protected function _pagingLink($which, $title = null, $options = array(), $disabledTitle = null, $disabledOptions = array()) { |
||
| 494 | $check = 'has' . $which; |
||
| 495 | $_defaults = array( |
||
| 496 | 'url' => array(), 'step' => 1, 'escape' => true, 'model' => null, |
||
| 497 | 'tag' => 'span', 'class' => strtolower($which), 'disabledTag' => null |
||
| 498 | ); |
||
| 499 | $options = (array)$options + $_defaults; |
||
| 500 | $paging = $this->params($options['model']); |
||
| 501 | if (empty($disabledOptions)) { |
||
| 502 | $disabledOptions = $options; |
||
| 503 | } |
||
| 504 | |||
| 505 | if (!$this->{$check}($options['model']) && (!empty($disabledTitle) || !empty($disabledOptions))) { |
||
| 506 | if (!empty($disabledTitle) && $disabledTitle !== true) { |
||
| 507 | $title = $disabledTitle; |
||
| 508 | } |
||
| 509 | $options = (array)$disabledOptions + array_intersect_key($options, $_defaults) + $_defaults; |
||
| 510 | } elseif (!$this->{$check}($options['model'])) { |
||
| 511 | return ''; |
||
| 512 | } |
||
| 513 | |||
| 514 | foreach (array_keys($_defaults) as $key) { |
||
| 515 | ${$key} = $options[$key];
|
||
| 516 | unset($options[$key]); |
||
| 517 | } |
||
| 518 | |||
| 519 | if ($this->{$check}($model)) { |
||
| 520 | $url = array_merge( |
||
| 521 | array('page' => $paging['page'] + ($which === 'Prev' ? $step * -1 : $step)), |
||
| 522 | $url
|
||
| 523 | ); |
||
| 524 | if ($tag === false) { |
||
| 525 | return $this->link( |
||
| 526 | $title,
|
||
| 527 | $url,
|
||
| 528 | compact('escape', 'model', 'class') + $options |
||
| 529 | ); |
||
| 530 | } |
||
| 531 | $link = $this->link($title, $url, compact('escape', 'model') + $options); |
||
| 532 | return $this->Html->tag($tag, $link, compact('class')); |
||
| 533 | } |
||
| 534 | unset($options['rel']); |
||
| 535 | if (!$tag) { |
||
| 536 | if ($disabledTag) { |
||
| 537 | $tag = $disabledTag; |
||
| 538 | $disabledTag = null; |
||
| 539 | } else {
|
||
| 540 | $tag = $_defaults['tag']; |
||
| 541 | } |
||
| 542 | } |
||
| 543 | if ($disabledTag) { |
||
| 544 | $title = $this->Html->tag($disabledTag, $title, compact('escape') + $options); |
||
| 545 | return $this->Html->tag($tag, $title, compact('class')); |
||
| 546 | } |
||
| 547 | return $this->Html->tag($tag, $title, compact('escape', 'class') + $options); |
||
| 548 | } |
||
| 549 | |||
| 550 | /**
|
||
| 551 | * Returns true if the given result set is not at the first page
|
||
| 552 | *
|
||
| 553 | * @param string $model Optional model name. Uses the default if none is specified.
|
||
| 554 | * @return bool True if the result set is not at the first page.
|
||
| 555 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::hasPrev
|
||
| 556 | */
|
||
| 557 | public function hasPrev($model = null) { |
||
| 558 | return $this->_hasPage($model, 'prev'); |
||
| 559 | } |
||
| 560 | |||
| 561 | /**
|
||
| 562 | * Returns true if the given result set is not at the last page
|
||
| 563 | *
|
||
| 564 | * @param string $model Optional model name. Uses the default if none is specified.
|
||
| 565 | * @return bool True if the result set is not at the last page.
|
||
| 566 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::hasNext
|
||
| 567 | */
|
||
| 568 | public function hasNext($model = null) { |
||
| 569 | return $this->_hasPage($model, 'next'); |
||
| 570 | } |
||
| 571 | |||
| 572 | /**
|
||
| 573 | * Returns true if the given result set has the page number given by $page
|
||
| 574 | *
|
||
| 575 | * @param string $model Optional model name. Uses the default if none is specified.
|
||
| 576 | * @param int $page The page number - if not set defaults to 1.
|
||
| 577 | * @return bool True if the given result set has the specified page number.
|
||
| 578 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::hasPage
|
||
| 579 | */
|
||
| 580 | public function hasPage($model = null, $page = 1) { |
||
| 581 | if (is_numeric($model)) { |
||
| 582 | $page = $model; |
||
| 583 | $model = null; |
||
| 584 | } |
||
| 585 | $paging = $this->params($model); |
||
| 586 | return $page <= $paging['pageCount']; |
||
| 587 | } |
||
| 588 | |||
| 589 | /**
|
||
| 590 | * Does $model have $page in its range?
|
||
| 591 | *
|
||
| 592 | * @param string $model Model name to get parameters for.
|
||
| 593 | * @param int $page Page number you are checking.
|
||
| 594 | * @return bool Whether model has $page
|
||
| 595 | */
|
||
| 596 | protected function _hasPage($model, $page) { |
||
| 597 | $params = $this->params($model); |
||
| 598 | return !empty($params) && $params[$page . 'Page']; |
||
| 599 | } |
||
| 600 | |||
| 601 | /**
|
||
| 602 | * Gets the default model of the paged sets
|
||
| 603 | *
|
||
| 604 | * @return string|null Model name or null if the pagination isn't initialized.
|
||
| 605 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::defaultModel
|
||
| 606 | */
|
||
| 607 | public function defaultModel() { |
||
| 608 | if ($this->_defaultModel) { |
||
| 609 | return $this->_defaultModel; |
||
| 610 | } |
||
| 611 | if (empty($this->request->params['paging'])) { |
||
| 612 | return null; |
||
| 613 | } |
||
| 614 | list($this->_defaultModel) = array_keys($this->request->params['paging']); |
||
| 615 | return $this->_defaultModel; |
||
| 616 | } |
||
| 617 | |||
| 618 | /**
|
||
| 619 | * Returns a counter string for the paged result set
|
||
| 620 | *
|
||
| 621 | * ### Options
|
||
| 622 | *
|
||
| 623 | * - `model` The model to use, defaults to PaginatorHelper::defaultModel();
|
||
| 624 | * - `format` The format string you want to use, defaults to 'pages' Which generates output like '1 of 5'
|
||
| 625 | * set to 'range' to generate output like '1 - 3 of 13'. Can also be set to a custom string, containing
|
||
| 626 | * the following placeholders `{:page}`, `{:pages}`, `{:current}`, `{:count}`, `{:model}`, `{:start}`, `{:end}` and any
|
||
| 627 | * custom content you would like.
|
||
| 628 | * - `separator` The separator string to use, default to ' of '
|
||
| 629 | *
|
||
| 630 | * The `%page%` style placeholders also work, but are deprecated and will be removed in a future version.
|
||
| 631 | *
|
||
| 632 | * @param array $options Options for the counter string. See #options for list of keys.
|
||
| 633 | * @return string Counter string.
|
||
| 634 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::counter
|
||
| 635 | */
|
||
| 636 | public function counter($options = array()) { |
||
| 637 | if (is_string($options)) { |
||
| 638 | $options = array('format' => $options); |
||
| 639 | } |
||
| 640 | |||
| 641 | $options += array( |
||
| 642 | 'model' => $this->defaultModel(), |
||
| 643 | 'format' => 'pages', |
||
| 644 | 'separator' => __d('cake', ' of ') |
||
| 645 | ); |
||
| 646 | |||
| 647 | $paging = $this->params($options['model']); |
||
| 648 | if (!$paging['pageCount']) { |
||
| 649 | $paging['pageCount'] = 1; |
||
| 650 | } |
||
| 651 | $start = 0; |
||
| 652 | if ($paging['count'] >= 1) { |
||
| 653 | $start = (($paging['page'] - 1) * $paging['limit']) + 1; |
||
| 654 | } |
||
| 655 | $end = $start + $paging['limit'] - 1; |
||
| 656 | if ($paging['count'] < $end) { |
||
| 657 | $end = $paging['count']; |
||
| 658 | } |
||
| 659 | |||
| 660 | switch ($options['format']) { |
||
| 661 | case 'range': |
||
| 662 | if (!is_array($options['separator'])) { |
||
| 663 | $options['separator'] = array(' - ', $options['separator']); |
||
| 664 | } |
||
| 665 | $out = $start . $options['separator'][0] . $end . $options['separator'][1]; |
||
| 666 | $out .= $paging['count']; |
||
| 667 | break;
|
||
| 668 | case 'pages': |
||
| 669 | $out = $paging['page'] . $options['separator'] . $paging['pageCount']; |
||
| 670 | break;
|
||
| 671 | default:
|
||
| 672 | $map = array( |
||
| 673 | '%page%' => $paging['page'], |
||
| 674 | '%pages%' => $paging['pageCount'], |
||
| 675 | '%current%' => $paging['current'], |
||
| 676 | '%count%' => $paging['count'], |
||
| 677 | '%start%' => $start, |
||
| 678 | '%end%' => $end, |
||
| 679 | '%model%' => strtolower(Inflector::humanize(Inflector::tableize($options['model']))) |
||
| 680 | ); |
||
| 681 | $out = str_replace(array_keys($map), array_values($map), $options['format']); |
||
| 682 | |||
| 683 | $newKeys = array( |
||
| 684 | '{:page}', '{:pages}', '{:current}', '{:count}', '{:start}', '{:end}', '{:model}' |
||
| 685 | ); |
||
| 686 | $out = str_replace($newKeys, array_values($map), $out); |
||
| 687 | } |
||
| 688 | return $out; |
||
| 689 | } |
||
| 690 | |||
| 691 | /**
|
||
| 692 | * Returns a set of numbers for the paged result set
|
||
| 693 | * uses a modulus to decide how many numbers to show on each side of the current page (default: 8).
|
||
| 694 | *
|
||
| 695 | * `$this->Paginator->numbers(array('first' => 2, 'last' => 2));`
|
||
| 696 | *
|
||
| 697 | * Using the first and last options you can create links to the beginning and end of the page set.
|
||
| 698 | *
|
||
| 699 | * ### Options
|
||
| 700 | *
|
||
| 701 | * - `before` Content to be inserted before the numbers
|
||
| 702 | * - `after` Content to be inserted after the numbers
|
||
| 703 | * - `model` Model to create numbers for, defaults to PaginatorHelper::defaultModel()
|
||
| 704 | * - `modulus` how many numbers to include on either side of the current page, defaults to 8.
|
||
| 705 | * - `separator` Separator content defaults to ' | '
|
||
| 706 | * - `tag` The tag to wrap links in, defaults to 'span'
|
||
| 707 | * - `first` Whether you want first links generated, set to an integer to define the number of 'first'
|
||
| 708 | * links to generate. If a string is set a link to the first page will be generated with the value
|
||
| 709 | * as the title.
|
||
| 710 | * - `last` Whether you want last links generated, set to an integer to define the number of 'last'
|
||
| 711 | * links to generate. If a string is set a link to the last page will be generated with the value
|
||
| 712 | * as the title.
|
||
| 713 | * - `ellipsis` Ellipsis content, defaults to '...'
|
||
| 714 | * - `class` Class for wrapper tag
|
||
| 715 | * - `currentClass` Class for wrapper tag on current active page, defaults to 'current'
|
||
| 716 | * - `currentTag` Tag to use for current page number, defaults to null
|
||
| 717 | *
|
||
| 718 | * @param array|bool $options Options for the numbers, (before, after, model, modulus, separator)
|
||
| 719 | * @return string Numbers string.
|
||
| 720 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::numbers
|
||
| 721 | */
|
||
| 722 | public function numbers($options = array()) { |
||
| 723 | if ($options === true) { |
||
| 724 | $options = array( |
||
| 725 | 'before' => ' | ', 'after' => ' | ', 'first' => 'first', 'last' => 'last' |
||
| 726 | ); |
||
| 727 | } |
||
| 728 | |||
| 729 | $defaults = array( |
||
| 730 | 'tag' => 'span', 'before' => null, 'after' => null, 'model' => $this->defaultModel(), 'class' => null, |
||
| 731 | 'modulus' => '8', 'separator' => ' | ', 'first' => null, 'last' => null, 'ellipsis' => '...', |
||
| 732 | 'currentClass' => 'current', 'currentTag' => null |
||
| 733 | ); |
||
| 734 | $options += $defaults; |
||
| 735 | |||
| 736 | $params = (array)$this->params($options['model']) + array('page' => 1); |
||
| 737 | unset($options['model']); |
||
| 738 | |||
| 739 | if (empty($params['pageCount']) || $params['pageCount'] <= 1) { |
||
| 740 | return ''; |
||
| 741 | } |
||
| 742 | |||
| 743 | extract($options); |
||
| 744 | unset($options['tag'], $options['before'], $options['after'], $options['model'], |
||
| 745 | $options['modulus'], $options['separator'], $options['first'], $options['last'], |
||
| 746 | $options['ellipsis'], $options['class'], $options['currentClass'], $options['currentTag'] |
||
| 747 | ); |
||
| 748 | $out = ''; |
||
| 749 | |||
| 750 | if ($modulus && $params['pageCount'] > $modulus) { |
||
| 751 | $half = (int)($modulus / 2); |
||
| 752 | $end = $params['page'] + $half; |
||
| 753 | |||
| 754 | if ($end > $params['pageCount']) { |
||
| 755 | $end = $params['pageCount']; |
||
| 756 | } |
||
| 757 | $start = $params['page'] - ($modulus - ($end - $params['page'])); |
||
| 758 | if ($start <= 1) { |
||
| 759 | $start = 1; |
||
| 760 | $end = $params['page'] + ($modulus - $params['page']) + 1; |
||
| 761 | } |
||
| 762 | |||
| 763 | $firstPage = is_int($first) ? $first : 0; |
||
| 764 | if ($first && $start > 1) { |
||
| 765 | $offset = ($start <= $firstPage) ? $start - 1 : $first; |
||
| 766 | if ($firstPage < $start - 1) { |
||
| 767 | $out .= $this->first($offset, compact('tag', 'separator', 'ellipsis', 'class')); |
||
| 768 | } else {
|
||
| 769 | $out .= $this->first($offset, compact('tag', 'separator', 'class', 'ellipsis') + array('after' => $separator)); |
||
| 770 | } |
||
| 771 | } |
||
| 772 | |||
| 773 | $out .= $before; |
||
| 774 | |||
| 775 | for ($i = $start; $i < $params['page']; $i++) { |
||
| 776 | $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class')) . $separator; |
||
| 777 | } |
||
| 778 | |||
| 779 | if ($class) { |
||
| 780 | $currentClass .= ' ' . $class; |
||
| 781 | } |
||
| 782 | if ($currentTag) { |
||
| 783 | $out .= $this->Html->tag($tag, $this->Html->tag($currentTag, $params['page']), array('class' => $currentClass)); |
||
| 784 | } else {
|
||
| 785 | $out .= $this->Html->tag($tag, $params['page'], array('class' => $currentClass)); |
||
| 786 | } |
||
| 787 | if ($i != $params['pageCount']) { |
||
| 788 | $out .= $separator; |
||
| 789 | } |
||
| 790 | |||
| 791 | $start = $params['page'] + 1; |
||
| 792 | for ($i = $start; $i < $end; $i++) { |
||
| 793 | $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class')) . $separator; |
||
| 794 | } |
||
| 795 | |||
| 796 | if ($end != $params['page']) { |
||
| 797 | $out .= $this->Html->tag($tag, $this->link($i, array('page' => $end), $options), compact('class')); |
||
| 798 | } |
||
| 799 | |||
| 800 | $out .= $after; |
||
| 801 | |||
| 802 | if ($last && $end < $params['pageCount']) { |
||
| 803 | $lastPage = is_int($last) ? $last : 0; |
||
| 804 | $offset = ($params['pageCount'] < $end + $lastPage) ? $params['pageCount'] - $end : $last; |
||
| 805 | if ($offset <= $lastPage && $params['pageCount'] - $end > $lastPage) { |
||
| 806 | $out .= $this->last($offset, compact('tag', 'separator', 'ellipsis', 'class')); |
||
| 807 | } else {
|
||
| 808 | $out .= $this->last($offset, compact('tag', 'separator', 'class', 'ellipsis') + array('before' => $separator)); |
||
| 809 | } |
||
| 810 | } |
||
| 811 | |||
| 812 | } else {
|
||
| 813 | $out .= $before; |
||
| 814 | |||
| 815 | for ($i = 1; $i <= $params['pageCount']; $i++) { |
||
| 816 | if ($i == $params['page']) { |
||
| 817 | if ($class) { |
||
| 818 | $currentClass .= ' ' . $class; |
||
| 819 | } |
||
| 820 | if ($currentTag) { |
||
| 821 | $out .= $this->Html->tag($tag, $this->Html->tag($currentTag, $i), array('class' => $currentClass)); |
||
| 822 | } else {
|
||
| 823 | $out .= $this->Html->tag($tag, $i, array('class' => $currentClass)); |
||
| 824 | } |
||
| 825 | } else {
|
||
| 826 | $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class')); |
||
| 827 | } |
||
| 828 | if ($i != $params['pageCount']) { |
||
| 829 | $out .= $separator; |
||
| 830 | } |
||
| 831 | } |
||
| 832 | |||
| 833 | $out .= $after; |
||
| 834 | } |
||
| 835 | |||
| 836 | return $out; |
||
| 837 | } |
||
| 838 | |||
| 839 | /**
|
||
| 840 | * Returns a first or set of numbers for the first pages.
|
||
| 841 | *
|
||
| 842 | * `echo $this->Paginator->first('< first');`
|
||
| 843 | *
|
||
| 844 | * Creates a single link for the first page. Will output nothing if you are on the first page.
|
||
| 845 | *
|
||
| 846 | * `echo $this->Paginator->first(3);`
|
||
| 847 | *
|
||
| 848 | * Will create links for the first 3 pages, once you get to the third or greater page. Prior to that
|
||
| 849 | * nothing will be output.
|
||
| 850 | *
|
||
| 851 | * ### Options:
|
||
| 852 | *
|
||
| 853 | * - `tag` The tag wrapping tag you want to use, defaults to 'span'
|
||
| 854 | * - `after` Content to insert after the link/tag
|
||
| 855 | * - `model` The model to use defaults to PaginatorHelper::defaultModel()
|
||
| 856 | * - `separator` Content between the generated links, defaults to ' | '
|
||
| 857 | * - `ellipsis` Content for ellipsis, defaults to '...'
|
||
| 858 | *
|
||
| 859 | * @param string|int $first if string use as label for the link. If numeric, the number of page links
|
||
| 860 | * you want at the beginning of the range.
|
||
| 861 | * @param array $options An array of options.
|
||
| 862 | * @return string Numbers string.
|
||
| 863 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::first
|
||
| 864 | */
|
||
| 865 | public function first($first = '<< first', $options = array()) { |
||
| 866 | $options = (array)$options + array( |
||
| 867 | 'tag' => 'span', |
||
| 868 | 'after' => null, |
||
| 869 | 'model' => $this->defaultModel(), |
||
| 870 | 'separator' => ' | ', |
||
| 871 | 'ellipsis' => '...', |
||
| 872 | 'class' => null |
||
| 873 | ); |
||
| 874 | |||
| 875 | $params = array_merge(array('page' => 1), (array)$this->params($options['model'])); |
||
| 876 | unset($options['model']); |
||
| 877 | |||
| 878 | if ($params['pageCount'] <= 1) { |
||
| 879 | return ''; |
||
| 880 | } |
||
| 881 | extract($options); |
||
| 882 | unset($options['tag'], $options['after'], $options['model'], $options['separator'], $options['ellipsis'], $options['class']); |
||
| 883 | |||
| 884 | $out = ''; |
||
| 885 | |||
| 886 | if ((is_int($first) || ctype_digit($first)) && $params['page'] >= $first) { |
||
| 887 | if ($after === null) { |
||
| 888 | $after = $ellipsis; |
||
| 889 | } |
||
| 890 | for ($i = 1; $i <= $first; $i++) { |
||
| 891 | $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class')); |
||
| 892 | if ($i != $first) { |
||
| 893 | $out .= $separator; |
||
| 894 | } |
||
| 895 | } |
||
| 896 | $out .= $after; |
||
| 897 | } elseif ($params['page'] > 1 && is_string($first)) { |
||
| 898 | $options += array('rel' => 'first'); |
||
| 899 | $out = $this->Html->tag($tag, $this->link($first, array('page' => 1), $options), compact('class')) . $after; |
||
| 900 | } |
||
| 901 | return $out; |
||
| 902 | } |
||
| 903 | |||
| 904 | /**
|
||
| 905 | * Returns a last or set of numbers for the last pages.
|
||
| 906 | *
|
||
| 907 | * `echo $this->Paginator->last('last >');`
|
||
| 908 | *
|
||
| 909 | * Creates a single link for the last page. Will output nothing if you are on the last page.
|
||
| 910 | *
|
||
| 911 | * `echo $this->Paginator->last(3);`
|
||
| 912 | *
|
||
| 913 | * Will create links for the last 3 pages. Once you enter the page range, no output will be created.
|
||
| 914 | *
|
||
| 915 | * ### Options:
|
||
| 916 | *
|
||
| 917 | * - `tag` The tag wrapping tag you want to use, defaults to 'span'
|
||
| 918 | * - `before` Content to insert before the link/tag
|
||
| 919 | * - `model` The model to use defaults to PaginatorHelper::defaultModel()
|
||
| 920 | * - `separator` Content between the generated links, defaults to ' | '
|
||
| 921 | * - `ellipsis` Content for ellipsis, defaults to '...'
|
||
| 922 | *
|
||
| 923 | * @param string|int $last if string use as label for the link, if numeric print page numbers
|
||
| 924 | * @param array $options Array of options
|
||
| 925 | * @return string Numbers string.
|
||
| 926 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::last
|
||
| 927 | */
|
||
| 928 | public function last($last = 'last >>', $options = array()) { |
||
| 929 | $options = (array)$options + array( |
||
| 930 | 'tag' => 'span', |
||
| 931 | 'before' => null, |
||
| 932 | 'model' => $this->defaultModel(), |
||
| 933 | 'separator' => ' | ', |
||
| 934 | 'ellipsis' => '...', |
||
| 935 | 'class' => null |
||
| 936 | ); |
||
| 937 | |||
| 938 | $params = array_merge(array('page' => 1), (array)$this->params($options['model'])); |
||
| 939 | unset($options['model']); |
||
| 940 | |||
| 941 | if ($params['pageCount'] <= 1) { |
||
| 942 | return ''; |
||
| 943 | } |
||
| 944 | |||
| 945 | extract($options); |
||
| 946 | unset($options['tag'], $options['before'], $options['model'], $options['separator'], $options['ellipsis'], $options['class']); |
||
| 947 | |||
| 948 | $out = ''; |
||
| 949 | $lower = $params['pageCount'] - $last + 1; |
||
| 950 | |||
| 951 | if ((is_int($last) || ctype_digit($last)) && $params['page'] <= $lower) { |
||
| 952 | if ($before === null) { |
||
| 953 | $before = $ellipsis; |
||
| 954 | } |
||
| 955 | for ($i = $lower; $i <= $params['pageCount']; $i++) { |
||
| 956 | $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class')); |
||
| 957 | if ($i != $params['pageCount']) { |
||
| 958 | $out .= $separator; |
||
| 959 | } |
||
| 960 | } |
||
| 961 | $out = $before . $out; |
||
| 962 | } elseif ($params['page'] < $params['pageCount'] && is_string($last)) { |
||
| 963 | $options += array('rel' => 'last'); |
||
| 964 | $out = $before . $this->Html->tag( |
||
| 965 | $tag, $this->link($last, array('page' => $params['pageCount']), $options), compact('class') |
||
| 966 | ); |
||
| 967 | } |
||
| 968 | return $out; |
||
| 969 | } |
||
| 970 | |||
| 971 | /**
|
||
| 972 | * Returns the meta-links for a paginated result set.
|
||
| 973 | *
|
||
| 974 | * `echo $this->Paginator->meta();`
|
||
| 975 | *
|
||
| 976 | * Echos the links directly, will output nothing if there is neither a previous nor next page.
|
||
| 977 | *
|
||
| 978 | * `$this->Paginator->meta(array('block' => true));`
|
||
| 979 | *
|
||
| 980 | * Will append the output of the meta function to the named block - if true is passed the "meta"
|
||
| 981 | * block is used.
|
||
| 982 | *
|
||
| 983 | * ### Options:
|
||
| 984 | *
|
||
| 985 | * - `model` The model to use defaults to PaginatorHelper::defaultModel()
|
||
| 986 | * - `block` The block name to append the output to, or false/absent to return as a string
|
||
| 987 | *
|
||
| 988 | * @param array $options Array of options.
|
||
| 989 | * @return string|null Meta links.
|
||
| 990 | */
|
||
| 991 | public function meta($options = array()) { |
||
| 992 | $model = isset($options['model']) ? $options['model'] : null; |
||
| 993 | $params = $this->params($model); |
||
| 994 | $urlOptions = isset($this->options['url']) ? $this->options['url'] : array(); |
||
| 995 | $links = array(); |
||
| 996 | if ($this->hasPrev()) { |
||
| 997 | $links[] = $this->Html->meta(array( |
||
| 998 | 'rel' => 'prev', |
||
| 999 | 'link' => $this->url(array_merge($urlOptions, array('page' => $params['page'] - 1)), true) |
||
| 1000 | )); |
||
| 1001 | } |
||
| 1002 | if ($this->hasNext()) { |
||
| 1003 | $links[] = $this->Html->meta(array( |
||
| 1004 | 'rel' => 'next', |
||
| 1005 | 'link' => $this->url(array_merge($urlOptions, array('page' => $params['page'] + 1)), true) |
||
| 1006 | )); |
||
| 1007 | } |
||
| 1008 | $out = implode($links); |
||
| 1009 | if (empty($options['block'])) { |
||
| 1010 | return $out; |
||
| 1011 | } |
||
| 1012 | if ($options['block'] === true) { |
||
| 1013 | $options['block'] = __FUNCTION__; |
||
| 1014 | } |
||
| 1015 | $this->_View->append($options['block'], $out); |
||
| 1016 | } |
||
| 1017 | |||
| 1018 | } |