Note that there are some explanatory texts on larger screens.

plurals
  1. POPaginate, filter and sort advanced search with calculated fields by function CakePHP
    primarykey
    data
    text
    <p>I'm looking for a better solution to solve this kind of problem. I need to paginate an advanced search for apartments with many search options: keyword, category, date from, date to, price range (price min, price max), and other fields ... In case you select the two dates I calculate the rental price of each apartment. To calculate the price I can not use a virtualField or one or more subqueries but I have to use a function of the model Apartment because it performs many calculations...</p> <p>So I decided to use the callback afterFind to calculate the rental price and adding a "column" rental_price to the array of query results:</p> <pre><code>public function afterFind($results, $primary){ if($this-&gt;dateFrom &amp;&amp; $this-&gt;dateTo){ foreach ($results as $key =&gt; $val) { if(isset($val['Apartment']['id'])){ $results[$key]['Apartment']['rental_price'] = $this-&gt;calculateRentalPrice($val['Apartment']['id'], $this-&gt;dateFrom, $this-&gt;dateTo); } } } return $results; } </code></pre> <p>On controller:</p> <pre><code>$this-&gt;paginate = array( ... ); // Array with the query $apartments = $this-&gt;paginate('Apartment'); // EDIT foreach ($apartments as $key =&gt; &amp;$apartment) { if($apartment['Apartment']['rental_price'] &lt; $priceMin || $apartment['Apartment']['rental_price'] &gt; $priceMax){ unset($apartments[$key]); } } $this-&gt;set('apartments', $apartments); </code></pre> <p>The problem is that now I want to re-filter the array $apartments with minimum price and maximum price, but if I directly manipulating $apartments I have a problem with pagination. What's the best way to solve this kind of scenario?</p> <pre><code> // 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-&gt;format("Y-m-d"); $dailyPrice = $this-&gt;ApartmentSeason-&gt;getDailyPrice($apartmentId, $date); $rentalPrice += $dailyPrice; } return $rentalPrice; } public function getDailyPrice($apartmentId, $date){ $apartmentSeason = $this-&gt;find('first', array( 'conditions' =&gt; array( 'ApartmentSeason.apartment_id' =&gt; $apartmentId, "'{$date}' BETWEEN ApartmentSeason.date_from AND ApartmentSeason.date_to", "ApartmentSeason.date_to != " =&gt; $date, ) )); $dailyPrice = $apartmentSeason['ApartmentSeason']['price'] / 7; return $dailyPrice; } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload