Skip to content
Permalink
Browse files

Implement mulitple paginators

This change provides the initial support for multiple paginators on a given page.

To use it, you can do something like the following in your controller layer:

```php
$users = $this->paginate($this->Users->find(), ['prefix' => 'users']);
$categories = $this->paginate($this->Categories->find(), ['prefix' => 'categories']);

$this->set(compact('users', 'categories'));
```

The in your view layer, specify the model option whenever the `PaginatorHelper` allows you to set options.

Closes #1731
  • Loading branch information...
josegonzalez authored and markstory committed Mar 18, 2016
1 parent 3b3a8b7 commit ed233e7167f2b693c90fa30fbba0d1ba58d3ec6d
@@ -18,6 +18,7 @@
use Cake\Datasource\QueryInterface;
use Cake\Datasource\RepositoryInterface;
use Cake\Network\Exception\NotFoundException;
use Cake\Utility\Hash;
/**
* This component is used to handle automatic model data pagination. The primary way to use this
@@ -202,7 +203,8 @@ public function paginate($object, array $settings = [])
'direction' => current($order),
'limit' => $defaults['limit'] != $limit ? $limit : null,
'sortDefault' => $sortDefault,
'directionDefault' => $directionDefault
'directionDefault' => $directionDefault,
'prefix' => Hash::get($options, 'prefix', null),
];
if (!isset($request['paging'])) {
@@ -257,7 +259,12 @@ public function mergeOptions($alias, $settings)
{
$defaults = $this->getDefaults($alias, $settings);
$request = $this->_registry->getController()->request;
$request = array_intersect_key($request->query, array_flip($this->_config['whitelist']));
$prefix = Hash::get($settings, 'prefix', null);
$query = $request->query;
if ($prefix) {
$query = Hash::get($request->query, $prefix, []);
}
$request = array_intersect_key($query, array_flip($this->_config['whitelist']));
return array_merge($defaults, $request);
}
@@ -671,11 +671,12 @@ public function referer($default = null, $local = false)
*
* @param \Cake\ORM\Table|string|\Cake\ORM\Query|null $object Table to paginate
* (e.g: Table instance, 'TableName' or a Query object)
* @param array $settings The settings/configuration used for pagination.
* @return \Cake\ORM\ResultSet Query results
* @link http://book.cakephp.org/3.0/en/controllers.html#paginating-a-model
* @throws \RuntimeException When no compatible table object can be found.
*/
public function paginate($object = null)
public function paginate($object = null, array $settings = [])
{
if (is_object($object)) {
$table = $object;
@@ -696,7 +697,8 @@ public function paginate($object = null)
if (empty($table)) {
throw new RuntimeException('Unable to locate an object compatible with paginate.');
}
return $this->Paginator->paginate($table, $this->paginate);
$settings = $settings + $this->paginate;
return $this->Paginator->paginate($table, $settings);
}
/**
@@ -14,6 +14,7 @@
*/
namespace Cake\View\Helper;
use Cake\Utility\Hash;
use Cake\Utility\Inflector;
use Cake\View\Helper;
use Cake\View\StringTemplateTrait;
@@ -165,6 +166,12 @@ public function options(array $options = [])
unset($options[$model]);
}
$this->_config['options'] = array_filter($options + $this->_config['options']);
if (empty($this->_config['options']['url'])) {
$this->_config['options']['url'] = [];
}
if (!empty($this->_config['options']['model'])) {
$this->defaultModel($this->_config['options']['model']);
}
}
/**
@@ -412,10 +419,16 @@ public function sort($key, $title = null, array $options = [])
$sortKey = $this->sortKey($options['model']);
$defaultModel = $this->defaultModel();
$model = Hash::get($options, 'model', $defaultModel);
list($table, $field) = explode('.', $key . '.');
if (!$field) {
$field = $table;
$table = $model;
}
$isSorted = (
$sortKey === $key ||
$sortKey === $table . '.' . $field ||
$sortKey === $defaultModel . '.' . $key ||
$key === $defaultModel . '.' . $sortKey
$table . '.' . $field === $defaultModel . '.' . $sortKey
);
$template = 'sort';
@@ -465,7 +478,8 @@ public function generateUrl(array $options = [], $model = null, $full = false)
];
if (!empty($this->_config['options']['url'])) {
$url = array_merge($url, $this->_config['options']['url']);
$key = implode('.', array_filter(['options.url', Hash::get($paging, 'prefix', null)]));
$url = array_merge($url, Hash::get($this->_config, $key, []));
}
$url = array_filter($url, function ($value) {
@@ -482,6 +496,12 @@ public function generateUrl(array $options = [], $model = null, $full = false)
) {
$url['sort'] = $url['direction'] = null;
}
if (!empty($paging['prefix'])) {
$url = [$paging['prefix'] => $url] + $this->_config['options']['url'];
if (empty($url[$paging['prefix']]['page'])) {
unset($url[$paging['prefix']]['page']);
}
}
return $this->Url->build($url, $full);
}
@@ -544,12 +564,16 @@ protected function _hasPage($model, $page)
}
/**
* Gets the default model of the paged sets
* Gets or sets the default model of the paged sets
*
* @param string|null $model Model name to set
* @return string|null Model name or null if the pagination isn't initialized.
*/
public function defaultModel()
public function defaultModel($model = null)
{
if ($model !== null) {
$this->_defaultModel = $model;
}
if ($this->_defaultModel) {
return $this->_defaultModel;
}

0 comments on commit ed233e7

Please sign in to comment.
You can’t perform that action at this time.