How to Limit the paginate in cakephp ?
Assume that i have 400 records.
I need to get only 25 records from 50th record to 75th record
and need to display 5 records per page.
How i can do this in paginate ?
Sample Code:
$this->paginate = array(
'contain'=>array('User'),
'recursive' => 2,
'order' => array('Profile.winning' => 'DESC'),
'limit' =>5
);
You can set conditions for the pagination.
function listRecords()
{
$this->paginate = array(
'conditions' => array('Model.id >=' => 50, 'Model.id <=' => 75),
'limit' => 5
);
$this->paginate('Model');
);
EDIT:
A solution from here:
$this->paginate = array(
'limit' => 20,
'totallimit' => 1000
);
And then in the Model:
public function paginateCount($conditions = null, $recursive = 0, $extra = array())
{
if( isset($extra['totallimit']) ) return $extra['totallimit'];
}
Improved version with reference of: http://www.mainelydesign.com/blog/view/best-paginatecount-cakephp-with-group-by-support
This return the correct total count base on whichever is less.
public function paginateCount($conditions = null, $recursive = 0, $extra = array())
{
$conditions = compact('conditions');
if ($recursive != $this->recursive) {
$conditions['recursive'] = $recursive;
}
unset( $extra['contain'] );
$count = $this->find('count', array_merge($conditions, $extra));
if (isset($extra['group'])) {
$count = $this->getAffectedRows();
}
if (isset($extra['totallimit']) && $extra['totallimit'] < $count) {
return $extra['totallimit'];
}
return $count;
}
Use maxLimit in CakePHP v2.x .
public $paginate = array(
// other keys here.
'maxLimit' => 10
);
read more about it here.
$query = $this->User->find('all', [
'recursive' => 2,
'order' => array('Profile.winning' => 'DESC'),
'limit' => 25,
'offset' => 50
]);
$this->paginate = array(
$query,
'limit' => 5
);
In cakephp 4.x version we have to call like below
public function index()
{
$this->loadComponent('Paginator');
$settings = array(
'limit' => 50
);
$prices = $this->Paginator->paginate($this->Prices->find(), $settings);
$this->set(compact('prices'));
}
Related
I am paginating associated model in view() function of another model.
public function view($id = null)
{
$category = $this->Categories->get($id, [
'contain' => ['Subcategories']
]);
// paginate products
$products = $this->paginate($this->Categories->Products->findByCategoryId($category->id, ['conditions' => ['stock >' => 0, 'selling_price >' => 0]]), [
'limit' => 21
]);
$this->set('products', $products);
$this->set('category', $category);
$this->set('_serialize', ['category']);
}
I want to restrict data to find where stock and selling_price is greater than 0.
But this is not working. How to apply conditions on findById ?
Try this :
$products = $this->paginate($this->Products->findByCategoryId($categoryId)->where(['stock >' => 0, 'selling_price >' => 0])->limit(21));
with $categoryId given.
I created a custom find type, and am trying to paginate the results, but the paginator seems to be ignoring the findType setting. Can someone tell me what I'm doing wrong?
(CakePHP 2.X)
In my Controller:
public function list($username=null) {
$this->Paginator->settings = array(
'Question' => array(
'findType' => 'unanswered',
'conditions' => array('Question.private' => 0),
);
$data = $this->Paginator->paginate('Question');
$this->set('data', $data);
);
Custom find type setup in my Model:
public $findMethods = array('unanswered' => true);
protected function _findUnanswered($state, $query, $results = array()) {
if ($state == 'before') {
$query['order'] = array('Question.created DESC');
$query['conditions'] = array_merge($query['conditions'], array('Question.date_answered' => ''));
return $query;
$this->log($query);
} elseif ($state == 'after') {
return $results;
}
}
Edit
I can paginate the query if I remove $this->Paginate->settings, and replace it with this:
$this->paginate = array('unanswered');
However, I want to add some additional conditions., this doesn't work:
$this->paginate = array('unanswered' => 'conditions' => array('Question.user_id' => $id, 'limit' => 4)) );
Is this possible?
findType was added to the paginator component in CakePHP 2.3, I was on 2.0
http://api.cakephp.org/2.3/class-PaginatorComponent.html
actually, i want to meet this sql requirement:
... where (type_id = 6 OR type_id = 8) and status = 2 ....
but i don NOT know how to set conditions in $paginate.
var $paginate = array(
'Student'=>array(
'limit' => 10,
'fields'=>array('Student.id','Student.firstname','Student.lastname'),
'order' =>array('Student.id'=>'desc'),
'conditions' => ?,
),
);
any one knows how to set conditions ?
Based on this site http://book.cakephp.org/1.3/view/1030/Complex-Find-Conditions
(It's not the lastes release, but try it)
var $paginate = array(
'Student'=>array(
'limit' => 10,
'fields'=>array('Student.id','Student.firstname','Student.lastname'),
'order' =>array('Student.id'=>'desc'),
'conditions' => array(
'Student.type_id' => array(6, 8),
'Student.status' => 2
)
),
);
or
var $paginate = array(
'Student'=>array(
'limit' => 10,
'fields'=>array('Student.id','Student.firstname','Student.lastname'),
'order' =>array('Student.id'=>'desc'),
'conditions' => array(
'Student.status' => 2,
"OR" => array (
'Student.type_id' => 6,
'Student.type_id' => 8
)
)
),
);
EDIT: This second version cannot be used in this situation, because now the OR array have two elements with the same keys and will check only the last (8)
[N.B.] Excuse me if I made some syntax error :)
Controller:
$data =
array(
'ContentI18n' =>
array(
0 =>
array(
'title' => 'first',
'author' => 'first',
'source' => 'sgfsdfrst',
'lang' => 'fa',
),
),
'Content' =>
array(
'publish' => 1,
'type' => 3,
'pages' => 8,
'volume' => 7,
'modified' => '2012-05-27 14:16:37',
'created' => '2012-05-27 14:16:37',
'lang' => 'fa',
),
);
$this->Content->create();
$this->Content->saveAll($data);
Model:
public $hasMany = array(
'ContentI18n' => array(
'className' => 'ContentI18n',
)
);
beforeSave function in behavior:
public function beforeSave(Model $model) {
// Define the new Translate model
App::uses($model->name . 'I18n', 'Model');
$varI18n = $model->name . 'I18n';
$modelI18n = new $varI18n;
foreach ($model->data[$model->name] as $key => $data) {
if (!in_array($key, $this->setting))
$modelData[$model->name][$key] = $data;
else
$modelData[$model->name . 'I18n'][0][$key] = $data;
}
$modelData[$model->name . 'I18n'][0]['lang'] = $model->locale;
$modelData[$model->name]['lang'] = $model->locale;
$model->data = $modelData;
//pr($model->data);
return TRUE;
}
every things seems be cause when is save it directly it's save with saveAll. but when i use same structure of data in behavior did not work without any error.
I found out that beforeSave callback will not trigger by saveAll. for executing some code before saveAll we must override saveAll function in our model.
public function saveAll($data, $options = array()) {
/*
your code you want execute before saving...
*/
parent::saveAll($data, $options);
}
for other saving methods such as saveMany,saveAssociated,... beforeSave trigger by them.
To get the DB result in basis of condition
if($keyword!='')
build condition;
/*
array('conditions' => array("AND" => array ("esl.esl_artistname LIKE"=>"%".$artistname."%",
"esl.esl_songname LIKE"=>"%".$songname."%")),
'limit' => $arrFind['limit'],
'page'=>$arrFind['page']));
*/
if(!name!='')
/*
array('conditions' => array("esl.esl_artistname LIKE"=>"%".$artistname."%"),
'limit' => $arrFind['limit'],
'page'=>$arrFind['page'] ))
*/
$this->find('all',condition);
how to do this? how to concatenate both conditions?
Why not initialize the conditions array and just append to it?
$conditions = array();
if( keyword != '' ) {
array_push(
'conditions'
, array( "AND" => array ("esl.esl_artistname LIKE"=>"%".$artistname."%", "esl.esl_songname LIKE"=>"%".$songname."%" ) )
}
if( !name != '' ) {
array_push( 'conditions', array("esl.esl_artistname LIKE"=>"%".$artistname."%")
}
$this->find( 'all', array( 'conditions' => $conditions, 'limit' => $arrFind['limit'], 'page' => $arrFind['page'];
I would do something like Rob Wilkerson suggested but like this:
$conditions = array();
if(keyword != '') {
$conditions[] = array( "AND" => array ("esl.esl_artistname LIKE"=>"%".$artistname."%", "esl.esl_songname LIKE"=>"%".$songname."%" ) );
}
if(!name != '') {
$conditions[] = array("esl.esl_artistname LIKE"=>"%".$artistname."%");
}
$this->find( 'all', array( 'conditions' => $conditions, 'limit' => $arrFind['limit'], 'page' => $arrFind['page'];
Concatenating condition could be done in following way:
$condition1 = array('Model1.field1 LIKE'=>'%'.$value.'%', 'Model1.field2'=>2);
$condition2 = array('Model2.field2 LIKE'=>'%'.$value.'%', 'Model2.field2'=>1);
$this->MyModel->find('all', array('conditions'=>am($condition1, $condition2)));
am is the cake's shortcut to array_merge.