Я ищу лучшее решение для решения этой проблемы. Мне нужно разбить на страницы расширенный поиск квартир со многими параметрами поиска: ключевое слово, категория, дата с, дата до, ценовой диапазон (цена минимальная, максимальная цена) и другие поля ... Если вы выберете две даты, я рассчитываю стоимость аренды каждой квартиры. Для расчета цены я не могу использовать виртуальное поле или один или несколько подзапросов, но мне приходится использовать функцию модели Apartment, потому что она выполняет множество вычислений...
Поэтому я решил использовать обратный вызов afterFind для расчета стоимости аренды и добавления «столбца» rent_price в массив результатов запроса:
public function afterFind($results, $primary){
if($this->dateFrom && $this->dateTo){
foreach ($results as $key => $val) {
if(isset($val['Apartment']['id'])){
$results[$key]['Apartment']['rental_price'] = $this->calculateRentalPrice($val['Apartment']['id'], $this->dateFrom, $this->dateTo);
}
}
}
return $results;
}
На контроллере:
$this->paginate = array( ... ); // Array with the query
$apartments = $this->paginate('Apartment');
// EDIT
foreach ($apartments as $key => &$apartment) {
if($apartment['Apartment']['rental_price'] < $priceMin || $apartment['Apartment']['rental_price'] > $priceMax){
unset($apartments[$key]);
}
}
$this->set('apartments', $apartments);
Проблема в том, что теперь я хочу перефильтровать массив $квартир с минимальной и максимальной ценой, но если я напрямую манипулирую $квартирами, у меня возникает проблема с нумерацией страниц. Каков наилучший способ решить такой сценарий?
// EDIT
public function calculateRentalPrice($apartmentId, $dateFrom, $dateTo){
$from = new DateTime($dateFrom);
$to = new DateTime($dateTo);
$period = new DatePeriod($from, DateInterval::createFromDateString('1 day'), $to);
$rentalPrice = 0;
foreach ($period as $day){
$date = $day->format("Y-m-d");
$dailyPrice = $this->ApartmentSeason->getDailyPrice($apartmentId, $date);
$rentalPrice += $dailyPrice;
}
return $rentalPrice;
}
public function getDailyPrice($apartmentId, $date){
$apartmentSeason = $this->find('first', array(
'conditions' => array(
'ApartmentSeason.apartment_id' => $apartmentId,
"'{$date}' BETWEEN ApartmentSeason.date_from AND ApartmentSeason.date_to",
"ApartmentSeason.date_to != " => $date,
)
));
$dailyPrice = $apartmentSeason['ApartmentSeason']['price'] / 7;
return $dailyPrice;
}
$apartments
. Это должны быть условия SQL. ИспользуйтеBETWEEN
. Вы должны заполнить расчетыafterSave
, а неafterFind
, чтобы использовать их в SQL-запросе. - person jeremyharris   schedule 04.10.2012calculateRentalPrice
. Вы должны быть в состоянии решить это с помощью подзапросов, так как это в основном то, что вы делаете вcalculateRentalPrice
в любом случае. - person jeremyharris   schedule 04.10.2012