repptilia repptilia - 16 days ago 12
PHP Question

Laravel 5 - Pretty paginator

So I'm trying to obtain pagination in Laravel 5 with pretty urls like

localhost/ads/1
where
1
stands for the page.

Up to my understanding, such an operation would require an overloading of
AbstractPaginator
, or
LengthAwarePaginator
, to aim at a modification of
Database\Query\Builder
.

Am I missing something, a binding or a dependency injection, or should there be the possibility to change the paginator we want to be used?

Answer

In the end, I had to code myself a Paginator. I'm posting here my solution, should it help anybody.

Note that the solution, while functional, requires some care for practical use (about validation); the class is simplified here to highlight the mechanism.

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

To use the class, you can define a route

Route::get('items/{page}','MyController@getElements');

Then in the said controller, in getElements:

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

Then, you can dispose of your elements as you normally would. Note: I added a path option, in order to integrate more complex pretty url designs. Hope it helps!

Comments