Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Collection Adapter for Phalcon
<?php
class MyModel
{
private static $data;
public static function setData(array $data)
{
self::$data = $data;
}
public static function count($parameters = null)
{
return count(self::$data);
}
public static function reset()
{
self::$data = null;
}
public static function find($parameters = null)
{
$data = [];
for ($i = 0; $i < count(self::$data); $i++) {
if ($parameters['skip']) {
$parameters['skip']--;
continue;
}
if ($parameters['limit']) {
$data[] = self::$data[$i];
$parameters['limit']--;
continue;
}
break;
}
return $data;
}
}
class CollectionAdapter implements \Phalcon\Paginator\AdapterInterface
{
/**
* @var \Phalcon\Mvc\CollectionInterface
*/
private $model;
/**
* @var int
*/
private $page;
/**
* @var int
*/
private $limit;
/**
* @param array $options
*/
public function __construct(array $options)
{
$this->model = $options['model'];
$this->page = $options['page'];
$this->limit = $options['limit'];
}
/**
* @param int $page
*/
public function setCurrentPage($page)
{
$this->page = $page;
}
/**
* @return \stdClass
*/
public function getPaginate()
{
$totalItems = call_user_func([$this->model, 'count']);
$totalPages = intval(ceil($totalItems / $this->limit));
$items = call_user_func(
[$this->model, 'find'],
[
'limit' => $this->limit,
'skip' => $this->limit * ($this->page - 1)
]
);
$before = null;
if ($this->page > 1) {
$before = $this->page - 1;
}
$next = $this->page + 1;
if ($next > $totalPages) {
$next = null;
}
return (object) [
'items' => $items,
'current' => $this->page,
'before' => $before,
'next' => $next,
'last' => $totalPages,
'total_pages' => $totalPages,
'total_items' => $totalItems,
];
}
}
class CollectionTest extends \PHPUnit_Framework_TestCase
{
public function testCreatePaginationForFirstPage()
{
$this->initModel(20);
$pagination = new CollectionAdapter([
'model' => MyModel::class,
'page' => 1,
'limit' => 3,
]);
$expected = (object) [
'items' => [[0], [1], [2]],
'current' => 1,
'before' => null,
'next' => 2,
'last' => 7,
'total_pages' => 7,
'total_items' => 20,
];
$this->assertEquals($expected, $pagination->getPaginate());
}
public function testCreatePaginationForAHigherPage()
{
$this->initModel(20);
$pagination = new CollectionAdapter([
'model' => MyModel::class,
'page' => 3,
'limit' => 3,
]);
$expected = (object) [
'items' => [[6], [7], [8]],
'current' => 3,
'before' => 2,
'next' => 4,
'last' => 7,
'total_pages' => 7,
'total_items' => 20,
];
$this->assertEquals($expected, $pagination->getPaginate());
}
public function testCreatePaginationForLastPage()
{
$this->initModel(20);
$pagination = new CollectionAdapter([
'model' => MyModel::class,
'page' => 7,
'limit' => 3,
]);
$expected = (object) [
'items' => [[18], [19]],
'current' => 7,
'before' => 6,
'next' => null,
'last' => 7,
'total_pages' => 7,
'total_items' => 20,
];
$this->assertEquals($expected, $pagination->getPaginate());
}
private function initModel($documentCount)
{
$initialData = [];
$total = $documentCount;
while ($documentCount) {
$initialData[] = [$total - $documentCount];
$documentCount--;
}
MyModel::setData($initialData);
}
public function tearDown()
{
MyModel::reset();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.