CakePHP Pagination with find() and a complex query
I've been hacking at this for a few hours now. Read about 7 or 8 online tutorials and I am still unable to get my pagination working with my search results.
Here are the basics of the situation:
In my plans_controller, I am call this in my search query function
$this->set('plans', $this->Plan->find('all', $options));
The closest I came (which was not throwing SQL errors) by doing
$this->set('plans', $this->Plan->find('all', $options), $this->paginate());
NOTE: $options is the actual search query joins and conditions (and the query works perfect w/out pagination).
But the above did nothing to carry the search query to the following pages, and did NOT even work on the first results set from the search.
Using pagination for my needs seem very complex with CakePHP, but with this thread I am hoping for a more rounded explanation where I should start to get this going (and any other simple yet effective advice is welcome :)).
This is my first time trying at this type of complex pagination.
Here is all of my controller code. You'll see that much of it is inapplicable, but still trying to resolve this.:
var $name = 'Plans';
function beforeFilter() {
$this->Auth->allow('search','index'); }
function search() {
$this->Plan->recursive = 2;
if(isset($this->data['Plan']['ApplicantAge'])) {
$ApplicantAge = $this->data['Plan']['ApplicantAge'];
} else {
$ApplicantAge = 25;
}
if(isset($this->data['Plan']['SpouseAge'])) {
$SpouseAge = $this->data['Plan']['SpouseAge'];
} else {
$SpouseAge = 0;
}
if(isset($this->data['Plan']['NumberChildren'])) {
$NumberChildren = $this->data['Plan']['NumberChildren'];
} else {
$NumberChildren = 0;
}
if(isset($this->data['Plan']['Vision'])) {
$Vision = $this->data['Plan']['Vision'];
} else {
$Vision = 0;
}
if(isset($this->data['Plan']['ZipCode'])) {
$Zip = $this->data['Plan']['ZipCode'];
} else {
$Zip = 0;
}
$memberCount = 1; //We can assume the applicant is there
if($SpouseAge > 0) {
$memberCount += 1;
}
if($NumberChildren > 0) {
$memberCount += $NumberChildren;
}
//2: Combo plan (1 adult + children, 1 adult + spouse + children)
$comboType = 'sa';
if($ApplicantAge < 18) {
//$comboType = 'sc';
}
if($SpouseAge > 0) {
if($NumberChildren > 0) {
$comboType = 'asc';
} else {
$comboType = 'as';
}
} else {
if($NumberChildren > 0) {
$comboType = 'ac';
}
}
$options = array(
'joins' => array (
array(
'table' => 'plans_zips',
'alias' => 'PZips',
'type' => 'inner',
'foreignKey' => false,
'conditions'=> array('Plan.id = PZips.plan_id')
),
array(
'table' => 'zips',
'alias' => 'Zips',
'type' => 'inner',
'foreignKey' => false,
'conditions'=> array('Zips.id = PZips.zip_id')
)
),
'conditions' => array(
"AND" => array(
array($ApplicantAge . ' BETWEEN Age.Min_Age AND Age.Max_age'),
'Zips.title' => $Zip,
'Applicant.amount' => array($comboType, $memberCount),
'PlanDetail.active' => 1)
)
);
$queryStr = "SELECT Plan.* FROM plans AS Plan ";
$queryStr = $queryStr . "INNER JOIN ages on age_id = ages.id ";
$queryStr = $queryStr . "INNER JOIN applicants on applicant_id = applicants.id ";
$queryStr = $queryStr . "WHERE (applicants.amount = '". $memberCount . "' OR applicants.amount = '" . $comboType . "')";
$queryStr开发者_StackOverflow中文版 = $queryStr . " AND (". $ApplicantAge . " BETWEEN ages.Min_Age+0 AND ages.Max_Age+0) ";
$queryStr = $queryStr . " AND Plan.id IN (SELECT plan_id FROM plans_zips where zip_id = (SELECT id FROM zips WHERE title = '". $Zip. "'))";
//Add the vision limiting item
if($Vision == 1) {
$queryStr = $queryStr . " AND dental_cost > 0";
array_push($options['conditions'], "dental_cost > 0");
}
//$this->set('plans', $this->Plan->find('all', $options));
$this->paginate = $options;
$plans = $this->paginate();
$this->set(compact('plans'));
}
Assuming your $options
variable contains a normal array of query parameters, all you need to do is replace the normal find
call with a paginate
call:
$options = array('conditions' => ...);
// normal find call
// $plans = $this->Plan->find('all', $options);
// same thing with pagination:
$this->paginate = $options;
$plans = $this->paginate();
$this->set(compact('plans'));
精彩评论