Merge branch '111_exports_suite' into calendar/finalization

This commit is contained in:
2022-10-24 11:10:44 +02:00
158 changed files with 3064 additions and 1522 deletions

View File

@@ -0,0 +1,50 @@
<?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\Type;
use Chill\MainBundle\Entity\LocationType;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
class PickLocationTypeType extends AbstractType
{
private TranslatableStringHelper $translatableStringHelper;
public function __construct(TranslatableStringHelper $translatableStringHelper)
{
$this->translatableStringHelper = $translatableStringHelper;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver
->setDefaults([
'class' => LocationType::class,
'choice_label' => function (LocationType $type) {
return $this->translatableStringHelper->localize($type->getTitle());
},
'placeholder' => 'Pick a location type',
'required' => false,
'attr' => ['class' => 'select2'],
'label' => 'Location type',
'multiple' => false,
])
->setAllowedTypes('multiple', ['bool']);
}
public function getParent(): string
{
return EntityType::class;
}
}

View File

@@ -0,0 +1,57 @@
<?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\Type;
use Chill\MainBundle\Entity\Location;
use Chill\MainBundle\Repository\LocationRepository;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
class PickUserLocationType extends AbstractType
{
private LocationRepository $locationRepository;
private TranslatableStringHelper $translatableStringHelper;
public function __construct(TranslatableStringHelper $translatableStringHelper, LocationRepository $locationRepository)
{
$this->translatableStringHelper = $translatableStringHelper;
$this->locationRepository = $locationRepository;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver
->setDefaults([
'class' => Location::class,
'choices' => $this->locationRepository->findByPublicLocations(),
'choice_label' => function (Location $entity) {
return $entity->getName() ?
$entity->getName() . ' (' . $this->translatableStringHelper->localize($entity->getLocationType()->getTitle()) . ')' :
$this->translatableStringHelper->localize($entity->getLocationType()->getTitle());
},
'placeholder' => 'Pick a location',
'required' => false,
'attr' => ['class' => 'select2'],
'label' => 'Current location',
'multiple' => false,
])
->setAllowedTypes('multiple', ['bool']);
}
public function getParent(): string
{
return EntityType::class;
}
}

View File

@@ -15,9 +15,9 @@ use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Form\DataMapper\ScopePickerDataMapper;
use Chill\MainBundle\Repository\ScopeRepository;
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use RuntimeException;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
@@ -26,11 +26,9 @@ use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Security\Core\Security;
use function array_map;
use Symfony\Component\Security\Core\Security;
use function count;
/**
@@ -44,47 +42,37 @@ use function count;
*/
class ScopePickerType extends AbstractType
{
protected AuthorizationHelperInterface $authorizationHelper;
private AuthorizationHelperInterface $authorizationHelper;
/**
* @var ScopeRepository
*/
protected $scopeRepository;
private Security $security;
protected Security $security;
/**
* @var TokenStorageInterface
*/
protected $tokenStorage;
/**
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
private TranslatableStringHelperInterface $translatableStringHelper;
public function __construct(
AuthorizationHelperInterface $authorizationHelper,
TokenStorageInterface $tokenStorage,
ScopeRepository $scopeRepository,
Security $security,
TranslatableStringHelper $translatableStringHelper
TranslatableStringHelperInterface $translatableStringHelper
) {
$this->authorizationHelper = $authorizationHelper;
$this->tokenStorage = $tokenStorage;
$this->scopeRepository = $scopeRepository;
$this->security = $security;
$this->translatableStringHelper = $translatableStringHelper;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$items = $this->authorizationHelper->getReachableScopes(
$this->security->getUser(),
$options['role'] instanceof Role ? $options['role']->getRole() : $options['role'],
$options['center']
$items = array_filter(
$this->authorizationHelper->getReachableScopes(
$this->security->getUser(),
$options['role'] instanceof Role ? $options['role']->getRole() : $options['role'],
$options['center']
),
static function (Scope $s) { return $s->isActive(); }
);
if (0 === count($items)) {
throw new RuntimeException('no scopes are reachable. This form should not be shown to user');
}
if (1 !== count($items)) {
$builder->add('scope', EntityType::class, [
'class' => Scope::class,
@@ -123,35 +111,4 @@ class ScopePickerType extends AbstractType
->setRequired('role')
->setAllowedTypes('role', ['string', Role::class]);
}
/**
* @param array|Center|Center[] $center
* @param string $role
*
* @return \Doctrine\ORM\QueryBuilder
*/
protected function buildAccessibleScopeQuery($center, $role)
{
$roles = $this->authorizationHelper->getParentRoles($role);
$roles[] = $role;
$centers = $center instanceof Center ? [$center] : $center;
$qb = $this->scopeRepository->createQueryBuilder('s');
$qb
// jointure to center
->join('s.roleScopes', 'rs')
->join('rs.permissionsGroups', 'pg')
->join('pg.groupCenters', 'gc')
// add center constraint
->where($qb->expr()->in('IDENTITY(gc.center)', ':centers'))
->setParameter('centers', array_map(static fn (Center $c) => $c->getId(), $centers))
// role constraints
->andWhere($qb->expr()->in('rs.role', ':roles'))
->setParameter('roles', $roles)
// user contraint
->andWhere(':user MEMBER OF gc.users')
->setParameter('user', $this->tokenStorage->getToken()->getUser());
return $qb;
}
}

View File

@@ -11,39 +11,14 @@ declare(strict_types=1);
namespace Chill\MainBundle\Form;
use Chill\MainBundle\Entity\Location;
use Chill\MainBundle\Repository\LocationRepository;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Chill\MainBundle\Form\Type\PickUserLocationType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class UserCurrentLocationType extends AbstractType
{
private LocationRepository $locationRepository;
private TranslatableStringHelper $translatableStringHelper;
public function __construct(TranslatableStringHelper $translatableStringHelper, LocationRepository $locationRepository)
{
$this->translatableStringHelper = $translatableStringHelper;
$this->locationRepository = $locationRepository;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('currentLocation', EntityType::class, [
'class' => Location::class,
'choices' => $this->locationRepository->findByPublicLocations(),
'choice_label' => function (Location $entity) {
return $entity->getName() ?
$entity->getName() . ' (' . $this->translatableStringHelper->localize($entity->getLocationType()->getTitle()) . ')' :
$this->translatableStringHelper->localize($entity->getLocationType()->getTitle());
},
'placeholder' => 'Pick a location',
'required' => false,
'attr' => ['class' => 'select2'],
]);
$builder->add('currentLocation', PickUserLocationType::class);
}
}