mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-12 13:24:25 +00:00
Feature: do not show desactivated Scope in ScopePickerType
This commit is contained in:
parent
f74f67b5c6
commit
4834eadc18
@ -15,9 +15,9 @@ use Chill\MainBundle\Entity\Center;
|
|||||||
use Chill\MainBundle\Entity\Scope;
|
use Chill\MainBundle\Entity\Scope;
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\MainBundle\Form\DataMapper\ScopePickerDataMapper;
|
use Chill\MainBundle\Form\DataMapper\ScopePickerDataMapper;
|
||||||
use Chill\MainBundle\Repository\ScopeRepository;
|
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
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\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
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\Form\FormView;
|
||||||
use Symfony\Component\OptionsResolver\Options;
|
use Symfony\Component\OptionsResolver\Options;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
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\Role\Role;
|
||||||
use Symfony\Component\Security\Core\Security;
|
|
||||||
|
|
||||||
use function array_map;
|
use Symfony\Component\Security\Core\Security;
|
||||||
use function count;
|
use function count;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,47 +42,37 @@ use function count;
|
|||||||
*/
|
*/
|
||||||
class ScopePickerType extends AbstractType
|
class ScopePickerType extends AbstractType
|
||||||
{
|
{
|
||||||
protected AuthorizationHelperInterface $authorizationHelper;
|
private AuthorizationHelperInterface $authorizationHelper;
|
||||||
|
|
||||||
/**
|
private Security $security;
|
||||||
* @var ScopeRepository
|
|
||||||
*/
|
|
||||||
protected $scopeRepository;
|
|
||||||
|
|
||||||
protected Security $security;
|
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var TokenStorageInterface
|
|
||||||
*/
|
|
||||||
protected $tokenStorage;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var TranslatableStringHelper
|
|
||||||
*/
|
|
||||||
protected $translatableStringHelper;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
AuthorizationHelperInterface $authorizationHelper,
|
AuthorizationHelperInterface $authorizationHelper,
|
||||||
TokenStorageInterface $tokenStorage,
|
|
||||||
ScopeRepository $scopeRepository,
|
|
||||||
Security $security,
|
Security $security,
|
||||||
TranslatableStringHelper $translatableStringHelper
|
TranslatableStringHelperInterface $translatableStringHelper
|
||||||
) {
|
) {
|
||||||
$this->authorizationHelper = $authorizationHelper;
|
$this->authorizationHelper = $authorizationHelper;
|
||||||
$this->tokenStorage = $tokenStorage;
|
|
||||||
$this->scopeRepository = $scopeRepository;
|
|
||||||
$this->security = $security;
|
$this->security = $security;
|
||||||
$this->translatableStringHelper = $translatableStringHelper;
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
{
|
{
|
||||||
$items = $this->authorizationHelper->getReachableScopes(
|
$items = array_filter(
|
||||||
$this->security->getUser(),
|
$this->authorizationHelper->getReachableScopes(
|
||||||
$options['role'] instanceof Role ? $options['role']->getRole() : $options['role'],
|
$this->security->getUser(),
|
||||||
$options['center']
|
$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)) {
|
if (1 !== count($items)) {
|
||||||
$builder->add('scope', EntityType::class, [
|
$builder->add('scope', EntityType::class, [
|
||||||
'class' => Scope::class,
|
'class' => Scope::class,
|
||||||
@ -123,35 +111,4 @@ class ScopePickerType extends AbstractType
|
|||||||
->setRequired('role')
|
->setRequired('role')
|
||||||
->setAllowedTypes('role', ['string', Role::class]);
|
->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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,127 @@
|
|||||||
|
<?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 Form\Type;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Center;
|
||||||
|
use Chill\MainBundle\Entity\Scope;
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
|
use Chill\MainBundle\Form\Type\ScopePickerType;
|
||||||
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
use Prophecy\Argument;
|
||||||
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
use Symfony\Bridge\Doctrine\Form\DoctrineOrmExtension;
|
||||||
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
|
use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
|
use Symfony\Component\Form\PreloadedExtension;
|
||||||
|
use Symfony\Component\Form\Test\TypeTestCase;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
final class ScopePickerTypeTest extends TypeTestCase
|
||||||
|
{
|
||||||
|
use ProphecyTrait;
|
||||||
|
|
||||||
|
public function testBuildOneScopeIsSuccessful()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create(ScopePickerType::class, null, [
|
||||||
|
'center' => new Center(),
|
||||||
|
'role' => 'ONE_SCOPE',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$view = $form->createView();
|
||||||
|
|
||||||
|
$this->assertContains('hidden', $view['scope']->vars['block_prefixes']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBuildThreeScopesIsSuccessful()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create(ScopePickerType::class, null, [
|
||||||
|
'center' => new Center(),
|
||||||
|
'role' => 'THREE_SCOPE',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$view = $form->createView();
|
||||||
|
|
||||||
|
$this->assertContains('entity', $view['scope']->vars['block_prefixes']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBuildTwoScopesIsSuccessful()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create(ScopePickerType::class, null, [
|
||||||
|
'center' => new Center(),
|
||||||
|
'role' => 'TWO_SCOPE',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$view = $form->createView();
|
||||||
|
|
||||||
|
$this->assertContains('entity', $view['scope']->vars['block_prefixes']);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getExtensions()
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
$role1Scope = 'ONE_SCOPE';
|
||||||
|
$role2Scope = 'TWO_SCOPE';
|
||||||
|
$role3Scope = 'THREE_SCOPE';
|
||||||
|
$scopeA = (new Scope())->setName(['fr' => 'scope a']);
|
||||||
|
$scopeB = (new Scope())->setName(['fr' => 'scope b']);
|
||||||
|
$scopeC = (new Scope())->setName(['fr' => 'scope b'])->setActive(false);
|
||||||
|
|
||||||
|
$authorizationHelper = $this->prophesize(AuthorizationHelperInterface::class);
|
||||||
|
$authorizationHelper->getReachableScopes($user, $role1Scope, Argument::any())
|
||||||
|
->willReturn([$scopeA]);
|
||||||
|
$authorizationHelper->getReachableScopes($user, $role2Scope, Argument::any())
|
||||||
|
->willReturn([$scopeA, $scopeB]);
|
||||||
|
$authorizationHelper->getReachableScopes($user, $role3Scope, Argument::any())
|
||||||
|
->willReturn([$scopeA, $scopeB, $scopeC]);
|
||||||
|
|
||||||
|
$security = $this->prophesize(Security::class);
|
||||||
|
$security->getUser()->willReturn($user);
|
||||||
|
|
||||||
|
$translatableStringHelper = $this->prophesize(TranslatableStringHelperInterface::class);
|
||||||
|
$translatableStringHelper->localize(Argument::type('array'))->will(
|
||||||
|
static function ($args) { return $args[0]['fr']; }
|
||||||
|
);
|
||||||
|
|
||||||
|
$type = new ScopePickerType(
|
||||||
|
$authorizationHelper->reveal(),
|
||||||
|
$security->reveal(),
|
||||||
|
$translatableStringHelper->reveal()
|
||||||
|
);
|
||||||
|
|
||||||
|
// add the mocks for creating EntityType
|
||||||
|
$entityManager = DoctrineTestHelper::createTestEntityManager();
|
||||||
|
$em = $this->prophesize(EntityManagerInterface::class);
|
||||||
|
$em->getClassMetadata(Scope::class)->willReturn($entityManager->getClassMetadata(Scope::class));
|
||||||
|
$em->contains(Argument::type(Scope::class))->willReturn(true);
|
||||||
|
$em->initializeObject(Argument::type(Scope::class))->willReturn(null);
|
||||||
|
$emRevealed = $em->reveal();
|
||||||
|
$managerRegistry = $this->prophesize(ManagerRegistry::class);
|
||||||
|
$managerRegistry->getManager(Argument::any())->willReturn($emRevealed);
|
||||||
|
$managerRegistry->getManagerForClass(Scope::class)->willReturn($emRevealed);
|
||||||
|
|
||||||
|
$entityType = $this->prophesize(EntityType::class);
|
||||||
|
$entityType->getParent()->willReturn(ChoiceType::class);
|
||||||
|
|
||||||
|
return [
|
||||||
|
new PreloadedExtension([$type], []),
|
||||||
|
new DoctrineOrmExtension($managerRegistry->reveal()),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user