Sorting on aggregate and composite fields using pagination in 1.2

By Michael Clark (michaelc)
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.
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 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($typearray_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 1334

CakePHP Team Comments Author Comments
 

Question

1 View caching and pagination

Hi,

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
Posted Jun 6, 2010 by Pramod