Integrating Pear Pager with cakephp 1.3

David Jones
@david3jones
avatar-davidejones

On a recent project of mine i decided that in order to overcome a certain problem i was having with pagination that i should try to use a third party addon like the pear pager. This is something i have used before in a non cake app and it seemed to work well and with very little effort so i thought it was worth a try. After some time browsing google and the bakery i came across this article and proceeded to follow the instructions. It appears to work well but i thought i would outline a few changes needed to make it work with cakephp 1.3. Step 1 - Download and install pear pager Download the PEAR pager package from http://pear.php.net/package/Pager. Unpack it and put the libraries in (e.g.) /vendors/Pear/Pager. Step 2 - Make the component Make a new file called “pager.php” and put it into your controllers/components folder and put in the following code.

<?php
class PagerComponent extends Object
{
        /**
         * The (calling) controller object.
         *
         * @access public
         * @var object
         */
         var $Controller;
         /**
          * The pager object.
          *
          * @access public
          * @var object
          */
         var $Pager;
         /**
          * Configuration parameters
          *
          * @access public
          * @var array
          */
         var $params;
        /**
         * Component pseudo controller
         *
         * @access public
         * @param object $controller Calling controller object
         * @return void
         */
        function startup($controller) {
            $this->Controller = $controller;
        }
        /**
         * Initializes the pager. Must be called before using the component.
         *
         * Takes user configuration and creates pager object ($this->Pager)
         *
         * @access public
         * @param array $config Configuration options for Pager::factory() method
         * @see http://pear.php.net/manual/en/package.html.pager.factory.php
         * @return void
         */
        function init($config)
        {
            // Get the correct URL, even with admin routes
            $here = array();
            if (defined('CAKE_ADMIN') !empty($this->Controller->params[CAKE_ADMIN])) {
                $here[0] = $this->Controller->params[CAKE_ADMIN];
                $here[2] = substr($this->Controller->params['action'], strlen($this->Controller->params[CAKE_ADMIN]) + 1);
            } else {
                $here[2] = $this->Controller->params['action'];
            }
            $here[1] = Inflector::underscore($this->Controller->params['controller']);
            ksort($here);
            $url = implode('/', $here);
            // Set up the default configuration vars
            $this->params = array(
                'mode' => 'Sliding',
                'perPage' => 10,
                'delta' => 5,
                'totalItems' => '',
                'httpMethod' => 'GET',
                'currentPage' => 1,
                'linkClass' => 'pager',
                'altFirst' => 'First page',
                'altPrev '=> 'Previous page',
                'altNext' => 'Next page',
                'altLast' => 'Last page',
                'separator' => '',
                'spacesBeforeSeparator' => 1,
                'spacesAfterSeparator' => 1,
                'useSessions' => false,
                'firstPagePre'     => '',
                'firstPagePost' => '',
                'firstPageText' => '![]('.$this->Controller->base.'/img/first.gif) ',
                'lastPagePre' => '',
                'lastPagePost' => '',
                'lastPageText' => '![]('.$this->Controller->base.'/img/last.gif)',
                'prevImg' => '![]('.$this->Controller->base.'/img/prev.gif)',
                'nextImg' => '![]('.$this->Controller->base.'/img/next.gif)',
                'altPage' => 'Page',
                'clearIfVoid' => true,
                'append' => false,
                'path' => '',
                'fileName' => $this->Controller->base . DS . $url . DS . '%d',
                'urlVar' => '',
            );
            //set include path for pear so further includes work
            $path = dirname(dirname(dirname(__FILE__))) . DS . "vendors" . DS . "Pear";
            set_include_path(get_include_path() . PATH_SEPARATOR . $path);
            App::import('Vendor', 'Pear/Pager/Pager');
            // Merge with user config
            $this->params = array_merge($this->params, $config);
            // sanitize requested page number
            if (!in_array($this->params['currentPage'], range(1, ceil($this->params['totalItems'] / $this->params['perPage'])))) {
                $this->params['currentPage'] = 1;
            }
            $this->Pager = Pager::factory($this->params);
            // Set the template vars
            $this->Controller->set('pageLinks',   $this->Pager->getLinks());
            $this->Controller->set('currentPage', $this->params['currentPage']);
            $this->Controller->set('isFirstPage', $this->Pager->isFirstPage());
            $this->Controller->set('isLastPage',  $this->Pager->isLastPage());
        }
?>

The difference with this component is that the way you use vendors has now changed. Also in order for this to work correctly for me i needed to set the include path for the other pear pager files to find what it needed. I imagine you wouldn’t need to do this if you have a pear library already referenced in your php installation. Step 3 - load the component Make sure you add the component to your components array either in app_controller or in the specific controller you are going to use this with.

<?php
var $components = array('Pager');
?>

Step 4 - Using the component After thats done all that is left is to use it in a controller. So fire up your controller and put in some code along the lines of this.

$page = 1;
             // setup the pager
            $params = array(
                'perPage'     => 3,
                'totalItems'  => $this->Department->Document->find('count'),
                'currentPage' => $page,
            );
            $this>Pager->init($params);
            // get the data
            $data = $this->Department->Document->find('all',
                array(
                    'order' => 'Document.created DESC',
                    'limit' => $this->Pager->params['perPage'],
                    'page' => $this->Pager->params['currentPage']
                )
            );
            pr($data);

Step 5 - Setting up the view

<?php
// Display pager if there are pages to display
if ($pageLinks['all']) {
        echo <div id="pager" class="pager">Pages:  ' . $pageLinks['all'] . </div>';
}
?>

it turns out i never needed to use the pear pager after all to solve my problem, i got it working just fine with cakes internal paging. Anyway hopefully this article will be useful to someone…

Comments

    Comments are currently closed