Zend_Paginator and Zend_Db_Table
I had been waiting for a pagination component to be added to the Zend Framework for quite some time, so when Jurrien Stutterheim and Matthew Ratzloff’s proposal got accepted I couldn’t wait to give it a try, however, I came across a problems almost instantly. By default the Zend_Paginator_Adapter_DbSelect doesn’t like Zend_Db_Table_Select objects and throws the following exception: “No table has been specified for the FROM clause”.
After searching the mailing lists I came across a solution, which works by force setting the from table in the select object:
$table = new Users();
$select = $table->select()->from($table);
$paginator = Zend_Paginator::factory($select);
However, the result of the query is returned as an array rather than a Zend_Db_Table_Rowset object. The downside of this is that I often use a Zend_Db_Table/Zend_Db_Table_Row combination as my model. To make this possible I have extended the Zend_Paginator_Adapter_DbSelect class, this is the code:
class Noginn_Paginator_Adapter_DbTable extends Zend_Paginator_Adapter_DbSelect
{
/**
* The table to select from
*
* @var Zend_Db_Table
*/
protected $_table;
/**
* Constructor.
*
* @param Zend_Db_Table_Select $select The select query
* @param Zend_Db_Table $table The table to select from
*/
public function __construct(Zend_Db_Table_Select $select, Zend_Db_Table $table)
{
$this->_select = $select;
$this->_table = $table;
}
/**
* Returns a rowset object
*
* @param integer $offset Page offset
* @param integer $itemCountPerPage Number of items per page
* @return Zend_Db_Table_Rowset
*/
public function getItems($offset, $itemCountPerPage)
{
$this->_select->limit($itemCountPerPage, $offset);
return $this->_table->fetchAll($this->_select);
}
/**
* Returns the total number of rows in the result set.
*
* @return integer
*/
public function count()
{
if ($this->_rowCount === null) {
$expression = new Zend_Db_Expr('COUNT(*) AS ' . self::ROW_COUNT_COLUMN);
$rowCount = clone $this->_select;
$rowCount->from($this->_table)
->reset(Zend_Db_Select::COLUMNS)
->reset(Zend_Db_Select::ORDER)
->reset(Zend_Db_Select::LIMIT_OFFSET)
->columns($expression);
$this->setRowCount($rowCount);
}
return $this->_rowCount;
}
}
Example usage of the class:
$table = new Users();
$select = $table->select()->order('last_name ASC');
$paginator = new Zend_Paginator(Noginn_Paginator_Adapter_DbTable($select, $table);
This is working well for me, but I would be interested to hear of any better solutions.
On a side note I am currently looking at the Zend_Model proposal also by Jurrien Stutterheim, which so far looks fairly promising and already has a custom paginator adapter.












3 Comments
2. John posted on 01/10/2008 at 4:02 PM
Thanks for this, it clarifies nicely. However where do you place the extension, what filename do you save it as, and how is it called? I understand how the extension would work, but am having a hard time getting the Zend Framework to see the extension.
Thank you!
John
3. Tom posted on 01/10/2008 at 4:55 PM
Hi John,
I’m glad you found it useful.
If you save the Noginn_Paginator_Adapter_DbTable class to
library/Noginn/Paginator/Adapter/DbTable.phpthen it should get picked loaded by the Zend_Loader autoloader.
Tom
4. John posted on 01/10/2008 at 5:44 PM
Aha! I was putting in in the wrong location, works perfect now. Thanks again!