Reputation: 1074
Cake handles pagination of a model with a simple $this->paginate(), but what should I use if I want to paginate a array of values?
The Scenario is like this:
$this->set('sitepages', $this->paginate());
This code in my index() returns an array like
Array
(
[0] => Array
(
[Sitepage] => Array
(
[id] => 13
[name] => Home
[urlslug] => home
[parent_id] => 1
[page_title] => Welcome to KIAMS, Pune
[order] => 1
)
)
[1] => Array
(
[Sitepage] => Array
(
[id] => 26
[name] => About Us
[urlslug] => aboutus
[parent_id] => 1
[page_title] =>
[order] => 2
)
)
[2] => Array
(
[Sitepage] => Array
(
[id] => 27
[name] => Overview of KIAMS
[urlslug] => aboutus/overview
[parent_id] => 26
[page_title] =>
[order] => 2
)
)
I retrieved the same data using $this->Sitepage->find('all') and then performed some manipulations as required and form a array which is very similar to the above one, but the ordering gets changed. I want to paginate this new array and pass it to the view. I tried
$this->set('sitepages',$this->paginate($newarray))
But the data is not getting paginated. Can some one please help with paginating the $newarray in CakePHP?
Upvotes: 1
Views: 13081
Reputation: 1383
There was a bug in find("count") and it returned incorrect count if the query resulted in records for only in group. This has been fixed click here
Upvotes: 0
Reputation: 497
I'm using cakephp version 1.3 and it seems this one is working:
at controller:
$result = $this->Paginate('Event');
$results = $this->Task->humanizeEvent($result);
$this->set('events', $results);
and it seems to display as a normal paginated array, at the view (setup your pagination in view as normal).
The humanizeEvent
function just edits a field on the results array, to make it a sentence based on other fields inside the array, and it seems to work properly.
Upvotes: 1
Reputation: 712
I've just dealt with this same problem...
I found the only way is to use the paginate()
function to handle all the logic, rather than passing it a custom array. However, this isn't as bad as it seems:
$this->paginate = array(
'limit' => 2,
'order' => array(
'Report.name' => 'asc'
),
'conditions' => array(
'Account.id' => $this->foo()
),
);
$reports = $this->paginate();
In this example, I'm paginating Reports - but some Reports will not be included, depending on which Account they belong to (Account has some relationship with Report, hasmany, etc.).
By writing $paginate
inside your action, you can use a custom callback for the conditions array. So function foo()
can be written in your controller (or shoved to model) and returns an array of valid Account IDs.
I found I could easily rewrite my custom logic in this function - keeping both me and the Cake paginator happy.
Hope that helps!
Upvotes: 1
Reputation: 4445
I create a component checking the paginator code..
Is not the best thing, but It work for me.....
Controller
$slicedArray = array_slice($fullArray,($page - 1) * $this->PaginatorArray->limit ,$this->PaginatorArray->limit)
$this->params['paging'] = $this->PaginatorArray->getParamsPaging('MyModel', $page, $total,count($slicedArray));
$this->helpers[] = 'Paginator';
Component
<?php
/* SVN FILE: $Id$ */
/**
* Pagination Array Component class file.
* @subpackage cake.cake.libs.view.helpers
*/
class PaginatorArrayComponent {
var $limit = 40;
var $step = 1;
function startup( & $controller){
$this->controller = & $controller;
}
function getParamsPaging($model, $page, $total, $current){
$pageCount = ceil($total / $this->limit);
$prevPage = '';
$nextPage = '';
if($page > 1)
$prevPage = $page - 1;
if($page + 1 <= $pageCount)
$nextPage = $page + 1;
return array(
$model => array(
'page' => $page,
'current' => $current,
'count' => $total,
'prevPage' => $prevPage,
'nextPage' => $nextPage,
'pageCount' => $pageCount,
'defaults' => array(
'limit' => $this->limit,
'step' => $this->step,
'order' => array(),
'conditions' => array(),
),
'options' => array(
'page' => $page,
'limit' => $this->limit,
'order' => array(),
'conditions' => array(),
)
)
);
}
}
?>
Upvotes: 0
Reputation: 7525
$this->paginate($newarray)
is the wrong way to paginate. The first parameter cannot be an array. It must be a model name. You may want to study pagination setup from the manual. This will order alphabetically:
var $paginate = array(
'limit' => 25,
'order' => array(
'Sitepage.name' => 'asc'
)
);
$this->set('sitepages', $this->paginate('Sitepage'));
Upvotes: 0
Reputation: 25147
To paginate in CakePHP you need to pass select conditions to the paginate() call.
Other data manipulation should be done in afterFind(), in your model file.
If you don't need these changes to be done in every single retrieval, you might as well consider creating a new model file pointing to the very same table as the current one, and adding an afterFind() method to that new file.
Upvotes: 2