Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 411
repptilia Avatar asked Nov 26 '22 06:11

repptilia


1 Answers

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!

like image 55
repptilia Avatar answered Nov 29 '22 03:11

repptilia