Feature: allow to filter acp by scope of the user #export #acp

This commit is contained in:
Julien Fastré 2022-10-10 20:49:17 +02:00
parent fce7c44907
commit cbd7acebd5
3 changed files with 34 additions and 27 deletions

View File

@ -14,26 +14,30 @@ namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Export\FilterInterface;
use Chill\MainBundle\Repository\ScopeRepositoryInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper; use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Export\Declarations; use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
use function in_array;
class CurrentUserScopeFilter implements FilterInterface class UserScopeFilter implements FilterInterface
{ {
private ScopeRepositoryInterface $scopeRepository;
private Security $security; private Security $security;
private TranslatableStringHelper $translatableStringHelper; private TranslatableStringHelper $translatableStringHelper;
public function __construct( public function __construct(
TranslatableStringHelper $translatableStringHelper, ScopeRepositoryInterface $scopeRepository,
Security $security Security $security,
TranslatableStringHelper $translatableStringHelper
) { ) {
$this->translatableStringHelper = $translatableStringHelper; $this->scopeRepository = $scopeRepository;
$this->security = $security; $this->security = $security;
$this->translatableStringHelper = $translatableStringHelper;
} }
public function addRole(): ?string public function addRole(): ?string
@ -43,21 +47,14 @@ class CurrentUserScopeFilter implements FilterInterface
public function alterQuery(QueryBuilder $qb, $data) public function alterQuery(QueryBuilder $qb, $data)
{ {
if (!in_array('acpscope', $qb->getAllAliases(), true)) { foreach ($data['scopes'] as $key => $scope) {
$qb->join('acp.scopes', 'acpscope'); /** @var Scope $scope */
$qb
->andWhere(
$qb->expr()->isMemberOf(':acp_scope_filter_s_' . $key, 'acp.scopes')
)
->setParameter('acp_scope_filter_s_' . $key, $scope);
} }
$where = $qb->getDQLPart('where');
$clause = $qb->expr()->eq('acpscope.id', ':userscope');
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->add('where', $where);
$qb->setParameter('userscope', $this->getUserMainScope());
} }
public function applyOn() public function applyOn()
@ -67,14 +64,25 @@ class CurrentUserScopeFilter implements FilterInterface
public function buildForm(FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder)
{ {
$builder->add('scopes', EntityType::class, [
'class' => Scope::class,
'choices' => $this->scopeRepository->findAllActive(),
'choice_label' => fn (Scope $s) => $this->translatableStringHelper->localize($s->getName()),
'multiple' => true,
'expanded' => true,
]);
} }
public function describeAction($data, $format = 'string') public function describeAction($data, $format = 'string')
{ {
return [ return [
'Filtered by user main scope: only %scope%', [ 'Filtered by user main scope: only %scope%', [
'%scope%' => $this->translatableStringHelper->localize( '%scope%' => implode(
$this->getUserMainScope()->getName() ', ',
array_map(
fn (Scope $s) => $this->translatableStringHelper->localize($s->getName()),
$data['scopes']->toArray()
)
), ),
], ],
]; ];

View File

@ -12,7 +12,7 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Tests\Export\Filter\AccompanyingCourseFilters; namespace Chill\PersonBundle\Tests\Export\Filter\AccompanyingCourseFilters;
use Chill\MainBundle\Test\Export\AbstractFilterTest; use Chill\MainBundle\Test\Export\AbstractFilterTest;
use Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\CurrentUserScopeFilter; use Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\UserScopeFilter;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
/** /**
@ -21,7 +21,7 @@ use Doctrine\ORM\EntityManagerInterface;
*/ */
final class CurrentUserScopeFilterTest extends AbstractFilterTest final class CurrentUserScopeFilterTest extends AbstractFilterTest
{ {
private CurrentUserScopeFilter $filter; private UserScopeFilter $filter;
protected function setUp(): void protected function setUp(): void
{ {

View File

@ -16,12 +16,11 @@ services:
- { name: chill.export, alias: avg_accompanyingcourse_duration } - { name: chill.export, alias: avg_accompanyingcourse_duration }
## Filters ## Filters
chill.person.export.filter_current_userscope: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\UserScopeFilter:
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\CurrentUserScopeFilter
autowire: true autowire: true
autoconfigure: true autoconfigure: true
tags: tags:
- { name: chill.export_filter, alias: accompanyingcourse_current_userscope_filter } - { name: chill.export_filter, alias: accompanyingcourse_userscope_filter }
chill.person.export.filter_current_userjob: chill.person.export.filter_current_userjob:
class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\CurrentUserJobFilter class: Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters\CurrentUserJobFilter