src/Collection.php
<?php
/**
* Collection.php
*
* @author Angel S. Moreno <angelxmoreno@gmail.com>
* @copyright 2017 AngelXMoreno
* @license http://www.spdx.org/licenses/MIT MIT License
* @see https://github.com/angelxmoreno/phalcon-collection-paginator
*/
namespace Phalcon\Paginator\Adapter;
use Phalcon\Mvc\Collection as CollectionModel;
use Phalcon\Paginator\AdapterInterface as PaginatorInterface;
use Phalcon\Paginator\Exception as PaginatorException;
/**
* Class Collection
*
* @package Phalcon\Paginator\Adapter
* @author Angel S. Moreno <angelxmoreno@gmail.com>
* @license http://www.spdx.org/licenses/MIT MIT License
*/
class Collection implements PaginatorInterface
{
const DEFAULT_LIMIT = 30;
const MISSING_COLLECTION = 'Missing Collection';
/**
* @var CollectionModel
*/
protected $collection;
/**
* @var integer
*/
protected $limit;
/**
* @var array
*/
protected $find_query;
/**
* @var integer
*/
protected $current_page;
/**
* Collection Adapter constructor
*
* @param array $config
*
* @throws PaginatorException
*/
public function __construct(array $config)
{
$limit = isset($config['limit']) ? $config['limit'] : self::DEFAULT_LIMIT;
if (!isset($config['collection'])) {
throw new PaginatorException(self::MISSING_COLLECTION);
}
$collection = $config['collection'];
$find_query = isset($config['find_query']) ? $config['find_query'] : [];
$current_page = (isset($config['current_page']))
? $config['current_page']
: (isset($config['page']) ? $config['page'] : 1);
$this->setLimit($limit);
$this->setCollection($collection);
$this->setFindQuery($find_query);
$this->setCurrentPage($current_page);
}
/**
* Returns a slice of the resultset to show in the pagination
*
* @return \stdClass
*/
public function getPaginate()
{
$find_query = $this->buildQuery();
$collection = $this->getCollection();
$result = $this->paginate($collection, $find_query);
return $this->createPaginationDataObj($result);
}
/**
* @return array
*/
protected function buildQuery()
{
$find_query = $this->getFindQuery();
$find_query['limit'] = $this->getLimit();
$find_query['skip'] = ($this->getCurrentPage() - 1) * $this->getLimit();
return $find_query;
}
/**
* @param string|CollectionModel $collection
* @param array $query
* @return array
*/
protected function paginate($collection, array $query)
{
return $collection::find($query);
}
/**
* @return int
*/
public function getLimit()
{
return $this->limit;
}
/**
* @param int $limit
* @return void
*/
public function setLimit($limit)
{
$this->limit = (int)$limit;
}
/**
* @return string|CollectionModel
*/
public function getCollection()
{
return $this->collection;
}
/**
* @param string|CollectionModel $collection
* @return void
*/
public function setCollection($collection)
{
$this->collection = $collection;
}
/**
* @return array
*/
public function getFindQuery()
{
return $this->find_query;
}
/**
* @param array $find_query
* @return void
*/
public function setFindQuery(array $find_query)
{
$this->find_query = $find_query;
}
/**
* @return int
*/
public function getCurrentPage()
{
return $this->current_page;
}
/**
* @param int $current_page
* @return void
*/
public function setCurrentPage($current_page)
{
$this->current_page = (int)$current_page;
}
/**
* @return integer
*/
protected function calcTotalItemsCount()
{
$collection = $this->getCollection();
return (int)$collection::count($this->getFindQuery());
}
/**
* @param integer $total_items
*
* @return integer
*/
protected function calcTotalPages($total_items)
{
return (int)ceil($total_items / $this->getLimit());
}
/**
* @param array $items
* @return \stdClass
*/
protected function createPaginationDataObj(array $items)
{
$current = $this->getCurrentPage();
$total_items = $this->calcTotalItemsCount();
$last = $this->calcTotalPages($total_items);
$before = max(1, $current - 1);
$next = min($last, $current + 1);
$page = new \stdClass();
$page->items = $items;
$page->first = 1;
$page->before = $before;
$page->current = $current;
$page->last = $last;
$page->next = $next;
$page->total_pages = $last;
$page->total_items = $total_items;
$page->limit = $this->getLimit();
return $page;
}
}