Currently, I am working on Cakephp Application. I want to first paginate and then sort the paginated data according to the condition show below or the other way around. First sort the data and then paginate it. Any hints on how to approach the problem.
I am just one week familiar with cakephp.
$condition[] = 'Banner.customer_id = "'.$loggedUserId.'"';
$this->Banner->recursive = 2;
$this->paginate = array(
'limit' => 20,
);
$data = $this->paginate('Banner', $condition);
$data_sorted = $this->Banner->find('all',array('order'=>array("Banner.created DESC")));
$this->set('loggedInUserId', $loggedUserId);
$this->set('savecrit', $savecrit);
$this->set('Banners', $data_sorted);
Try this:
$this->paginate = array(
'conditions' => array('Banner.customer_id' => $loggedUserId),
'limit' => 20,
'order' => array('id' => 'DESC'),
);
Related
I can't load my Model with 'find' but can load that with 'read'.
I want to get Model attributes by order. But I think 'read' function doesn't have that. How can I use 'find' instead of 'read'?
It works
$itemfiles = $this->Item->read(null, $id);
It doesn't work
$itemfiles = $this->Item->find('all', array(
'order' => array('Upload.order' => 'asc'),
'conditions' => array('Item.id' => $id)
));
And also is there any way to get data by order using 'read'?
You can do this like way
$itemfiles = $this->Item->Upload->find('all',
array (
'conditions' => array('Item.id' => $id),
'order' => array('Upload.order' => 'asc')
)
);
I'm making an application with AngularJS & CakePHP.
I have one web service in Cake that might return data ordered but it doesn't do that, it returns data as came from DB.
This is part of my code:
$this->Paginator->settings = array('limit' => 20, 'page' => $this->request->data['page']+1, 'recursive' => -1);
$data = $this->Paginator->paginate('Country', $conditions, $order);
Anyone have an idea?
Here's the signature of Paginator's paginate component (See http://book.cakephp.org/2.0/en/core-libraries/components/pagination.html#custom-query-pagination):
public function paginate(Model $model, $conditions, $fields, $order, $limit,
$page = 1, $recursive = null, $extra = array())
The second argument you should be passing is fields, not order.
However, you can also just define the order in your settings array, like you do with a find condition.
Try this
$this->paginate = array(
'limit' => 20,
'conditions'=>$conditions,
'order' => $order
);
$data = $this->paginate('Country');
I am making simple pagination which using this code:
$paginate = array(
'limit' => 30,
'fields' => array('DISTINCT Doctor.id','Doctor.*'),
'order' => array('Doctor.id' => 'desc'),
'joins' => array(
array('table' => 'doctors_medical_degrees',
'alias' => 'DoctorsMedicalDegree',
'type' => 'INNER',
'conditions' => array(
'Doctor.id = DoctorsMedicalDegree.doctor_id',
)
),
),
'recursive' => -1,
);
$this->Paginator->settings = $paginate;
$data = $this->Paginator->paginate('Doctor');
Now the problem is I am using Inner join so for Distinct result I am using Distinct Doctor.id, but the cakephp when doing query for pagination the count query not including Distinct Doctor.id
'query' => 'SELECT COUNT(*) AS `count` FROM `pharma`.`doctors` AS `Doctor` INNER JOIN `pharma`.`doctors_medical_degrees` AS `DoctorsMedicalDegree` ON (`Doctor`.`id` = `DoctorsMedicalDegree`.`doctor_id`)'
as you can see No
COUNT(DISTINCT Doctor.id)
so pagination return more number of result which it can actually return for
The problem is that the paginator doesn't pass the fields to the find('count') call, so by default it will always count on *.
But even if it would pass the fields, passing an array would make the find('count') call expect that the field to count is passed as a COUNT() expression, ie something like
'fields' => array('COUNT(DISTINCT Doctor.id) as `count`')
However that won't work with the paginator anyways, so what you need is a customized find('count') call.
Custom query pagination to the rescue
See Cookbook > Pagination > Custom Query Pagination for more information.
Custom query pagination is probably your best bet, that way it's totally up to you how counting is being done.
For example you could make use of the extra values passed by the paginator component, that way you could pass the field to count on to the find('count')` call, something like this (untested example code):
class Doctor extends AppModel {
// ...
public function paginateCount($conditions = null, $recursive = 0, $extra = array()) {
$parameters = compact('conditions');
if($recursive != $this->recursive) {
$parameters['recursive'] = $recursive;
}
if(!empty($extra['countField'])) {
$parameters['fields'] = $extra['countField'];
unset($extra['countField']);
}
return $this->find('count', array_merge($parameters, $extra));
}
}
$this->Paginator->settings = array(
'limit' => 30,
'fields' => array('DISTINCT Doctor.id','Doctor.*'),
// ...
'countField' => 'DISTINCT Doctor.id'
);
$data = $this->Paginator->paginate('Doctor');
This should then create a COUNT query that looks like
SELECT COUNT(DISTINCT Doctor.id) AS `count` ...
I found the solution on CakePHP - Pagination total count differs from actual count when using DISTINCT
Add the public function paginateCount in your model and use the distinct option in your paginator like:
$this->paginate = array('limit' => $limit, 'order' => array('Item.created' => 'ASC', 'Item.code' => 'ASC'),
'fields' => 'DISTINCT Item.*',
'conditions' => $conditions,
'countField' => array('Item.id'),
'joins' => $joins,
'distinct' => 'Item.id',
'contain' => array(
'Image' => array('limit' => 1),
'ItemsTag'
)
);
i have a table in which i want to get only two columns data .. right now i am using findAll method ... i don't know how can I get the specific two fields data in CakePHP
$recentContacts = $this->Contact->find('all',
array(
'order'=>'Contact.idContacts DESC',
'limit' => 6,
'conditions' => array(
'Contact.User_id' => $id)));
in my contacts table there are two fields one is "name" and other is "number"
which I want to extract ...
You can do this by adding fields attribute.
$recentContacts = $this->Contact->find('all',
array
(
'order'=> array( 'Contact.id' , 'Contacts DESC'),
'limit' => 6,
'fields' => array(
'Contact.name',
'Contact.number'
),
'conditions' => array
(
'Contact.User_id' => $id
)
));
you can use like this way with your same code to add fields
$recentContacts = $this->Contact->find('all',
array(
'order'=>'Contact.idContacts DESC',
'limit' => 6,
'fields' => array(
'Contact.name',
'Contact.number'
),
'conditions' => array(
'Contact.User_id' => $id)));
in previous answer they have changed you id instead of idContacts, you can just copy my code and solve your problem.
let me know if i can help you more.
So this is what I am trying to do.
My table say(Courses) has multiple entries with same id.
When I get the data from paginate it shows all the records. So if I have 3 records with Id 5 it will show record number 5 three times.
Now What I want is that it should show the record only once.
I searched online but can't find anything.
If anyone has come across such problem and found a solution to it please let me know.
Thanks,
I came across your problem, as I had a similar problem. David Z's solution did not work for me, but I did find that the group variable in $paginate worked for me.
So using your code sample above, this is how I'd think it should work.
$paginate = array(
'Courses' => array(
'limit' => 20,
'fields' => array('Courses.id'),
'conditions' => $cond,
'group' => array('Courses.id'),
'order' => array('Courses.id' => 'asc')
)
);
To hopefully shed some more light on the solution that worked for me, I have Systems that belong to Companies. I wanted to get a list of the unique companies, for the systems I have. This is the exact code I used, that worked for me
$this->paginate = array ('fields' => array ('Company.*'),
'order' => array('Company.name' => 'ASC'),
'group' => array('Company.id'));
$this->set('companies', $this->paginate($this->Company->System));
Hope this has helped
Looking at the CakePHP cookbook, the documentation for pagination shows that you can override the $paginate member. Behind the scenes, this similar to passing in the parameters for your model's find('all'). Maybe try setting parameter to explicitly return the filds that you are interested with the distinct keyword to narrow down the values you need?
class RecipesController extends AppController {
var $paginate = array(
'fields' => array('Model.field1', 'DISTINCT Model.field2')
);
}
So here is how my paginate variable looks like:
var $paginate = array(
'Courses' => array(
'limit' => 20,
'page' => 1,
'order' => array(
'Courses.id' => 'asc')
),
);
The condition variable looks something like this:
$cond = array("Courses.id LIKE "=>$this->data['id_search'],
"Courses.length LIKE "=>$this->data['length_search'],
"Courses.marks LIKE "=>$this->data['marks']
);
And this is how I am calling paginate.
$data = $this->paginate('CdmaRfReport',$cond);
I tried doing
$paginate = array(
'Courses' => array(
'limit' => 20,
'fields' => array('DISTINCT Courses.id'),
'page' => 1,
'conditions' => $cond,
'group' => array('id'),
'order' => array(
'Courses.id' => 'asc')
)
);
It doesn't seem to help.
I also tried
$cond = array("DISTINCT Courses.id "=>$this->data['id_search'],
"Courses.length LIKE "=>$this->data['length_search'],
"Courses.marks LIKE "=>$this->data['marks']
);
Even this errors out
I might be something wrong. But I am not able to figure it out.
Any suggestions please let me know.