| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- <?php
- declare(strict_types=1);
- namespace App\Filter\DoctrineFilter;
- use App\Annotation\DateTimeConstraintAware;
- use App\Service\Utils\DateTimeConstraint;
- use App\Service\Utils\StringsUtils;
- use App\Tests\Filter\DoctrineFilter\DateTimeFilterTest;
- use Doctrine\ORM\Mapping\ClassMetadata;
- use Doctrine\ORM\Query\Filter\SQLFilter;
- /**
- * Classe DateTimeFilter qui définie la requête SQL devant être ajoutée aux Entités possédant l'annotation DateTimeConstraintAware
- */
- final class DateTimeFilter extends SQLFilter
- {
- private DateTimeConstraint $dateTimeConstraint;
- /**
- * Méthode surchargée de SQLFilter
- * @param ClassMetadata $targetEntity
- * @param string $targetTableAlias
- * @return string
- * @throws \Exception
- */
- public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias): string
- {
- if(!$this->hasParameter('_time_constraint')
- || !boolval(StringsUtils::unquote($this->getParameter('_time_constraint')))
- || !$this->hasParameter('accessId')
- )
- return '';
- $dateTimeConstraintAware = $targetEntity->getReflectionClass()->getAttributes(DateTimeConstraintAware::class)[0] ?? null;
- $startFieldName = $dateTimeConstraintAware?->getArguments()['startDateFieldName'] ?? null;
- $endFieldName = $dateTimeConstraintAware?->getArguments()['endDateFieldName'] ?? null;
- if ($startFieldName === '' || is_null($startFieldName) || $endFieldName === '' || is_null($endFieldName)) {
- return '';
- }
- $accessId = intval(StringsUtils::unquote($this->getParameter('accessId')));
- $constraints = $this->dateTimeConstraint->invoke($accessId);
- $fields = [
- DateTimeConstraint::START_KEY => $startFieldName,
- DateTimeConstraint::END_KEY => $endFieldName
- ];
-
- return $this->constructQuery($constraints, $targetTableAlias, $fields);
- }
- /**
- * Fonction permettant de construire la requête SQL correspondante aux contraintes
- * @param array $constraints
- * @param string $targetTableAlias
- * @param array $fields
- * @return string
- */
- private function constructQuery(array $constraints, string $targetTableAlias, array $fields): string{
- $queryConditionsAND = [];
- foreach ($constraints as $key => $constraint) {
- $queryConditionsOR = [];
- foreach ($constraint as $date => $conditions){
- foreach ($conditions as $condition){
- $arithmetic = $this->getArithmeticValue($condition);
- if(!is_null($arithmetic))
- $queryConditionsOR[] = sprintf("%s.%s %s '%s'", $targetTableAlias, $fields[$key], $arithmetic, $date);
- else
- $queryConditionsOR[] = sprintf("%s.%s IS NULL", $targetTableAlias, $fields[$key]);
- }
- }
- if(!empty($queryConditionsOR))
- $queryConditionsAND[] = sprintf("(%s)", join(' OR ', $queryConditionsOR));
- }
- return join(" AND ", $queryConditionsAND);
- }
- /**
- * Fonction retournant la valeur arithmétique correspondant à la condition de la contrainte
- * @param $condition
- * @return string|null
- * @see DateTimeFilterTest::testGetArithmeticValue()
- */
- private function getArithmeticValue($condition): string|null{
- switch ($condition){
- case DateTimeConstraint::INF : return '<';
- case DateTimeConstraint::EQUAL : return '=';
- case DateTimeConstraint::SUP : return '>';
- case DateTimeConstraint::INF + DateTimeConstraint::EQUAL : return '<=';
- case DateTimeConstraint::SUP + DateTimeConstraint::EQUAL : return '>=';
- }
- return null;
- }
- /**
- * Permets d'assurer l'injection de dépendance du service DateTimeConstraint
- * @param DateTimeConstraint $dateTimeConstraint
- */
- public function setDateTimeConstraint(DateTimeConstraint $dateTimeConstraint){
- $this->dateTimeConstraint = $dateTimeConstraint;
- }
- }
|