diff --git a/src/Bundle/ChillMainBundle/Controller/ExportController.php b/src/Bundle/ChillMainBundle/Controller/ExportController.php index 84bf80c6b..caeec8327 100644 --- a/src/Bundle/ChillMainBundle/Controller/ExportController.php +++ b/src/Bundle/ChillMainBundle/Controller/ExportController.php @@ -298,6 +298,8 @@ class ExportController extends AbstractController 'csrf_protection' => $isGenerate ? false : true, ]); + // TODO: add a condition to be able to select a regroupment of centers? + if ('centers' === $step || 'generate_centers' === $step) { $builder->add('centers', PickCenterType::class, [ 'export_alias' => $alias, diff --git a/src/Bundle/ChillMainBundle/Entity/Regroupment.php b/src/Bundle/ChillMainBundle/Entity/Regroupment.php index 5faffd17c..96953abf5 100644 --- a/src/Bundle/ChillMainBundle/Entity/Regroupment.php +++ b/src/Bundle/ChillMainBundle/Entity/Regroupment.php @@ -24,7 +24,7 @@ class Regroupment /** * @var Center * @ORM\ManyToMany( - * targetEntity="Chill\MainBundle\Entity\Center" + * targetEntity=Center::class * ) * @ORM\Id */ @@ -43,7 +43,7 @@ class Regroupment private bool $isActive = true; /** - * @ORM\Column(type="string", length=15, options={"default": ""}, nullable=false) + * @ORM\Column(type="text", options={"default": ""}, nullable=false) */ private string $name = ''; @@ -52,7 +52,7 @@ class Regroupment $this->centers = new ArrayCollection(); } - public function getCenters(): ?Collection + public function getCenters(): Collection { return $this->centers; } diff --git a/src/Bundle/ChillMainBundle/Form/DataMapper/ExportPickCenterDataMapper.php b/src/Bundle/ChillMainBundle/Form/DataMapper/ExportPickCenterDataMapper.php new file mode 100644 index 000000000..0d21b0adb --- /dev/null +++ b/src/Bundle/ChillMainBundle/Form/DataMapper/ExportPickCenterDataMapper.php @@ -0,0 +1,84 @@ + $form */ + $form = iterator_to_array($forms); + + $pickedRegroupment = []; + + foreach ($this->regroupmentRepository->findAll() as $regroupment) { + [$contained, $notContained] = $regroupment->getCenters()->partition(static function (Center $center) { + }); + + if (0 === count($notContained)) { + $pickedRegroupment[] = $regroupment; + } + } + + $form['regroupment']->setData($pickedRegroupment); + $form['centers']->setData($data); + } + + /** + * @param iterable $forms + * @param array $data + * + * @return void + */ + public function mapFormsToData($forms, &$data) + { + /** @var array $forms */ + $forms = iterator_to_array($forms); + + $centers = []; + + foreach ($forms['center']->getData() as $center) { + $centers[spl_object_hash($center)] = $center; + } + + foreach ($forms['regroupment']->getData() as $regroupment) { + /** @var Regroupment $regroupment */ + foreach ($regroupment->getCenters() as $center) { + $centers[spl_object_hash($center)] = $center; + } + } + + $data = array_values($centers); + } +} diff --git a/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php b/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php index 20db0b535..55157b1ab 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/Export/PickCenterType.php @@ -13,55 +13,45 @@ namespace Chill\MainBundle\Form\Type\Export; use Chill\MainBundle\Center\GroupingCenterInterface; use Chill\MainBundle\Entity\Center; +use Chill\MainBundle\Entity\Regroupment; use Chill\MainBundle\Export\ExportManager; +use Chill\MainBundle\Form\DataMapper\ExportPickCenterDataMapper; +use Chill\MainBundle\Repository\RegroupmentRepository; use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\CallbackTransformer; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\User\UserInterface; -use function array_intersect; -use function array_key_exists; -use function array_merge; -use function array_unique; use function count; -use function in_array; /** * Pick centers amongst available centers for the user. */ -class PickCenterType extends AbstractType +final class PickCenterType extends AbstractType { public const CENTERS_IDENTIFIERS = 'c'; - protected AuthorizationHelperInterface $authorizationHelper; + private AuthorizationHelperInterface $authorizationHelper; - protected ExportManager $exportManager; + private ExportManager $exportManager; - /** - * @var array|GroupingCenterInterface[] - */ - protected array $groupingCenters = []; + private RegroupmentRepository $regroupmentRepository; - protected UserInterface $user; + private UserInterface $user; public function __construct( TokenStorageInterface $tokenStorage, ExportManager $exportManager, + RegroupmentRepository $regroupmentRepository, AuthorizationHelperInterface $authorizationHelper ) { $this->exportManager = $exportManager; $this->user = $tokenStorage->getToken()->getUser(); $this->authorizationHelper = $authorizationHelper; - } - - public function addGroupingCenter(GroupingCenterInterface $grouping) - { - $this->groupingCenters[md5($grouping->getName())] = $grouping; + $this->regroupmentRepository = $regroupmentRepository; } public function buildForm(FormBuilderInterface $builder, array $options) @@ -72,97 +62,33 @@ class PickCenterType extends AbstractType $export->requiredRole() ); - $builder->add(self::CENTERS_IDENTIFIERS, EntityType::class, [ + $builder->add('center', EntityType::class, [ 'class' => Center::class, + 'label' => 'center', 'choices' => $centers, 'multiple' => true, 'expanded' => true, 'choice_label' => static function (Center $c) { return $c->getName(); }, - 'data' => count($this->groupingCenters) > 0 ? null : $centers, - ]); - - if (count($this->groupingCenters) > 0) { - $groupingBuilder = $builder->create('g', null, [ - 'compound' => true, + 'data' => $centers, + ]) + ->add('regroupment', EntityType::class, [ + 'class' => Regroupment::class, + 'label' => 'regroupment', + 'multiple' => true, + 'expanded' => true, + 'choices' => $this->regroupmentRepository->findAllActive(), + 'choice_label' => static function (Regroupment $r) { + return $r->getName(); + }, ]); - foreach ($this->groupingCenters as $key => $gc) { - $choices = $this->buildChoices($centers, $gc); - - if (count($choices) > 0) { - $groupingBuilder->add($key, ChoiceType::class, [ - 'choices' => $choices, - 'multiple' => true, - 'expanded' => true, - 'label' => $gc->getName(), - 'required' => false, - ]); - } - } - - if ($groupingBuilder->count() > 0) { - $builder->add($groupingBuilder); - } - } - - $builder->addModelTransformer(new CallbackTransformer( - function ($data) use ($centers) { - return $this->transform($data, $centers); - }, - function ($data) use ($centers) { - return $this->reverseTransform($data, $centers); - } - )); + $builder->setDataMapper(new ExportPickCenterDataMapper()); } public function configureOptions(OptionsResolver $resolver) { $resolver->setRequired('export_alias'); } - - protected function buildChoices($reachablesCenters, GroupingCenterInterface $gc) - { - $result = []; - - foreach ($gc->getGroups() as $group) { - foreach ($gc->getCentersForGroup($group) as $center) { - if (in_array($center, $reachablesCenters, true)) { - $result[$group] = $group; - } - } - } - - return $result; - } - - protected function reverseTransform($data, $centers) - { - $picked = $data[self::CENTERS_IDENTIFIERS] - instanceof \Doctrine\Common\Collections\Collection ? - $data[self::CENTERS_IDENTIFIERS]->toArray() - : - $data[self::CENTERS_IDENTIFIERS]; - - if (array_key_exists('g', $data)) { - foreach ($data['g'] as $gcid => $group) { - $picked = - array_merge( - array_intersect( - $this->groupingCenters[$gcid]->getCentersForGroup($group), - $centers - ), - $picked - ); - } - } - - return array_unique($picked); - } - - protected function transform($data, $centers) - { - return $data; - } } diff --git a/src/Bundle/ChillMainBundle/Repository/RegroupmentRepository.php b/src/Bundle/ChillMainBundle/Repository/RegroupmentRepository.php new file mode 100644 index 000000000..a28f2f341 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Repository/RegroupmentRepository.php @@ -0,0 +1,66 @@ +repository = $entityManager->getRepository(Regroupment::class); + } + + public function find($id, $lockMode = null, $lockVersion = null): ?Regroupment + { + return $this->repository->find($id, $lockMode, $lockVersion); + } + + /** + * @return Regroupment[] + */ + public function findAll(): array + { + return $this->repository->findAll(); + } + + public function findAllActive(): array + { + return $this->repository->findBy(['isActive' => true], ['name' => 'ASC']); + } + + /** + * @param mixed|null $limit + * @param mixed|null $offset + * + * @return Regroupment[] + */ + public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array + { + return $this->repository->findBy($criteria, $orderBy, $limit, $offset); + } + + public function findOneBy(array $criteria, ?array $orderBy = null): ?Regroupment + { + return $this->repository->findOneBy($criteria, $orderBy); + } + + public function getClassName() + { + return Regroupment::class; + } +} diff --git a/src/Bundle/ChillMainBundle/Resources/views/Export/new_centers_step.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Export/new_centers_step.html.twig index 8874744c4..e08ec84d9 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Export/new_centers_step.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Export/new_centers_step.html.twig @@ -1,5 +1,5 @@ {# - * Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, + * Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, / * * This program is free software: you can redistribute it and/or modify @@ -22,39 +22,33 @@ {% block content %}
- + {{ include('@ChillMain/Export/_breadcrumb.html.twig') }} - +

{{ export.title|trans }}

- +

{{ export.description|trans }}

- + {{ form_start(form) }} - +
- +

{{ 'Pick centers'|trans }}

- +

{{ 'The export will contains only data from the picked centers.'|trans }} {{ 'This will eventually restrict your possibilities in filtering the data.'|trans }}

- - {{ form_widget(form.centers.c) }} - - {% if form.centers.children.g is defined %} - -

{{ 'Pick aggregated centers'|trans }}

- - {% for f in form.centers.children.g.children %} - {{ form_row(f) }} - {% endfor %} - - {% endif %} - + +

{{ 'Center'|trans }}

+ {{ form_widget(form.centers.center) }} + +

{{ 'Pick aggregated centers'|trans }}

+ {{ form_widget(form.centers.regroupment) }} +
- +

{{ form_widget(form.submit, { 'attr' : { 'class' : 'btn btn-action btn-create' }, 'label' : 'Go to export options' } ) }}

- + {{ form_end(form) }} - +
{% endblock content %} diff --git a/src/Bundle/ChillMainBundle/config/services/form.yaml b/src/Bundle/ChillMainBundle/config/services/form.yaml index 232e81dd6..226af2afe 100644 --- a/src/Bundle/ChillMainBundle/config/services/form.yaml +++ b/src/Bundle/ChillMainBundle/config/services/form.yaml @@ -139,6 +139,7 @@ services: autoconfigure: true Chill\MainBundle\Form\AbsenceType: ~ + Chill\MainBundle\Form\DataMapper\RegroupmentDataMapper: ~ Chill\MainBundle\Form\RegroupmentType: ~ Chill\MainBundle\Form\DataTransformer\IdToLocationDataTransformer: ~ diff --git a/src/Bundle/ChillMainBundle/migrations/Version20230301155213.php b/src/Bundle/ChillMainBundle/migrations/Version20230301155213.php new file mode 100644 index 000000000..6d93b71d9 --- /dev/null +++ b/src/Bundle/ChillMainBundle/migrations/Version20230301155213.php @@ -0,0 +1,26 @@ +addSql('ALTER TABLE regroupment ALTER name TYPE TEXT'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE regroupment ALTER name TYPE VARCHAR(15)'); + } +}