Merge remote-tracking branch 'origin/master' into upgrade-php82

This commit is contained in:
2023-03-03 16:18:47 +01:00
37 changed files with 578 additions and 190 deletions

View File

@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Form;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Form\Type\ChillDateType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class AbsenceType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('absenceStart', ChillDateType::class, [
'required' => true,
'input' => 'datetime_immutable',
'label' => 'absence.Absence start',
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
]);
}
}

View File

@@ -0,0 +1,84 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Form\DataMapper;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\Regroupment;
use Chill\MainBundle\Repository\RegroupmentRepository;
use Exception;
use Symfony\Component\Form\DataMapperInterface;
use Symfony\Component\Form\FormInterface;
use function count;
class ExportPickCenterDataMapper implements DataMapperInterface
{
protected RegroupmentRepository $regroupmentRepository;
/**
* @param array|Center[] $data
* @param $forms
*
* @throws Exception
*
* @return mixed
*/
public function mapDataToForms($data, $forms)
{
if (null === $data) {
return;
}
/** @var array<string, FormInterface> $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<string, FormInterface> $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);
}
}

View File

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

View File

@@ -15,6 +15,7 @@ use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\Location;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\UserJob;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\MainBundle\Form\Type\PickCivilityType;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\ORM\EntityRepository;
@@ -110,6 +111,11 @@ class UserType extends AbstractType
return $qb;
},
])
->add('absenceStart', ChillDateType::class, [
'required' => false,
'input' => 'datetime_immutable',
'label' => 'absence.Absence start',
]);
// @phpstan-ignore-next-line