Home > PHP, Zend Framework > Filters for Zend_Paginator

Filters for Zend_Paginator

January 13th, 2009 Leave a comment Go to comments

Zend_Paginator has a new feature! It is now possible to add a filter to your Paginator object which acts on the data retrieved from the adapter. This filter can be any instance of Zend_Filter_Interface, including a filter-chain. If a filter(-chain) is set, the raw data from the adapter will be passed to the filter() method.


So why would you want to apply filters to your result set? Usually my domain models don’t inherit from Zend_Db_Table_Row but that is the data type I get from the Paginator when I use the DbTableSelect adapter (wrapped in a nice Zend_Db_Table_Rowset). Instead, I would like to load my rows into my models and preferably without using the Paginator abilities or having to apply weird hacks. Previously this was only possible (in a sane way) by subclassing an adapter so it could return a collection of model objects instead of a rowset. With the new filter support you can just inject a filter to do this for you.

Lets have a look at an example. In this example I want to list all my users from the database. I’ll grab the name of the user from the row and inject it into a User object.

<?php
class User
{
    private $_name = '';

    public function getName()
    {
        return $this->_name;
    }

    public function setName($name)
    {
        $this->_name = $name;
    }
}

class UserFilter implements Zend_Filter_Interface
{
    public function filter($rows)
    {
        $users = array();

        foreach ($rows as $row) {
            $user = new User();
            $user->setName($row->name);

            $users[] = $user;
        }

        return $rows;
    }
}

class MyModel
{
    public static function getUserPaginator()
    {
        $userTable = new UserTable();
        $paginator = Zend_Paginator::factory($userTable->select());
        $paginator->setFilter(new UserFilter());

        return $paginator;
    }
}

$paginator = MyModel::getUserPaginator();
$items = $paginator->getCurrentItems();

foreach ($items as $user) {
    echo 'Current name: ' . $user->getName() . '<br />' . PHP_EOL;
}

To simplify adding a simple filter to your paginator I’ve also added Zend_Filter_Callback. This allows you to specify a callback method that does the same as the filter in the previous example.

<?php
class MyModel
{
    public static function getUserPaginator()
    {
        $userTable = new UserTable();
        $paginator = Zend_Paginator::factory($userTable->select());
        $paginator->setFilter(new Zend_Filter_Callback(
            array('MyModel', 'filter'))
        );

        return $paginator;
    }

    public static function filter($rows)
    {
        $users = array();

        foreach ($rows as $row) {
            $user = new User();
            $user->setName($row->name);

            $users[] = $user;
        }

        return $rows;
    }
}

The callback also accepts object instead of a static reference to a class. Internally it uses call_user_func to execute the filter() method, so any notation that works there, works with the Callback filter.

Enjoy!

Categories: PHP, Zend Framework Tags:
  1. No comments yet.
  1. No trackbacks yet.