瀏覽代碼

refactors time filters / listener / services

Olivier Massot 2 年之前
父節點
當前提交
a3b4944884

+ 7 - 0
config/packages/doctrine.yaml

@@ -30,6 +30,13 @@ doctrine:
         auto_generate_proxy_classes: true
         entity_managers:
             default:
+                filters:
+                    date_time_filter:
+                        class: App\Filter\Doctrine\TimeConstraint\DatetimeFilter
+                        enabled: false
+                    activity_year_filter:
+                        class: App\Filter\Doctrine\TimeConstraint\ActivityYearFilter
+                        enabled: false
                 connection: default
                 auto_mapping: true
                 mappings:

+ 0 - 114
src/Doctrine/TimeConstraint/AbstractTimeExtension.php

@@ -1,114 +0,0 @@
-<?php
-declare(strict_types=1);
-
-namespace App\Doctrine\TimeConstraint;
-
-use App\Attribute\ActivityYearConstraintAware;
-use App\Attribute\DateTimeConstraintAware;
-use App\Doctrine\AbstractExtension;
-use App\Entity\Access\Access;
-use App\Service\Constraint\ActivityYearConstraint;
-use App\Service\Constraint\DateTimeConstraint;
-use App\Service\Utils\StringsUtils;
-use App\Tests\Filter\DoctrineFilter\DateTimeFilterTest;
-use Doctrine\Common\Collections\Criteria;
-use Doctrine\ORM\EntityManager;
-use Symfony\Component\HttpFoundation\RequestStack;
-use Doctrine\ORM\QueryBuilder;
-use Symfony\Bundle\SecurityBundle\Security;
-use Doctrine\ORM\Mapping\ClassMetadata;
-use Doctrine\ORM\EntityManagerInterface;
-
-/**
- * Applique les contraintes temporelles aux entités possédant l'annotation requise
- */
-abstract class AbstractTimeExtension extends AbstractExtension
-{
-    protected ?Access $access = null;
-
-    protected static ?string $constraintAnnotation = null;
-
-    public function __construct(
-        protected EntityManagerInterface $entityManager,
-        protected Security $security,
-        protected RequestStack $requestStack
-    ) {
-        if (static::$constraintAnnotation === null) {
-            throw new \RuntimeException('Constraint annotation has not been set');
-        }
-    }
-
-    protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass): void
-    {
-        $access = $this->security->getUser();
-        if (!$access) {
-            return;
-        }
-
-        if (!$this->areTimeConstraintsEnabled()) {
-            return;
-        }
-
-        $classMetadata = $this->entityManager->getClassMetadata($resourceClass);
-        $constraintAnnotation = $classMetadata->getReflectionClass()->getAttributes(static::$constraintAnnotation)[0] ?? null;
-        if (!$constraintAnnotation) {
-            return;
-        }
-
-        $startFieldName = $constraintAnnotation->getArguments()['startYearFieldName'] ?? null;
-        $endFieldName = $constraintAnnotation->getArguments()['endYearFieldName'] ?? null;
-        if (!$startFieldName || !$endFieldName) {
-            throw new \RuntimeException('Missing start and/or end field names in constraint annotation');
-        }
-
-        $constraints = $this->getConstraints($this->access->getId());
-
-        $fields = [
-            ActivityYearConstraint::START_KEY => $startFieldName,
-            ActivityYearConstraint::END_KEY => $endFieldName
-        ];
-
-        $rootAlias = $queryBuilder->getRootAliases()[0];
-
-        foreach ($constraints as $key => $constraint) {
-            $orExpr = $queryBuilder->expr()->orX();
-
-            foreach ($constraint as $date => $conditions) {
-                foreach ($conditions as $condition) {
-                    $operator = $this->getSqlOperator($condition);
-
-                    if ($operator !== null) {
-                        $orExpr->add(sprintf("%s.%s %s '%s'", $rootAlias, $fields[$key], $operator, $date));
-                    } else {
-                        $orExpr->add(sprintf("%s.%s IS NULL", $rootAlias, $fields[$key]));
-                    }
-                }
-            }
-            $queryBuilder->andWhere($orExpr);
-        }
-    }
-
-    abstract protected function getConstraints(int $accessId): array;
-
-    protected function areTimeConstraintsEnabled(): bool {
-        return $this->requestStack->getMainRequest()->get('_time_constraint', true);
-    }
-
-    /**
-     * Fonction retournant la valeur arithmétique correspondant à la condition de la contrainte
-     * @param int $condition
-     * @return string|null
-     * @see DateTimeFilterTest::testGetArithmeticValue()
-     */
-    protected function getSqlOperator(int $condition): ?string
-    {
-        return match ($condition) {
-            DateTimeConstraint::INF => '<',
-            DateTimeConstraint::EQUAL => '=',
-            DateTimeConstraint::SUP => '>',
-            DateTimeConstraint::INF + DateTimeConstraint::EQUAL => '<=',
-            DateTimeConstraint::SUP + DateTimeConstraint::EQUAL => '>=',
-            default => null,
-        };
-    }
-}

+ 0 - 34
src/Doctrine/TimeConstraint/ActivityYearExtension.php

@@ -1,34 +0,0 @@
-<?php
-
-namespace App\Doctrine\TimeConstraint;
-
-use App\Attribute\ActivityYearConstraintAware;
-use App\Doctrine\AbstractExtension;
-use App\Service\Constraint\ActivityYearConstraint;
-use Doctrine\ORM\EntityManager;
-use Symfony\Component\HttpFoundation\RequestStack;
-use Symfony\Bundle\SecurityBundle\Security;
-use Doctrine\ORM\EntityManagerInterface;
-
-/**
- * Applique les contraintes temporelles aux entités possédant l'annotation ActivityYearConstraintAware
- */
-class ActivityYearExtension extends AbstractTimeExtension
-{
-    protected static ?string $constraintAnnotation = ActivityYearConstraintAware::class;
-
-    public function __construct(
-        protected EntityManagerInterface $entityManager,
-        protected Security $security,
-        protected RequestStack $requestStack,
-        protected ActivityYearConstraint $activityYearConstraint
-    )
-    {
-        parent::__construct($entityManager, $security, $requestStack);
-    }
-
-    protected function getConstraints(int $accessId): array
-    {
-        return $this->activityYearConstraint->invoke($accessId);
-    }
-}

+ 0 - 36
src/Doctrine/TimeConstraint/DateTimeExtension.php

@@ -1,36 +0,0 @@
-<?php
-
-namespace App\Doctrine\TimeConstraint;
-
-use App\Attribute\DateTimeConstraintAware;
-use App\Doctrine\AbstractExtension;
-use App\Service\Constraint\ActivityYearConstraint;
-use App\Service\Constraint\DateTimeConstraint;
-use Doctrine\ORM\EntityManager;
-use Symfony\Component\HttpFoundation\RequestStack;
-use Symfony\Bundle\SecurityBundle\Security;
-use Doctrine\ORM\EntityManagerInterface;
-
-/**
- * Applique les contraintes temporelles aux entités possédant l'annotation DateTimeConstraintAware
- */
-class DateTimeExtension extends AbstractTimeExtension
-{
-    protected static ?string $constraintAnnotation = DateTimeConstraintAware::class;
-
-    public function __construct(
-        protected EntityManagerInterface $entityManager,
-        protected Security $security,
-        protected RequestStack $requestStack,
-        protected DateTimeConstraint $dateTimeConstraint
-    )
-    {
-        parent::__construct($entityManager, $security, $requestStack);
-    }
-
-    protected function getConstraints(int $accessId): array
-    {
-        return $this->dateTimeConstraint->invoke($accessId);
-    }
-
-}

+ 2 - 2
src/Entity/Access/Access.php

@@ -41,14 +41,14 @@ use App\Entity\Person\CompanyPerson;
 use App\Entity\Person\Medal;
 use App\Entity\Product\Equipment;
 use App\Entity\Product\EquipmentLoan;
-use App\Filter\Person\FullNameFilter;
+use App\Filter\ApiPlatform\Person\FullNameFilter;
 use App\Entity\Billing\AccessIntangible;
 use App\Entity\Billing\AccessPayer;
 use App\Entity\Core\Notification;
 use App\Entity\Core\NotificationUser;
 use App\Entity\Organization\Organization;
 use App\Entity\Organization\OrganizationLicence;
-use App\Filter\Utils\InFilter;
+use App\Filter\ApiPlatform\Utils\InFilter;
 use App\Repository\Access\AccessRepository;
 use App\Entity\Person\Person;
 use App\Entity\Person\PersonActivity;

+ 1 - 1
src/Entity/Public/FederationStructure.php

@@ -9,7 +9,7 @@ use ApiPlatform\Metadata\ApiResource;
 use ApiPlatform\Doctrine\Orm\Filter\NumericFilter;
 use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
 use ApiPlatform\Metadata\ApiFilter;
-use App\Filter\Utils\FindInSetFilter;
+use App\Filter\ApiPlatform\Utils\FindInSetFilter;
 use App\Repository\Public\FederationStructureRepository;
 use Doctrine\ORM\Mapping as ORM;
 use Symfony\Component\Serializer\Annotation\Groups;

+ 1 - 1
src/Entity/Public/PublicEvent.php

@@ -11,7 +11,7 @@ use ApiPlatform\Doctrine\Orm\Filter\DateFilter;
 use ApiPlatform\Doctrine\Orm\Filter\NumericFilter;
 use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
 use ApiPlatform\Metadata\ApiFilter;
-use App\Filter\Utils\DistanceFilter;
+use App\Filter\ApiPlatform\Utils\DistanceFilter;
 use App\Repository\Public\PublicEventRepository;
 use Doctrine\ORM\Mapping as ORM;
 

+ 0 - 55
src/EventListener/DoctrineFilter/DoctrineFilterListener.php

@@ -1,55 +0,0 @@
-<?php
-declare(strict_types=1);
-
-namespace App\EventListener\DoctrineFilter;
-
-use App\Entity\Access\Access;
-use App\Filter\DoctrineFilter\ActivityYearFilter;
-use App\Filter\DoctrineFilter\DateTimeFilter;
-use App\Service\Constraint\ActivityYearConstraint;
-use App\Service\Constraint\DateTimeConstraint;
-use Doctrine\ORM\EntityManagerInterface;
-use Symfony\Component\HttpFoundation\RequestStack;
-use Symfony\Component\HttpKernel\Event\RequestEvent;
-use Symfony\Bundle\SecurityBundle\Security;
-use Symfony\Component\Security\Core\User\UserInterface;
-
-/**
- * Classe DoctrineFilterListener qui permet d'assurer l'injection de dépendance pour le SQL Filter
- */
-class DoctrineFilterListener
-{
-    public function __construct(
-        private EntityManagerInterface $entityManager,
-        private DateTimeConstraint $dateTimeConstraint,
-        private ActivityYearConstraint $activityYearConstraint,
-        private Security $security,
-        private RequestStack $requestStack
-    )
-    {
-    }
-
-    public function onKernelRequest(RequestEvent $event): void
-    {
-        if (!$event->isMainRequest()) {
-            // don't do anything if it's not the main request
-            return;
-        }
-
-        /** @var Access $access */
-        $access = $this->security->getUser();
-        if ($access) {
-            /** @var DateTimeFilter $dateTimeFilter */
-            $dateTimeFilter = $this->entityManager->getFilters()->getFilter('date_time_filter');
-            $dateTimeFilter->setParameter('accessId', $access->getId());
-            $dateTimeFilter->setParameter('_time_constraint', $this->requestStack->getMainRequest()->get('_time_constraint', true));
-            $dateTimeFilter->setDateTimeConstraint($this->dateTimeConstraint);
-
-            /** @var ActivityYearFilter $activityYearFilter */
-            $activityYearFilter = $this->entityManager->getFilters()->getFilter('activity_year_filter');
-            $activityYearFilter->setParameter('accessId', $access->getId());
-            $activityYearFilter->setParameter('_time_constraint', $this->requestStack->getMainRequest()->get('_time_constraint', true));
-            $activityYearFilter->setActivityYearConstraint($this->activityYearConstraint);
-        }
-    }
-}

+ 52 - 0
src/EventListener/OnKernelRequestPreRead.php

@@ -0,0 +1,52 @@
+<?php
+
+namespace App\EventListener;
+
+use ApiPlatform\Symfony\EventListener\EventPriorities;
+use App\Entity\Access\Access;
+use App\Service\Doctrine\FiltersConfigurationService;
+use App\Service\OnStart\SessionParametersSetter;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Event\RequestEvent;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Bundle\SecurityBundle\Security;
+use App\Service\Utils\StringsUtils;
+
+class OnKernelRequestPreRead implements EventSubscriberInterface
+{
+    public function __construct(
+        private RequestStack $requestStack,
+        private Security $security,
+        private FiltersConfigurationService $filtersConfigurationService
+    ) {}
+
+    public static function getSubscribedEvents()
+    {
+        return [
+            KernelEvents::REQUEST => ['onKernelRequest', EventPriorities::PRE_READ]
+        ];
+    }
+
+    public function onKernelRequest(RequestEvent $event): void {
+        if (!$event->isMainRequest()) {
+            // don't do anything if it's not the main request
+            return;
+        }
+
+        $mainRequest = $this->requestStack->getMainRequest();
+
+        /** @var Access $access */
+        $access = $this->security->getUser();
+        if ($access) {
+
+            $timeConstraintEnabled = (bool) StringsUtils::unquote(
+                $this->requestStack->getMainRequest()->get('_time_constraint', true)
+            );
+
+            if ($timeConstraintEnabled) {
+                $this->filtersConfigurationService->configureTimeConstraintFilters($access->getId());
+            }
+        }
+    }
+}

+ 2 - 2
src/Filter/ApiPlatform/Person/FullNameFilter.php

@@ -1,7 +1,7 @@
 <?php
 declare(strict_types=1);
 
-namespace App\Filter\Person;
+namespace App\Filter\ApiPlatform\Person;
 
 use ApiPlatform\Doctrine\Orm\Filter\AbstractFilter;
 use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
@@ -55,4 +55,4 @@ class FullNameFilter extends AbstractFilter {
             ]
         ];
     }
-}
+}

+ 1 - 1
src/Filter/ApiPlatform/Utils/DistanceFilter.php

@@ -1,7 +1,7 @@
 <?php
 declare(strict_types=1);
 
-namespace App\Filter\Utils;
+namespace App\Filter\ApiPlatform\Utils;
 
 use ApiPlatform\Doctrine\Orm\Filter\AbstractFilter;
 use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;

+ 1 - 1
src/Filter/ApiPlatform/Utils/FindInSetFilter.php

@@ -1,7 +1,7 @@
 <?php
 declare(strict_types=1);
 
-namespace App\Filter\Utils;
+namespace App\Filter\ApiPlatform\Utils;
 
 use ApiPlatform\Doctrine\Orm\Filter\AbstractFilter;
 use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;

+ 1 - 1
src/Filter/ApiPlatform/Utils/InFilter.php

@@ -1,7 +1,7 @@
 <?php
 declare(strict_types=1);
 
-namespace App\Filter\Utils;
+namespace App\Filter\ApiPlatform\Utils;
 
 use ApiPlatform\Doctrine\Orm\Filter\AbstractFilter;
 use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;

+ 62 - 26
src/Filter/Doctrine/TimeConstraint/AbstractTimeFilter.php

@@ -3,19 +3,24 @@
 namespace App\Filter\Doctrine\TimeConstraint;
 
 use App\Entity\Access\Access;
+use App\Service\Constraint\AbstractTimeConstraintUtils;
 use App\Service\Constraint\ActivityYearConstraint;
 use App\Service\Constraint\DateTimeConstraint;
+use App\Service\Constraint\TimeConstraintInterface;
 use Doctrine\ORM\EntityManagerInterface;
 use Doctrine\ORM\Query\Filter\SQLFilter;
 use Symfony\Bundle\SecurityBundle\Security;
 use Symfony\Component\HttpFoundation\RequestStack;
+use Doctrine\ORM\Mapping\ClassMetadata;
+use Symfony\Contracts\Service\Attribute\Required;
 
 /**
  * Applique les contraintes temporelles aux entités possédant l'annotation requise
  */
 abstract class AbstractTimeFilter extends SQLFilter
 {
-    protected ?Access $access = null;
+    protected ?int $accessId = null;
+    protected ?TimeConstraintInterface $timeConstraint = null;
 
     /**
      * Annotation expected, have to be re-defined in subclasses
@@ -23,24 +28,70 @@ abstract class AbstractTimeFilter extends SQLFilter
      */
     protected static ?string $constraintAnnotation = null;
 
+    /**
+     * Parameter of the annotation that design the field containing the starting date of the period
+     * Have to be re-defined in subclasses
+     * @var string|null
+     */
+    protected static ?string $annotationStartField = null;
+
+    /**
+     * Parameter of the annotation that design the field containing the ending date of the period
+     * Have to be re-defined in subclasses
+     * @var string|null
+     */
+    protected static ?string $annotationEndField = null;
+
     // <--- Dependency injections
     protected EntityManagerInterface $entityManager;
-    protected Security $security;
-    protected RequestStack $requestStack;
-
-    public function setEntityManagerInterface(EntityManagerInterface $entityManager) { $this->entityManager = $entityManager;}
-    public function setSecurity(Security $security) { $this->security = $security;}
-    public function setRequestStack(RequestStack $requestStack) { $this->requestStack = $requestStack;}
 
+    #[Required]
+    public function setEntityManagerInterface(EntityManagerInterface $entityManager): void { $this->entityManager = $entityManager;}
     // --->
 
+    public function setAccessId(int $accessId): void {
+        $this->accessId = $accessId;
+    }
+
+    public function setTimeConstraint(TimeConstraintInterface $timeConstraint): void {
+        $this->timeConstraint = $timeConstraint;
+    }
+
+    /**
+     * Retourne les noms des champs contenant les dates de début et de fin de la période de la ressource testée.
+     *
+     * @param array<string, string> $arguments
+     * @return array<string>
+     */
+    protected function getStartAndEndFields(array $arguments): array {
+        if (static::$annotationStartField === null || static::$annotationEndField) {
+            throw new \RuntimeException('Constraint annotation has not been properly configured');
+        }
+
+        $startField = $arguments[static::$annotationStartField] ?? null;
+        $endField = $arguments[static::$annotationEndField] ?? null;
+
+        return [$startField, $endField];
+    }
+
+    /**
+     * Invoke the TimeConstraintUtils to retrieve the active constraints for the given user
+     *
+     * @param int $accessId
+     * @return array<string, array<string, list<int>>>
+     * @throws \Exception
+     */
+    protected function getConstraints(int $accessId): array
+    {
+        return $this->timeConstraint->invoke($accessId);
+    }
+
     /**
      * Méthode surchargée de SQLFilter permettant d'appliquer un filtre supplémentaire aux requêtes SQL
      *
      * @param ClassMetadata $targetEntity
      * @param string $targetTableAlias
      * @return string
-     * @throws Exception
      */
     public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias): string
     {
@@ -48,27 +99,17 @@ abstract class AbstractTimeFilter extends SQLFilter
             throw new \RuntimeException('Constraint annotation has not been set');
         }
 
-        $access = $this->security->getUser();
-        if (!$access) {
-            return '';
-        }
-
-        if (!$this->areTimeConstraintsEnabled()) {
-            return '';
-        }
-
         $constraintAnnotation = $targetEntity->getReflectionClass()->getAttributes(static::$constraintAnnotation)[0] ?? null;
         if (!$constraintAnnotation) {
             return '';
         }
 
-        $startFieldName = $constraintAnnotation->getArguments()['startYearFieldName'] ?? null;
-        $endFieldName = $constraintAnnotation->getArguments()['endYearFieldName'] ?? null;
+        [$startFieldName, $endFieldName] = $this->getStartAndEndFields($constraintAnnotation->getArguments());
         if (!$startFieldName || !$endFieldName) {
             throw new \RuntimeException('Missing start and/or end field names in constraint annotation');
         }
 
-        $constraints = $this->getConstraints($this->access->getId());
+        $constraints = $this->getConstraints($this->accessId);
 
         $fields = [
             ActivityYearConstraint::START_KEY => $startFieldName,
@@ -78,12 +119,6 @@ abstract class AbstractTimeFilter extends SQLFilter
         return $this->constructQuery($constraints, $targetTableAlias, $fields);
     }
 
-    protected function areTimeConstraintsEnabled(): bool {
-        return $this->requestStack->getMainRequest()->get('_time_constraint', true);
-    }
-
-    abstract protected function getConstraints(int $accessId): array;
-
     /**
      * Fonction permettant de construire la requête SQL correspondante aux contraintes
      *
@@ -117,6 +152,7 @@ abstract class AbstractTimeFilter extends SQLFilter
 
     /**
      * Fonction retournant la valeur arithmétique correspondant à la condition de la contrainte
+     *
      * @param int $condition
      * @return string|null
      * @see DateTimeFilterTest::testGetArithmeticValue()

+ 15 - 17
src/Filter/Doctrine/TimeConstraint/ActivityYearFilter.php

@@ -4,29 +4,27 @@ namespace App\Filter\Doctrine\TimeConstraint;
 
 use App\Attribute\ActivityYearConstraintAware;
 use App\Service\Constraint\ActivityYearConstraint;
+use Symfony\Contracts\Service\Attribute\Required;
 
+/**
+ * Filtre Doctrine permettant d'assurer les contraintes de temps sur l'année d'activité actuelle
+ * de l'utilisateur en cours
+ */
 class ActivityYearFilter extends AbstractTimeFilter
 {
+    /**
+     * @inheritdoc
+     * @var string|null
+     */
     protected static ?string $constraintAnnotation = ActivityYearConstraintAware::class;
-
-    protected ActivityYearConstraint $activityYearConstraint;
-
     /**
-     * Dependency injection
-     * @param ActivityYearConstraint $activityYearConstraint
-     * @return void
+     * @inheritdoc
+     * @var string|null
      */
-    public function setActivityYearConstraint(ActivityYearConstraint $activityYearConstraint) {
-        $this->activityYearConstraint = $activityYearConstraint;
-    }
-
+    protected static ?string $annotationStartField = 'startYearFieldName';
     /**
-     * @param int $accessId
-     * @return array<string, array<string, list<int>>>
-     * @throws \Exception
+     * @inheritdoc
+     * @var string|null
      */
-    protected function getConstraints(int $accessId): array
-    {
-        return $this->activityYearConstraint->invoke($accessId);
-    }
+    protected static ?string $annotationEndField = 'endYearFieldName';
 }

+ 0 - 32
src/Filter/Doctrine/TimeConstraint/DatetimeExtensionFilter.php

@@ -1,32 +0,0 @@
-<?php
-
-namespace App\Filter\Doctrine\TimeConstraint;
-
-use App\Attribute\DateTimeConstraintAware;
-use App\Service\Constraint\DateTimeConstraint;
-
-class DatetimeExtensionFilter extends AbstractTimeFilter
-{
-    protected static ?string $constraintAnnotation = DateTimeConstraintAware::class;
-
-    protected DateTimeConstraint $dateTimeConstraint;
-
-    /**
-     * Dependency injection
-     *
-     * @param DateTimeConstraint $dateTimeConstraint
-     * @return void
-     */
-    public function setDateTimeConstraint(DateTimeConstraint $dateTimeConstraint) {
-        $this->dateTimeConstraint = $dateTimeConstraint;
-    }
-
-    /**
-     * @param int $accessId
-     * @return array
-     */
-    protected function getConstraints(int $accessId): array
-    {
-        return $this->dateTimeConstraint->invoke($accessId);
-    }
-}

+ 29 - 0
src/Filter/Doctrine/TimeConstraint/DatetimeFilter.php

@@ -0,0 +1,29 @@
+<?php
+
+namespace App\Filter\Doctrine\TimeConstraint;
+
+use App\Attribute\DateTimeConstraintAware;
+use App\Service\Constraint\DateTimeConstraint;
+use Symfony\Contracts\Service\Attribute\Required;
+
+/**
+ * Filtre Doctrine permettant d'assurer les contraintes de temps sur la période choisie par l'utilisateur en cours
+ */
+class DatetimeFilter extends AbstractTimeFilter
+{
+    /**
+     * @inheritdoc
+     * @var string|null
+     */
+    protected static ?string $constraintAnnotation = DateTimeConstraintAware::class;
+    /**
+     * @inheritdoc
+     * @var string|null
+     */
+    protected static ?string $annotationStartField = 'startDateFieldName';
+    /**
+     * @inheritdoc
+     * @var string|null
+     */
+    protected static ?string $annotationEndField = 'endDateFieldName';
+}

+ 1 - 1
src/Service/Constraint/ActivityYearConstraint.php

@@ -11,7 +11,7 @@ use Doctrine\ORM\EntityManagerInterface;
  * Classe ActivityYearConstraint qui définie l'année de début (et de fin dans le cas d'une période custom)
  * par rapport aux contraintes temporelles choisies par un utilisateur.
  */
-class ActivityYearConstraint extends AbstractTimeConstraintUtils
+class ActivityYearConstraint extends AbstractTimeConstraintUtils implements TimeConstraintInterface
 {
     public function __construct(
         private EntityManagerInterface $entityManager,

+ 1 - 1
src/Service/Constraint/DateTimeConstraint.php

@@ -13,7 +13,7 @@ use Exception;
  * Classe DateTimeConstraint qui définie les dates de débuts et fin de périodes
  * par rapport au contraintes temporelles choisies par un utilisateur.
  */
-class DateTimeConstraint extends AbstractTimeConstraintUtils
+class DateTimeConstraint extends AbstractTimeConstraintUtils implements TimeConstraintInterface
 {
     public function __construct(
         readonly private EntityManagerInterface $entityManager,

+ 8 - 0
src/Service/Constraint/TimeConstraintInterface.php

@@ -0,0 +1,8 @@
+<?php
+
+namespace App\Service\Constraint;
+
+interface TimeConstraintInterface
+{
+    public function invoke(int $accessId);
+}

+ 53 - 0
src/Service/Doctrine/FiltersConfigurationService.php

@@ -0,0 +1,53 @@
+<?php
+
+namespace App\Service\Doctrine;
+
+use App\Filter\Doctrine\TimeConstraint\AbstractTimeFilter;
+use App\Filter\Doctrine\TimeConstraint\ActivityYearFilter;
+use App\Filter\Doctrine\TimeConstraint\DatetimeFilter;
+use App\Service\Constraint\AbstractTimeConstraintUtils;
+use App\Service\Constraint\ActivityYearConstraint;
+use App\Service\Constraint\DateTimeConstraint;
+use Doctrine\ORM\EntityManagerInterface;
+use Doctrine\ORM\Query\Filter\SQLFilter;
+use Doctrine\ORM\Query\FilterCollection;
+
+/**
+ * Service de configuration des filtres doctrine
+ *
+ * @see src/EventListener/OnKernelRequestPreRead.php
+ */
+class FiltersConfigurationService
+{
+    public function __construct(
+        private EntityManagerInterface $entityManager,
+        private DateTimeConstraint $dateTimeConstraint,
+        private ActivityYearConstraint $activityYearConstraint
+    ) {}
+
+    /**
+     * Return the existing Doctrine SQLFilters
+     * @return FilterCollection
+     */
+    protected function getFilters(): FilterCollection {
+        return $this->entityManager->getFilters();
+    }
+
+    /**
+     * Enable and preconfigure the doctrine sql filters that apply the time constraints
+     *
+     * @param int $accessId
+     * @return void
+     */
+    public function configureTimeConstraintFilters(int $accessId): void {
+        /** @var DatetimeFilter $dateTimeFilter */
+        $dateTimeFilter = $this->getFilters()->enable('date_time_filter');
+        $dateTimeFilter->setAccessId($accessId);
+        $dateTimeFilter->setTimeConstraint($this->dateTimeConstraint);
+
+        /** @var ActivityYearFilter $activityYearFilter */
+        $activityYearFilter = $this->getFilters()->enable('date_time_filter');
+        $activityYearFilter->setAccessId($accessId);
+        $activityYearFilter->setTimeConstraint($this->activityYearConstraint);
+    }
+}

+ 0 - 1
src/Service/Typo3/SubdomainService.php

@@ -13,7 +13,6 @@ use App\Service\Mailer\Model\SubdomainChangeModel;
 use App\Service\Organization\Utils as OrganizationUtils;
 use Doctrine\DBAL\Connection;
 use Doctrine\ORM\EntityManagerInterface;
-use Symfony\Bundle\SecurityBundle\Security;
 use Symfony\Component\Console\Exception\InvalidArgumentException;
 use Symfony\Component\Messenger\MessageBusInterface;
 use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;