Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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 Jul 2, 2016
1 parent 3b3a8b7 commit ed233e7
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 9 deletions.
11 changes: 9 additions & 2 deletions src/Controller/Component/PaginatorComponent.php
Expand Up @@ -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
Expand Down Expand Up @@ -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'])) {
Expand Down Expand Up @@ -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);
}

Expand Down
6 changes: 4 additions & 2 deletions src/Controller/Controller.php
Expand Up @@ -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;
Expand All @@ -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);
}

/**
Expand Down
34 changes: 29 additions & 5 deletions src/View/Helper/PaginatorHelper.php
Expand Up @@ -14,6 +14,7 @@
*/
namespace Cake\View\Helper;

use Cake\Utility\Hash;
use Cake\Utility\Inflector;
use Cake\View\Helper;
use Cake\View\StringTemplateTrait;
Expand Down Expand Up @@ -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']);
}
}

/**
Expand Down Expand Up @@ -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';
Expand Down Expand Up @@ -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) {
Expand All @@ -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);
}

Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit ed233e7

Please sign in to comment.