To change the way pagination works, you can create a custom paginator class that extends the default Laravel paginator. In this custom class, you can override the toArray method to modify the structure of the pagination data.
Here's an example of how you can create a custom paginator class:
use Illuminate\Pagination\LengthAwarePaginator;
class CustomPaginator extends LengthAwarePaginator
{
public function toArray()
{
$data = parent::toArray();
return [
'data' => $data['data'],
'links' => $data['links'],
'meta' => [
'current_page' => $data['current_page'],
'last_page' => $data['last_page'],
'per_page' => $data['per_page'],
'total' => $data['total'],
],
];
}
}
In this example, the toArray method returns an array with a data key that contains the paginated data, a links key that contains the pagination links, and a meta key that contains the pagination metadata.
To use this custom paginator class, you can pass it as the second argument to the paginate method:
$threads = Thread::query()
->select('*')
->with('creator:id,username,email')
->with(['replies' => function ($query) {
$query->select('replies.id', 'replies.thread_id', 'replies.body', 'replies.created_at', 'replies.updated_at', 'replies.user_id')
->with('owner:id,username,email')
->leftJoin('users', 'users.id', '=', 'replies.user_id');
}])
->latest()
->paginate(20, ['*'], 'page', 1, [
'paginator' => new CustomPaginator,
])
->through(function ($thread) {
$firstReply = $thread->replies->first();
return [
'title' => $thread->title,
'body' => $thread->body,
'slug' => $thread->slug,
'views' => $thread->views,
'solved' => $thread->solved,
'created_at' => $thread->created_at->diffForHumans(null),
'replies' => $thread->replies->count() ? [
'count' => $thread->replies->count(),
'first' => [
'body' => $firstReply->body,
'created_at' => $firstReply->created_at->diffForHumans(null),
'updated_at' => $firstReply->updated_at->diffForHumans(null),
'owner' => [
'username' => $firstReply->owner->username,
'email' => $firstReply->owner->email,
]
],
] : null,
'creator' => [
'username' => $thread->creator->username,
'email' => $thread->creator->email,
],
];
});
In this example, the paginate method is called with an additional fifth argument that contains an array with a paginator key that specifies the custom paginator class to use.
With this custom paginator class, the pagination data will be returned in the desired structure with a data key that contains the paginated data, a links key that contains the pagination links, and a meta key that contains the pagination metadata.