0

The combination of Collection function (in my case 'filter') and paginate() causes a error. The simplified PHP code is below:

$rooms = $this->Rooms
    ->find('all')
    ->formatResults(function ($results) {
        return $results->map(function ($row) {
            //... 
            $row->free_booking=0;      
            if($someCondition) $row->free_booking=1;
            //...

            return $row;
        });        
    })
    ->filter(function ($booking, $key) {
        return $booking->free_booking == 1;
    });
$this->set('rooms',$this->paginate($rooms));

The error is below:

Error: Call to undefined method ArrayIterator::alias() File .../public_html/vendor/cakephp/cakephp/src/Controller/Component/PaginatorComponent.php Line: 174


How to solve this problem?

2

You are calling filter() on the query object, that will cause the query to be executed, and converted to a collection, and paginating collections isn't supported.

You should generally refrain from manipulating results (adding/removing entries) on PHP level if you're using pagination, this will almost certainly mess up your pagination, as the number of records on PHP level won't match the counted records on SQL level.

Move your filtering logic into the query instead, ie filter on SQL level.

  • The problem is in app performance. The application is very fast if used $this->set('rooms',$this->paginate($rooms)); and very very slow if used $roomSegments = $rooms->take($limit,$offset)->toArray(); $this->set('rooms',$roomSegments);. The application processes a large amount of data – user3661042 Jun 7 at 13:56
  • @user3661042 I'm not saying that you shouldn't use pagination, I'm just suggesting that you should filter on SQL level instead of on PHP level. – ndm Jun 7 at 14:02
  • @user3661042 If you add your code that creates $someCondition, then maybe I can add an example on how to do it with SQL. – ndm Jun 7 at 16:12
  • Unfortunately, this can not be done with SQL because the '$someCondition' is extremely complex. One of the parts of the '$someCondition' is also room price calculation and booking check. – user3661042 Jun 8 at 5:40
  • @user3661042 I mean, SQL is generally able to do complex operations, and even very large, complicated queries can still be fast, but it all depends of course. Without seeing the calculations I can't really give you any further advice tho, all I can say is that filtering on PHP level will break your pagination, as you don't know about the total number of records, and thus the pagination calculations will be wrong. – ndm Jun 8 at 9:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.