Clause
June 25, 2018, 12:57pm
1
I would like to make a widget that indicates the next birthdays from a lot of people.
my approach was:
That Kirby spends all persons who are still on birthday from today on a defined period.
So we created a method like this:
<?php
class PersonPage extends Page {
public function geburtsdatumsort() {
return date('md', $this->geburtsdatum());
}
}
Our output from kirby like this:
$Personen = panel()->page('intern/personen')->children()->filterBy('geburtsdatum', '!=', '')->sortBy('geburtsdatumsort', 'asc' )->filter(function($child) { echo $child->geburtsdatumsort() . '#' . $child->title()->value() . ' ' . intval($child->date('md', 'geburtsdatum')) .' > ' . intval(date('md')) . '<br />'; return intval($child->date('md', 'geburtsdatum')) > intval(date('md'));})->limit(10);
But the Page method will not work.
Do a page method not work in a widget?
I’m not sure if a page model works in the Panel, but instead of a page model you could try with a custom page method, however, I don’t even think you need. this model or method at all.
The main problem is that you’re messing something up in your collection filter code. You can’t echo anything from a custom filter but have to return a child depending on your condition. Then afterwards loop through your filtered collection and output whatever you want to output.
Clause
June 25, 2018, 2:29pm
3
The Echo, was for Debugging. Sorry for the confusion.
When i set this:
$Personen = panel()->page('intern/personen')->children()->filterBy('geburtsdatum', '!=', '')->sortBy('geburtsdatumsort', 'asc' )->filter(function($child) { return intval($child->date('md', 'geburtsdatum')) > intval(date('md'));})->limit(10);
in the result the names came sorted by ABC.
But i want the list sorted by the next birthdays dependent on the date now…
when i check:
$now = date('m-d');
return $child->date('m-d', 'geburtsdatum') > date('m-d');
with with year will kirby calculate?
Or otherwise:
$now = strtotime(date('m-d'));
$Personen = panel()->page('intern/personen')->children()->filterBy('geburtsdatum', '!=', '')->sortBy('geburtsdatumsort', 'asc' )->filter(function($child) use($now) {
return strtotime('+30 days', strtotime($child->geburtstag())) > $now;
})->limit(10);
How i can get the solution, that the output is not caluating with the year…
I’d do it like this:
$personen = panel()->page('intern/personen')->children()->map(function($child) {
$child->shortGeb = $child->date('md', 'geburtstag');
return $child;
})->sortBy('shortGeb')->filter(function($child) {
return $child->date('md', 'geburtstag') > date('md');
});
foreach($personen as $person) {
echo $person->title(). ' hat am ' .$person->date('d.m.Y', 'geburtstag'). ' Geburstag. Happy Birthday!';
}
Clause
June 25, 2018, 5:59pm
5
Top!
and again learned something!
that means with $child->variable
you can create a variable on the fly …
how would look the issue for the next 4 weeks?
like this?
$personen = panel()->page('intern/personen')->children()->map(function($child) {
$child->shortGeb = $child->date('md', 'geburtsdatum');
$child->alter = floor((time() - strtotime($child->date('Ymd', 'geburtsdatum')))/31556926);
$child->jetzt = strtotime('now');
$child->enddatum = strtotime('+4 week');
return $child;
})->sortBy('shortGeb')->filter(function($child) {
return $child->date('md', 'geburtsdatum') >= date('md');
})->filter(function($child) {
return $enddatum >= $jetzt;
});
You don’t need all these extra dates:
$personen = panel()->page('intern/personen')->map(function($child) {
$child->shortGeb = $child->date('md', 'geburtstag');
return $child;
})->sortBy('shortGeb')->filter(function($child) {
// return everything between now and in four weeks
return $child->date('md', 'geburtstag') > date('md') && $child->date('md', 'geburtstag') <= date('md',strtotime('+ 4 week'));
});