Reputation: 962
I'm building an application using Laravel 4.2. I have a model for units
and another for users
and pivot table user_units
. Every user in this application can select a unit and add it to his favorite list then he can publish this unit with his information as an ad.
I want to select all units published by all users
The user_units
(pivot) table has the following columns:
id
user_id
unit_id
publish
adtype
addinfo
created_at
updated_at
With relations methods on models
public function users() {
return $this->belongsToMany('User', 'user_units')
->withPivot('id','publish', 'adtype', 'addinfo');
}
public function units() {
return $this->belongsToMany('Unit', 'user_units')
->withPivot('id','publish', 'adtype', 'addinfo');
}
My query to select all published units by all users
// Get all published units by users for sale.
$users = User::all();
$publishedSaleUnits = [];
foreach($users as $user){
$userUnits = $user->units()->orderBy('adtype', 'desc')->get();
if(count($userUnits)){
foreach($userUnits as $unit){
if($unit->pivot->publish == 1 && $unit->unit_purpose_id == 1){
if( $unit->pivot->adtype ){
//push all featured ads onto the beginning of array
array_unshift($publishedSaleUnits, $unit);
}else{
//push all normal ads onto the end of array
array_push($publishedSaleUnits, $unit);
}
}
}
}
}
Now I got the result but I can't use pagination with results because it's an array of objects.
So is there any better solution to get all published units by user with pagination?
Upvotes: 8
Views: 53607
Reputation: 594
This worked for me:
<?php
namespace App\Utils;
use Illuminate\Pagination\Paginator;
use Illuminate\Pagination\LengthAwarePaginator;
use \Illuminate\Support\Facades\Request;
class Paginate
{
public static function paginate($items, $perPage = 10, $page = null)
{
$page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
$total = count($items);
$currentpage = $page;
$offset = ($currentpage * $perPage) - $perPage ;
$itemstoshow = array_slice($items , $offset , $perPage);
return new LengthAwarePaginator($itemstoshow, $total, $perPage, $page,
['path'=> Request::fullUrl()]);
}
}
You can visit this link as well: Laravel Create Pagination From Array Tutorial
Upvotes: 0
Reputation: 91
Using Laravel 8, if any of you are having trouble in the paginator getting lost with the URL after page 1, just add in the LengthAwarePaginator
options
parameter the URL path for you original page.
Example:
return new LengthAwarePaginator($items->forPage($page, $perPage), $items->count(), $perPage, $page, ['path' => 'users']);
Upvotes: 2
Reputation: 56
this code work for me on laravel 8
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Collection;
public function paginate($items, $perPage = 5, $page = null, $options = [])
{
$page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
$items = $items instanceof Collection ? $items : Collection::make($items);
return new LengthAwarePaginator($items->forPage($page, $perPage), $items->count(), $perPage, $page, $options);
}
according to this refrence https://www.itsolutionstuff.com/post/how-to-create-pagination-from-array-in-laravelexample.html
Upvotes: 0
Reputation: 1744
according to this article https://www.itsolutionstuff.com/post/how-to-create-pagination-from-array-in-laravelexample.html
you can paginate your array by creating a custom method and using LengthAwarePaginator
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
class PaginationController extends Controller
{
public function index()
{
$myArray = [
['id'=>1, 'title'=>'Laravel CRUD'],
['id'=>2, 'title'=>'Laravel Ajax CRUD'],
['id'=>3, 'title'=>'Laravel CORS Middleware'],
];
$data = $this->paginate($myArray);
return view('paginate', compact('data'));
}
public function paginate($items, $perPage = 5, $page = null, $options = [])
{
$page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
$items = $items instanceof Collection ? $items : Collection::make($items);
return new LengthAwarePaginator($items->forPage($page, $perPage), $items->count(), $perPage, $page, $options);
}
}
Upvotes: 35
Reputation: 2632
You can try my code with your own array,
$page = isset($request->page) ? $request->page : 1; // Get the page=1 from the url
$perPage = $pagination_num; // Number of items per page
$offset = ($page * $perPage) - $perPage;
$entries = new LengthAwarePaginator(
array_slice($contact_list, $offset, $perPage, true),
count($contact_list), // Total items
$perPage, // Items per page
$page, // Current page
['path' => $request->url(), 'query' => $request->query()] // We
need this so we can keep all old query parameters from the url
);
Upvotes: 4
Reputation: 962
I got a better solution to paginate array result and I found the answer here
Paginator::make
function we need to pass only the required values instead of all values. Because paginator::make
function simply displays the data send to it. To send the correct offset paginated data to the paginator::make
, the following method should be followed
$perPage = 5;
$page = Input::get('page', 1);
if ($page > count($publishedSaleUnits) or $page < 1) { $page = 1; }
$offset = ($page * $perPage) - $perPage;
$perPageUnits = array_slice($publishedSaleUnits,$offset,$perPage);
$pagination = Paginator::make($perPageUnits, count($publishedSaleUnits), $perPage);
Upvotes: 1
Reputation: 5910
Your approach to query the data is extremely inefficient. Fetch your data in one query. Nested traversing is not only hard to read but also a performance killer.
To the pagination problem:
Laravel provides a Pagignator Factory. With it you will be able to build your own Paginator with your own data.
It's as easy as
$units = Paginator::make($unit, count($unit), 10);
if you're using the Facade. Otherwise Illuminate\Pagination\Factory
is the class you are looking for.
Upvotes: 6