Customize genderFilter to include a NULL choice + add translation and adjust test

This commit is contained in:
Julie Lenaerts 2024-10-21 16:45:45 +02:00
parent 30ebd00693
commit 0d2e0b4e91
3 changed files with 31 additions and 24 deletions

View File

@ -14,11 +14,13 @@ namespace Chill\PersonBundle\Export\Filter\PersonFilters;
use Chill\MainBundle\Entity\Gender; use Chill\MainBundle\Entity\Gender;
use Chill\MainBundle\Export\ExportElementValidatedInterface; use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Repository\GenderRepository;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Chill\PersonBundle\Export\Declarations; use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
@ -27,7 +29,8 @@ class GenderFilter implements
ExportElementValidatedInterface, ExportElementValidatedInterface,
FilterInterface FilterInterface
{ {
public function __construct(private readonly TranslatorInterface $translator, private readonly TranslatableStringHelperInterface $translatableStringHelper) {} // inject gender repository and find the active genders so that you can pass them to the ChoiceType (ordered by ordering)
public function __construct(private readonly TranslatorInterface $translator, private readonly TranslatableStringHelperInterface $translatableStringHelper, private readonly GenderRepository $genderRepository) {}
public function addRole(): ?string public function addRole(): ?string
{ {
@ -39,23 +42,17 @@ class GenderFilter implements
$where = $qb->getDQLPart('where'); $where = $qb->getDQLPart('where');
$isIn = $qb->expr()->in('person.gender', ':person_gender'); $isIn = $qb->expr()->in('person.gender', ':person_gender');
if (!\in_array('null', $data['accepted_genders']->toArray(), true)) { $acceptedGenders = $data['accepted_genders_entity'];
$nullIncluded = in_array(null, $acceptedGenders, true);
if (!$nullIncluded) {
$clause = $isIn; $clause = $isIn;
} else { } else {
$clause = $qb->expr()->orX($isIn, $qb->expr()->isNull('person.gender')); $clause = $qb->expr()->orX($isIn, $qb->expr()->isNull('person.gender'));
} }
if ($where instanceof Expr\Andx) { $qb->andWhere($clause);
$where->add($clause); $qb->setParameter('person_gender', array_filter($acceptedGenders, fn($gender) => $gender !== null));
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('person_gender', \array_filter(
$data['accepted_genders']->toArray(),
static fn ($el) => 'null' !== $el
));
} }
public function applyOn() public function applyOn()
@ -65,11 +62,18 @@ class GenderFilter implements
public function buildForm(FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder)
{ {
$builder->add('accepted_genders', EntityType::class, [ $genderChoices = $this->genderRepository->findByActiveOrdered();
'class' => Gender::class, $choices = ['None' => null];
'choice_label' => fn (Gender $g) => $this->translatableStringHelper->localize($g->getLabel()),
foreach ($genderChoices as $gender) {
$choices[$this->translatableStringHelper->localize($gender->getLabel())] = $gender->getId();
}
$builder->add('accepted_genders_entity', ChoiceType::class, [
'choices' => $choices,
'multiple' => true, 'multiple' => true,
'expanded' => true, 'expanded' => true,
'placeholder' => 'Select gender',
]); ]);
} }
@ -82,11 +86,11 @@ class GenderFilter implements
{ {
$genders = []; $genders = [];
foreach ($data['accepted_genders'] as $g) { foreach ($data['accepted_genders_entity'] as $g) {
if ('null' === $g) { if (null === $g) {
$genders[] = $this->translator->trans('Not given'); $genders[] = $this->translator->trans('export.filter.person.gender.no_gender');
} else { } else {
$genders[] = $this->translatableStringHelper->localize($g->getLabel()); $genders[] = $this->translatableStringHelper->localize($this->genderRepository->find($g)->getLabel());
} }
} }
@ -108,7 +112,7 @@ class GenderFilter implements
public function validateForm($data, ExecutionContextInterface $context) public function validateForm($data, ExecutionContextInterface $context)
{ {
if (!\is_iterable($data['accepted_genders']) || 0 === \count($data['accepted_genders'])) { if (!\is_iterable($data['accepted_genders_entity']) || 0 === \count($data['accepted_genders_entity'])) {
$context->buildViolation('You should select an option') $context->buildViolation('You should select an option')
->addViolation(); ->addViolation();
} }

View File

@ -11,6 +11,7 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Tests\Export\Filter\PersonFilters; namespace Chill\PersonBundle\Tests\Export\Filter\PersonFilters;
use Chill\MainBundle\Entity\GenderEnum;
use Chill\MainBundle\Test\Export\AbstractFilterTest; use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Export\Filter\PersonFilters\GenderFilter; use Chill\PersonBundle\Export\Filter\PersonFilters\GenderFilter;
@ -41,13 +42,13 @@ final class GenderFilterTest extends AbstractFilterTest
{ {
return [ return [
[ [
'accepted_genders' => [Person::FEMALE_GENDER], 'accepted_genders_entity' => [GenderEnum::FEMALE],
], ],
[ [
'accepted_genders' => [Person::MALE_GENDER], 'accepted_genders_entity' => [GenderEnum::MALE],
], ],
[ [
'accepted_genders' => [Person::MALE_GENDER, Person::BOTH_GENDER], 'accepted_genders_entity' => [GenderEnum::MALE, GenderEnum::NEUTRAL],
], ],
]; ];
} }

View File

@ -1189,6 +1189,8 @@ export:
date_after: Après le date_after: Après le
date_before: Avant le date_before: Avant le
title: Filtrer les usagers n'ayant été associés à aucun parcours title: Filtrer les usagers n'ayant été associés à aucun parcours
gender:
no_gender: genre non specifié
course: course:
not_having_address_reference: not_having_address_reference: