15

Pagination::make() method doesn't exist in Pagination class anymore in Laravel 5.

Is there a workaround to make manual pagination work in Laravel 5?

Marcin Nabiałek
  • 109,655
  • 42
  • 258
  • 291
aBhijit
  • 5,261
  • 10
  • 36
  • 56

8 Answers8

32

You need to add use:

use Illuminate\Pagination\LengthAwarePaginator as Paginator;

and now you can use:

 $paginator = new Paginator($items, $count, $limit, $page, [
            'path'  => $this->request->url(),
            'query' => $this->request->query(),
        ]);

to get data in the same format as paginating on model object;

Marcin Nabiałek
  • 109,655
  • 42
  • 258
  • 291
10

Example of using the Illuminate\Pagination\LengthAwarePaginator:

use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;

public function getItems(Request $request)
{
    $items = []; // get array/collection data from somewhere
    $paginator = $this->getPaginator($request, $items);

    // now we can treat $paginator as an array/collection
    return view('some-view')->with('items', $paginator);
}

private function getPaginator(Request $request, $items)
{
    $total = count($items); // total count of the set, this is necessary so the paginator will know the total pages to display
    $page = $request->page ?? 1; // get current page from the request, first page is null
    $perPage = 3; // how many items you want to display per page?
    $offset = ($page - 1) * $perPage; // get the offset, how many items need to be "skipped" on this page
    $items = array_slice($items, $offset, $perPage); // the array that we actually pass to the paginator is sliced

    return new LengthAwarePaginator($items, $total, $perPage, $page, [
        'path' => $request->url(),
        'query' => $request->query()
    ]);
}

Then in some-view.blade.php file, for example:

@foreach($items as $item)
    {{--  --}}
@endforeach


{{ $items->links() }}

See https://laravel.com/docs/5.7/pagination#manually-creating-a-paginator

Avishay28
  • 2,288
  • 4
  • 25
  • 47
  • I wish I could upvote more than once. This kind of example should be added to the official docs. They just mentioned that you can manually create pagination but don't show how. Your code works just as expected thanks. – rotimi-best Mar 01 '20 at 06:51
3

You can create manual pagination like this

$data = DB::table('post')->skip(0)->take(20)->get();

CinCout
  • 9,486
  • 12
  • 49
  • 67
3

Pretty way to instance this class

 use Illuminate\Pagination\LengthAwarePaginator as Paginator;
 //...
 $paginator = new Paginator($items->forPage($page, $limit), $count, $limit, $page, [
            'path'  => Paginator::resolveCurrentPath()
        ]);

Note items must be a Collection Object. Use collect(Array()) to convert Array to Collection

More informations

Goms
  • 2,424
  • 4
  • 19
  • 36
1

Try below code for manual pagination

<?php

namespace App\Http\Controllers;

use Illuminate\Pagination\LengthAwarePaginator as Paginator;
// use Illuminate\Pagination\Paginator;
use Illuminate\Http\Request;
use App\Product;
class MyController extends Controller
{
    public function index(Request $request){
        $items = Product::all();

        $filter_products = []; // Manual filter or your array for pagination

        foreach($items as $item){
            if($item['id']>40 && $item['id']<50){
                array_push($filter_products, $item);
            }
        }

        $count = count($filter_products); // total product for pagination
        $page = $request->page; // current page for pagination

        // manually slice array of product to display on page
        $perPage = 5;
        $offset = ($page-1) * $perPage;
        $products = array_slice($filter_products, $offset, $perPage);

        // your pagination 
        $products = new Paginator($products, $count, $perPage, $page, ['path'  => $request->url(),'query' => $request->query(),]);
        // use {{ $products->appends($_GET)->links() }} to dispaly your pagination
        return view('index',['products' => $products]);
    }
}
Sangeet
  • 21
  • 4
  • 7
    Add some explanation to your answer . Code only answer are not really useful. – ADM Apr 20 '18 at 14:27
0
public function myData($userid)
{
    $data = static::get();


    $result = [];
    if(!empty($data)){
        foreach ($data as $key => $value) {
            $result[$value->type.'-'.$value->postid][] = $value;
        }
    }


    $paginate = 10;
    $page = Input::get('page', 1);


    $offSet = ($page * $paginate) - $paginate;  
    $itemsForCurrentPage = array_slice($result, $offSet, $paginate, true);  
    $result = new \Illuminate\Pagination\LengthAwarePaginator($itemsForCurrentPage, count($result), $paginate, $page);
    $result = $result->toArray();
    return $result;
}
-1

based on @Avishay28, i think php array_slice is not needed.

working in laravel 8.

i think this is a better approach in terms of performance, because we are not querying "SELECT * FROM products"

$items_per_page = 5;
$page_id = (int)$request->query('page') ?? 1;
$model_docs_count = Product::count();
$total_pages = ceil($model_docs_count / $items_per_page);
$model = Product::skip(($page_id - 1) * $items_per_page)->limit($items_per_page)->latest();
// dd($model->toSql()); "SELECT * FROM `products` WHERE ORDER BY `created_at` DESC LIMIT 5 OFFSET 0"

$custom_paginate = new LengthAwarePaginator($model, $total_pages, $items_per_page, $page_id, [
    'path' => $request->url(),
    'query' => $request->query()
]);

return response()->json([$custom_paginate], 200);
Subramanya Rao
  • 151
  • 3
  • 6
-5

Another way of using pagination would be like this:

public function index()
{
    $posts = DB::table('posts')->paginate(15);
}
Vojtech Ruzicka
  • 16,384
  • 15
  • 63
  • 66
n31l
  • 93
  • 1
  • 11