From a7ade9dac466df979811ea52d9b5b42ac1b8ec1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 18 Oct 2022 10:42:37 +0200 Subject: [PATCH] DX: use tags iterator to inject aggregators, filters and export during ExportManager's construct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Squashed commit of the following: commit dc2bbc8f4da24549a1d42feb3b453af9f79ab2ff Author: Julien Fastré Date: Tue Oct 18 10:40:14 2022 +0200 Fixes: remove iterator_to_array on formatter, which causes a PHP crashes commit 4ce56a01a77103661fb790d0988df6625f1fb11b Author: Julien Fastré Date: Mon Oct 17 17:41:14 2022 +0200 DX: use tags and dependency injection to build ExportManager --- .../config/services/export.yaml | 12 +- .../CompilerPass/ExportsCompilerPass.php | 103 +----------------- .../ChillMainBundle/Export/ExportManager.php | 78 ++++--------- .../ChillMainBundle/config/services.yaml | 8 ++ 4 files changed, 35 insertions(+), 166 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/config/services/export.yaml b/src/Bundle/ChillActivityBundle/config/services/export.yaml index 69565e29a..d4548109e 100644 --- a/src/Bundle/ChillActivityBundle/config/services/export.yaml +++ b/src/Bundle/ChillActivityBundle/config/services/export.yaml @@ -4,18 +4,15 @@ services: autoconfigure: true ## Indicators - chill.activity.export.count_activity_linked_to_person: - class: Chill\ActivityBundle\Export\Export\LinkedToPerson\CountActivity + Chill\ActivityBundle\Export\Export\LinkedToPerson\CountActivity: tags: - { name: chill.export, alias: 'count_activity_linked_to_person' } - chill.activity.export.sum_activity_duration_linked_to_person: - class: Chill\ActivityBundle\Export\Export\LinkedToPerson\StatActivityDuration + Chill\ActivityBundle\Export\Export\LinkedToPerson\StatActivityDuration: tags: - { name: chill.export, alias: 'sum_activity_duration_linked_to_person' } - chill.activity.export.list_activity_linked_to_person: - class: Chill\ActivityBundle\Export\Export\LinkedToPerson\ListActivity + Chill\ActivityBundle\Export\Export\LinkedToPerson\ListActivity: tags: - { name: chill.export, alias: 'list_activity_linked_to_person' } @@ -116,8 +113,7 @@ services: - { name: chill.export_filter, alias: 'activity_userscope_filter' } ## Aggregators - chill.activity.export.reason_aggregator: - class: Chill\ActivityBundle\Export\Aggregator\PersonAggregators\ActivityReasonAggregator + Chill\ActivityBundle\Export\Aggregator\PersonAggregators\ActivityReasonAggregator: tags: - { name: chill.export_aggregator, alias: activity_reason_aggregator } diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ExportsCompilerPass.php b/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ExportsCompilerPass.php index ae85ba22c..5c351728a 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ExportsCompilerPass.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ExportsCompilerPass.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\MainBundle\DependencyInjection\CompilerPass; +use Chill\MainBundle\Export\ExportManager; use LogicException; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -30,53 +31,19 @@ class ExportsCompilerPass implements CompilerPassInterface { public function process(ContainerBuilder $container) { - if (!$container->has('Chill\MainBundle\Export\ExportManager')) { - throw new LogicException('service Chill\MainBundle\Export\ExportManager ' + if (!$container->has(ExportManager::class)) { + throw new LogicException('service ' . ExportManager::class . ' ' . 'is not defined. It is required by ExportsCompilerPass'); } $chillManagerDefinition = $container->findDefinition( - 'Chill\MainBundle\Export\ExportManager' + ExportManager::class ); - $this->compileExports($chillManagerDefinition, $container); - $this->compileFilters($chillManagerDefinition, $container); - $this->compileAggregators($chillManagerDefinition, $container); $this->compileFormatters($chillManagerDefinition, $container); $this->compileExportElementsProvider($chillManagerDefinition, $container); } - private function compileAggregators( - Definition $chillManagerDefinition, - ContainerBuilder $container - ) { - $taggedServices = $container->findTaggedServiceIds( - 'chill.export_aggregator' - ); - - $knownAliases = []; - - foreach ($taggedServices as $id => $tagAttributes) { - foreach ($tagAttributes as $attributes) { - if (!isset($attributes['alias'])) { - throw new LogicException("the 'alias' attribute is missing in your " . - "service '{$id}' definition"); - } - - if (array_search($attributes['alias'], $knownAliases, true)) { - throw new LogicException('There is already a chill.export_aggregator service with alias ' - . $attributes['alias'] . '. Choose another alias.'); - } - $knownAliases[] = $attributes['alias']; - - $chillManagerDefinition->addMethodCall( - 'addAggregator', - [new Reference($id), $attributes['alias']] - ); - } - } - } - private function compileExportElementsProvider( Definition $chillManagerDefinition, ContainerBuilder $container @@ -108,68 +75,6 @@ class ExportsCompilerPass implements CompilerPassInterface } } - private function compileExports( - Definition $chillManagerDefinition, - ContainerBuilder $container - ) { - $taggedServices = $container->findTaggedServiceIds( - 'chill.export' - ); - - $knownAliases = []; - - foreach ($taggedServices as $id => $tagAttributes) { - foreach ($tagAttributes as $attributes) { - if (!isset($attributes['alias'])) { - throw new LogicException("the 'alias' attribute is missing in your " . - "service '{$id}' definition"); - } - - if (array_search($attributes['alias'], $knownAliases, true)) { - throw new LogicException('There is already a chill.export service with alias ' - . $attributes['alias'] . '. Choose another alias.'); - } - $knownAliases[] = $attributes['alias']; - - $chillManagerDefinition->addMethodCall( - 'addExport', - [new Reference($id), $attributes['alias']] - ); - } - } - } - - private function compileFilters( - Definition $chillManagerDefinition, - ContainerBuilder $container - ) { - $taggedServices = $container->findTaggedServiceIds( - 'chill.export_filter' - ); - - $knownAliases = []; - - foreach ($taggedServices as $id => $tagAttributes) { - foreach ($tagAttributes as $attributes) { - if (!isset($attributes['alias'])) { - throw new LogicException("the 'alias' attribute is missing in your " . - "service '{$id}' definition"); - } - - if (array_search($attributes['alias'], $knownAliases, true)) { - throw new LogicException('There is already a chill.export_filter service with alias ' - . $attributes['alias'] . '. Choose another alias.'); - } - $knownAliases[] = $attributes['alias']; - - $chillManagerDefinition->addMethodCall( - 'addFilter', - [new Reference($id), $attributes['alias']] - ); - } - } - } - private function compileFormatters( Definition $chillManagerDefinition, ContainerBuilder $container diff --git a/src/Bundle/ChillMainBundle/Export/ExportManager.php b/src/Bundle/ChillMainBundle/Export/ExportManager.php index aec5998ff..f39926083 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportManager.php +++ b/src/Bundle/ChillMainBundle/Export/ExportManager.php @@ -14,10 +14,8 @@ namespace Chill\MainBundle\Export; use Chill\MainBundle\Form\Type\Export\ExportType; use Chill\MainBundle\Form\Type\Export\PickCenterType; use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; -use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\QueryBuilder; use Generator; -use InvalidArgumentException; use LogicException; use Psr\Log\LoggerInterface; use RuntimeException; @@ -50,8 +48,6 @@ class ExportManager private AuthorizationHelperInterface $authorizationHelper; - private EntityManagerInterface $em; - /** * Collected Exports, injected by DI. * @@ -82,16 +78,28 @@ class ExportManager public function __construct( LoggerInterface $logger, - EntityManagerInterface $em, AuthorizationCheckerInterface $authorizationChecker, AuthorizationHelperInterface $authorizationHelper, - TokenStorageInterface $tokenStorage + TokenStorageInterface $tokenStorage, + iterable $exports, + iterable $aggregators, + iterable $filters + //iterable $formatters, + //iterable $exportElementProvider ) { $this->logger = $logger; - $this->em = $em; $this->authorizationChecker = $authorizationChecker; $this->authorizationHelper = $authorizationHelper; $this->user = $tokenStorage->getToken()->getUser(); + $this->exports = iterator_to_array($exports); + $this->aggregators = iterator_to_array($aggregators); + $this->filters = iterator_to_array($filters); + // NOTE: PHP crashes on the next line (exit error code 11). This is desactivated until further investigation + //$this->formatters = iterator_to_array($formatters); + + //foreach ($exportElementProvider as $prefix => $provider) { + // $this->addExportElementsProvider($provider, $prefix); + //} } /** @@ -141,52 +149,17 @@ class ExportManager } } - /** - * add an aggregator. - * - * @internal used by DI - * - * @param string $alias - */ - public function addAggregator(AggregatorInterface $aggregator, $alias) - { - $this->aggregators[$alias] = $aggregator; - } - - /** - * add an export. - * - * @internal used by DI - * - * @param DirectExportInterface|ExportInterface $export - * @param type $alias - */ - public function addExport($export, $alias) - { - if ($export instanceof ExportInterface || $export instanceof DirectExportInterface) { - $this->exports[$alias] = $export; - } else { - throw new InvalidArgumentException(sprintf( - 'The export with alias %s ' - . 'does not implements %s or %s.', - $alias, - ExportInterface::class, - DirectExportInterface::class - )); - } - } - public function addExportElementsProvider(ExportElementsProviderInterface $provider, $prefix) { foreach ($provider->getExportElements() as $suffix => $element) { $alias = $prefix . '_' . $suffix; if ($element instanceof ExportInterface) { - $this->addExport($element, $alias); + $this->exports[$alias] = $element; } elseif ($element instanceof FilterInterface) { - $this->addFilter($element, $alias); + $this->filters[$alias] = $element; } elseif ($element instanceof AggregatorInterface) { - $this->addAggregator($element, $alias); + $this->aggregators[$alias] = $element; } elseif ($element instanceof FormatterInterface) { $this->addFormatter($element, $alias); } else { @@ -196,24 +169,12 @@ class ExportManager } } - /** - * add a Filter. - * - * @internal Normally used by the dependency injection - * - * @param string $alias - */ - public function addFilter(FilterInterface $filter, $alias) - { - $this->filters[$alias] = $filter; - } - /** * add a formatter. * * @internal used by DI * - * @param type $alias + * @param string $alias */ public function addFormatter(FormatterInterface $formatter, $alias) { @@ -231,7 +192,6 @@ class ExportManager public function generate($exportAlias, array $pickedCentersData, array $data, array $formatterData) { $export = $this->getExport($exportAlias); - //$qb = $this->em->createQueryBuilder(); $centers = $this->getPickedCenters($pickedCentersData); if ($export instanceof DirectExportInterface) { diff --git a/src/Bundle/ChillMainBundle/config/services.yaml b/src/Bundle/ChillMainBundle/config/services.yaml index 74c495bff..040db1a9f 100644 --- a/src/Bundle/ChillMainBundle/config/services.yaml +++ b/src/Bundle/ChillMainBundle/config/services.yaml @@ -90,6 +90,14 @@ services: Chill\MainBundle\Export\ExportManager: autoconfigure: true autowire: true + arguments: + $exports: !tagged_iterator { tag: chill.export, index_by: alias } + $aggregators: !tagged_iterator { tag: chill.export_aggregator, index_by: alias } + $filters: !tagged_iterator { tag: chill.export_filter, index_by: alias } + # for an unknown reason, iterator_to_array($formatter) cause a segmentation fault error (php-fpm code 11). removed temporarily + # $formatters: !tagged_iterator { tag: chill.export_formatter, index_by: alias } + # remove until we can properly test it + # $exportElementProvider: !tagged_iterator { tag: chill.export_elements_provider, index_by: prefix } Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface: '@Chill\MainBundle\Security\Resolver\CenterResolverDispatcher'