2014-12-29 5 views
5

Итак, я пытаюсь получить разбивку на страницы в Laravel 5 с хорошими адресами, например localhost/ads/1, где 1 - это страница.Laravel 5 - Pretty paginator

Насколько я понимаю, для такой операции потребуется перегрузка AbstractPaginator, или LengthAwarePaginator, с целью изменения модификации Database\Query\Builder.

У меня что-то отсутствует, привязка или инъекция зависимости, или должна ли быть возможность изменить страницу, которую мы хотим использовать?

+0

Не могли бы вы использовать 'mod_rewrite' для преобразования URL-адрес правильной строки запроса? Преобразовать его внутренне в 'localhost/ads? Page = 1'. –

+0

@BenHarold Конечно, это сработает для перенаправления ссылок. Однако, я думаю, это не изменит проблему генерации ссылок. – repptilia

ответ

3

В конце концов, мне пришлось закодировать себе Paginator. Я отправляю здесь свое решение, если оно поможет кому-либо.

Обратите внимание, что решение, в то время как функциональное, требует некоторой осторожности для практического использования (о валидации); класс упрощается здесь, чтобы выделить механизм.

<?php namespace App\Services; 

use Illuminate\Support\Collection; 
use Illuminate\Pagination\BootstrapThreePresenter; 
use Illuminate\Pagination\LengthAwarePaginator as BasePaginator; 

class Paginator extends BasePaginator{ 



    /** 
    * Create a new paginator instance. 
    * 
    * @param mixed $items 
    * @param int $perPage 
    * @param string $path Base path 
    * @param int $page 
    * @return void 
    */ 
    public function __construct($items, $perPage, $path, $page){ 
     // Set the "real" items that will appear here 
     $trueItems = []; 

     // That is, add the correct items 
     for ($i = $perPage*($page-1) ; $i < min(count($items),$perPage*$page) ; $i++){ 
      $trueItems[] = $items[$i]; 
     } 

     // Set path as provided 
     $this->path = $path; 

     // Call parent 
     parent::__construct($trueItems,count($items),$perPage); 

     // Override "guessing" of page 
     $this->currentPage = $page; 
    } 

    /** 
    * Get a URL for a given page number. 
    * 
    * @param int $page 
    * @return string 
    */ 
    public function url($page){ 
     if ($page <= 0) $page = 1; 

     return $this->path.$page; 
    } 
} 

Чтобы использовать класс, вы можете определить маршрут,

Route::get('items/{page}','[email protected]'); 

Затем в указанном контроллере, в getElements:

$items = new Paginator(Model::all(),$numberElementsPerPage,url('items'),$page); 

Затем вы можете выбрасывайте элементы, как вы обычно будет. Примечание. Я добавил путь, чтобы интегрировать более сложные проекты с узором. Надеюсь, это поможет!

+1

Не означает ли это, что вам нужно загрузить всю таблицу в память, прежде чем вы сможете разбивать страницы на нужные вам? – Puzbie

+0

'Model :: all' возвращает весь набор ... это перебор, не так ли? – Toskan

-3

Удалить из этого RewriteRule ^(.*)/$ /$1 [L,R=301] код с .htaccess.

+1

Эта строка не имеет ничего общего с вопросом. – ceejayoz

1

Я написал это для Laravel 5,3 без негативов производительности: PlumPrettyUrlPaginator.php

<?php 
namespace Plum\Cmc\Paginator; 

use Illuminate\Pagination\LengthAwarePaginator; 
use Illuminate\Support\Collection; 

class PlumPrettyUrlPaginator extends LengthAwarePaginator{ 

    /** 
    * basically a copy of LengthAwarePaginator constructor and then replacing all in our own 
    */ 
    public function __construct(LengthAwarePaginator $p, $path, $currentPage = null) { 

    $this->total = $p->total; 
    $this->perPage = $p->perPage; 
    $this->lastPage = (int) ceil($p->total/$p->perPage); 
// $this->path = ((stripos(strrev($p->path), '/') === 0) ? $p->path : $p->path.'/'); 
    $this->path = $path; 
    $this->currentPage = $p->setCurrentPage($currentPage ?? $p->currentPage, $p->pageName); 
    $this->items = $p->items; 
    } 

    public function url($page){ 
    if ($page <= 0) $page = 1; 
    return $this->path.$page; 
    } 
} 

маршруты:

Route::get('/', [ function (Request $request) { 
    $data = PlumSearchService::PrepareSearchView($request); 
    return view('inventory.search_products', $data); 
}]); 


Route::get('/page/{pageNr}', [ function (Request $request, int $pageNr) { 
    $data = PlumSearchService::PrepareSearchView($request, false, $pageNr); 
    return view('inventory.search_products', $data); 
}]); 

затем в PlumSearchService

$query = Product::select('product.*') //... 
     $paginator = $query->paginate(15, ['*'], 'page', $pageNr); 
     $products = new PlumPrettyUrlPaginator($paginator, '/page/', $pageNr); 
Смежные вопросы