How to paginate an array query result in cakephp 3

908 Views Asked by At
  1. Hello, I have an array of query results that I want to be paginated. But somehow I got an error that says :

Unable to locate an object compatible with paginate.

Here's my current code:

        $this->paginate = ['limit' => 10];

        $comment = TableRegistry::get('Comments');
        $comments = $comment
            ->find()
            ->where(['Comments.post_id' => $id])
            ->contain(['Users'])
            ->order(['Comments.created' => 'ASC'])
            ->all()
            ->toArray(); //the results will be array

        $comments = $this->paginate($comments);
  1. My second question is, is there a way to always have an array result instead of object results when having a query in the controller so that I won't need to include ->toArray() into my code?

Thank you!

1

There are 1 best solutions below

0
On

The built in paginator doesn't supports arrays, it only works with queries. You'd have to build a custom paginator if you needed to paginate an array.

However there's no need to pass an array in the first place, pass a query instead, and if it's really necessary, convert the result set that the paginator returns (\Cake\ORM\ResultSet|\Cake\Datasource\ResultSetInterface) into an array instead, it's the same outcome, ie:

$comments = $comment
    ->find()
    ->where(['Comments.post_id' => $id])
    ->contain(['Users'])
    ->order(['Comments.created' => 'ASC']);

$comments = $this->paginate($comments);
$comments = $comments->toArray();

I'm not sure why you'd do that though, as the result set implements \ArrayAccess, ie it can be iterated and accessed just like an array, you're just limiting yourself by doing this conversion.

Furthermore there's no really straightforward way to automate this, the only thing that comes close would be to use the model's beforeFind() event/callback to modify the query, and attach a result formatter that converts the result set into an array, but result formatters are kinda expected to return \Cake\Collection\CollectionInterface, as they are somewhat promised to also receive that. Formatters are processed in sequence, and a subsequent formatter will receive the value that previous formatter returns.