From b6985e0e5f29bafa030dcbde7e45ede7f987b1ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 25 Apr 2025 18:24:26 +0200 Subject: [PATCH] Refactor form data handling in export filters and aggregators Improved normalization and denormalization of form data by introducing default values and null handling across various filters and aggregators. Added `ExportDataNormalizerTrait` and repository dependencies where necessary to streamline data processing. This ensures more robust data handling and better default value management. --- .../ACPFilters/BySocialActionFilter.php | 14 +++++++--- .../Export/Filter/LocationTypeFilter.php | 13 +++++++--- .../ReferrerAggregator.php | 7 ++++- .../ReferrerScopeAggregator.php | 7 ++++- .../SocialActionFilter.php | 17 ++++++++++-- .../SocialIssueFilter.php | 18 ++++++------- .../UserJobFilter.php | 6 +++-- .../UserScopeFilter.php | 8 +++++- ...yingPeriodWorkEndDateBetweenDateFilter.php | 8 ++++-- ...ngPeriodWorkStartDateBetweenDateFilter.php | 8 ++++-- .../SocialWorkTypeFilter.php | 26 ++++++++++++++++--- 11 files changed, 100 insertions(+), 32 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php index e95f599f7..e9400cad3 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php @@ -12,17 +12,21 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Export\Filter\ACPFilters; use Chill\ActivityBundle\Export\Declarations; +use Chill\MainBundle\Export\ExportDataNormalizerTrait; use Chill\MainBundle\Export\ExportGenerationContext; use Chill\MainBundle\Export\FilterInterface; use Chill\PersonBundle\Entity\SocialWork\SocialAction; use Chill\PersonBundle\Form\Type\PickSocialActionType; +use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository; use Chill\PersonBundle\Templating\Entity\SocialActionRender; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; class BySocialActionFilter implements FilterInterface { - public function __construct(private readonly SocialActionRender $actionRender) {} + use ExportDataNormalizerTrait; + + public function __construct(private readonly SocialActionRender $actionRender, private readonly SocialActionRepository $socialActionRepository) {} public function addRole(): ?string { @@ -63,17 +67,19 @@ class BySocialActionFilter implements FilterInterface public function normalizeFormData(array $formData): array { - return ['accepted_socialactions' => $formData['accepted_socialactions']]; + return ['accepted_socialactions' => $this->normalizeDoctrineEntity($formData['accepted_socialactions'])]; } public function denormalizeFormData(array $formData, int $fromVersion): array { - return ['accepted_socialactions' => $formData['accepted_socialactions']]; + return ['accepted_socialactions' => $this->denormalizeDoctrineEntity($formData['accepted_socialactions'], $this->socialActionRepository)]; } public function getFormDefaultData(): array { - return []; + return [ + 'accepted_socialactions' => [] + ]; } public function describeAction($data, ExportGenerationContext $context): array diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/LocationTypeFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/LocationTypeFilter.php index 073baf374..4c3e0304b 100644 --- a/src/Bundle/ChillActivityBundle/Export/Filter/LocationTypeFilter.php +++ b/src/Bundle/ChillActivityBundle/Export/Filter/LocationTypeFilter.php @@ -12,9 +12,12 @@ declare(strict_types=1); namespace Chill\ActivityBundle\Export\Filter; use Chill\ActivityBundle\Export\Declarations; +use Chill\MainBundle\Export\ExportDataNormalizerTrait; use Chill\MainBundle\Export\ExportGenerationContext; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Form\Type\PickLocationTypeType; +use Chill\MainBundle\Repository\LocationRepository; +use Chill\MainBundle\Repository\LocationTypeRepository; use Chill\MainBundle\Templating\TranslatableStringHelper; use Doctrine\ORM\Query\Expr\Andx; use Doctrine\ORM\QueryBuilder; @@ -22,7 +25,9 @@ use Symfony\Component\Form\FormBuilderInterface; class LocationTypeFilter implements FilterInterface { - public function __construct(private readonly TranslatableStringHelper $translatableStringHelper) {} + use ExportDataNormalizerTrait; + + public function __construct(private readonly TranslatableStringHelper $translatableStringHelper, private LocationTypeRepository $locationTypeRepository) {} public function addRole(): ?string { @@ -68,17 +73,17 @@ class LocationTypeFilter implements FilterInterface public function normalizeFormData(array $formData): array { - return ['accepted_locationtype' => $formData['accepted_locationtype']]; + return ['accepted_locationtype' => $this->normalizeDoctrineEntity($formData['accepted_locationtype'])]; } public function denormalizeFormData(array $formData, int $fromVersion): array { - return ['accepted_locationtype' => $formData['accepted_locationtype']]; + return ['accepted_locationtype' => $this->denormalizeDoctrineEntity($formData['accepted_locationtype'], $this->locationTypeRepository)]; } public function getFormDefaultData(): array { - return []; + return ['accepted_locationtype' => []]; } public function describeAction($data, ExportGenerationContext $context): array diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php index cd07f0967..e94869747 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php @@ -91,7 +91,12 @@ final readonly class ReferrerAggregator implements AggregatorInterface, DataTran public function denormalizeFormData(array $formData, int $fromVersion): array { - return ['start_date' => RollingDate::fromNormalized($formData['start_date']), 'end_date' => RollingDate::fromNormalized($formData['end_date'])]; + $defaultData = $this->getFormDefaultData(); + + return [ + 'start_date' => array_key_exists('start_date', $formData) ? RollingDate::fromNormalized($formData['start_date']) : $defaultData['start_date'], + 'end_date' => array_key_exists('end_date', $formData) ? RollingDate::fromNormalized($formData['end_date']) : $defaultData['end_date'], + ]; } public function getFormDefaultData(): array diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerScopeAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerScopeAggregator.php index 8d4f556b6..d0f8ae64c 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerScopeAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerScopeAggregator.php @@ -101,7 +101,12 @@ readonly class ReferrerScopeAggregator implements AggregatorInterface, DataTrans public function denormalizeFormData(array $formData, int $fromVersion): array { - return ['start_date' => RollingDate::fromNormalized($formData['start_date']), 'end_date' => RollingDate::fromNormalized($formData['end_date'])]; + $default = $this->getFormDefaultData(); + + return [ + 'start_date' => array_key_exists('start_date', $formData) ? RollingDate::fromNormalized($formData['start_date']) : $default['start_date'], + 'end_date' => array_key_exists('end_date', $formData) ? RollingDate::fromNormalized($formData['end_date']): $default['end_date'], + ]; } public function getFormDefaultData(): array diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialActionFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialActionFilter.php index fbd5ef295..1c108ae03 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialActionFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialActionFilter.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters; +use Chill\MainBundle\Export\ExportDataNormalizerTrait; use Chill\MainBundle\Export\ExportGenerationContext; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Form\Type\PickRollingDateType; @@ -19,6 +20,7 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\SocialWork\SocialAction; use Chill\PersonBundle\Export\Declarations; use Chill\PersonBundle\Form\Type\PickSocialActionType; +use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository; use Chill\PersonBundle\Templating\Entity\SocialActionRender; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; @@ -26,12 +28,15 @@ use Symfony\Contracts\Translation\TranslatorInterface; final readonly class SocialActionFilter implements FilterInterface { + use ExportDataNormalizerTrait; + private const PREFIX = 'acp_by_social_action_filter'; public function __construct( private SocialActionRender $actionRender, private RollingDateConverterInterface $rollingDateConverter, private TranslatorInterface $translator, + private SocialActionRepository $socialActionRepository, ) {} public function addRole(): ?string @@ -120,12 +125,20 @@ final readonly class SocialActionFilter implements FilterInterface public function normalizeFormData(array $formData): array { - return ['accepted_socialactions' => $formData['accepted_socialactions'], 'start_date_after' => $formData['start_date_after']?->normalize(), 'start_date_before' => $formData['start_date_before']?->normalize(), 'end_date_after' => $formData['end_date_after']?->normalize(), 'end_date_before' => $formData['end_date_before']?->normalize()]; + return ['accepted_socialactions' => $this->normalizeDoctrineEntity($formData['accepted_socialactions']), + 'start_date_after' => $formData['start_date_after']?->normalize(), + 'start_date_before' => $formData['start_date_before']?->normalize(), + 'end_date_after' => $formData['end_date_after']?->normalize(), + 'end_date_before' => $formData['end_date_before']?->normalize()]; } public function denormalizeFormData(array $formData, int $fromVersion): array { - return ['accepted_socialactions' => $formData['accepted_socialactions'], 'start_date_after' => \Chill\MainBundle\Service\RollingDate\RollingDate::fromNormalized($formData['start_date_after']), 'start_date_before' => \Chill\MainBundle\Service\RollingDate\RollingDate::fromNormalized($formData['start_date_before']), 'end_date_after' => \Chill\MainBundle\Service\RollingDate\RollingDate::fromNormalized($formData['end_date_after']), 'end_date_before' => \Chill\MainBundle\Service\RollingDate\RollingDate::fromNormalized($formData['end_date_before'])]; + return ['accepted_socialactions' => $this->denormalizeDoctrineEntity($formData['accepted_socialactions'], $this->socialActionRepository), + 'start_date_after' => \Chill\MainBundle\Service\RollingDate\RollingDate::fromNormalized($formData['start_date_after'] ?? null), + 'start_date_before' => \Chill\MainBundle\Service\RollingDate\RollingDate::fromNormalized($formData['start_date_before'] ?? null), + 'end_date_after' => \Chill\MainBundle\Service\RollingDate\RollingDate::fromNormalized($formData['end_date_after'] ?? null), + 'end_date_before' => \Chill\MainBundle\Service\RollingDate\RollingDate::fromNormalized($formData['end_date_before'] ?? null)]; } public function getFormDefaultData(): array diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialIssueFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialIssueFilter.php index a1a9c9a3e..97838b349 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialIssueFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialIssueFilter.php @@ -11,11 +11,13 @@ declare(strict_types=1); namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters; +use Chill\MainBundle\Export\ExportDataNormalizerTrait; use Chill\MainBundle\Export\ExportGenerationContext; use Chill\MainBundle\Export\FilterInterface; use Chill\PersonBundle\Entity\SocialWork\SocialIssue; use Chill\PersonBundle\Export\Declarations; use Chill\PersonBundle\Form\Type\PickSocialIssueType; +use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository; use Chill\PersonBundle\Templating\Entity\SocialIssueRender; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\QueryBuilder; @@ -24,17 +26,13 @@ use Symfony\Contracts\Translation\TranslatorInterface; class SocialIssueFilter implements FilterInterface { - /** - * @var TranslatorInterface - */ - protected $translator; + use ExportDataNormalizerTrait; public function __construct( - TranslatorInterface $translator, + private readonly TranslatorInterface $translator, private readonly SocialIssueRender $socialIssueRender, - ) { - $this->translator = $translator; - } + private readonly SocialIssueRepository $socialIssueRepository, + ) {} public function addRole(): ?string { @@ -77,12 +75,12 @@ class SocialIssueFilter implements FilterInterface public function normalizeFormData(array $formData): array { - return ['accepted_socialissues' => $formData['accepted_socialissues']]; + return ['accepted_socialissues' => $this->normalizeDoctrineEntity($formData['accepted_socialissues'])]; } public function denormalizeFormData(array $formData, int $fromVersion): array { - return ['accepted_socialissues' => $formData['accepted_socialissues']]; + return ['accepted_socialissues' => $this->denormalizeDoctrineEntity($formData['accepted_socialissues'], $this->socialIssueRepository)]; } public function getFormDefaultData(): array diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserJobFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserJobFilter.php index 6e2273502..b3da6d50b 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserJobFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserJobFilter.php @@ -140,10 +140,12 @@ final readonly class UserJobFilter implements FilterInterface, DataTransformerIn public function denormalizeFormData(array $formData, int $fromVersion): array { + $default = $this->getFormDefaultData(); + return [ 'jobs' => $this->denormalizeDoctrineEntity($formData['jobs'], $this->userJobRepository), - 'start_date' => RollingDate::fromNormalized($formData['start_date']), - 'end_date' => RollingDate::fromNormalized($formData['end_date']), + 'start_date' => array_key_exists('start_date', $formData) ? RollingDate::fromNormalized($formData['start_date']) : $default['start_date'], + 'end_date' => array_key_exists('end_date', $formData) ? RollingDate::fromNormalized($formData['end_date']) : $default['end_date'], ]; } diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserScopeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserScopeFilter.php index cc7ca465f..4bd8a1abb 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserScopeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserScopeFilter.php @@ -110,7 +110,13 @@ final readonly class UserScopeFilter implements FilterInterface, DataTransformer public function denormalizeFormData(array $formData, int $fromVersion): array { - return ['scopes' => $this->denormalizeDoctrineEntity($formData['scopes'], $this->scopeRepository), 'start_date' => RollingDate::fromNormalized($formData['start_date']), 'end_date' => RollingDate::fromNormalized($formData['end_date'])]; + $default = $this->getFormDefaultData(); + + return [ + 'scopes' => $this->denormalizeDoctrineEntity($formData['scopes'], $this->scopeRepository), + 'start_date' => array_key_exists('start_date', $formData) ? RollingDate::fromNormalized($formData['start_date']) : $default['start_date'], + 'end_date' => array_key_exists('end_date', $formData) ? RollingDate::fromNormalized($formData['end_date']) : $default['end_date'], + ]; } public function describeAction($data, ExportGenerationContext $context): string|\Symfony\Contracts\Translation\TranslatableInterface|array diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php index ed8fa4699..0131641f0 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkEndDateBetweenDateFilter.php @@ -54,12 +54,16 @@ final readonly class AccompanyingPeriodWorkEndDateBetweenDateFilter implements F public function denormalizeFormData(array $formData, int $fromVersion): array { - return ['start_date' => RollingDate::fromNormalized($formData['start_date']), 'end_date' => RollingDate::fromNormalized($formData['end_date']), 'keep_null' => $formData['keep_null']]; + return [ + 'start_date' => RollingDate::fromNormalized($formData['start_date']), + 'end_date' => RollingDate::fromNormalized($formData['end_date']), + 'keep_null' => (bool) ($formData['keep_null'] ?? true) + ]; } public function getFormDefaultData(): array { - return ['start_date' => new RollingDate(RollingDate::T_TODAY), 'end_date' => new RollingDate(RollingDate::T_TODAY)]; + return ['start_date' => new RollingDate(RollingDate::T_TODAY), 'end_date' => new RollingDate(RollingDate::T_TODAY), 'keep_null' => true]; } public function getTitle(): string diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php index f3911de5e..b061ab550 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/AccompanyingPeriodWorkStartDateBetweenDateFilter.php @@ -54,12 +54,16 @@ final readonly class AccompanyingPeriodWorkStartDateBetweenDateFilter implements public function denormalizeFormData(array $formData, int $fromVersion): array { - return ['start_date' => RollingDate::fromNormalized($formData['start_date']), 'end_date' => RollingDate::fromNormalized($formData['end_date']), 'keep_null' => $formData['keep_null']]; + return [ + 'start_date' => RollingDate::fromNormalized($formData['start_date']), + 'end_date' => RollingDate::fromNormalized($formData['end_date']), + 'keep_null' => (bool) ($formData['keep_null'] ?? true), + ]; } public function getFormDefaultData(): array { - return ['start_date' => new RollingDate(RollingDate::T_TODAY), 'end_date' => new RollingDate(RollingDate::T_TODAY)]; + return ['start_date' => new RollingDate(RollingDate::T_TODAY), 'end_date' => new RollingDate(RollingDate::T_TODAY), 'keep_null' => true]; } public function getTitle(): string diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php index 1677d133c..b16ecac5f 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\PersonBundle\Export\Filter\SocialWorkFilters; +use Chill\MainBundle\Export\ExportDataNormalizerTrait; use Chill\MainBundle\Export\ExportGenerationContext; use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Templating\TranslatableStringHelper; @@ -27,7 +28,13 @@ use Symfony\Component\Form\FormBuilderInterface; class SocialWorkTypeFilter implements FilterInterface { - public function __construct(private readonly SocialActionRender $socialActionRender, private readonly TranslatableStringHelper $translatableStringHelper, private readonly EntityManagerInterface $em) {} + use ExportDataNormalizerTrait; + + public function __construct( + private readonly SocialActionRender $socialActionRender, + private readonly TranslatableStringHelper $translatableStringHelper, + private readonly EntityManagerInterface $em, + ) {} public function addRole(): ?string { @@ -103,12 +110,25 @@ class SocialWorkTypeFilter implements FilterInterface public function normalizeFormData(array $formData): array { - return []; + return [ + 'actionType' => $formData['actionType'], + 'goal' => $formData['goal'], + 'result' => $formData['result'], + ]; } public function denormalizeFormData(array $formData, int $fromVersion): array { - return []; + return [ + 'actionType' => $this->denormalizeDoctrineEntity($this->denormalizeStringRepresentation($formData['actionType']), $this->em->getRepository(SocialAction::class)), + 'goal' => $this->denormalizeDoctrineEntity($this->denormalizeStringRepresentation($formData['goal']), $this->em->getRepository(Goal::class)), + 'result' => $this->denormalizeDoctrineEntity($this->denormalizeStringRepresentation($formData['result']), $this->em->getRepository(Result::class)), + ]; + } + + private function denormalizeStringRepresentation(string $ids): array + { + return array_map(fn (string $id) => (int) $id, explode(',', $ids)); } public function getFormDefaultData(): array