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.
Related
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
I have created following function in controller:
function beg($status_id = null) {
if(!empty($status_id)){
$conditions = array('winner_id >' => 0, 'Product.beginner' => '1', 'Product.status_id' => $status_id);
}else{
$conditions = array('winner_id >' => 0, 'Product.beginner' => '1');
}
$this->paginate = array('conditions' => $conditions, 'limit' => $this->appConfigurations['adminPageLimit'], 'order' => array('end_time' => 'asc'), 'contain' => array('Product' => array('Category'), 'Status', 'Winner'));
$this->set('products', $this->paginate('Product'));
$this->set('statuses', $this->Product->Status->find('list'));
$this->set('selected', $status_id);
$this->set('extraCrumb', array('title' => __('Product List', true), 'url' => 'beg'));
$this->render('beg');
}
I want to add one more condition in it, that is:
Search winner_id from Accounts table match with 'user_id' in accounts table, and only add Products in the list where winner Id is in Accounts table ('user_id' in accounts table).
Anybody know how to add condition with this $conditions = array('winner_id >' => 0, 'Product.beginner' => '1', 'Product.status_id' => $status_id);
I have added on more condition like below
$acc_id = $this->Account->find('all', array('Account.user_id'));
$conditions += array('Product.winner_id' => $acc_id);
But its not working, anybody please tell me where I am getting wrong
if you wanted to add one more condition to the $conditions than you can try using code
$conditions += array('Product.status_id' => $status_id);
hope it will help
yes you can add it with code like below
if ($account_user){
$conditions['accounts.user_id'] = $account_userid;
}
above code will add one more conditions in same array $conditions.
I am struggeling with a custom find in cakephp 2.1.
In my model I have this function:
public function findByGenres($data = array()) {
$this->Item2genre->Behaviors->attach('Containable', array('autoFields' => false));
$this->Item2genre->Behaviors->attach('Search.Searchable');
$query = $this->Item2genre->getQuery('all', array(
'conditions' => array('Genre.name' => $data['genre']),
'fields' => array('item_id'),
'contain' => array('Genre')
));
return $query;
}
This returns the following query:
SELECT `Item`.`id` FROM `items` AS `Item`
WHERE `Item`.`id`
IN(SELECT `Item2genre`.`item_id` FROM `item2genre` AS Item2genre
LEFT JOIN `genres` AS Genre ON(`genre_id` = `Genre`.`id`)
WHERE `Genre`.`name`
IN ('Comedy', 'Thriller')
)
The result of the query returns Items with either 'Comedy' or 'Thriller' genre associated to them.
How can I modify the query to only return Items with 'Comedy' AND 'Thriller' genre associated to them?
Any suggestions?
edit:
content of data is:
'genre' => array(
(int) 0 => 'Comedy',
(int) 1 => 'Thriller'
)
You would want your 'conditions' key to be this:
'conditions' => array(
array('Genre.name' => 'Comedy'),
array('Genre.name' => 'Thriller')
)
So specifically to your problem your $data['genre'] is array('Comedy', 'Thriller'). So you could create a variable that has contents similar to what you need by doing:
$conditions = array();
foreach ($data['genre'] as $genre) {
$conditions[] = array('Genre.name' => $genre);
}
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.
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'));
}