CakePHP pagination maximum limit not working - php

I am using cakephp 2.x. I am unable to set maximum limit of my record.
Please check my code:
App::uses('AppController', 'Controller');
class BroadcastsController extends AppController {
public $components = array('Paginator');
public function broadcast(){
$this->Paginator->settings = array('limit' => 10, 'order' => array('Broadcast.no_of_user' => 'DESC'), 'group' => 'Broadcast.broadcaster_id');
$popularRooms = $this->Paginator->paginate('Broadcast');
pr($popularRooms); //fetch 200 records
$this->set('popularRooms', $popularRooms);
}
}
Above pr($popularRooms); I am getting 200 records but I want first 50 records and per page showing 10 records. I was using 'maxLimit'=>50 but this code same as 'limit'=>50. Please help me.

In that case, you can use the 'extras' array in your paginator setting
$this->Paginator->settings = array('limit' => 10, 'max_record'=>50, 'order' => array('Broadcast.no_of_user' => 'DESC'), 'group' => 'Broadcast.broadcaster_id');
in your model or AppModel overiding the paginateCount function
class Broadcast extends AppModel {
function paginateCount($conditions, $recursive, $extra) {
$param = array_merge(compact('conditions', 'recursive'), $extra);
$count = $this->find('count', $param);
if (!empty($extra['max_record']) && $count > $extra['max_records']) {
$count = $extra['max_record'];
}
return $count;
}
}

By default CakePHP limits the maximum number of rows that can be fetched to 100.You can adjust it as part of the pagination options like below
public $paginate = array(
// other keys here.
'maxLimit' => 10
);
For you code set the maxLimit like this
$this->Paginator->settings = array('limit' => 10,'maxLimit'=>50,'order' => array('Broadcast.no_of_user' => 'DESC'), 'group' => 'Broadcast.broadcaster_id');

public function list_posts() {
$settings = array(
'limit' => 25, // here
'order' => array(
'Post.title' => 'asc'
)
);
$this->Paginator->settings = $this->settings;
// similar to findAll(), but fetches paged results
$data = $this->Paginator->paginate('Posts');
$this->set('data', $data);
}

I believe you don't have to have $this->Paginator->settings =.
public function list_posts() {
$settings = array(
'limit' => 25, // here
'order' => array(
'Post.title' => 'asc'
)
);
// similar to findAll(), but fetches paged results
$data = $this->Paginator->paginate('Posts');
$this->set('data', $data);

Set maxLimit first in your paginator settings before limit like this:
$this->Paginator->settings = array(
'maxLimit' => 50,
'limit' => 10,
'order' => array('Broadcast.no_of_user' => 'DESC'),
'group' => 'Broadcast.broadcaster_id'
);
Only setting one of them logically does not change anything.

Related

How to use parameter in function with pagination CodeIgniter?

I have function which takes state name as a parameter and displays all the cities of that specific state. Since list of cities is very long I have used pagination in the same function but when I click on the 'Next' or any other pagination link the function accepts the offset value in the $state variable. The function is
public function load_Page($state){
$this->load->database();
$this->load->library('pagination');
$a = 1;
$this->db->select("*")->where("userstate" , $a)->where("state" , $state);
$query0 = $this->db->get("city");
$this->db->select("*")->where("userstate" , $a)->where("state" , $state);
$query1 = $this->db->get('city' , 10 , $this->uri->segment(3));
$config["base_url"] = base_url()."index.php/city/load_Page";
$total_row = $query0->num_rows();
$config['page_query_string'] = TRUE;
$config["total_rows"] = $total_row;
$config["per_page"] = 10;
$this->pagination->initialize($config);
$data["state"] = $state;
$data["result"] = $query1->result();
//$data["rows"] = $query1->num_rows();
$this->load->view('header');
$this->load->view('city', $data);
$this->load->view('footer');
}
Is there any other way out to do it or I am going completely wrong?
First of all, when you are paginating, the page number has to come from the URL, and that's always available as a parameter in the controller method. It should default to page 1.
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class City extends CI_Controller {
public function load_page( $state, $page = 1 ){
// I'm going to use an alias for this model
$this->load->model('example_model', 'model');
// Use the URL helper for site_url()
$this->load->helper('url');
// Set pagination config
$config['pagination_settings'] = [
'per_page' => 10,
'use_page_numbers' => TRUE,
'uri_segment' => 4, // This is very important!!!
'base_url' => site_url('city/load_page/' . $state)
];
// Get the total rows
$config['pagination_settings']["total_rows"] = $this->model->pagination_count( $state );
// Load and initialize pagination
$this->load->library('pagination');
$this->pagination->initialize($config['pagination_settings']);
$data = [
'state' => $state,
'rows' => $this->model->get_cities( $state, $page, $config['pagination_settings']['per_page'] ),
'links' => $this->pagination->create_links()
];
// Use data in views or wherever needed ...
$this->load->view('city', $data);
}
/**
* Create the rows to paginate
*/
public function setup()
{
// I'm going to use an alias for this model
$this->load->model('example_model', 'model');
$this->model->setup();
}
// -----------------------------------------------------------------------
}
Next, you should move your database queries to a model. You don't need to use transactions for your 2 select type queries.
<?php
defined('BASEPATH') or exit('No direct script access allowed');
class Example_model extends CI_Model{
public function __construct()
{
parent::__construct();
$this->load->database();
}
public function pagination_count( $state )
{
return $this->db->where("state" , $state)
->count_all_results('city');
}
public function get_cities( $state, $page, $limit )
{
$offset = ( $page * $limit ) - $limit;
$query = $this->db->where("state" , $state)
->limit( $limit, $offset )
->get('city');
if( $query->num_rows() > 0 )
return $query->result();
return NULL;
}
/**
* Setup for testing
*/
public function setup()
{
$this->load->dbforge();
$fields = array(
'id' => array(
'type' => 'INT',
'constraint' => 5,
'unsigned' => TRUE,
'auto_increment' => TRUE
),
'state' => array(
'type' => 'VARCHAR',
'constraint' => '32',
),
'city' => array(
'type' => 'VARCHAR',
'constraint' => '32',
),
);
$this->dbforge->add_field($fields);
$this->dbforge->add_key('id', TRUE);
$this->dbforge->create_table('city', TRUE);
for( $x = 1; $x <= 40; $x++ )
{
$this->db->insert('city', array(
'state' => 'ca',
'city' => 'x' . $x
));
}
}
}
This is the view that I used:
<?php
echo '<h1>' . $state . '</h1>';
echo $links . '<br /><br />';
foreach( $rows as $row )
{
echo $row->city . '<br />';
}
To set up the database for testing, I went to:
http://localhost/index.php/city/setup
Then to check out that the pagination works, I went to:
http://localhost/index.php/city/load_page/ca
It should work for you, as this code is now fully tested.
UPDATE --------------------
If you want to add more parameters to your pagination, do it with query strings. You will need to set the pagination config with this extra setting:
$config['pagination_settings']['reuse_query_string'] = TRUE;
That means the config would look like this:
$config['pagination_settings'] = [
'per_page' => 10,
'use_page_numbers' => TRUE,
'uri_segment' => 4, // This is very important!!!
'base_url' => site_url('city/load_page/' . $state),
'reuse_query_string' => TRUE
];
And then you create the link to the first page with your params:
http://localhost/index.php/city/load_page/ca?a=1&b=2&c=3
And because of the reuse_query_strings being set to TRUE, that means that ?a=1&b=2&c=3 would all be attached to the pagination links.

Show related products, exclude current product from grid

I have a grid that shows related products in Cakephp2, it works just fine however the same product being viewed shows up in the grid of related products, how can i exclude it?
Here is my artworks controller code:
public function view($id = null) {
if (!$this->Artwork->exists($id)) {
throw new NotFoundException(__('Invalid artwork'));
}
$options = array('conditions' => array(
'Artwork.' . $this->Artwork->primaryKey => $id),
'recursive' => 0);
$artwork = $this->Artwork->find('first', $options);
$this->set('artwork', $artwork);
// related artworks
$status = 'Artwork.status';
$id = 'Artwork.artist_id';
$related = $this->Artwork->find('all',
array(
'limit' => 4,
'conditions' => array(
$status => 1,
$id => $artwork['Artwork']['artist_id'])));
$this->set('artworks', $related);
}
You need to exclude the Artwork from related:
'Artwork.id !=' => $artwork['Artwork']['id']
Try this:
public function view($id = null) {
if (!$this->Artwork->exists($id)) {
throw new NotFoundException(__('Invalid artwork'));
}
$options = array('conditions' => array(
'Artwork.' . $this->Artwork->primaryKey => $id),
'recursive' => 0);
$artwork = $this->Artwork->find('first', $options);
$this->set('artwork', $artwork);
// related artworks
$status = 'Artwork.status';
$id = 'Artwork.artist_id';
$related = $this->Artwork->find('all',
array(
'limit' => 4,
'conditions' => array(
$status => 1,
$id => $artwork['Artwork']['artist_id'],
'Artwork.id !=' => $artwork['Artwork']['id']
)));
$this->set('artworks', $related);
}

Why am I getting 'Call to undefined method PaginatorComponent::sort()' in CakePHP 2.x?

I just started learning PHP,cakePHP and I am unable to sort my page.
My Controller is as follows;
public $helpers = array('Html', 'Form', 'Flash', 'Paginator');
public function index()
{
$this->Post->recursive = 0;
$this->paginate = array ('limit' => 5);
$this->set('posts', $this->paginate());
$this->set('posts', $this->Post->find('all'));
echo $this->Paginator->sort('id');
}
Paginate is working fine, but for sort I get a fatal error as follows
Call to undefined method PaginatorComponent::sort()
could not find anything related to the error as well. It might be really basic but it will really help me to learn more, and I want to learn more! Any help will be appreciated.
Thank you in advance!
Update:
I added the following code in my index view,
<th><?php echo $paginator->sort('Id', 'id'); ?></th>
But now I am getting the following error
Call to a member function sort() on null
I believe you are trying to set pagination defaults. The proper way of doing so is defining in your controller:
public $paginate = array(
'order' => array(
'Post.id' => 'desc'
)
);
or in the action:
$this->paginate = array (
'limit' => 5,
'order' => array(
'Post.id' => 'desc'
)
);
Your index action should look like this:
public function index() {
$this->Post->recursive = 0;
$this->paginate = array (
'limit' => 5,
'order' => array(
'Post.id' => 'desc'
)
);
$this->Paginator->settings = $this->paginate;
$this->set('posts', $this->paginate());
}
In your view, the correct syntax for CakePHP 2.x is
<?php echo $this->Paginator->sort('id'); ?>
In my index()
$this->paginate = array ('limit' => 5);
later in my index view I used
<?php echo $this->Paginator->sort('id','Id'); ?>
syntax : this->Paginator->sort('column name','label name');
Instead of normal html code. And it worked!

pagination is not working with store procedure in yii

I wants to do pagination with Store Procedure yii, when i load page first time it shows me 10 records but when i click on 2nd page it shows me no record found, Here is my code
if(isset($_GET['page']) && $_GET['page']!='') {
$page = $_GET['page'];
} else {
$page = 1;
}
$SP = "CALL Dormantreport(1,'2015-01-01','2015-12-31','',".$page.",10)";
$command = Yii::app()->db->createCommand($SP);
$rawDataWithArray = $command->queryAll();
$filteredData=$filtersForm->filter($rawDataWithArray);
$model = new CArrayDataProvider($rawDataWithArray, array(
'keyField' => 'MemberID',
'totalItemCount' => 78, //count($rawDataWithArray),
'sort' => array(
'attributes' => array(
'MemberID',
),
'defaultOrder' => array(
'MemberID' => CSort::SORT_DESC,
),
),
'pagination' => array(
'pageSize' => $PageSize,
),
));
return $model;
Can anyone please tell me what i need to do now to solve this pagination issue, any help will be really appreciated,
In your model,
public function search() {
// #todo Please modify the following code to remove attributes that should not be searched.
$criteria = new CDbCriteria;
$criteria->order = 'employeedetailsid DESC';
$criteria->compare('employeedetailsid', $this->employeedetailsid);
$criteria->compare('employeemasterid', $this->employeemasterid);
$criteria->compare('employeedetails_qualification', $this->employeedetails_qualification, true);
$criteria->compare('employeedetails_experience', $this->employeedetails_experience, true);
$criteria->compare('employeedetails_address1', $this->employeedetails_address1, true);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
'pagination' => array(
'pagesize' => 25,
)
));
}
Try this....

CakePHP trouble linking data from 2 tables in models

I am having trouble with linking data like first name from the table Users in the view of chats using cakePHP. Below is my code and whatever I do, the script does not select the user_id from the chats database table to display the first name. I must be overseeing something, but the loop I'm thinking in is giving me some headaches. Can someone please get me out of this loop?
User.php
<?php
class User extends AppModel {
public $hasMany = array(
'Ondutylog',
'Chat'
);
}
?>
Chat.php
<?php
class Chat extends AppModel {
public $belongsTo = array(
'User'
);
}
?>
ChatsController.php
<?php
class ChatsController extends AppController {
var $uses = array('User', 'Chat');
public function view() {
$chats = $this->Chat->find('all', array(
'order' => array('id' => 'ASC'),
'recursive' => -1
));
$this->set('chats', $chats);
$id = $chats['Chat']['user_id'];
$userdetails = $this->Chat->User->find('first', array(
'conditions' => array(
'id' => $id
),
recursive' => -1
));
return $userdetails;
}
}
?>
view.ctp
<?php
foreach($chats as $chat) :
echo "<tr>";
echo "<td>".$userdetails['User']['firstname']."</td>";
echo "<td>".$chat['Chat']['user_id']."</td>";
echo "<td>".$chat['Chat']['text']."</td>";
echo "<td>".$chat['Chat']['created']."</td>";
echo "</tr>";
endforeach
?>
The array I get returned in $chats
[Chat] => Array
(
[id] => 1
[user_id] => 11
[text] => hello
[created] => 2014-05-21 19:56:16
[modified] => 2014-05-21 19:56:16
)
Change
return $userdetails;
to
$this->set(compact('userDetails'));
You are supposed to set the view var not return the info.
Though why are you making a separate query for it instead of just using 'recursive' => 0 which would get the associated user record through table join and you can just use $chat['User']['firstname'] in view.
Also get rid of var $uses = array('User', 'Chat');. It's not needed. $this->Chat is already available and the User model is accessed through association as $this->Chat->User as you have already done.
You need charge the model in your controller
class ChatsController extends AppController {
public function view() {
$this->loadModel('User');
$this->loadModel('Chat');
$chats = $this->Chat->find('all', array(
'order' => array('id' => 'ASC'),
'recursive' => -1
));
$this->set('chats', $chats);
$id = $chats['Chat']['user_id'];
$userdetails = $this->Chat->User->find('first', array(
'conditions' => array(
'id' => $id
),
recursive => -1
));
$this->set(compact('userDetails'));
}
}
I found the solution and it's closer than I thought of myself. Because the Models User and Chat were already joined I just had to use a couple of lines in the Controller. So I modified it like this:
public function view() {
$chats = $this->Chat->find('all');
$this->set('chats', $chats);
}
And nothing more...

Categories