Laravel Paginate usage with DB::raw query - php

How I can use paginate() with this query?
$result = DB::select(DB::raw(" select a.user_id, a.user_email,
a.user_account_status, a.created_at, b.s_account_limit AS account_limit,
c.consumed_limit, ((b.s_account_limit*1024) - c.consumed_limit) AS
remaining_limit FROM upload_limits as b, users AS a JOIN user_upload_limits as
c WHERE (a.user_id=c.user_id) AND a.user_type='Simple'"));

You may use ->paginate() method or if you want to create a pagination manually, you would do something like:
$perPage = $request->input("per_page", 10);
$page = $request->input("page", 1);
$skip = $page * $perPage;
if($take < 1) { $take = 1; }
if($skip < 0) { $skip = 0; }
$basicQuery = DB::select(DB::raw(" select a.user_id, a.user_email, a.user_account_status, a.created_at, b.s_account_limit AS account_limit, c.consumed_limit, ((b.s_account_limit*1024) - c.consumed_limit) AS remaining_limit FROM upload_limits as b, users AS a JOIN user_upload_limits as c WHERE (a.user_id=c.user_id) AND a.user_type='Simple'"));
$totalCount = $basicQuery->count();
$results = $basicQuery
->take($perPage)
->skip($skip)
->get();
$paginator = new \Illuminate\Pagination\LengthAwarePaginator($results, $totalCount, $take, $page);
return $paginator;

You can also add a custom sort method that you pass in your array result of DB::raw along with your params:
public function sort($array_of_objects, $sort_by=null, $order, $page)
{
$collection = collect($array_of_objects);
if ($sort_by)
{
if ($order=='desc') {
$sorted = $collection->sortBy(function($role) use ($sort_by)
{
return $role->{$sort_by};
})->reverse();
} else if ($order=='asc') {
$sorted = $collection->sortBy(function($role) use ($sort_by)
{
return $role->{$sort_by};
});
}
} else {
$sorted = $collection;
}
$num_per_page = 20;
if (!$page) {
$page = 1;
}
$offset = ( $page - 1) * $num_per_page;
$sorted = $sorted->splice($offset, $num_per_page);
return new Paginator($sorted, count($array_of_objects), $num_per_page, $page);
}

Related

Pagination in codeigniter 3 and send to api

I have following function.
public function sendstocktobl()
{
if ($_SERVER['REMOTE_ADDR'] !== $this->localhost) {
echo $_SERVER['REMOTE_ADDR'];
} else {
$this->load->database();
$url = get_integration_url('baselinker');
$this->db->select('user_id');
$this->db->where('bl_send_stock', 1);
$this->db->where('is_baselinker', 1);
$this->db->where('is_active', 1);
$resArr = $this->db->get('ci_users')->result_array();
foreach ($resArr as $row) {
$user_id = $row['user_id'];
$limit = 1000;
$offset = 0;
$where = "quantity is NOT NULL";
$this->db->where($where);
$this->db->where('is_active', 1);
$this->db->where('user_id', $user_id);
$total_results = $this->db->count_all('ci_products');
$total_pages = ceil($total_results / $limit);
$token = get_bl_token($user_id);
$inventoryid = get_bl_inventory($user_id);
$blwh = get_bl_warehouse($user_id);
for ($page = 1; $page <= $total_pages; $page++) {
$arr = [
"inventory_id" => $inventoryid,
"products" => [],
];
$this->db->select('*');
$where = "quantity is NOT NULL";
$this->db->where($where);
$this->db->where('is_active', 1);
$this->db->where('user_id', $user_id);
$prodArr = $this->db->get('ci_products')->result_array();
foreach ($prodArr as $prod) {
$arr['products'][$prod['id']] = [$blwh => $prod['quantity']];
}
$offset += $limit;
}
$preparebl = json_encode($arr);
echo $preparebl;
}
}
}
Long story short, i need to grab data from sql and send to an api for each users which meets some requirements. I need to prepare apicall like this it's now $arr , but the point it's that pagination it's not working, for user 1 i have 1077 records and i get just one json array with products (1077 products), instead of 2 with maximum 1k .
Could someone help me a bit cause i'm not getting where is the error in my script..
Forgotted to add $limit and offset there:
$prodArr = $this->db->get('ci_products')->result_array();
Correct:
$prodArr = $this->db->get('ci_products', $limit, $offset)->result_array();
And added also apicall in "for" loop.
I let here my function which, now it's working fine, maybel it will help someone to inspire.
public function sendstocktobl(){
if ($_SERVER['REMOTE_ADDR'] !== $this->localhost) {echo $_SERVER['REMOTE_ADDR'];}
else{
$this->load->database();
$url = get_integration_url('baselinker');
$this->db->select('user_id');
$this->db->where('bl_send_stock',1);
$this->db->where('is_baselinker',1);
$this->db->where('is_active',1);
$resArr = $this->db->get('ci_users')->result_array();
foreach ($resArr as $row){
$user_id = $row['user_id'];
$limit = 1000;
$offset = 0;
$where = "quantity is NOT NULL";
$total_results = $this->db->where('user_id',$user_id)->where('is_active',1)->where($where)->from("ci_products")->count_all_results();
$total_pages = ceil($total_results / $limit);
$token = get_bl_token($user_id);
$inventoryid = get_bl_inventory($user_id);
$blwh = get_bl_warehouse($user_id);
for ($page = 1; $page <= $total_pages; $page++) {
$arr = [
"inventory_id" => $inventoryid,
"products" => [],
];
$this->db->select('*');
$where = "quantity is NOT NULL";
$this->db->where($where);
$this->db->where('is_active',1);
$this->db->where('user_id',$user_id);
$prodArr = $this->db->get('ci_products', $limit, $offset)->result_array();
foreach($prodArr as $prod){
$arr['products'][$prod['id']] = [$blwh => $prod['quantity']];
}
$preparebl = json_encode($arr);
echo $preparebl;
$offset += $limit;
}
}
}
}

Method paginate does not exist Laravel 5.2

I get the following error when I try to paginate in Laravel 5.2.
BadMethodCallException in Macroable.php line 81: Method paginate does
not exist.
And code:
Illuminate\Contracts\Pagination\Paginator;
...
$count = 0;
$gdprecords = Gdprecord::all();
foreach($gdprecords as $gdprecord) {
$count++;
$Pa = $gdprecord->adultpopulation;
$Pc = $gdprecord->childpopulation;
$P = $Pa + $Pc; // total population
$T = ($gdprecord->gdpcapita * $P) * $gdpratio; // basic income for country
if($bi_ratio == 0) {
$gdprecord->bi_adult = round($T / $Pa, 2);
} else {
$gdprecord->bi_adult = round($T / ($Pa + ($Pc / $bi_ratio)), 2);
}
$gdprecord->bi_adult_monthly = round($gdprecord->bi_adult / 12, 2);
$gdprecord->bi_adult_daily = round($gdprecord->bi_adult / 365, 2);
if($bi_ratio == 0) {
$gdprecord->bi_child = 0;
} else {
$gdprecord->bi_child = round($gdprecord->bi_adult / $bi_ratio, 2);
}
$gdprecord->bi_child_monthly = round($gdprecord->bi_child / 12, 2);
$gdprecord->bi_child_daily = round($gdprecord->bi_child / 365, 2);
}
$sorted_gdprecords = $gdprecords->sortByDesc('bi_adult')->paginate(25);
I don't want to paginate until after the array has been sorted. How do I make this work?
Thanks, Philip
Here is a solution I found, borrowing code from someone else:
public function paginate($items,$perPage)
{
$pageStart = \Request::get('page', 1);
// Start displaying items from this number;
$offSet = ($pageStart * $perPage) - $perPage;
// Get only the items you need using array_slice
$itemsForCurrentPage = array_slice($items, $offSet, $perPage, true);
return new LengthAwarePaginator($itemsForCurrentPage, count($items), $perPage,Paginator::resolveCurrentPage(), array('path' => Paginator::resolveCurrentPath()));
}
and add this code:
$gdprecords2 = $gdprecords->sortByDesc('bi_adult')->all();
$perPage = 25;
$sorted_gdprecords = self::paginate($gdprecords2, $perPage);
Thanks for your help. -Philip

Doctrine query builder offset changeable

I'm a Symfony beginner & I'm trying to load my contact from the database using the Doctrine Query Builder as follows:
ContactRepository.php:
public function getcontactByLimit($offset, $limit)
{
$queryBuilder = $this->_em->createQueryBuilder()
->select('contact')
->from($this->_entityName, 'contact')
->setFirstResult( $offset )
->setMaxResults( $limit )
$query = $queryBuilder->getQuery();
$results = $query->getResult();
return $results;
}
DefaultController.php:
$contacts = $repository->getContactByLimit(0, 3);
Now I want to get all contacts I have in the database but just 3 by 3, what means I'm supposed to change the offset value at every loop (to 3 then 6 then 9...)
Have you any idea how to do it ?
It seems for me, that you want to load objects in parts to save memory.
For that, you can use an Iterator:
$query = $queryBuilder->getQuery();
$iterator = $query->iterate();
return $iterator;
And iterate in your Controller
foreach ($iterator as $row) {
}
What will happen, is that doctrine uses PDO and select your result but not read it out directly. There is a cursor on the ResultSet of the Database, which is moving on each iteration. So your PHP-Application will get each Row from Database one by one.
To get 3 by 3 packages, you could use the internal position:
$currentPackage = array();
foreach ($iterator as $position => $row) {
if($position % 3){
// do here something with your 3er package before unset
$currentPackage = array();
$entityManager->clear(); // clear doctrine, could free memory
}
$currentPackage[] = $row;
}
That what I did, & it works fine !
DefaultController.php:
$offset = 0;
$limit = 2;
$sizeData /= $limit;
for( $i = 0; $i < $sizeData; $i++)
{
$contacts = $repository->getListByLimit($offset, $limit);
$sender->setContacts($contacts);
$offset += $limit;
}
ContactRepository.php:
public function getListByLimit($offset, $limit)
{
$queryBuilder = $this->_em->createQueryBuilder()
->select('contact')
->from($this->_entityName, 'contact')
->setFirstResult( $offset )
->setMaxResults( $limit );
$query = $queryBuilder->getQuery();
$results = $query->getResult();
return $results;

Pagination for foreach loop

I currently have a method inside my "car class" that display the car:
static function getCars(){
$autos = DB::query("SELECT * FROM automoviles");
$retorno = array();
foreach($autos as $a){
$automovil = automovil::fromDB($a->marca, $a->modelo, $a->version, $a->year, $a->usuario_id, $a->kilometraje, $a->info,
$a->hits, $a->cilindrada, $a->estado, $a->color, $a->categoria, $a->precio, $a->idAutomovil);
array_push($retorno, $automovil);
}
return $retorno;
}
In my index.php I call that function
foreach(car::getCars() as $a){
That allows me to display the info this way ( of course inside the foreach I have a huge code with the details I'll display.
Is there a way to implement a pagination to that thing so I can handle 8 cars per page, instead of showing all of them at the same page?
You can add a $limit and $page parameter on your function so that it will only return a maximum of $limit number of items starting from $limit * $page(or will call it the $offset). You also need to add a function to get the total number of rows you have for automoviles table.
static function getCars($page = 0, $limit = 8){
$offset = $limit * max(0, $page - 1);
//replace this with prepared statement
$autos = DB::query("SELECT * FROM automoviles LIMIT $offset, $limit");
$retorno = array();
foreach($autos as $a){
$automovil = automovil::fromDB($a->marca, $a->modelo, $a->version, $a->year, $a->usuario_id, $a->kilometraje, $a->info,
$a->hits, $a->cilindrada, $a->estado, $a->color, $a->categoria, $a->precio, $a->idAutomovil);
array_push($retorno, $automovil);
}
return $retorno;
}
static function getTotal()
{
//query to get total number of rows in automoviles table
}
In your index.php do this:
foreach(car::getCars((isset($_GET['page']) ? $_GET['page'] : 1)) as $a){
...
}
and add the pagination links.
$total = car::getTotal();
if($total > 8) {
for($i = 1; $i <= intval(ceil(1.0 * $total / $limit)); $i++) {
echo '' . $i . ';
}
}

codeigniter pagination showing all query results in one page

hi every one i am trying to display mysql database records using codeigniter pagination..for that i written the following below codes..and when i run this it shows me all the results in one page while the page numbers are displayed right according to the given per_page limit..
Model:
function get_records($user_name, $limit, $start) {
$this->db->limit($limit, $start);
$this->db->select('GROUP_CONCAT(cid) AS cIDs');
$this->db->where('user_name', $user_name);
$this->db->group_by("company_user");
$this->db->from('company_records');
$query = $this->db->get();
if ($query->num_rows() > 0) {
foreach ($query->result() as $row) {
$data[] = $row;
}
return $data;
}
return false;
}
function count_records($user_name) {
$this->db->select('GROUP_CONCAT(cid) AS cIDs');
$this->db->where('user_name', $user_name);
$this->db->group_by("company_user");
return $this->db->count_all('company_records');
}
Controller:
$this->load->model('Records', 'Records', TRUE);
$this->load->library('pagination');
$config['base_url'] = base_url() . 'records/index';
$config['total_rows'] = $this->Records->count_records($this->session->userdata('user'));
$config['per_page'] = 10;
$config["uri_segment"] = 4;
$config['use_page_numbers'] = TRUE;
$config['full_tag_open'] = '<div id="pagination">';
$config['full_tag_close'] = '</div>';
$this->pagination->initialize($config);
/* $start = ($this->uri->segment(3)) ? $this->uri->segment(3) : 0; */
if ($this->uri->segment(4) > 0) {
$offset = ($this->uri->segment(4) + 0) * $config['per_page'] - $config['per_page'];
} else {
$offset = $this->uri->segment(4);
}
$data['recordsDetails'] = $this->Records->get_records($this->session->userdata('user'), $config["per_page"], $offset);
$data['pages'] = $this->pagination->create_links();
i have tried google search and stackoverflow.. but not yet found any solutions to this..may be i have issue with the query or i dont know..
please help me...
I used this code for pagination.
In the model
//Search for results
public function search($id, $table, $pageNumber) {
//Get the number of pages
$numOfPage = $this->findResults($id, $table, RETURN_NUM_OF_PAGES, $pageNumber);
if ($numOfPage < 1) {
return false; //If there are no search results return false
} else {
$row = array();
$res = $this->findResults($id, $table, RETURN_RESULTS, $pageNumber);
for ($j = 0; $j < $res->num_rows(); $j++) {
$row[$j] = $res->row($j);
}
return $row; //Return the results
}
}
// Find the results from DB and return number of pages/ results
function findResults($id, $table, $returnType, $pageNumber) {
$this->db->where('id', $id);
$this->db->order_by('reputation', 'desc'); //Order the users by reputation
$itemsPerPage = 4;
$startingItem = ($pageNumber - 1) * $itemsPerPage;
if ($returnType == RETURN_RESULTS) {
$res = $this->db->get($table, $itemsPerPage, $startingItem);
return $res; //Return the results
} else { //Return the number of pages
$res = $this->db->get($table);
$count = $res->num_rows(); //Get the total number of results
$numofPages = (int) ($count / $itemsPerPage);
if ($count % $itemsPerPage != 0)
$numofPages = $numofPages + 1; //If the number of items < $itemsPerPage there should be 1 page
return $numofPages; //Return the number of pages
}
}
So from the controller you have to call the function search($id, $table, $pageNumber).
Also the constants were defined in config/constants.php file as follows.
define('RETURN_NUM_OF_PAGES', 0);
define('RETURN_RESULTS', 1);

Categories