Для реализации курсорной пагинации с отображением соседних страниц в Laravel, вам нужно немного модифицировать стандартную логику пагинации.
Курсорная пагинация обычно использует только курсор вперед и назад, однако вы можете создать свои собственные курсоры для соседних страниц, используя offset и limit. Далее приведены шаги, которые помогут вам в этом процессе:
1. **Создание контроллера**: В вашем контроллере, где вы обрабатываете запросы на получение данных, добавьте логику для получения соседних курсоров.
2. **Получение необходимых данных**: Для реализации соседних курсоров, вы должны сохранить данные о последнем полученном элементе. Затем используйте SQL-запрос, чтобы выбрать соседние записи.
3. **Формирование курсоров**: Создайте курсоры для страниц, которые отображаются рядом с текущей. Например, если вы находитесь на странице 5, вычислите курсоры для страниц 3, 4, 6 и 7, а также для первой страницы.
4. **Генерация ссылок**: Генерируйте ссылки на соседние страницы, передавая нужные курсоры в URL.
### Пример кода
Допустим, у вас есть модель `Post`, и вы хотите реализовать курсорную пагинацию с отображением соседних страниц. Вот пример логики в контроллере:
```php
public function index(Request $request)
{
$currentCursor = $request->input('cursor');
$limit = 10;
// Получаем данные с курсорной пагинацией
$postsQuery = Post::query();
// Применение курсора к запросу
if ($currentCursor) {
$postsQuery->where('id', '>', decodeCursor($currentCursor));
}
// Получаем текущую страницу
$posts = $postsQuery->take($limit)->get();
// Получаем курсоры для соседних страниц
$previousCursor = $this->getCursor($postsQuery, $limit, -1);
$nextCursor = $this->getCursor($postsQuery, $limit, 1);
// Генерация курсоров для соседних страниц
$neighborCursors = [];
if ($previousCursor) {
$neighborCursors[] = $this->generateCursorLink($previousCursor);
}
if ($nextCursor) {
$neighborCursors[] = $this->generateCursorLink($nextCursor);
}
return view('posts.index', [
'posts' => $posts,
'previousCursor' => $previousCursor,
'nextCursor' => $nextCursor,
'neighborCursors' => $neighborCursors,
]);
}
private function getCursor($query, $limit, $direction)
{
$cursorQuery = $query->orderBy('id');
if ($direction < 0) {
$cursorQuery->take(1)->skip(max(0, $query->count() - $limit - 1))->get()->last();
} else {
$cursorQuery->skip(count($query->get()) - 1)->take(1)->get();
}
return $cursorQuery->first();
}
private function generateCursorLink($cursor)
{
return url()->current() . '?cursor=' . encodeCursor($cursor->id);
}
private function encodeCursor($id)
{
return base64_encode($id);
}
private function decodeCursor($cursor)
{
return base64_decode($cursor);
}
```
### Комментарии к коду:
- `getCursor()`: Эта функция получает предыдущий или следующий элемент в зависимости от направления.
- `encodeCursor()` и `decodeCursor()`: Эти функции для кодирования и декодирования курсора, чтобы использовать его в URL.
- `generateCursorLink()`: Эта функция создает ссылку для курсора.
### Визуализация в представлении
В вашем представлении вы можете отобразить курсоры так, чтобы пользователи могли переходить на соседние страницы:
```blade
@if($neighborCursors)
<div class="pagination">
@foreach($neighborCursors as $cursorLink)
<a href="{{ $cursorLink }}">{{ $cursorLink }}</a>
@endforeach
</div>
@endif
```
Этот подход позволит вам отображать не только предыдущую или следующую страницу, но и соседние страницы, используя курсорную пагинацию.