October 13, 2013

12:31 pm
In this article, we are going to discuss about How to achieve pagination cachin in CakePHP. Pagination is nothing but, it is a mechanism which provides users with additional navigation options for browsing through single parts of the given article. Parts of the article are usually referred to by numbers, hints, arrows as well as "previous" and "next"-buttons. In this, we are going to discuss about How to achieve this in CakePHP.

In most cases pagination is better than traditional "previous – next" navigation as it offers visitors a more quick and convenient navigation through the site. It's not a must, but a useful nice-to-have-feature.

If we have large number of datas it will producing unneccessary high load on the database. To reduce the load in database, we can use "Caching". Unlike normal returned data from the database paginated data can not be cached as easily, as the paginate method needs to be called to generate the pagination numbers etc. So we need to do a custom pagination query with cache built in.

To implement pagination caching in CakePHP, add the below code in your app_model.php file.

function paginate ($conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = array()) 
{
    $args = func_get_args();
    $uniqueCacheId = '';
    foreach ($args as $arg) {
        $uniqueCacheId .= serialize($arg);
    }
    if (!empty($extra['contain'])) {
        $contain = $extra['contain'];   
    }
    $uniqueCacheId = md5($uniqueCacheId);
    $pagination = Cache::read('pagination-'.$this->alias.'-'.$uniqueCacheId, 'paginate_cache');
    if (empty($pagination)) {
        $pagination = $this->find('all', compact('conditions', 'fields', 'order', 'limit', 'page', 'recursive', 'group', 'contain'));
        Cache::write('pagination-'.$this->alias.'-'.$uniqueCacheId, $pagination, 'paginate_cache');
    }
    return $pagination;
}

function paginateCount ($conditions = null, $recursive = 0, $extra = array()) {
    $args = func_get_args();
    $uniqueCacheId = '';
    foreach ($args as $arg) {
        $uniqueCacheId .= serialize($arg);
    }
    $uniqueCacheId = md5($uniqueCacheId);
    if (!empty($extra['contain'])) {
        $contain = $extra['contain'];   
    }
     
    $paginationcount = Cache::read('paginationcount-'.$this->alias.'-'.$uniqueCacheId, 'paginate_cache');
    if (empty($paginationcount)) {
        $paginationcount = $this->find('count', compact('conditions', 'contain', 'recursive'));
        Cache::write('paginationcount-'.$this->alias.'-'.$uniqueCacheId, $paginationcount, 'paginate_cache');
    }
    return $paginationcount;
}

This will then take over from any paginate calls and generate a cached version of the dataset for the paginated items and the pagination controls, unique to each page and query set.


You need to specify the caching rule in core.php, something like:

Cache::config('paginate_cache', array(
    'engine'        => 'File',
    'path'      => CACHE .'sql'. DS,
    'serialize' => true,
        'duration' => '+1 hour',
));

0 comments:

Post a Comment