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.
This commit is contained in:
Julien Fastré 2025-04-25 18:24:26 +02:00
parent 6d76b94644
commit b6985e0e5f
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
11 changed files with 100 additions and 32 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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'],
];
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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