Skip to content

Instantly share code, notes, and snippets.

@burzum
Created August 21, 2017 10:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save burzum/31bc2d672b75d7de52960f92de8f1325 to your computer and use it in GitHub Desktop.
Save burzum/31bc2d672b75d7de52960f92de8f1325 to your computer and use it in GitHub Desktop.
CakePHP ES Paginator
<?php
declare(strict_types=1);
namespace App\Datasource;
use Cake\Datasource\Paginator;
use Cake\Datasource\RepositoryInterface;
use Cake\ElasticSearch\Query;
use Cake\Network\Exception\NotFoundException;
/**
* Elastic Paginator Component
*
* @link https://gist.github.com/lorenzo/53e74a85fe9b4eaa6860
*/
class ElasticPaginator extends Paginator {
/**
* Events supported by this component.
*
* @return array
*/
public function implementedEvents() {
return [];
}
/**
* Elastic Pagination
*
* @param \Cake\Datasource\RepositoryInterface|\Cake\Datasource\QueryInterface $object The table or query to paginate.
* @param array $params Request params
* @param array $settings The settings/configuration used for pagination.
* @return \Cake\Datasource\ResultSetInterface Query results
* @throws \Cake\ORM\Exception\PageOutOfBoundsException
*/
public function paginate($object, array $params = [], array $settings = []) {
if ($object instanceof Query) {
$query = $object;
$object = $query->repository();
}
$alias = $object->getAlias();
$options = $this->mergeOptions($params, $settings);
$options = $this->validateSort($object, $options);
$options = $this->checkLimit($options);
$options += ['page' => 1];
$options['page'] = (int)$options['page'] < 1 ? 1 : (int)$options['page'];
list($finder, $options) = $this->_extractFinder($options);
if (empty($query)) {
$query = $object->find($finder, $options);
} else {
$query->applyOptions($options);
}
$results = $query->all();
$numResults = $results->count();
$count = $numResults ? $results->getTotalHits() : 0;
$defaults = $this->getDefaults($alias, $settings);
unset($defaults[0]);
$page = $options['page'];
$limit = $options['limit'];
$pageCount = (int)ceil($count / $limit);
$requestedPage = $page;
$page = max(min($page, $pageCount), 1);
$order = (array)$options['order'];
$sortDefault = $directionDefault = false;
if (!empty($defaults['order']) && count($defaults['order']) == 1) {
$sortDefault = key($defaults['order']);
$directionDefault = current($defaults['order']);
}
$paging = [
'finder' => $finder,
'page' => $page,
'current' => $numResults,
'count' => $count,
'perPage' => $limit,
'prevPage' => ($page > 1),
'nextPage' => ($count > ($page * $limit)),
'pageCount' => $pageCount,
'sort' => key($order),
'direction' => current($order),
'limit' => $defaults['limit'] != $limit ? $limit : null,
'maxLimit' => 100,
'sortDefault' => $sortDefault,
'directionDefault' => $directionDefault
];
if (!isset($params['paging'])) {
$params['paging'] = [];
}
$params['paging'] = [$alias => $paging] + (array)$params['paging'];
if ($requestedPage > $page) {
throw new NotFoundException(__d('wa', 'The page number {0} does not exist!', $requestedPage));
}
return $results;
}
/**
* Prefixes the field with the type alias if possible.
*
* @param \Cake\Datasource\RepositoryInterface $object Repository object.
* @param array $order Order array.
* @param bool $whitelisted Whether or not the field was whitelisted
* @return array Final order array.
*/
protected function _prefix(RepositoryInterface $object, $order, $whitelisted = false) {
return $order;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment