137 lines
3.9 KiB
PHP
137 lines
3.9 KiB
PHP
|
<?php
|
||
|
|
||
|
declare(strict_types=1);
|
||
|
|
||
|
namespace Shaarli\Bookmark;
|
||
|
|
||
|
/**
|
||
|
* Read-only class used to represent search result, including pagination.
|
||
|
*/
|
||
|
class SearchResult
|
||
|
{
|
||
|
/** @var Bookmark[] List of result bookmarks with pagination applied */
|
||
|
protected $bookmarks;
|
||
|
|
||
|
/** @var int number of Bookmarks found, with pagination applied */
|
||
|
protected $resultCount;
|
||
|
|
||
|
/** @var int total number of result found */
|
||
|
protected $totalCount;
|
||
|
|
||
|
/** @var int pagination: limit number of result bookmarks */
|
||
|
protected $limit;
|
||
|
|
||
|
/** @var int pagination: offset to apply to complete result list */
|
||
|
protected $offset;
|
||
|
|
||
|
public function __construct(array $bookmarks, int $totalCount, int $offset, ?int $limit)
|
||
|
{
|
||
|
$this->bookmarks = $bookmarks;
|
||
|
$this->resultCount = count($bookmarks);
|
||
|
$this->totalCount = $totalCount;
|
||
|
$this->limit = $limit;
|
||
|
$this->offset = $offset;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Build a SearchResult from provided full result set and pagination settings.
|
||
|
*
|
||
|
* @param Bookmark[] $bookmarks Full set of result which will be filtered
|
||
|
* @param int $offset Start recording results from $offset
|
||
|
* @param int|null $limit End recording results after $limit bookmarks is reached
|
||
|
* @param bool $allowOutOfBounds Set to false to display the last page if the offset is out of bound,
|
||
|
* return empty result set otherwise (default: false)
|
||
|
*
|
||
|
* @return SearchResult
|
||
|
*/
|
||
|
public static function getSearchResult(
|
||
|
$bookmarks,
|
||
|
int $offset = 0,
|
||
|
?int $limit = null,
|
||
|
bool $allowOutOfBounds = false
|
||
|
): self {
|
||
|
$totalCount = count($bookmarks);
|
||
|
if (!$allowOutOfBounds && $offset > $totalCount) {
|
||
|
$offset = $limit === null ? 0 : $limit * -1;
|
||
|
}
|
||
|
|
||
|
if ($bookmarks instanceof BookmarkArray) {
|
||
|
$buffer = [];
|
||
|
foreach ($bookmarks as $key => $value) {
|
||
|
$buffer[$key] = $value;
|
||
|
}
|
||
|
$bookmarks = $buffer;
|
||
|
}
|
||
|
|
||
|
return new static(
|
||
|
array_slice($bookmarks, $offset, $limit, true),
|
||
|
$totalCount,
|
||
|
$offset,
|
||
|
$limit
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/** @return Bookmark[] List of result bookmarks with pagination applied */
|
||
|
public function getBookmarks(): array
|
||
|
{
|
||
|
return $this->bookmarks;
|
||
|
}
|
||
|
|
||
|
/** @return int number of Bookmarks found, with pagination applied */
|
||
|
public function getResultCount(): int
|
||
|
{
|
||
|
return $this->resultCount;
|
||
|
}
|
||
|
|
||
|
/** @return int total number of result found */
|
||
|
public function getTotalCount(): int
|
||
|
{
|
||
|
return $this->totalCount;
|
||
|
}
|
||
|
|
||
|
/** @return int pagination: limit number of result bookmarks */
|
||
|
public function getLimit(): ?int
|
||
|
{
|
||
|
return $this->limit;
|
||
|
}
|
||
|
|
||
|
/** @return int pagination: offset to apply to complete result list */
|
||
|
public function getOffset(): int
|
||
|
{
|
||
|
return $this->offset;
|
||
|
}
|
||
|
|
||
|
/** @return int Current page of result set in complete results */
|
||
|
public function getPage(): int
|
||
|
{
|
||
|
if (empty($this->limit)) {
|
||
|
return $this->offset === 0 ? 1 : 2;
|
||
|
}
|
||
|
$base = $this->offset >= 0 ? $this->offset : $this->totalCount + $this->offset;
|
||
|
|
||
|
return (int) ceil($base / $this->limit) + 1;
|
||
|
}
|
||
|
|
||
|
/** @return int Get the # of the last page */
|
||
|
public function getLastPage(): int
|
||
|
{
|
||
|
if (empty($this->limit)) {
|
||
|
return $this->offset === 0 ? 1 : 2;
|
||
|
}
|
||
|
|
||
|
return (int) ceil($this->totalCount / $this->limit);
|
||
|
}
|
||
|
|
||
|
/** @return bool Either the current page is the last one or not */
|
||
|
public function isLastPage(): bool
|
||
|
{
|
||
|
return $this->getPage() === $this->getLastPage();
|
||
|
}
|
||
|
|
||
|
/** @return bool Either the current page is the first one or not */
|
||
|
public function isFirstPage(): bool
|
||
|
{
|
||
|
return $this->offset === 0;
|
||
|
}
|
||
|
}
|