lampager / lampager-laravel
Rapid pagination for Laravel
Installs: 30 609
Dependents: 0
Suggesters: 0
Security: 0
Stars: 77
Watchers: 9
Forks: 3
Open Issues: 2
Requires
- php: ^8.0
- ext-json: *
- illuminate/contracts: ^9.0 || ^10.0 || ^11.0
- illuminate/database: ^9.0 || ^10.0 || ^11.0
- illuminate/support: ^9.0 || ^10.0 || ^11.0
- lampager/lampager: ^0.4
Requires (Dev)
- nilportugues/sql-query-formatter: ^1.2.2
- orchestra/testbench: *
- orchestra/testbench-core: >=7.0
- phpunit/phpunit: >=9.5
README
Lampager for Laravel
Rapid pagination without using OFFSET
Requirements
- PHP:
^8.0
- Laravel:
^9.0 || ^10.0 || ^11.0
- lampager/lampager:
^0.4
Installing
composer require lampager/lampager-laravel
Basic Usage
Register service provider.
config/app.php
:
/* * Package Service Providers... */ Lampager\Laravel\MacroServiceProvider::class,
Then you can chain ->lampager()
method from Query Builder, Eloquent Builder and Relation.
$cursor = [ 'id' => 3, 'created_at' => '2017-01-10 00:00:00', 'updated_at' => '2017-01-20 00:00:00', ]; $result = App\Post::whereUserId(1) ->lampager() ->forward() ->limit(5) ->orderByDesc('updated_at') // ORDER BY `updated_at` DESC, `created_at` DESC, `id` DESC ->orderByDesc('created_at') ->orderByDesc('id') ->seekable() ->paginate($cursor) ->toJson(JSON_PRETTY_PRINT);
It will run the optimized query.
( SELECT * FROM `posts` WHERE `user_id` = 1 AND ( `updated_at` = '2017-01-20 00:00:00' AND `created_at` = '2017-01-10 00:00:00' AND `id` > 3 OR `updated_at` = '2017-01-20 00:00:00' AND `created_at` > '2017-01-10 00:00:00' OR `updated_at` > '2017-01-20 00:00:00' ) ORDER BY `updated_at` ASC, `created_at` ASC, `id` ASC LIMIT 1 ) UNION ALL ( SELECT * FROM `posts` WHERE `user_id` = 1 AND ( `updated_at` = '2017-01-20 00:00:00' AND `created_at` = '2017-01-10 00:00:00' AND `id` <= 3 OR `updated_at` = '2017-01-20 00:00:00' AND `created_at` < '2017-01-10 00:00:00' OR `updated_at` < '2017-01-20 00:00:00' ) ORDER BY `updated_at` DESC, `created_at` DESC, `id` DESC LIMIT 6 )
And you'll get
{ "records": [ { "id": 3, "user_id": 1, "text": "foo", "created_at": "2017-01-10 00:00:00", "updated_at": "2017-01-20 00:00:00" }, { "id": 5, "user_id": 1, "text": "bar", "created_at": "2017-01-05 00:00:00", "updated_at": "2017-01-20 00:00:00" }, { "id": 4, "user_id": 1, "text": "baz", "created_at": "2017-01-05 00:00:00", "updated_at": "2017-01-20 00:00:00" }, { "id": 2, "user_id": 1, "text": "qux", "created_at": "2017-01-17 00:00:00", "updated_at": "2017-01-18 00:00:00" }, { "id": 1, "user_id": 1, "text": "quux", "created_at": "2017-01-16 00:00:00", "updated_at": "2017-01-18 00:00:00" } ], "has_previous": false, "previous_cursor": null, "has_next": true, "next_cursor": { "updated_at": "2017-01-18 00:00:00", "created_at": "2017-01-14 00:00:00", "id": 6 } }
Resource Collection
Lampager supports Laravel's API Resources.
Use helper traits on Resource and ResourceCollection.
use Illuminate\Http\Resources\Json\JsonResource; use Lampager\Laravel\LampagerResourceTrait; class PostResource extends JsonResource { use LampagerResourceTrait; }
use Illuminate\Http\Resources\Json\ResourceCollection; use Lampager\Laravel\LampagerResourceCollectionTrait; class PostResourceCollection extends ResourceCollection { use LampagerResourceCollectionTrait; }
$posts = App\Post::lampager() ->orderByDesc('id') ->paginate(); return new PostResourceCollection($posts);
{ "data": [/* ... */], "has_previous": false, "previous_cursor": null, "has_next": true, "next_cursor": {/* ... */} }
Classes
Note: See also lampager/lampager.
Paginator
, Processor
and PaginationResult
are macroable.
API
Note: See also lampager/lampager.
Paginator::__construct()
Paginator::create()
Create a new paginator instance.
If you use Laravel macros, however, you don't need to directly instantiate.
static Paginator create(QueryBuilder|EloquentBuilder|Relation $builder): static Paginator::__construct(QueryBuilder|EloquentBuilder|Relation $builder)
QueryBuilder
means\Illuminate\Database\Query\Builder
EloquentBuilder
means\Illuminate\Database\Eloquent\Builder
Relation
means\Illuminate\Database\Eloquent\Relation
Paginator::transform()
Transform Lampager Query into Illuminate builder.
Paginator::transform(Query $query): QueryBuilder|EloquentBuilder|Relation
Paginator::build()
Perform configure + transform.
Paginator::build(\Lampager\Contracts\Cursor|array $cursor = []): QueryBuilder|EloquentBuilder|Relation
Paginator::paginate()
Perform configure + transform + process.
Paginator::paginate(\Lampager\Contracts\Cursor|array $cursor = []): \Lampager\Laravel\PaginationResult
Arguments
(mixed)
$cursor
An associative array that contains$column => $value
or an object that implements\Lampager\Contracts\Cursor
. It must be all-or-nothing.- For initial page, omit this parameter or pass empty array.
- For subsequent pages, pass all parameters. Partial parameters are not allowd.
Return Value
e.g.
(Default format when using \Illuminate\Database\Eloquent\Builder
)
object(Lampager\Laravel\PaginationResult)#1 (5) { ["records"]=> object(Illuminate\Database\Eloquent\Collection)#2 (1) { ["items":protected]=> array(5) { [0]=> object(App\Post)#2 (26) { ... } [1]=> object(App\Post)#3 (26) { ... } [2]=> object(App\Post)#4 (26) { ... } [3]=> object(App\Post)#5 (26) { ... } [4]=> object(App\Post)#6 (26) { ... } } } ["hasPrevious"]=> bool(false) ["previousCursor"]=> NULL ["hasNext"]=> bool(true) ["nextCursor"]=> array(2) { ["updated_at"]=> string(19) "2017-01-18 00:00:00" ["created_at"]=> string(19) "2017-01-14 00:00:00" ["id"]=> int(6) } }
Paginator::useFormatter()
Paginator::restoreFormatter()
Paginator::process()
Invoke Processor methods.
Paginator::useFormatter(Formatter|callable $formatter): $this Paginator::restoreFormatter(): $this Paginator::process(\Lampager\Query $query, \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Collection $rows): \Lampager\Laravel\PaginationResult
PaginationResult::toArray()
PaginationResult::jsonSerialize()
Convert the object into array.
IMPORTANT: camelCase
properties are converted into snake_case
form.
PaginationResult::toArray(): array PaginationResult::jsonSerialize(): array
PaginationResult::__call()
Call macro or Collection methods.
PaginationResult::__call(string $name, array $args): mixed
e.g.
PaginationResult::macro('foo', function () { return ...; }); $foo = $result->foo();
$first = $result->first();