From 0fe793307a8949b79b1a0b75741925e51869e5eb Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Mon, 11 Jul 2022 08:59:32 +0200 Subject: [PATCH] Weimar events Add event to alter the View Variables in foreign code. This is used for grouped dates list on weimar. --- Classes/Controller/DateController.php | 65 ++-- Classes/Domain/Model/Dto/DateDemand.php | 2 +- Classes/Domain/Model/Event.php | 6 + .../Events/Controller/DateListVariables.php | 76 +++++ .../Events/Controller/DateSearchVariables.php | 105 +++++++ Documentation/Changelog/2.5.0.rst | 5 + .../Controller/DateListVariablesTest.php | 186 ++++++++++++ .../Controller/DateSearchVariablesTest.php | 278 ++++++++++++++++++ phpstan-baseline.neon | 5 + 9 files changed, 693 insertions(+), 35 deletions(-) create mode 100644 Classes/Events/Controller/DateListVariables.php create mode 100644 Classes/Events/Controller/DateSearchVariables.php create mode 100644 Tests/Unit/Events/Controller/DateListVariablesTest.php create mode 100644 Tests/Unit/Events/Controller/DateSearchVariablesTest.php diff --git a/Classes/Controller/DateController.php b/Classes/Controller/DateController.php index 7ae81e0..50b57a3 100644 --- a/Classes/Controller/DateController.php +++ b/Classes/Controller/DateController.php @@ -2,7 +2,7 @@ namespace Wrm\Events\Controller; -use TYPO3\CMS\Core\Database\QueryGenerator; +use TYPO3\CMS\Core\EventDispatcher\EventDispatcher; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Annotation as Extbase; use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface; @@ -12,6 +12,8 @@ use Wrm\Events\Domain\Model\Dto\DateDemandFactory; use Wrm\Events\Domain\Repository\CategoryRepository; use Wrm\Events\Domain\Repository\DateRepository; use Wrm\Events\Domain\Repository\RegionRepository; +use Wrm\Events\Events\Controller\DateListVariables; +use Wrm\Events\Events\Controller\DateSearchVariables; use Wrm\Events\Service\DataProcessingForModels; /** @@ -40,43 +42,29 @@ class DateController extends AbstractController protected $categoryRepository; /** - * @var QueryGenerator + * @var EventDispatcher */ - protected $queryGenerator; + protected $eventDispatcher; /** * @var DataProcessingForModels */ protected $dataProcessing; - /** - * @var array - */ - protected $pluginSettings; - - /* - * @param RegionRepository $regionRepository - * @param DateRepository $dateRepository - * @param CategoryRepository $categoryRepository - */ public function __construct( DateDemandFactory $demandFactory, RegionRepository $regionRepository, DateRepository $dateRepository, - CategoryRepository $categoryRepository + CategoryRepository $categoryRepository, + DataProcessingForModels $dataProcessing, + EventDispatcher $eventDispatcher ) { $this->demandFactory = $demandFactory; $this->regionRepository = $regionRepository; $this->dateRepository = $dateRepository; $this->categoryRepository = $categoryRepository; - } - - /** - * @param DataProcessingForModels $dataProcessing - */ - public function injectDataProcessingForModels(DataProcessingForModels $dataProcessing): void - { $this->dataProcessing = $dataProcessing; + $this->eventDispatcher = $eventDispatcher; } protected function initializeAction(): void @@ -86,9 +74,6 @@ class DateController extends AbstractController $this->demandFactory->setContentObjectRenderer($contentObject); } $this->dataProcessing->setConfigurationManager($this->configurationManager); - $this->pluginSettings = $this->configurationManager->getConfiguration( - ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK - ); } /** @@ -110,11 +95,15 @@ class DateController extends AbstractController $demand = $this->demandFactory->fromSettings($this->settings); } - $this->view->assignMultiple([ - 'search' => $search, - 'demand' => $demand, - 'dates' => $this->dateRepository->findByDemand($demand), - ]); + $event = $this->eventDispatcher->dispatch(new DateListVariables( + $search, + $demand, + $this->dateRepository->findByDemand($demand) + )); + if (!$event instanceof DateListVariables) { + throw new \Exception('Did not retrieve DateSearchVariables from event dispatcher, got: ' . get_class($event), 1657542318); + } + $this->view->assignMultiple($event->getVariablesForView()); } /** @@ -131,18 +120,26 @@ class DateController extends AbstractController unset($arguments['events_search']); } + // For legacy systems. $this->view->assignMultiple([ 'searchword' => $arguments['searchword'] ?? '', 'selRegion' => $arguments['region'] ?? '', 'start' => $arguments['start'] ?? '', 'end' => $arguments['end'] ?? '', 'considerDate' => $arguments['considerDate'] ?? '', - 'search' => $search, - 'demand' => DateDemand::createFromRequestValues($arguments, $this->settings), - 'regions' => $this->regionRepository->findAll(), - 'categories' => $this->categoryRepository->findAllCurrentlyAssigned($this->settings['uids']['categoriesParent'] ?? 0, 'categories'), - 'features' => $this->categoryRepository->findAllCurrentlyAssigned($this->settings['uids']['featuresParent'] ?? 0, 'features'), ]); + + $event = $this->eventDispatcher->dispatch(new DateSearchVariables( + $search, + DateDemand::createFromRequestValues($arguments, $this->settings), + $this->regionRepository->findAll(), + $this->categoryRepository->findAllCurrentlyAssigned($this->settings['uids']['categoriesParent'] ?? 0, 'categories'), + $this->categoryRepository->findAllCurrentlyAssigned($this->settings['uids']['featuresParent'] ?? 0, 'features') + )); + if (!$event instanceof DateSearchVariables) { + throw new \Exception('Did not retrieve DateSearchVariables from event dispatcher, got: ' . get_class($event), 1657542318); + } + $this->view->assignMultiple($event->getVariablesForView()); } public function teaserAction(): void diff --git a/Classes/Domain/Model/Dto/DateDemand.php b/Classes/Domain/Model/Dto/DateDemand.php index a4c1440..0b8be1a 100644 --- a/Classes/Domain/Model/Dto/DateDemand.php +++ b/Classes/Domain/Model/Dto/DateDemand.php @@ -132,7 +132,7 @@ class DateDemand $instance->setUserCategories($submittedValues['userCategories']); } - if (is_array($submittedValues['features'])) { + if (isset($submittedValues['features']) && is_array($submittedValues['features'])) { $instance->setFeatures($submittedValues['features']); } diff --git a/Classes/Domain/Model/Event.php b/Classes/Domain/Model/Event.php index 8a3ab2e..f78d395 100644 --- a/Classes/Domain/Model/Event.php +++ b/Classes/Domain/Model/Event.php @@ -534,6 +534,9 @@ class Event extends AbstractEntity $this->categories->attach($category); } + /** + * @return array + */ public function getCategories(): array { $categories = $this->categories->toArray(); @@ -553,6 +556,9 @@ class Event extends AbstractEntity $this->categories = $categories; } + /** + * @return array + */ public function getFeatures(): array { $features = $this->features->toArray(); diff --git a/Classes/Events/Controller/DateListVariables.php b/Classes/Events/Controller/DateListVariables.php new file mode 100644 index 0000000..78f267d --- /dev/null +++ b/Classes/Events/Controller/DateListVariables.php @@ -0,0 +1,76 @@ + + */ + private $dates; + + /** + * @var array + */ + private $variables = []; + + public function __construct( + array $search, + DateDemand $demand, + QueryResult $dates + ) { + $this->search = $search; + $this->demand = $demand; + $this->dates = $dates; + } + + public function getSearch(): array + { + return $this->search; + } + + public function getDemand(): DateDemand + { + return $this->demand; + } + + /** + * @return QueryResult + */ + public function getDates(): QueryResult + { + return $this->dates; + } + + /** + * @param mixed $value + */ + public function addVariable(string $key, $value): void + { + $this->variables[$key] = $value; + } + + public function getVariablesForView(): array + { + return array_merge([ + 'search' => $this->search, + 'demand' => $this->demand, + 'dates' => $this->dates, + ], $this->variables); + } +} diff --git a/Classes/Events/Controller/DateSearchVariables.php b/Classes/Events/Controller/DateSearchVariables.php new file mode 100644 index 0000000..cbd68c4 --- /dev/null +++ b/Classes/Events/Controller/DateSearchVariables.php @@ -0,0 +1,105 @@ + + */ + private $regions; + + /** + * @var array + */ + private $categories; + + /** + * @var array + */ + private $features; + + /** + * @var array + */ + private $variables = []; + + /** + * @param QueryResultInterface $regions + */ + public function __construct( + array $search, + DateDemand $demand, + QueryResultInterface $regions, + array $categories, + array $features + ) { + $this->search = $search; + $this->demand = $demand; + $this->regions = $regions; + $this->categories = $categories; + $this->features = $features; + } + + public function getSearch(): array + { + return $this->search; + } + + public function getDemand(): DateDemand + { + return $this->demand; + } + + /** + * @return QueryResultInterface + */ + public function getRegions(): QueryResultInterface + { + return $this->regions; + } + + public function getCategories(): array + { + return $this->categories; + } + + public function getFeatures(): array + { + return $this->features; + } + + /** + * @param mixed $value + */ + public function addVariable(string $key, $value): void + { + $this->variables[$key] = $value; + } + + public function getVariablesForView(): array + { + return array_merge([ + 'search' => $this->search, + 'demand' => $this->demand, + 'regions' => $this->regions, + 'categories' => $this->categories, + 'features' => $this->features, + ], $this->variables); + } +} diff --git a/Documentation/Changelog/2.5.0.rst b/Documentation/Changelog/2.5.0.rst index b579167..5be9dc8 100644 --- a/Documentation/Changelog/2.5.0.rst +++ b/Documentation/Changelog/2.5.0.rst @@ -39,6 +39,11 @@ Features It is possible to add them to user submitted filter. +* Add PSR-14 events to Date controller. Those events allow to alter the variables + assigned to views within list and search action. + This might be used to add further variables or to alter variables, e.g. hide some + categories, group dates, etc. + Fixes ----- diff --git a/Tests/Unit/Events/Controller/DateListVariablesTest.php b/Tests/Unit/Events/Controller/DateListVariablesTest.php new file mode 100644 index 0000000..f53862a --- /dev/null +++ b/Tests/Unit/Events/Controller/DateListVariablesTest.php @@ -0,0 +1,186 @@ +prophesize(QueryResult::class)->reveal() + ); + + self::assertInstanceOf( + DateListVariables::class, + $subject + ); + } + + /** + * @test + */ + public function returnsInitialSearch(): void + { + $subject = new DateListVariables( + [ + 'executed' => '1', + ], + new DateDemand(), + $this->prophesize(QueryResult::class)->reveal() + ); + + self::assertSame( + [ + 'executed' => '1', + ], + $subject->getSearch() + ); + } + + /** + * @test + */ + public function returnsInitialDemand(): void + { + $demand = new DateDemand(); + $subject = new DateListVariables( + [ + ], + $demand, + $this->prophesize(QueryResult::class)->reveal() + ); + + self::assertSame( + $demand, + $subject->getDemand() + ); + } + + /** + * @test + */ + public function returnsInitialDates(): void + { + $dates = $this->prophesize(QueryResult::class)->reveal(); + $subject = new DateListVariables( + [ + ], + new DateDemand(), + $dates + ); + + self::assertSame( + $dates, + $subject->getDates() + ); + } + + /** + * @test + */ + public function returnsInitialVariablesForView(): void + { + $demand = new DateDemand(); + $dates = $this->prophesize(QueryResult::class)->reveal(); + $subject = new DateListVariables( + [ + 'executed' => '1', + ], + $demand, + $dates + ); + + self::assertSame( + [ + 'search' => [ + 'executed' => '1', + ], + 'demand' => $demand, + 'dates' => $dates, + ], + $subject->getVariablesForView() + ); + } + + /** + * @test + */ + public function returnsVariablesForViewWithAddedVariables(): void + { + $demand = new DateDemand(); + $dates = $this->prophesize(QueryResult::class)->reveal(); + $subject = new DateListVariables( + [ + 'executed' => '1', + ], + $demand, + $dates + ); + + $subject->addVariable('variable 1', 'Value 1'); + $subject->addVariable('variable 2', 'Value 2'); + + self::assertSame( + [ + 'search' => [ + 'executed' => '1', + ], + 'demand' => $demand, + 'dates' => $dates, + 'variable 1' => 'Value 1', + 'variable 2' => 'Value 2', + ], + $subject->getVariablesForView() + ); + } + + /** + * @test + */ + public function returnsVariablesForViewWithOverwrittenVariables(): void + { + $demand = new DateDemand(); + $dates = $this->prophesize(QueryResult::class)->reveal(); + $subject = new DateListVariables( + [ + 'executed' => '1', + ], + $demand, + $dates + ); + + $subject->addVariable('variable 1', 'Value 1'); + $subject->addVariable('variable 1', 'Value 2'); + $subject->addVariable('dates', 'Value 2'); + + self::assertSame( + [ + 'search' => [ + 'executed' => '1', + ], + 'demand' => $demand, + 'dates' => 'Value 2', + 'variable 1' => 'Value 2', + ], + $subject->getVariablesForView() + ); + } +} diff --git a/Tests/Unit/Events/Controller/DateSearchVariablesTest.php b/Tests/Unit/Events/Controller/DateSearchVariablesTest.php new file mode 100644 index 0000000..dae8bd8 --- /dev/null +++ b/Tests/Unit/Events/Controller/DateSearchVariablesTest.php @@ -0,0 +1,278 @@ +prophesize(QueryResult::class)->reveal(), + [], + [] + ); + + self::assertInstanceOf( + DateSearchVariables::class, + $subject + ); + } + + /** + * @test + */ + public function returnsInitializeSearch(): void + { + $subject = new DateSearchVariables( + [ + 'executed' => '1', + ], + new DateDemand(), + $this->prophesize(QueryResult::class)->reveal(), + [], + [] + ); + + self::assertSame( + [ + 'executed' => '1', + ], + $subject->getSearch() + ); + } + + /** + * @test + */ + public function returnsInitializeDemand(): void + { + $demand = new DateDemand(); + $subject = new DateSearchVariables( + [ + ], + $demand, + $this->prophesize(QueryResult::class)->reveal(), + [], + [] + ); + + self::assertSame( + $demand, + $subject->getDemand() + ); + } + + /** + * @test + */ + public function returnsInitialRegions(): void + { + $regions = $this->prophesize(QueryResult::class)->reveal(); + $subject = new DateSearchVariables( + [ + ], + new DateDemand(), + $regions, + [], + [] + ); + + self::assertSame( + $regions, + $subject->getRegions() + ); + } + + /** + * @test + */ + public function returnsInitialCategories(): void + { + $subject = new DateSearchVariables( + [ + ], + new DateDemand(), + $this->prophesize(QueryResult::class)->reveal(), + [ + ['example category'], + ], + [] + ); + + self::assertSame( + [ + ['example category'], + ], + $subject->getCategories() + ); + } + + /** + * @test + */ + public function returnsInitialFeatures(): void + { + $subject = new DateSearchVariables( + [ + ], + new DateDemand(), + $this->prophesize(QueryResult::class)->reveal(), + [ + ], + [ + ['example feature category'], + ] + ); + + self::assertSame( + [ + ['example feature category'], + ], + $subject->getFeatures() + ); + } + + /** + * @test + */ + public function returnsInitialVariablesForView(): void + { + $demand = new DateDemand(); + $regions = $this->prophesize(QueryResult::class)->reveal(); + $subject = new DateSearchVariables( + [ + 'executed' => '1', + ], + $demand, + $regions, + [ + ['example category category'], + ], + [ + ['example feature category'], + ] + ); + + self::assertSame( + [ + 'search' => [ + 'executed' => '1', + ], + 'demand' => $demand, + 'regions' => $regions, + 'categories' => [ + ['example category category'], + ], + 'features' => [ + ['example feature category'], + ], + ], + $subject->getVariablesForView() + ); + } + + /** + * @test + */ + public function returnsVariablesForViewWithAddedVariables(): void + { + $demand = new DateDemand(); + $regions = $this->prophesize(QueryResult::class)->reveal(); + $subject = new DateSearchVariables( + [ + 'executed' => '1', + ], + $demand, + $regions, + [ + ['example category category'], + ], + [ + ['example feature category'], + ] + ); + + $subject->addVariable('variable 1', 'Value 1'); + $subject->addVariable('variable 2', 'Value 2'); + + self::assertSame( + [ + 'search' => [ + 'executed' => '1', + ], + 'demand' => $demand, + 'regions' => $regions, + 'categories' => [ + ['example category category'], + ], + 'features' => [ + ['example feature category'], + ], + 'variable 1' => 'Value 1', + 'variable 2' => 'Value 2', + ], + $subject->getVariablesForView() + ); + } + + /** + * @test + */ + public function returnsVariablesForViewWithOverwrittenVariables(): void + { + $demand = new DateDemand(); + $regions = $this->prophesize(QueryResult::class)->reveal(); + $subject = new DateSearchVariables( + [ + 'executed' => '1', + ], + $demand, + $regions, + [ + ['example category category'], + ], + [ + ['example feature category'], + ] + ); + + $subject->addVariable('variable 1', 'Value 1'); + $subject->addVariable('variable 1', 'Value 2'); + $subject->addVariable('features', 'Value 2'); + + self::assertSame( + [ + 'search' => [ + 'executed' => '1', + ], + 'demand' => $demand, + 'regions' => $regions, + 'categories' => [ + ['example category category'], + ], + 'features' => 'Value 2', + 'variable 1' => 'Value 2', + ], + $subject->getVariablesForView() + ); + } +} diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 62566af..30bf9ac 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -34,3 +34,8 @@ parameters: count: 1 path: Classes/Service/DestinationDataImportService.php + - + message: "#^Method Wrm\\\\Events\\\\Service\\\\DestinationDataImportService\\\\CategoriesAssignment\\:\\:getCategories\\(\\) should return TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\ObjectStorage\\ but returns TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\ObjectStorage\\\\.$#" + count: 2 + path: Classes/Service/DestinationDataImportService/CategoriesAssignment.php +