81 lines
2.3 KiB
PHP
81 lines
2.3 KiB
PHP
<?php declare(strict_types=1);
|
|
|
|
namespace App\Services\Search;
|
|
|
|
use App\Models\Role;
|
|
use Illuminate\Container\Container;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Database\Eloquent\Relations\Relation;
|
|
use Illuminate\Pagination\CursorPaginator;
|
|
use Illuminate\Pagination\LengthAwarePaginator;
|
|
use Illuminate\Pagination\Paginator;
|
|
use Illuminate\Support\Collection;
|
|
use App\Contracts\Search as SearchContract;
|
|
|
|
final readonly class Search implements SearchContract
|
|
{
|
|
public function __construct(
|
|
private Relation|Builder $query
|
|
) { }
|
|
|
|
public function all(): Collection
|
|
{
|
|
return $this->query->get();
|
|
}
|
|
|
|
public function get(int $limit): Collection
|
|
{
|
|
return $this->query->limit($limit)->get();
|
|
}
|
|
|
|
public function pagination(int $limit, int $page = 1): LengthAwarePaginator
|
|
{
|
|
if ($page > 100) {
|
|
return $this->paginationPerfomance($limit, $page);
|
|
}
|
|
return $this->query->paginate($limit, page: $page)->withQueryString();
|
|
}
|
|
|
|
public function cursorPaginate(int $limit): CursorPaginator
|
|
{
|
|
return $this->query->cursorPaginate($limit);
|
|
}
|
|
|
|
private function paginationPerfomance(int $limit, int $page = 1): LengthAwarePaginator
|
|
{
|
|
$total = $this->query->clone()->count();
|
|
$options = [
|
|
'path' => Paginator::resolveCurrentPath(),
|
|
'pageName' => 'page',
|
|
];
|
|
|
|
$result = collect();
|
|
if ($total > 0) {
|
|
$result = $this->subQuery($limit, $page);
|
|
}
|
|
|
|
$pagination = Container::getInstance()->makeWith(LengthAwarePaginator::class, [
|
|
'items' => $result,
|
|
'total' => $total,
|
|
'perPage' => $limit,
|
|
'currentPage' => $page,
|
|
'options' => $options
|
|
]);
|
|
|
|
return $pagination->withQueryString();
|
|
}
|
|
|
|
private function subQuery(int $limit, int $page): Collection
|
|
{
|
|
$table = $this->query->getModel()->getTable();
|
|
return $this->query->getModel()::query()
|
|
->select($table.'.*')
|
|
->with($this->query->getEagerLoads())
|
|
->from(
|
|
clone $this->query->select('id')->forPage($page, $limit),
|
|
'q'
|
|
)->join($table.' as '.$table, $table.'.id', '=', 'q.id')
|
|
->get();
|
|
}
|
|
}
|