I've just baked a simple CakePHP app, and I'm trying to customize how records are paginated. I have this action in my controller:
public function index() {
$this->Recipe->recursive = 0;
$this->set('recipes', $this->Recipe->paginate());
}
This works fine with the default pagination. I'm trying to customize the amount of rows returned and their order by using a class property called $paginate in the same controller:
public $paginate = array(
'limit' => 1,
'order' => array(
'Recipe.title' => 'asc'
)
);
However it's taking no effect at all. The results still have the default limit and sort order. I've also tried setting up $this->paginate in my action, however this seems to get ignored also:
public function index() {
$this->paginate = array(
'limit' => 1,
'order' => array(
'Recipe.title' => 'asc'
)
);
$this->set('recipes', $this->Paginator->paginate());
}
What could be causing Cake to ignore the pagination options I'm setting? Does it perhaps do something funky when you bake the application which I'm not aware of?
Try
public function index() {
$this->Paginator->settings = array(
'limit' => 1,
'order' => array(
'Recipe.title' => 'asc'
)
);
$this->set('recipes', $this->Paginator->paginate());
}
Related
I'm using CakePHP v2.4.1, and I'm trying to have two separate models be paginated on the same page, through the same controller action (index)
I want to have a NewsPost paginated on a single page, and the EventPost also paginated separately on the same page. Is this bad practice, or is it possible to set conditions to change the $this->paginate variable to paginate properly depending on which model it is on?
My Controller looks like this:
public $uses = array(
'NewsPost',
'NewsPostComment',
'EventPost',
'EventPostComment'
);
public $paginate = array(
'limit' => 9,
'order' => array(
'NewsPost.created' => 'desc'
),
'recursive' => 1,
);
public function index() {
$this->paginate = array(
'limit' => 1,
'order' => array(
'EventPost.created' => 'desc'
),
'recursive' => 1,
);
$this->Paginator->settings = $this->paginate;
$newsPosts = $this->paginate('NewsPost');
$eventPosts = $this->EventPost->find('all');
$this->set(array('newsPosts' => $newsPosts, 'eventPosts' => $eventPosts));
The built-in cake paginator does not seem to allow for the options of paginating separate models, or am I wrong?
Here is the view for pagination:
<?php
$params = $this->Paginator->params();
if ($params['count'] > 0): ?>
<div class="pagination-totals pull-left">
<?php echo $this->Paginator->counter(array('format' => __('{:start} to {:end} of {:count}'))) ?>
</div>
<?php endif; ?>
<?php echo $this->Paginator->numbers(array(
'class' => 'pull-right',
'prev' => '<',
'next' => '>',
));
?>
The problem is, when I choose page two for the NewsPost, it switches to page two for the EventPost, so how can I differentiate between both separate models on the same page using CakePHP pagination?
Thanks
You have just one params named page in your page so the result in normal.
You have to handle this with ajax request and separated actions
Within CakePHP 2 I am using pagination which works great until I see the URL which is page:2, how can I make this ?page=2 ?
The next question is that I use this code for my controller which powers /domain.com/offers/top, /domain.com/offers/newest, /domain.com/offers/popular and then the categories like /domain.com/offers/tv-and-video. The thing is when it is paginated for /domain.com/offers/top instead of being /offers/top/page:2 it goes to /offers/bycategory/top/page:2.
public function bycategory($slug = null)
{
$userId = $this->Session->read("UserAuth.User.id");
if ($slug == 'top') {
//Get the top rated offers
$this->paginate = array(
'limit' => 15,
'order' => array(
'Offer.vote' => 'desc'
)
);
} elseif ($slug == 'newest') {
//Get the latest offers
$this->paginate = array(
'limit' => 15,
'order' => array(
'Offer.created' => 'desc'
)
);
} elseif ($slug == 'popular') {
//Get the most talked about offers
} else {
//This is the categories, so just get the category slug.
$this->paginate = array(
'conditions' => array('Category.slug =' => $slug),
'limit' => 15,
'order' => array(
'Offer.created' => 'desc'
)
);
}
$offers = $this->paginate('Offer');
// pass the value to our view.ctp
$this->set('offers', $offers);
$this->set('userId', $userId);
$this->render('/Offers/index');
}
This is my custom route:
Router::connect(
'/offers/:catslug',
array('controller' => 'offers', 'action' => 'bycategory'),
array(
'pass' => array('catslug')
));
how can I make this ?page=2 ?
By setting the paramType option in paginator component options as mentioned in manual.
You second issue looks like reverse routing issue. Have you setup any custom routes?
I have a model association that works as followed:
Users hasAndBelongsToMany Tags
I want to be able to paginate a group of users based on their tags. Users can have many tags and filter requested can be complex i.e. a query can ask for all the users with tags A and B but not C. Its way more manageable to handle this by using pagination on tags (so that the condiditions array can apply to the Tag model) and getting back the users that are within that tags subset.
The issue then comes when trying to paginate, because I set up the pagination as followed:
$this->paginate = array(
'conditions' => $conditions,
'contain' => array('User'),
'limit' => 5,
);
$this->paginate('Tag')
So then pagination does exactly what is expected, it returns the array for pagination based on tags, but what I want is to paginate by the users. Switching the pagination to hinge on the users creates its own set of problems ('that is what I was using before'). Just pagination exist for model relates like this? I feel like this is the type of thing cakephp might be able to do. Thank you to anyone who helps.
Place this into the model.
function paginateCount($conditions = null, $recursive = 0, $extra = array()) {
$parameters = compact('conditions');
$this->recursive = $recursive;
$count = $this->find('count', array_merge($parameters, $extra));
if (isset($extra['group'])) {
$count = $this->getAffectedRows();
}
return $count;
}
You should use custom finder: cakephp documentation link. In you example in Users Model create protected function:
protected function _findUsersByTag($state, $query, $results = array()) {
if($state == 'before') {
$query['joins'] = array(
'Tag' => array('type' => 'inner', 'alias' => 'Tag', 'table' => 'tags', 'conditions' => array('Users.tag_id = Tag.id')
);
return $query;
}
return $results;
}
Second add in Users Model:
public $findMethods = array('usersByTag' => true);
And in the controller you definie you pagination to use custom finder using 0 index of array or in 2.3 and higther cake version property called findType:
public $pagination = array('User' => array(
'usersByTag',
'limit' => 5,
'conditions' => $conditions
));
I have an action called index and another one called manage, both in PostsController. I want to implement pagination for both, and I've set up this class attribute:
public $paginate = array(
'limit' => 10,
'order' => array(
'Post.created' => 'desc'
)
);
then I'm using the pagination in my index action like so: $this->set('posts', $this->paginate('Post'));
This results in a URL like so: http://dev/posts/page:2 which is fine.
However, when I try to use pagination in my manage action just like I did with index ($this->set('posts', $this->paginate('Post'));), the pagination links on my view redirect to the URL above, rather than the manage action.
Basically, Cake is getting confused because I'm using pagination twice in the same controller and it's redirecting both to the same URL. How can I make sure that the pagination for the manage action works properly?
Do the followings.
<?php
class PostsController extends AppController
{
var $name = 'Posts';
public $paginate = array
(
'limit' => 10,
'order' => array
(
'Post.created' => 'desc'
)
);
function index()
{
$this->Post->recursive = 0;
$this->set('posts', $this->paginate('Post'));
}
function manage()
{
$this->Post->recursive = 0;
$this->set('posts', $this->paginate('Post'));
}
}
make changes in view file as defined below.
index.ctp
$options = array
(
'url'=> array
(
'controller' => 'posts',
'action' => 'index'
)
);
$paginator->options($options);
manage.ctp
$options = array
(
'url'=> array
(
'controller' => 'posts',
'action' => 'manage'
)
);
$paginator->options($options);
And you are done.
I'm trying to create a single, one-off page that will combine information from several models. This is the code I'm trying to use:
public function index() {
$this->loadModel('people');
$this->people->find('all', array(
'order'=>'people.last_name ASC',
'conditions' => array(
'People.member =' => '1',
),
));
$this->set('people', $this->paginate('people') );
}
But it seems that my call to find() has no impact on $this->set(), and I don't understand why.
public function index() {
$this->loadModel('people');
$findPeople = $this->people->find('all', array(
'order'=>'people.last_name ASC',
'conditions' => array(
'People.member =' => '1',
),
));
$this->set('people', $findPeople);
}
I think paginate will ignore your conditions unless you put the conditions in the paginate...