2014-12-29 36 views
5

Quindi sto cercando di ottenere l'impaginazione in Laravel 5 con URL piuttosto come localhost/ads/1 dove 1 indica la pagina.Laravel 5 - Pretty paginator

A mio avviso, un'operazione del genere richiederebbe un sovraccarico di AbstractPaginator o LengthAwarePaginator per mirare a una modifica di Database\Query\Builder.

Mi manca qualcosa, una rilegatura o un'iniezione di dipendenza, o dovrebbe esserci la possibilità di cambiare l'impaginatore che vogliamo usare?

+0

Potresti usare 'mod_rewrite' per convertire l'URL della stringa di query corretta? Converti internamente in 'localhost/ads? Page = 1'. –

+0

@BenHarold Certo, funzionerebbe per reindirizzare i collegamenti. Tuttavia, non cambierà il problema della generazione dei link, penso. – repptilia

risposta

3

Alla fine, ho dovuto codificarmi un paginatore. Sto postando qui la mia soluzione, dovrebbe aiutare qualcuno.

Si noti che la soluzione, sebbene funzionale, richiede una certa attenzione per l'uso pratico (sulla convalida); la classe è semplificata qui per evidenziare il meccanismo.

<?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; 
    } 
} 

di utilizzare la classe, è possibile definire un percorso

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

Poi in detto controllore, in getElements:

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

Quindi, è possibile smaltire i elementi, come si normalmente lo farebbe. Nota: ho aggiunto un'opzione di percorso, al fine di integrare progetti di url piuttosto complessi. Spero che aiuti!

+1

Non significa che devi caricare l'intero tavolo in memoria prima di poter impaginare ciò che vuoi? – Puzbie

+0

'Model :: all' restituisce l'intero set ... che è eccessivo, non è vero? – Toskan

-3

Rimuovere questa riga di codice RewriteRule ^(.*)/$ /$1 [L,R=301] da .htaccess.

+1

Questa linea non ha nulla a che fare con la domanda. – ceejayoz

1

Ho scritto questo per laravel 5.3 senza negativi prestazioni: 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; 
    } 
} 

percorsi:

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); 
}]); 

poi nel PlumSearchService

$query = Product::select('product.*') //... 
     $paginator = $query->paginate(15, ['*'], 'page', $pageNr); 
     $products = new PlumPrettyUrlPaginator($paginator, '/page/', $pageNr);