Vincent GUFFON 3 years ago
parent
commit
742a78b43e

+ 53 - 0
src/Doctrine/Booking/CurrentCoursesExtension.php

@@ -0,0 +1,53 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Doctrine\Booking;
+
+use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryCollectionExtensionInterface;
+use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryItemExtensionInterface;
+use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
+use App\Entity\Access\Access;
+use App\Entity\Booking\Course;
+use Doctrine\ORM\QueryBuilder;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\Security\Core\Security;
+
+/**
+ * Class CurrentCoursesExtension : Filtre de sécurité par défaut pour une resource Course
+ * @package App\Doctrine\Core
+ */
+final class CurrentCoursesExtension implements QueryCollectionExtensionInterface, QueryItemExtensionInterface
+{
+    public function __construct(private Security $security, private RequestStack $requestStack)
+    { }
+
+    public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null): void
+    {
+        $this->addWhere($queryBuilder, $resourceClass, $operationName);
+    }
+
+    public function applyToItem(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, array $identifiers, string $operationName = null, array $context = []): void
+    {
+        $this->addWhere($queryBuilder, $resourceClass, $operationName);
+    }
+
+    /**
+     * @todo : A la suite de la migration, il faut supprimer le where avec le discr.
+     */
+    private function addWhere(QueryBuilder $queryBuilder, string $resourceClass, string $operationName): void
+    {
+        if (Course::class !== $resourceClass) {
+            return;
+        }
+
+        /** @var Access $currentUser */
+        $currentUser = $this->security->getUser();
+        $rootAlias = $queryBuilder->getRootAliases()[0];
+        $queryBuilder
+            ->andWhere(sprintf('%s.discr = :discr', $rootAlias))
+            ->andWhere(sprintf('%s.organization = :organization', $rootAlias))
+            ->setParameter('discr', 'course')
+            ->setParameter('organization', $currentUser->getOrganization())
+        ;
+    }
+}

+ 88 - 0
src/Entity/Booking/Course.php

@@ -0,0 +1,88 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Entity\Booking;
+
+use ApiPlatform\Core\Annotation\ApiResource;
+use App\Annotation\OrganizationDefaultValue;
+use App\Annotation\YearConstraintAware;
+use App\Entity\Organization\Organization;
+use App\Entity\Traits\ActivityYearTrait;
+use App\Repository\Booking\CourseRepository;
+use Doctrine\ORM\Mapping as ORM;
+
+/**
+ * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table Course, et supprimer l'attribut discr.
+ *
+ * Classe Course qui permet de gérer les cours de la structure.
+ */
+#[ApiResource(
+    collectionOperations:[
+        'get'
+    ],
+    itemOperations: [
+        "get" => ["security" => "is_granted('ROLE_COURSE_VIEW') and object.getOrganization().getId() == user.getOrganization().getId()"],
+    ]
+)]
+#[ORM\Entity(repositoryClass:CourseRepository::class)]
+#[YearConstraintAware(startYearFieldName: "startYear", endYearFieldName: "endYear")]
+#[OrganizationDefaultValue(fieldName: "organization")]
+
+#[ORM\Table(name: 'Booking')]
+class Course
+{
+    use ActivityYearTrait;
+
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
+
+    #[ORM\Column(length: 255, nullable: false)]
+    private string $discr = 'course';
+
+    #[ORM\ManyToOne(inversedBy: 'organizationAddressPostals')]
+    #[ORM\JoinColumn(nullable: false)]
+    private Organization $organization;
+
+    #[ORM\Column(type: 'datetime', nullable: true)]
+    private ?\DateTimeInterface $datetimeStart = null;
+
+    #[ORM\Column(type: 'datetime', nullable: true)]
+    private ?\DateTimeInterface $datetimeEnd = null;
+
+    public function getId(): ?int
+    {
+        return $this->id;
+    }
+
+    public function getOrganization(): ?Organization
+    {
+        return $this->organization;
+    }
+
+    public function setOrganization(Organization $organization): self
+    {
+        $this->organization = $organization;
+
+        return $this;
+    }
+
+    public function getDatetimeStart(): ?\DateTimeInterface {
+        return $this->datetimeStart;
+    }
+
+    public function setDatetimeStart(?\DateTimeInterface $datetimeStart = null): self {
+        $this->datetimeStart = $datetimeStart;
+        return $this;
+    }
+
+    public function getDatetimeEnd(): ?\DateTimeInterface {
+        return $this->datetimeEnd;
+    }
+
+    public function setDatetimeEnd(?\DateTimeInterface $datetimeEnd = null) :self {
+        $this->datetimeEnd = $datetimeEnd;
+        return $this;
+    }
+}

+ 46 - 0
src/Repository/Booking/CourseRepository.php

@@ -0,0 +1,46 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Repository\Booking;
+
+use App\Entity\Booking\Course;
+use App\Entity\Organization\Organization;
+use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
+use Doctrine\Persistence\ManagerRegistry;
+
+class CourseRepository extends ServiceEntityRepository
+{
+    public function __construct(ManagerRegistry $registry)
+    {
+        parent::__construct($registry, Course::class);
+    }
+
+    /**
+     * Récupère les cours d'une organisation d'une date à une autre
+     * @param Organization $organization
+     * @param \DateTimeInterface $start
+     * @param \DateTimeInterface $end
+     * @return array
+     */
+    public function getCoursesToFrom(Organization $organization, \DateTimeInterface $start, \DateTimeInterface $end): array{
+        $this->_em->getFilters()->disable('year_time_filter');
+
+        $queryBuilder = $this->createQueryBuilder('course');
+
+        $queryBuilder
+            ->andWhere(
+                $queryBuilder->expr()->between('course.datetimeStart', ':dateStart', ':dateEnd')
+            )
+            ->andWhere('course.organization = :organization')
+            ->setParameter('dateStart', $start)
+            ->setParameter('dateEnd', $end)
+            ->setParameter('organization', $organization)
+        ;
+
+        $results = $queryBuilder->getQuery()->getResult();
+
+        $this->_em->getFilters()->enable('year_time_filter');
+
+        return $results;
+    }
+}