ZF-9731: Zend_Paginator::toJson() returns an object of objects instead of an array of objects

Description

Use case: retrieve paginated data from database, serialize them in JSON and return it to populate a dojox.data.JsonRestStore on the client side.

Here is a code sample of the model:


// ...
$select = $this->select();
$adapter = $select->getAdapter();
$adapter->setFetchMode(Zend_Db::FETCH_ASSOC);
$paginator = new Zend_Paginator(
    new Zend_Paginator_Adapter_DbSelect($select));

And the corresponding code sample of the view script:


// ...
$this->response->setHeader('Content-Type', 'application/json');
$paginator = $this->paginator;
echo $paginator->toJson();

Whatever $adapter->setFetchMode() I choose, I get an object like this:


{
  "0":{"id":"CUSTOMERS","nature":"external","name":"Clients"},
  "1":{"id":"ABCDEFGHI","nature":"consignment","name":"Example"},
  "2":{"id":"SUPPLIERS","nature":"external","name":"Fournisseurs"}
}

If I switch from PHP encoder to built-in encoder (with "Zend_Json::$useBuiltinEncoderDecoder = true;"), I get:


{
  "__className":"ArrayIterator",
  0:{"id":"CUSTOMERS","nature":"external","name":"Clients"},
  1:{"id":"ABCDEFGHI","nature":"consignment","name":"Example"},
  2:{"id":"SUPPLIERS","nature":"external","name":"Fournisseurs"}
}

But a JsonRestStore expects an array of objects like this:


[
  {"id":"CUSTOMERS","nature":"external","name":"Clients"},
  {"id":"ABCDEFGHI","nature":"consignment","name":"Example"},
  {"id":"SUPPLIERS","nature":"external","name":"Fournisseurs"}
]

Comments

I would suggest this modification in Zend_Paginator:


    public function getItemsByPage($pageNumber)
    {
        $pageNumber = $this->normalizePageNumber($pageNumber);

        if ($this->_cacheEnabled()) {
            $data = self::$_cache->load($this->_getCacheId($pageNumber));
            if ($data !== false) {
                return $data;
            }
        }

        $offset = ($pageNumber - 1) * $this->getItemCountPerPage();

        $items = $this->_adapter->getItems($offset, $this->getItemCountPerPage());

        $filter = $this->getFilter();

        if ($filter !== null) {
            $items = $filter->filter($items);
        }

        // ZF-9731 change
        // Previously:
        // if (!$items instanceof Traversable) {
        if (!is_array($items) 
            && (is_object($items) && !$items instanceof Traversable)
        ) {
            $items = new ArrayIterator($items);
        }
        // ...