Sorting on aggregate and composite fields using pagination in 1.2
While it may not be a common problem, I ran into this while working on a simple website I was building, and have recieved permission to share it with the community. I had a paginated table, and wanted a SUMed column to support sorting. This is how I did it.
Note that the coming release of CakePHP 1.3, has an awesome feature known as Virtual Fields http://book.cakephp.org/view/1608/Virtual-fields, which are far superior to this little trick.
Note that the coming release of CakePHP 1.3, has an awesome feature known as Virtual Fields http://book.cakephp.org/view/1608/Virtual-fields, which are far superior to this little trick.
The first step was to disable CakePHP's field check for the field in question, let's call it `sum`. So, I added
Download code
It's not a cut and paste solution, but hopefully helps others with this same task. When CakePHP 1.3 is released it will be easier to just use a virtual field.
Download code
function hasField($name) {
if ($name === 'sum') {
return true;
}
return parent::hasField($name);
}
to my model. This reveals a second step - now that Cake has been tricked into thinking that field is in the table, it specifies the table name. To remove it, I created the paginate() method in my model, as seen below:Model Class:
Download code
<?php
class DemoModel extends AppModel {
var $name = 'Demo';
function hasField($name) {
if ($name === 'sum') {
return true;
}
return parent::hasField($name);
}
function paginate($conditions, $fields, $order, $limit, $page, $recursive, $extra) {
// Perform an in-place key replacement, preserving order
if (isset($order['Demo.sum'])) {
$keys = array_keys($order);
$vals = array_values($order);
if( ($index = array_search('Demo.sum', $keys)) !== false) {
$keys[$index] = 'sum';
}
$order = array_combine($keys, $vals);
}
$type = 'all';
if (isset($extra['type'])) {
$type = $extra['type'];
}
$parameters = compact('conditions', 'fields', 'order', 'limit', 'page');
if ($recursive != $this->recursive) {
$parameters['recursive'] = $recursive;
}
$results = $this->find($type, array_merge($parameters, $extra));
return $results;
}
}
?>
It's not a cut and paste solution, but hopefully helps others with this same task. When CakePHP 1.3 is released it will be easier to just use a virtual field.
Comments
Question
1 View caching and pagination
I am viewing with a paginated view results using Ajax caching'm trying to set in Cake 1.1.
Hi.. Michael Clark,
I'm getting some strange behavior and I think is a bug.
I turn on caching in core.php, so I cached a whole controller.
Index / controller when to go (paginated view) right first time
There is as yet any caching. But then when I return I just
Cached without visual layout. This is because when I think
Pagination component for the index to process AJAX requests
It only gets control content, layout without such,
The only thing that is cached without visual layout.
So what we should do now For use it in cake 1.2