Skip to content

Commit

Permalink
Merge pull request #5 from emonkak/redesign-pagination
Browse files Browse the repository at this point in the history
Redesign pagination
  • Loading branch information
emonkak committed Jun 17, 2020
2 parents 426d66b + 334712b commit 3dc64f0
Show file tree
Hide file tree
Showing 21 changed files with 591 additions and 450 deletions.
67 changes: 67 additions & 0 deletions src/Pagination/AbstractPage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

declare(strict_types=1);

namespace Emonkak\Orm\Pagination;

use Emonkak\Enumerable\EnumerableExtensions;

/**
* @template T
* @implements \IteratorAggregate<T>
* @implements PageInterface<T>
*/
abstract class AbstractPage implements \IteratorAggregate, PageInterface
{
/**
* @use EnumerableExtensions<T>
*/
use EnumerableExtensions;

public function getOffset(): int
{
return $this->getIndex() * $this->getPerPage();
}

/**
* {@inheritdoc}
*/
public function forward(): iterable
{
$page = $this;

yield $page;

while ($page->hasNext()) {
$page = $page->next();

yield $page;
}
}

/**
* {@inheritdoc}
*/
public function backward(): iterable
{
$page = $this;

yield $page;

while ($page->hasPrevious()) {
$page = $page->previous();

yield $page;
}
}

public function isFirst(): bool
{
return !$this->hasPrevious();
}

public function isLast(): bool
{
return !$this->hasNext();
}
}
4 changes: 2 additions & 2 deletions src/Pagination/AbstractPaginator.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ public function has(int $index): bool
/**
* {@inheritdoc}
*/
public function firstPage(): PageInterface
public function firstPage(): PaginatablePageInterface
{
return $this->at(0);
}

/**
* {@inheritdoc}
*/
public function lastPage(): PageInterface
public function lastPage(): PaginatablePageInterface
{
$totalPages = $this->getTotalPages();
return $this->at($totalPages > 0 ? $totalPages - 1 : 0);
Expand Down
6 changes: 3 additions & 3 deletions src/Pagination/EmptyPaginator.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function __construct(int $perPage)
/**
* {@inheritdoc}
*/
public function at(int $index): PageInterface
public function at(int $index): PaginatablePageInterface
{
return new Page(new \EmptyIterator(), $index, $this);
}
Expand All @@ -46,15 +46,15 @@ public function has(int $index): bool
/**
* {@inheritdoc}
*/
public function firstPage(): PageInterface
public function firstPage(): PaginatablePageInterface
{
return $this->at(0);
}

/**
* {@inheritdoc}
*/
public function lastPage(): PageInterface
public function lastPage(): PaginatablePageInterface
{
return $this->at(0);
}
Expand Down
43 changes: 13 additions & 30 deletions src/Pagination/Page.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,13 @@

namespace Emonkak\Orm\Pagination;

use Emonkak\Enumerable\EnumerableExtensions;

/**
* @template T
* @implements \IteratorAggregate<T>
* @implements PageInterface<T>
* @extends AbstractPage<T>
* @implements PaginatablePageInterface<T>
*/
class Page implements \IteratorAggregate, PageInterface
class Page extends AbstractPage implements PaginatablePageInterface
{
/**
* @use EnumerableExtensions<T>
*/
use EnumerableExtensions;

/**
* @psalm-var \Traversable<T>
* @var \Traversable
Expand Down Expand Up @@ -62,49 +55,39 @@ public function getPaginator(): PaginatorInterface
return $this->paginator;
}

public function getIndex(): int
public function getPerPage(): int
{
return $this->index;
return $this->paginator->getPerPage();
}

public function getOffset(): int
public function getIndex(): int
{
return $this->index * $this->paginator->getPerPage();
return $this->index;
}

/**
* {@inheritdoc}
*/
public function previous(): PageInterface
public function next(): PageInterface
{
return $this->paginator->at($this->index - 1);
return $this->paginator->at($this->index + 1);
}

/**
* {@inheritdoc}
*/
public function next(): PageInterface
{
return $this->paginator->at($this->index + 1);
}

public function hasPrevious(): bool
public function previous(): PageInterface
{
return $this->paginator->has($this->index - 1);
return $this->paginator->at($this->index - 1);
}

public function hasNext(): bool
{
return $this->paginator->has($this->index + 1);
}

public function isFirst(): bool
{
return !$this->hasPrevious();
}

public function isLast(): bool
public function hasPrevious(): bool
{
return !$this->hasNext();
return $this->paginator->has($this->index - 1);
}
}
23 changes: 15 additions & 8 deletions src/Pagination/PageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,31 @@
*/
interface PageInterface extends EnumerableInterface
{
/**
* @psalm-return PaginatorInterface<T>
*/
public function getPaginator(): PaginatorInterface;
public function getPerPage(): int;

public function getIndex(): int;

public function getOffset(): int;

/**
* @psalm-return PageInterface<T>
* @psalm-return self<T>
*/
public function next(): self;

/**
* @psalm-return self<T>
*/
public function previous(): self;

/**
* @psalm-return iterable<self<T>>
*/
public function previous(): PageInterface;
public function forward(): iterable;

/**
* @psalm-return PageInterface<T>
* @psalm-return iterable<self<T>>
*/
public function next(): PageInterface;
public function backward(): iterable;

public function hasPrevious(): bool;

Expand Down
28 changes: 0 additions & 28 deletions src/Pagination/PageIteratorInterface.php

This file was deleted.

21 changes: 21 additions & 0 deletions src/Pagination/PaginatablePageInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Emonkak\Orm\Pagination;

/**
* @template T
* @extends PageInterface<T>
* @method self<T> next()
* @method self<T> previous()
* @method iterable<self<T>> forward()
* @method iterable<self<T>> backward()
*/
interface PaginatablePageInterface extends PageInterface
{
/**
* @psalm-return PaginatorInterface<T>
*/
public function getPaginator(): PaginatorInterface;
}
12 changes: 6 additions & 6 deletions src/Pagination/PaginatorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,23 @@
interface PaginatorInterface extends EnumerableInterface
{
/**
* @psalm-return PageInterface<T>
* @psalm-return PaginatablePageInterface<T>
*/
public function at(int $index): PageInterface;
public function at(int $index): PaginatablePageInterface;

public function getPerPage(): int;

public function has(int $index): bool;

/**
* @psalm-return PageInterface<T>
* @psalm-return PaginatablePageInterface<T>
*/
public function firstPage(): PageInterface;
public function firstPage(): PaginatablePageInterface;

/**
* @psalm-return PageInterface<T>
* @psalm-return PaginatablePageInterface<T>
*/
public function lastPage(): PageInterface;
public function lastPage(): PaginatablePageInterface;

public function getTotalItems(): int;

Expand Down
20 changes: 9 additions & 11 deletions src/Pagination/PrecountPaginator.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@
*/
class PrecountPaginator extends AbstractPaginator
{
/**
* @psalm-var callable(int,int):\Traversable<T>
* @var callable(int,int):\Traversable
*/
private $itemsFetcher;

/**
* @var int
*/
Expand All @@ -26,22 +20,26 @@ class PrecountPaginator extends AbstractPaginator
*/
private $totalItems;

/**
* @psalm-var callable(int,int):\Traversable<T>
* @var callable(int,int):\Traversable
*/
private $itemsFetcher;

/**
* @psalm-param callable(int,int):\Traversable<T> $itemsFetcher
* @psalm-param int $perPage
* @psalm-param int $totalItems
*/
public function __construct(callable $itemsFetcher, int $perPage, int $totalItems)
public function __construct(int $perPage, int $totalItems, callable $itemsFetcher)
{
$this->itemsFetcher = $itemsFetcher;
$this->perPage = $perPage;
$this->totalItems = $totalItems;
$this->itemsFetcher = $itemsFetcher;
}

/**
* {@inheritdoc}
*/
public function at(int $index): PageInterface
public function at(int $index): PaginatablePageInterface
{
if ($index >= 0 && $index < $this->getTotalPages()) {
$itemsFetcher = $this->itemsFetcher;
Expand Down

0 comments on commit 3dc64f0

Please sign in to comment.