Nested array argument in filterBy …

Hello everyone, for filtering by pages from the last three years, their names being year-ss or year-ws, I’d like to use a nested array as as argument in filterBy, à la …

filterBy('semester', 'in', [[date('Y'), date('Y') - 1, date('Y') - 2] . ['-ss', '-ws'])

Any ideas on how to achieve this?

I think wildcards for -ss and -ws are also not possible, are they?

Thank you!

It’s probably better to use ->filter() then: https://getkirby.com/docs/reference/objects/pages/filter

Sorry I’m not sure how to use filter() for this problem …

filter() takes a function with the page as param. the return value must be a boolean. be careful with comparing string and int

->filter(function($p){
  $a = [date('Y'), date('Y') - 1, date('Y') - 2];
  $b = [];
  foreach($a as $aa) { 
    $b[] = $aa . '-ws';
    $b[] = $aa . '-ss';
  }
  return in_array((string)$p->semester()->value(), $b);
})

you could move $b outside of the closure and use it like this…

->filter(function($p) use ($b) {
  return in_array((string)$p->semester()->value(), $b);
})
1 Like

Thank you, @bnomei … I’ll try to understand that example!

For now I used filterBy() like the following, which work but just doesn’t look that nice …

>filterBy('semester', 'in', [date('Y') . '-ss', date('Y') . '-ws', date('Y') - 1 . '-ss', date('Y') - 1 . '-ws', date('Y') - 2 . '-ss', date('Y') - 2 . '-ws', date('Y') - 3 . '-ss', date('Y') - 3 . '-ws'])

i do not know of a way to create a array in php with nested [] syntax. would be neat.
your original array matches the $b.

Maybe someone else knows. Maybe it’s not even possible.

I’ll play around with your provided method, thank you very much!

Alternative:

$filtered = $page
  ->children()
  ->map(function ($child) {
      $child->year = str::substr($child->semester()->value(), 0, 4);
      return $child;
    })
 ->filterBy('year', 'between', [date('Y')-2, date('Y')]);
1 Like

@texnixe using the page method map to create a temporary member in the page object called year and check that dynamic value later. so map can be used as a quick alternative for a custom page method - nice idea!

It’s also possible without the map() function, while still more elegant than the array solutions, I think:

  $filtered = $page
  ->children()
  ->filter(function ($child) {
      return str::substr($child->semester()->value(), 0, 4) >= date('Y')-2 &&
      str::substr($child->semester()->value(), 0, 4) <= date('Y');
    });