Issue with filtering data using structures

Hi,

I’m just starting out in the process of moving my custom built PHP/MySQL site over to Kirby CMS (really liking it so far), but running into an issue with trying to filter data that uses structures.

I’m tried following this as a guide, but I’m running into an issue. Note my code below is inside of a controller:

<?php
return function($site, $pages, $page) {
    // we need to check first to see if this is a platform-specific page
    if (param('platform') != null) {
        // get together all of the platform-specific reviews
        $reviews = $page->children()->visible()->filter(function($p) {
            $structure = $p->scores()->toStructure();            
            return $structure->platform() == urldecode(param('platform'));
        })->sortBy('posted_on', 'desc')->paginate(11);
    } else {
        // get together all of the reviews
        $reviews = $page->children()->visible()->sortBy('posted_on', 'desc')->paginate(11);
    }
    
    // set the pagination object so we can utilize it later
    $pagination = $reviews->pagination();
    
    // pass $reviews to the template
    return compact('pagination', 'reviews');
};

And my blueprint and an example of how the data shows up in a sample page is below:

  scores:
    label: Scores
    type: structure
    entry: >
      <strong>{{platform}}</strong>: {{score}}/10
    fields:
      platform:
        label: Platform
        type: select
        options:
          PS4: PS4
          Xbox One: Xbox One
          Wii U: Wii U
          3DS: 3DS
          Vita: Vita
          PC: PC
          PS3: PS3
          Xbox 360: Xbox 360
          Wii: Wii
          DS: DS
          PSP: PSP
      score:
        label: Score
        type: select
        options:
          10: 10
          9.5: 9.5
          9: 9
          8.5: 8.5
          8: 8
          7.5: 7.5
          7: 7
          6.5: 6.5
          6: 6
          5.5: 5.5
          5: 5
          4.5: 4.5
          4: 4
          3.5: 3.5
          3: 3
          2.5: 2.5
          2: 2
          1.5: 1.5
          1: 1
          0.5: 0.5
          0: 0

(blank space to make the code tool not combine these two blocks)

----

Scores: 

- 
  platform: Wii
  score: "2"

I did out error_log() statements to the console and saw that if I debugged $structure before toStructure() was called, it did grab the raw data as expected. But if I debugged $structure afterwards, it printed out:

Wii<br />2

And if I do $structure->platform or $structure->score, they print out nothing. It seems off that $structure has that text, so I’m thinking something is wrong then? Any ideas?

Try this:

$reviews = $page->children()->visible()->filter(function($p) {       
  return $p->scores()->toStructure()->filterBy('platform', '==', urldecode(param('platform')))->count() > 0;
})->sortBy('posted_on', 'desc')->paginate(11);
1 Like

@texnixe Something about that code wasn’t wanting to run right, but I think I figured out to get it working right.

Seems like this code below did the trick. Not sure if it’s optimal or if there’s a better way to do it, but it is filtering things correctly right now:

<?php
return function($site, $pages, $page) {
    // we need to check first to see if this is a platform-specific page
    if (param('platform') != null) {
        // get together all of the platform-specific reviews
        $reviews = $page->children()->visible()->filter(function($p) {
            $structure = $p->scores()->toStructure();
            
            foreach($structure as $s) {
                return $s->platform() == urldecode(param('platform'));
            }
        })->sortBy('posted_on', 'desc')->paginate(11);
    } else {
        // get together all of the reviews
        $reviews = $page->children()->visible()->sortBy('posted_on', 'desc')->paginate(11);
    }
    
    // set the pagination object so we can utilize it later
    $pagination = $reviews->pagination();
    
    // pass $reviews to the template
    return compact('pagination', 'reviews');
};

I’m a bit surprised it does not work, because I used similar code in one of my projects. What was the issue?

I think it was something about the } character or one of those around there, i.e. not being escaped right.

Oh, a closing parenthesis was missing, I have fixed it above in Sonja’s post.

Oh, yes, these parenthesis, thanks for correcting, @lukasbestle.

Just tested and replaced the code with that updated syntax, it worked perfectly. Thanks @lukasbestle and @texnixe! :slight_smile: