Cameron
Cameron

Reputation: 28793

Pagination in CakePHP 3.0

I have been playing with the developer preview version of CakePHP 3.0 and I'm stuck trying to get the new ORM working with pagination.

In my PostsController.php I have:

<?php

namespace App\Controller;

use App\Controller\AppController;

class PostsController extends AppController {

    public $name = 'Posts';

    public $uses = 'Posts';

    public $components = ['Paginator'];

    public $paginate = [
        'fields' => ['Posts.id'],
        'limit' => 1,
        'order' => [
            'Post.id' => 'asc'
        ]
    ];

    public function index() {

        $posts = $this->paginate('Posts');

        $this->set('posts', $posts);


    }

}

However the paging is working but the data doesn't come back. Apparently this because the data isn't directly returned in the new ORM but an object... Has anyone tried this yet? Knows how to fix the issue to get it working with the paginator?

I've been reading the Migration Guide: http://book.cakephp.org/3.0/en/appendices/orm-migration.html but don't see anything about combining it with the paginator.

Note: I can't debug $posts and show it here because it's about 2000 lines of code containing all sorts of stuff about the ORM. Here's a taster...

object(Cake\ORM\ResultSet) {
    [protected] _query => object(Cake\ORM\Query) {
        [protected] _table => object(Cake\ORM\Table) {
            [protected] _table => 'posts'
            [protected] _alias => 'Posts'
            [protected] _connection => object(Cake\Database\Connection) {
                [protected] _config => array(
                    'password' => '*****',
                    'login' => '*****',
                    'host' => '*****',
                    'database' => '*****',
                    'prefix' => '*****',
                    'persistent' => false,
                    'encoding' => 'utf8',
                    'name' => 'default',
                    'datasource' => object(Cake\Database\Driver\Mysql) {
                        [protected] _baseConfig => array(
                            'password' => '*****',
                            'login' => '*****',
                            'host' => '*****',
                            'database' => '*****',
                            'port' => '*****',
                            'persistent' => true,
                            'flags' => array(),
                            'encoding' => 'utf8',
                            'timezone' => null,
                            'init' => array(),
                            'dsn' => null
                        )
                        [protected] _config => array(
                            'password' => '*****',
                            'login' => '*****',
                            'host' => '*****',
                            'database' => '*****',
                            'port' => '*****',
                            'prefix' => '*****',
                            'persistent' => false,
                            'encoding' => 'utf8',
                            'name' => 'default',
                            'flags' => array(),
                            'timezone' => null,
                            'init' => array(),
                            'dsn' => null
                        )
                        [protected] _autoQuoting => false...

So as you can see it's a huge object and presumably the data is somewhere within it.

Upvotes: 4

Views: 10383

Answers (2)

Naresh Dudhat
Naresh Dudhat

Reputation: 245

This will be in your controller.

public function index() {
         $this->set('users', $this->paginate($this->Users));
         $this->set('_serialize', ['users'])
}

This you can put in your action

Paginatore logic

Upvotes: 0

floriank
floriank

Reputation: 25698

Apparently this because the data isn't directly returned in the new ORM but an object...

It's not a bug it's a feature. ;) CakePHP3 returns a ResultSet object as you can see and entity objects for records. You'll have to work with these objects now instead of arrays.

I wounder if you really read the migration guide you've linked because it is all in there:

  • Cake\ORM\ResultSet - A collection of results that gives powerful tools for manipulating data in aggregate.
  • Cake\ORM\Entity - Represents a single row result. Makes accessing data and serializing to various formats a snap.

Further down on that page there is even more info about that. Take a look at the ResultSet API. You'll see that it implements Iterator, you can use it like an array:

Controller method:

public function index() {
    $this->set('users', $this->Paginator->paginate($this->Users, [
        'limit' => 5,
        'conditions' => [
            'Users.active' => 1
        ]
    ]));
}

There is a lot of documentation to read in the doc block of the paginate() method.

View index.ctp:

foreach ($users as $user) {
    debug($user);
}

This will show you Entity objects. I'm not pasting the whole long debug output here, just a part of it.

object(Cake\ORM\Entity) {
    [protected] _properties => array(
        'password' => '*****',
        'id' => '52892217-91ec-4e5d-a9f4-1b6cc0a8000a',
        'username' => 'burzum',
        'slug' => '',
        // ...

To get something from the object back just do this:

echo $user->username;

The actual data is in the protected property Entity::$_properties and accessed by __get.

Upvotes: 2

Related Questions