Hier die in 5.5 funktionierenden Codes:
Bei den Events gibt es ein zusätzliches Auswahlfeld, um einen Terminausfall wegen Ferien zu kennzeichnen:
PHP-Code:
<?php
// contao/dca/tl_calendar_events.php
use Contao\CoreBundle\DataContainer\PaletteManipulator;
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['custom_event_status'] = [
'label' => &$GLOBALS['TL_LANG']['tl_calendar_events']['custom_event_status'],
'inputType' => 'select',
'options' => array('ok' => 'Geplant / findet statt',
'holiday' => 'Entfällt wegen Ferien'),
'eval' => array('tl_class'=>'w50', 'includeBlankOption' => false),
'sql' => "varchar(32) NOT NULL default 'ok'"
];
PaletteManipulator::create()
->addField('custom_event_status', 'date_legend', PaletteManipulator::POSITION_APPEND)
->applyToPalette('default', 'tl_calendar_events')
->applyToPalette('internal', 'tl_calendar_events')
;
Bei den Modulen wurde ein Filter-Auswahlfeld ergänzt, um Ferienausfälle aus der Ergebnisliste herausfiltern zu können:
PHP-Code:
<?php
// contao/dca/tl_module.php
$GLOBALS['TL_DCA']['tl_module']['fields']['custom_hook_filter_rehearsals'] = [
'label' => &$GLOBALS['TL_LANG']['tl_module']['custom_hook_filter_rehearsals'],
'inputType' => 'select',
'options' => array('1' => 'Keinen Filter anwenden (Standard)',
'2' => 'Nur Termin der nächsten Probe (ohne Ausfall wegen Ferien)',
'3' => 'Nächste Probentermine (Ferienausfall nur einmal zeigen)'),
'eval' => array('tl_class'=>'w50', 'includeBlankOption' => false),
'sql' => "varchar(32) NOT NULL default '1'"
];
Im EventListener wird je nach Filterauswahl im Modul die Event-Ergebnisliste manipuliert:
PHP-Code:
<?php
// src/EventListener/FilterRehearsalListener.php
namespace App\EventListener;
use Contao\CoreBundle\ServiceAnnotation\Hook;
use Contao\Module;
/**
* @Hook("getAllEvents")
*/
#[AsHook('filterRehearsal')]
class FilterRehearsalListener {
public function __invoke(array $events, array $calendars, int $timeStart, int $timeEnd, Module $module): array {
// Ergebnisse nur bearbeiten, wenn der Hook im Modul aktiviert wurde und angewendet werden soll
// Option '1' => 'Keinen Filter anwenden (Standard)'
// Option '2' => 'Nur Termin der nächsten Probe (ohne Ausfall wegen Ferien)'
if ( $module->custom_hook_filter_rehearsals == '2' ) {
// In den Sommerferien kann es 7 aufeinanderfolgende Ausfälle wegen Ferien geben
// Im Modul werden daher 9 Events für die Liste abgefragt (damit mind. zwei Proben nach Ferien enthalten ist)
// Es sollen maximal X Probetermine angezeigt werden
// (dieser Hook gibt somit weniger Events zurück, als im Modul ausgewählt)
$max_events = 1;
// Leerer Array für die Speicherung der Ergebnisse
$processed = [];
// Zähler für den Loop, wird in jeder Schleife hochgezählt um zu wissen, das wievielte Event gerade bearbeitet wird
$loop_count = 0;
// Zähler für die Ergebnisliste, um die Anzahl der Ergebnisse zu begrenzen
$result_count = 0;
foreach ($events as $groupKey => $groupEvents) {
foreach ($groupEvents as $dateKey => $dateEvents) {
foreach ($dateEvents as $event) {
++$loop_count;
// Das aktuelle Event nur in den Ergebnis-Array aufnehmen, wenn es kein Ausfall wegen Ferien ist,
// und wenn die maximale Anzahl an Ergebnissen noch nicht erreicht wurde
if ( $event['custom_event_status'] != 'holiday' && $result_count < $max_events ) {
// Dieses Event in Ergebnisliste speichern
$processed[$groupKey][$dateKey][] = $event;
++$result_count;
}
}
}
}
$events = $processed;
}
// Option '3' => 'Nächste Probentermine (Ferienausfall nur einmal zeigen)'
else if ( $module->custom_hook_filter_rehearsals == '3' ) {
// In den Sommerferien kann es 7 aufeinanderfolgende Ausfälle wegen Ferien geben
// Im Modul werden daher 9 Events für die Liste abgefragt (damit mind. zwei Proben nach Ferien enthalten ist)
// Es sollen maximal X Probetermine angezeigt werden
// (dieser Hook gibt somit weniger Events zurück, als im Modul ausgewählt)
$max_events = 3;
// Leerer Array für die Speicherung der Ergebnisse
$processed1 = [];
$processed2 = [];
// Zähler für den Loop, wird in jeder Schleife hochgezählt um zu wissen, das wievielte Event gerade bearbeitet wird
$loop_count = 0;
// Zähler für die Ergebnisliste, um die Anzahl der Ergebnisse zu begrenzen
$result_count = 0;
// Hilfsvariable um zu wissen, ob der erste Termin ein Ausfall wegen Ferien ist
$first_is_holiday = false;
// Das events-Array ist zunächst nach seltsamen Gruppen sortiert (unklar, könnten Kalender-Gruppen sein).
// Innerhalb dieser Gruppen sind die Einträge nach Tagen sortiert.
// Damit Events aus mehreren Kalendern in der korrekten Reihenfolge verarbeitet werden, müssen diese
// zunächst in einem Array zusammengefasst und nach Datum (Array-Schlüssel) sortiert werden.
foreach ($events as $groupKey => $groupEvents) {
foreach ($groupEvents as $dateKey => $dateEvents) {
foreach ($dateEvents as $event) {
$processed1[$groupKey][$dateKey][] = $event;
}
}
}
// Ergebnis-Array aufsteigend sortieren
ksort($processed1);
foreach ($processed1 as $groupKey => $groupEvents) {
foreach ($groupEvents as $dateKey => $dateEvents) {
foreach ($dateEvents as $event) {
++$loop_count;
// Der erste (aktuellste) Termin soll auf jeden Fall in der Ergebnisliste
// enthalten sein, auch wenn es ein Ausfall wegen Ferien ist
if ( $loop_count == 1 ) {
// Dieses Event in Ergebnisliste speichern
$processed2[$groupKey][$dateKey][] = $event;
++$result_count;
// Falls dieser Termin ein Ausfall wegen Ferien ist, die Variable ändern
if ( $event['custom_event_status'] == 'holiday' ) {
$first_is_holiday = true;
}
}
// Bei den weiteren Terminen muss geprüft werden
else {
// Falls das erste Ergebnis ein Ferientermin war
if ( $first_is_holiday == true ) {
// Das aktuelle Event nur in den Ergebnis-Array aufnehmen, wenn es kein weiterer Ausfall wegen Ferien ist,
// und wenn die maximale Anzahl an Ergebnissen noch nicht erreicht wurde
if ( $event['custom_event_status'] != 'holiday' && $result_count < $max_events ) {
// Dieses Event in Ergebnisliste speichern
$processed2[$groupKey][$dateKey][] = $event;
++$result_count;
}
}
// Falls das erste Ergebnis KEIN Ferientermin war
else {
// Das aktuelle Event nur in den Ergebnis-Array aufnehmen,
// wenn die maximale Anzahl an Ergebnissen noch nicht erreicht wurde
if ( $result_count < $max_events ) {
// Dieses Event in Ergebnisliste speichern
$processed2[$groupKey][$dateKey][] = $event;
++$result_count;
}
}
}
}
}
}
$events = $processed2;
}
return $events;
}
}
Und hier die Stack Trackes, welche ich mit obigem Code in Contao 5.6-RC2 erhalte:
[2/2] RuntimeError
Code:
Twig\Error\RuntimeError:
An exception has been thrown during the rendering of a template ("App\EventListener\FilterRehearsalListener::__invoke(): Argument #5 ($module) must be of type Contao\Module, Contao\CalendarBundle\Generator\CalendarEventsGenerator given, called in /var/www/html/vendor/contao/calendar-bundle/src/Generator/CalendarEventsGenerator.php on line 108") in "@Contao/content_element/element_group.html.twig" at line 5.
at vendor/contao/core-bundle/contao/templates/twig/content_element/element_group.html.twig:5
at Twig\Template->yieldBlock()
(var/cache/dev/twig/17/17f758d6f945fe4e38857f809715cf42.php:224)
at __TwigTemplate_882982ae885bb90adcbfb6fcc79b4de8->block_inner()
(vendor/twig/twig/src/Template.php:446)
at Twig\Template->yieldBlock()
(var/cache/dev/twig/17/17f758d6f945fe4e38857f809715cf42.php:138)
at __TwigTemplate_882982ae885bb90adcbfb6fcc79b4de8->block_wrapper()
(vendor/twig/twig/src/Template.php:446)
at Twig\Template->yieldBlock()
(var/cache/dev/twig/17/17f758d6f945fe4e38857f809715cf42.php:86)
at __TwigTemplate_882982ae885bb90adcbfb6fcc79b4de8->doDisplay()
(vendor/twig/twig/src/Template.php:402)
at Twig\Template->yield()
(var/cache/dev/twig/aa/aaad26b68b3b0b226be5f2f0d8650bcf.php:51)
at __TwigTemplate_3dc9553bc21334f9ac2233cee571d35d->doDisplay()
(vendor/twig/twig/src/Template.php:402)
at Twig\Template->yield()
(vendor/twig/twig/src/Template.php:358)
at Twig\Template->display()
(vendor/twig/twig/src/Template.php:373)
at Twig\Template->render()
(vendor/twig/twig/src/TemplateWrapper.php:51)
at Twig\TemplateWrapper->render()
(vendor/twig/twig/src/Environment.php:333)
at Twig\Environment->render()
(vendor/symfony/framework-bundle/Controller/AbstractController.php:459)
at Symfony\Bundle\FrameworkBundle\Controller\AbstractController->doRenderView()
(vendor/symfony/framework-bundle/Controller/AbstractController.php:464)
at Symfony\Bundle\FrameworkBundle\Controller\AbstractController->doRender()
(vendor/symfony/framework-bundle/Controller/AbstractController.php:278)
at Symfony\Bundle\FrameworkBundle\Controller\AbstractController->render()
(vendor/contao/core-bundle/src/Controller/AbstractFragmentController.php:241)
at Contao\CoreBundle\Controller\AbstractFragmentController->render()
(vendor/contao/core-bundle/src/Controller/AbstractFragmentController.php:118)
at Contao\CoreBundle\Controller\AbstractFragmentController->{closure:Contao\CoreBundle\Controller\AbstractFragmentController::createTemplate():88}()
(vendor/contao/core-bundle/src/Twig/FragmentTemplate.php:130)
at Contao\CoreBundle\Twig\FragmentTemplate->getResponse()
(vendor/contao/core-bundle/src/Controller/ContentElement/ElementGroupController.php:26)
at Contao\CoreBundle\Controller\ContentElement\ElementGroupController->getResponse()
(vendor/contao/core-bundle/src/Controller/ContentElement/AbstractContentElementController.php:40)
at Contao\CoreBundle\Controller\ContentElement\AbstractContentElementController->__invoke()
(vendor/symfony/http-kernel/HttpKernel.php:183)
at Symfony\Component\HttpKernel\HttpKernel->handleRaw()
(vendor/symfony/http-kernel/HttpKernel.php:76)
at Symfony\Component\HttpKernel\HttpKernel->handle()
(vendor/symfony/http-kernel/HttpCache/SubRequestHandler.php:86)
at Symfony\Component\HttpKernel\HttpCache\SubRequestHandler::handle()
(vendor/symfony/http-kernel/Fragment/InlineFragmentRenderer.php:75)
at Symfony\Component\HttpKernel\Fragment\InlineFragmentRenderer->render()
(vendor/symfony/http-kernel/Fragment/FragmentHandler.php:81)
at Symfony\Component\HttpKernel\Fragment\FragmentHandler->render()
(vendor/contao/core-bundle/src/Fragment/FragmentHandler.php:67)
at Contao\CoreBundle\Fragment\FragmentHandler->render()
(vendor/contao/core-bundle/contao/elements/ContentProxy.php:74)
at Contao\ContentProxy->generate()
(vendor/contao/core-bundle/contao/library/Contao/Controller.php:618)
at Contao\Controller::getContentElement()
(vendor/contao/core-bundle/contao/modules/ModuleArticle.php:189)
at Contao\ModuleArticle->compile()
(vendor/contao/core-bundle/contao/modules/Module.php:214)
at Contao\Module->generate()
(vendor/contao/core-bundle/contao/modules/ModuleArticle.php:69)
at Contao\ModuleArticle->generate()
(vendor/contao/core-bundle/contao/library/Contao/Controller.php:493)
at Contao\Controller::getArticle()
(vendor/contao/core-bundle/contao/library/Contao/Controller.php:356)
at Contao\Controller::getFrontendModule()
(vendor/contao/core-bundle/contao/pages/PageRegular.php:208)
at Contao\PageRegular->prepare()
(vendor/contao/core-bundle/contao/pages/PageRegular.php:47)
at Contao\PageRegular->getResponse()
(vendor/contao/core-bundle/contao/controllers/FrontendIndex.php:73)
at Contao\FrontendIndex->renderPage()
(vendor/symfony/http-kernel/HttpKernel.php:183)
at Symfony\Component\HttpKernel\HttpKernel->handleRaw()
(vendor/symfony/http-kernel/HttpKernel.php:76)
at Symfony\Component\HttpKernel\HttpKernel->handle()
(vendor/symfony/http-kernel/Kernel.php:182)
at Symfony\Component\HttpKernel\Kernel->handle()
(public/index.php:42)
Stack Trace [1/2] TypeError
Code:
TypeError:
App\EventListener\FilterRehearsalListener::__invoke(): Argument #5 ($module) must be of type Contao\Module, Contao\CalendarBundle\Generator\CalendarEventsGenerator given, called in /var/www/html/vendor/contao/calendar-bundle/src/Generator/CalendarEventsGenerator.php on line 108
at src/EventListener/FilterRehearsalListener.php:30
at App\EventListener\FilterRehearsalListener->__invoke()
(vendor/contao/calendar-bundle/src/Generator/CalendarEventsGenerator.php:108)
at Contao\CalendarBundle\Generator\CalendarEventsGenerator->getAllEvents()
(vendor/contao/calendar-bundle/contao/classes/Events.php:97)
at Contao\Events->getAllEvents()
(vendor/contao/calendar-bundle/contao/modules/ModuleEventlist.php:173)
at Contao\ModuleEventlist->compile()
(vendor/contao/core-bundle/contao/modules/Module.php:214)
at Contao\Module->generate()
(vendor/contao/calendar-bundle/contao/modules/ModuleEventlist.php:85)
at Contao\ModuleEventlist->generate()
(vendor/contao/core-bundle/contao/library/Contao/Controller.php:403)
at Contao\Controller::getFrontendModule()
(vendor/contao/core-bundle/contao/elements/ContentModule.php:59)
at Contao\ContentModule->generate()
(vendor/contao/core-bundle/contao/library/Contao/Controller.php:618)
at Contao\Controller::getContentElement()
(vendor/contao/core-bundle/src/Framework/Adapter.php:38)
at Contao\CoreBundle\Framework\Adapter->__call()
(vendor/contao/core-bundle/src/Twig/Runtime/FragmentRuntime.php:57)
at Contao\CoreBundle\Twig\Runtime\FragmentRuntime->renderContent()
(var/cache/dev/twig/aa/aaad26b68b3b0b226be5f2f0d8650bcf.php:80)
at __TwigTemplate_3dc9553bc21334f9ac2233cee571d35d->block_content()
(vendor/twig/twig/src/Template.php:446)
at Twig\Template->yieldBlock()
(var/cache/dev/twig/17/17f758d6f945fe4e38857f809715cf42.php:224)
at __TwigTemplate_882982ae885bb90adcbfb6fcc79b4de8->block_inner()
(vendor/twig/twig/src/Template.php:446)
at Twig\Template->yieldBlock()
(var/cache/dev/twig/17/17f758d6f945fe4e38857f809715cf42.php:138)
at __TwigTemplate_882982ae885bb90adcbfb6fcc79b4de8->block_wrapper()
(vendor/twig/twig/src/Template.php:446)
at Twig\Template->yieldBlock()
(var/cache/dev/twig/17/17f758d6f945fe4e38857f809715cf42.php:86)
at __TwigTemplate_882982ae885bb90adcbfb6fcc79b4de8->doDisplay()
(vendor/twig/twig/src/Template.php:402)
at Twig\Template->yield()
(var/cache/dev/twig/aa/aaad26b68b3b0b226be5f2f0d8650bcf.php:51)
at __TwigTemplate_3dc9553bc21334f9ac2233cee571d35d->doDisplay()
(vendor/twig/twig/src/Template.php:402)
at Twig\Template->yield()
(vendor/twig/twig/src/Template.php:358)
at Twig\Template->display()
(vendor/twig/twig/src/Template.php:373)
at Twig\Template->render()
(vendor/twig/twig/src/TemplateWrapper.php:51)
at Twig\TemplateWrapper->render()
(vendor/twig/twig/src/Environment.php:333)
at Twig\Environment->render()
(vendor/symfony/framework-bundle/Controller/AbstractController.php:459)
at Symfony\Bundle\FrameworkBundle\Controller\AbstractController->doRenderView()
(vendor/symfony/framework-bundle/Controller/AbstractController.php:464)
at Symfony\Bundle\FrameworkBundle\Controller\AbstractController->doRender()
(vendor/symfony/framework-bundle/Controller/AbstractController.php:278)
at Symfony\Bundle\FrameworkBundle\Controller\AbstractController->render()
(vendor/contao/core-bundle/src/Controller/AbstractFragmentController.php:241)
at Contao\CoreBundle\Controller\AbstractFragmentController->render()
(vendor/contao/core-bundle/src/Controller/AbstractFragmentController.php:118)
at Contao\CoreBundle\Controller\AbstractFragmentController->{closure:Contao\CoreBundle\Controller\AbstractFragmentController::createTemplate():88}()
(vendor/contao/core-bundle/src/Twig/FragmentTemplate.php:130)
at Contao\CoreBundle\Twig\FragmentTemplate->getResponse()
(vendor/contao/core-bundle/src/Controller/ContentElement/ElementGroupController.php:26)
at Contao\CoreBundle\Controller\ContentElement\ElementGroupController->getResponse()
(vendor/contao/core-bundle/src/Controller/ContentElement/AbstractContentElementController.php:40)
at Contao\CoreBundle\Controller\ContentElement\AbstractContentElementController->__invoke()
(vendor/symfony/http-kernel/HttpKernel.php:183)
at Symfony\Component\HttpKernel\HttpKernel->handleRaw()
(vendor/symfony/http-kernel/HttpKernel.php:76)
at Symfony\Component\HttpKernel\HttpKernel->handle()
(vendor/symfony/http-kernel/HttpCache/SubRequestHandler.php:86)
at Symfony\Component\HttpKernel\HttpCache\SubRequestHandler::handle()
(vendor/symfony/http-kernel/Fragment/InlineFragmentRenderer.php:75)
at Symfony\Component\HttpKernel\Fragment\InlineFragmentRenderer->render()
(vendor/symfony/http-kernel/Fragment/FragmentHandler.php:81)
at Symfony\Component\HttpKernel\Fragment\FragmentHandler->render()
(vendor/contao/core-bundle/src/Fragment/FragmentHandler.php:67)
at Contao\CoreBundle\Fragment\FragmentHandler->render()
(vendor/contao/core-bundle/contao/elements/ContentProxy.php:74)
at Contao\ContentProxy->generate()
(vendor/contao/core-bundle/contao/library/Contao/Controller.php:618)
at Contao\Controller::getContentElement()
(vendor/contao/core-bundle/contao/modules/ModuleArticle.php:189)
at Contao\ModuleArticle->compile()
(vendor/contao/core-bundle/contao/modules/Module.php:214)
at Contao\Module->generate()
(vendor/contao/core-bundle/contao/modules/ModuleArticle.php:69)
at Contao\ModuleArticle->generate()
(vendor/contao/core-bundle/contao/library/Contao/Controller.php:493)
at Contao\Controller::getArticle()
(vendor/contao/core-bundle/contao/library/Contao/Controller.php:356)
at Contao\Controller::getFrontendModule()
(vendor/contao/core-bundle/contao/pages/PageRegular.php:208)
at Contao\PageRegular->prepare()
(vendor/contao/core-bundle/contao/pages/PageRegular.php:47)
at Contao\PageRegular->getResponse()
(vendor/contao/core-bundle/contao/controllers/FrontendIndex.php:73)
at Contao\FrontendIndex->renderPage()
(vendor/symfony/http-kernel/HttpKernel.php:183)
at Symfony\Component\HttpKernel\HttpKernel->handleRaw()
(vendor/symfony/http-kernel/HttpKernel.php:76)
at Symfony\Component\HttpKernel\HttpKernel->handle()
(vendor/symfony/http-kernel/Kernel.php:182)
at Symfony\Component\HttpKernel\Kernel->handle()
(public/index.php:42)