James Dawson
James Dawson

Reputation: 5409

Using pagination with a custom model method in CakePHP

I'm setting up pagination to display a list of images belonging to the user in their account. This is what I have in my controller:

class UsersController extends AppController {

    public $paginate = array(
        'limit' => 5,
        'order' => array(
            'Image.uploaded' => 'DESC'
        )
    );

    // ...

    public function images() {
        $this->set('title_for_layout', 'Your images');

        $albums = $this->Album->find('all', array(
            'conditions' => array('Album.user_id' => $this->Auth->user('id'))
        ));
        $this->set('albums', $albums);

        // Grab the users images
        $options['userID'] = $this->Auth->user('id');
        $images = $this->paginate('Image');
        $this->set('images', $images);
    }

    // ...

}

It works, but before I implemented this pagination I had a custom method in my Image model to grab the users images. Here it is:

public function getImages($options) {
    $params = array('conditions' => array());

    // Specific user
    if (!empty($options['userID'])) {
        array_push($params['conditions'], array('Image.user_id' => $options['userID']));
    }

    // Specific album
    if (!empty($options['albumHash'])) {
        array_push($params['conditions'], array('Album.hash' => $options['albumHash']));
    }

    // Order of images
    $params['order'] = 'Image.uploaded DESC';
    if (!empty($options['order'])) {
        $params['order'] = $options['order'];
    }

    return $this->find('all', $params);
}

Is there a way I can use this getImages() method instead of the default paginate()? The closest thing I can find in the documentation is "Custom Query Pagination" but I don't want to write my own queries, I just want to use the getImages() method. Hopefully I can do that.

Cheers.

Upvotes: 1

Views: 1867

Answers (1)

Dave
Dave

Reputation: 29121

Yes.

//controller
$opts['userID'] = $this->Auth->user('id');
$opts['paginate'] = true;
$paginateOpts = $this->Image->getImages($opts);
$this->paginate = $paginateOpts;
$images = $this->paginate('Image');


//model
if(!empty($opts['paginate'])) {
    return $params;
} else {
    return $this->find('all', $params);
}

Explanation:

Basically, you just add another parameter (I usually just call it "paginate"), and if it's true in the model, instead of passing back the results of the find, you pass back your dynamically created parameters - which you then use to do the paginate in the controller.

This lets you continue to keep all your model/database logic within the model, and just utilize the controller to do the pagination after the model builds all the complicated parameters based on the options you send it.

Upvotes: 1

Related Questions