Bladeren bron

Entities, repository & doctrine extension

Vincent GUFFON 4 jaren geleden
bovenliggende
commit
3190155be3

+ 54 - 0
src/Doctrine/Core/NotificationExtension.php

@@ -0,0 +1,54 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Doctrine\Core;
+
+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\Core\Notification;
+use Doctrine\ORM\QueryBuilder;
+use Symfony\Component\Security\Core\Security;
+
+/**
+ * Class NotificationExtension : Filtre de sécurité par défaut pour une resource Notification
+ * @package App\Doctrine\Core
+ */
+final class NotificationExtension implements QueryCollectionExtensionInterface, QueryItemExtensionInterface
+{
+    public function __construct(private Security $security)
+    { }
+
+    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 (Notification::class !== $resourceClass) {
+            return;
+        }
+
+        /** @var Access $currentUser */
+        $currentUser = $this->security->getUser();
+        $rootAlias = $queryBuilder->getRootAliases()[0];
+        $queryBuilder
+            ->andWhere(sprintf('%s.discr = :discr', $rootAlias))
+            ->andWhere(sprintf('%s.recipientAccess = :current_access', $rootAlias))
+            ->andWhere('o.availabilityDate IS NULL or o.availabilityDate <= :today')
+            ->setParameter('discr', 'notification')
+            ->setParameter('current_access', $currentUser)
+            ->setParameter('today', new \DateTime())
+        ;
+    }
+}

+ 50 - 0
src/Doctrine/Core/NotificationUserExtension.php

@@ -0,0 +1,50 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Doctrine\Core;
+
+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\Core\NotificationUser;
+use Doctrine\ORM\QueryBuilder;
+use Symfony\Component\Security\Core\Security;
+
+/**
+ * Class NotificationExtension : Filtre de sécurité par défaut pour une resource Notification
+ * @package App\Doctrine\Core
+ */
+final class NotificationUserExtension implements QueryCollectionExtensionInterface, QueryItemExtensionInterface
+{
+    public function __construct(private Security $security)
+    { }
+
+    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 (NotificationUser::class !== $resourceClass) {
+            return;
+        }
+
+        /** @var Access $currentUser */
+        $currentUser = $this->security->getUser();
+        $rootAlias = $queryBuilder->getRootAliases()[0];
+        $queryBuilder
+            ->andWhere(sprintf('%s.access = :current_access', $rootAlias))
+            ->setParameter('current_access', $currentUser)
+        ;
+    }
+}

+ 64 - 0
src/Entity/Access/Access.php

@@ -7,6 +7,8 @@ use ApiPlatform\Core\Annotation\ApiResource;
 use ApiPlatform\Core\Annotation\ApiSubresource;
 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\Repository\Access\AccessRepository;
@@ -91,6 +93,12 @@ class Access implements UserInterface
     #[ORM\OneToMany(mappedBy: 'access', targetEntity: PersonalizedList::class, cascade: ['persist'], orphanRemoval: true)]
     private Collection $personalizedLists;
 
+    #[ORM\OneToMany(mappedBy: 'recipientAccess', targetEntity: Notification::class, orphanRemoval: true)]
+    private Collection $notifications;
+
+    #[ORM\OneToMany(mappedBy: 'access', targetEntity: NotificationUser::class, orphanRemoval: true)]
+    private Collection $notificationUsers;
+
     #[ORM\ManyToMany(targetEntity: Access::class, mappedBy: 'children', cascade: ['persist'])]
     private Collection $guardians;
 
@@ -120,6 +128,8 @@ class Access implements UserInterface
         $this->billingPayers = new ArrayCollection();
         $this->billingReceivers = new ArrayCollection();
         $this->accessIntangibles = new ArrayCollection();
+        $this->notifications = new ArrayCollection();
+        $this->notificationUsers = new ArrayCollection();
     }
 
     public function getId(): ?int
@@ -434,6 +444,60 @@ class Access implements UserInterface
         return $this;
     }
 
+    public function getNotifications(): Collection
+    {
+        return $this->notifications;
+    }
+
+    public function addNotification(Notification $notification): self
+    {
+        if (!$this->notifications->contains($notification)) {
+            $this->notifications[] = $notification;
+            $notification->setRecipientAccess($this);
+        }
+
+        return $this;
+    }
+
+    public function removeNotification(Notification $notification): self
+    {
+        if ($this->notifications->removeElement($notification)) {
+            // set the owning side to null (unless already changed)
+            if ($notification->getRecipientAccess() === $this) {
+                $notification->setRecipientAccess(null);
+            }
+        }
+
+        return $this;
+    }
+
+    public function getNotificationUsers(): Collection
+    {
+        return $this->notificationUsers;
+    }
+
+    public function addNotificationUser(NotificationUser $notificationUser): self
+    {
+        if (!$this->notificationUsers->contains($notificationUser)) {
+            $this->notificationUsers[] = $notificationUser;
+            $notificationUser->setAccess($this);
+        }
+
+        return $this;
+    }
+
+    public function removeNotificationUser(NotificationUser $notificationUser): self
+    {
+        if ($this->notificationUsers->removeElement($notificationUser)) {
+            // set the owning side to null (unless already changed)
+            if ($notificationUser->getAccess() === $this) {
+                $notificationUser->setAccess(null);
+            }
+        }
+
+        return $this;
+    }
+
     #[Pure] public function getUserIdentifier(): string
     {
         return $this->person->getUsername();

+ 1 - 1
src/Entity/Core/AddressPostal.php

@@ -16,7 +16,7 @@ class AddressPostal
     private ?int $id = null;
 
     #[ORM\ManyToOne]
-    private Country $addressCountry;
+    private ?Country $addressCountry = null;
 
     #[ORM\Column(length: 100, nullable: true)]
     private ?string $addressCity = null;

+ 171 - 0
src/Entity/Core/Notification.php

@@ -0,0 +1,171 @@
+<?php
+declare(strict_types=1);
+
+
+namespace App\Entity\Core;
+
+use ApiPlatform\Core\Annotation\ApiResource;
+use App\Entity\Access\Access;
+use App\Repository\Core\NotificationRepository;
+use Doctrine\Common\Collections\ArrayCollection;
+use Doctrine\Common\Collections\Collection;
+use Doctrine\ORM\Mapping as ORM;
+use JetBrains\PhpStorm\Pure;
+use Symfony\Component\Validator\Constraints as Assert;
+
+/**
+ * @todo : A la suite de la migration, il faut supprimer le nom de la table pour avoir une table Notification, et supprimer l'attribut discr.
+ *
+ * Classe Notification. qui permet de gérer les notifications aux utilisateurs.
+ */
+#[ApiResource(
+    collectionOperations:[
+        'get' => [
+            'pagination_client_items_per_page' => true,
+            'pagination_maximum_items_per_page' => 20,
+            'order' => [
+                'id' => 'DESC'
+            ]
+        ]
+    ],
+    itemOperations: [
+        'get'
+    ]
+)]
+#[ORM\Entity(repositoryClass:NotificationRepository::class)]
+#[ORM\Table(name: 'Information')]
+class Notification
+{
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
+
+    #[ORM\Column(length: 255, nullable: false)]
+    private string $discr = 'notification';
+
+    #[ORM\ManyToOne(inversedBy: 'notifications')]
+    #[ORM\JoinColumn(nullable: false)]
+    private ?Access $recipientAccess;
+
+    #[ORM\Column(length: 40, nullable: true)]
+    private ?string $name = null;
+
+    #[ORM\Column(type: 'json', length: 4294967295, nullable: true)]
+    private ?array $message = [];
+
+    #[ORM\Column(nullable: true)]
+    #[Assert\Choice(callback: ['\App\Enum\Core\NotificationTypeEnum', 'toArray'], message: 'invalid-type')]
+    private ?string $type = null;
+
+    #[ORM\Column(length: 255, nullable: true)]
+    private ?string $link = null;
+
+    #[ORM\Column(type: 'date', nullable: true)]
+    private ?\DateTimeInterface $availabilityDate = null;
+
+    #[ORM\OneToMany(mappedBy: 'notification', targetEntity: NotificationUser::class, cascade: ['persist'], orphanRemoval: true)]
+    private Collection $notificationUsers;
+
+    #[Pure] public function __construct()
+    {
+        $this->notificationUsers = new ArrayCollection();
+    }
+
+    public function getId(): ?int
+    {
+        return $this->id;
+    }
+
+    public function setName(?string $name): self
+    {
+        $this->name = $name;
+        return $this;
+    }
+
+    public function getName(): ?string
+    {
+        return $this->name;
+    }
+
+    public function setRecipientAccess(?Access $recipientAccess): self
+    {
+        $this->recipientAccess = $recipientAccess;
+        return $this;
+    }
+
+    public function getRecipientAccess(): ?Access
+    {
+        return $this->recipientAccess;
+    }
+
+    public function setMessage(?array $message): self
+    {
+        $this->message = $message;
+        return $this;
+    }
+
+    public function getMessage(): ?array
+    {
+        return $this->message;
+    }
+
+    public function setType(?string $type): self
+    {
+        $this->type = $type;
+        return $this;
+    }
+
+    public function getType(): ?string
+    {
+        return $this->type;
+    }
+
+    public function setLink(?string $link): self
+    {
+        $this->link = $link;
+        return $this;
+    }
+
+    public function getLink(): ?string
+    {
+        return $this->link;
+    }
+
+    public function getAvailabilityDate(): ?string {
+        return $this->availabilityDate?->format('Y-m-d');
+    }
+
+    public function setAvailabilityDate(?\DateTime $availabilityDate = null): self {
+        if($availabilityDate == null) $availabilityDate = new \DateTime();
+        $this->availabilityDate = $availabilityDate;
+        return $this;
+    }
+
+    public function getNotificationUsers(): Collection
+    {
+        return $this->notificationUsers;
+    }
+
+    public function addNotificationUser(NotificationUser $notificationUsers): self
+    {
+        if (!$this->notificationUsers->contains($notificationUsers)) {
+            $this->notificationUsers[] = $notificationUsers;
+            $notificationUsers->setNotification($this);
+        }
+
+        return $this;
+    }
+
+    public function removeNotificationUser(NotificationUser $notificationUsers): self
+    {
+        if ($this->notificationUsers->removeElement($notificationUsers)) {
+            // set the owning side to null (unless already changed)
+            if ($notificationUsers->getNotification() === $this) {
+                $notificationUsers->setNotification(null);
+            }
+        }
+
+        return $this;
+    }
+}

+ 82 - 0
src/Entity/Core/NotificationUser.php

@@ -0,0 +1,82 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Entity\Core;
+
+use ApiPlatform\Core\Annotation\ApiResource;
+use App\Entity\Access\Access;
+use App\Repository\Core\NotificationUserRepository;
+use Doctrine\ORM\Mapping as ORM;
+
+/**
+ *
+ * Classe NotificationUser. qui permet de gérer les notifications qui ont été lues par les Users.
+ */
+#[ApiResource(
+    collectionOperations: [
+        'post' => [
+            'security_post_denormalize' => 'object.getAccess().getId() == user.getId() 
+                       and object.getNotification().getRecipientAccess().getOrganization().getId() == user.getOrganization().getId()'
+        ]
+    ],
+    itemOperations: [
+        'get'
+    ]
+)]
+#[ORM\Entity(repositoryClass:NotificationUserRepository::class)]
+class NotificationUser
+{
+    #[ORM\Id]
+    #[ORM\Column]
+    #[ORM\GeneratedValue]
+    private ?int $id = null;
+
+    #[ORM\ManyToOne(inversedBy: 'notificationUsers')]
+    #[ORM\JoinColumn(nullable: false)]
+    private Notification $notification;
+
+    #[ORM\ManyToOne(inversedBy: 'notificationUsers')]
+    #[ORM\JoinColumn(nullable: false)]
+    private Access $access;
+
+    #[ORM\Column(nullable: false)]
+    private bool $isRead = true;
+
+    public function getId(): ?int
+    {
+        return $this->id;
+    }
+
+    public function setNotification(?Notification $notification): self
+    {
+        $this->notification = $notification;
+        return $this;
+    }
+
+    public function getNotification(): Notification
+    {
+        return $this->notification;
+    }
+
+    public function setAccess(?Access $access): self
+    {
+        $this->access = $access;
+        return $this;
+    }
+
+    public function getAccess(): Access
+    {
+        return $this->access;
+    }
+
+    public function setIsRead(?bool $isRead): self
+    {
+        $this->isRead = $isRead;
+        return $this;
+    }
+
+    public function getIsRead(): ?bool
+    {
+        return $this->isRead;
+    }
+}

+ 19 - 0
src/Enum/Core/NotificationTypeEnum.php

@@ -0,0 +1,19 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Enum\Core;
+
+use MyCLabs\Enum\Enum;
+
+/**
+ * Type de notifications
+ *
+ */
+class NotificationTypeEnum extends Enum
+{
+    private const SYSTEM = 'SYSTEM';
+    private const FILE = 'FILE';
+    private const MESSAGE = 'MESSAGE';
+    private const PRINTING = 'PRINTING';
+    private const ERROR = 'ERROR';
+}

+ 16 - 0
src/Repository/Core/NotificationRepository.php

@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Repository\Core;
+
+use App\Entity\Core\Notification;
+use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
+use Doctrine\Persistence\ManagerRegistry;
+
+class NotificationRepository extends ServiceEntityRepository
+{
+    public function __construct(ManagerRegistry $registry)
+    {
+        parent::__construct($registry, Notification::class);
+    }
+}

+ 16 - 0
src/Repository/Core/NotificationUserRepository.php

@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Repository\Core;
+
+use App\Entity\Core\NotificationUser;
+use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
+use Doctrine\Persistence\ManagerRegistry;
+
+class NotificationUserRepository extends ServiceEntityRepository
+{
+    public function __construct(ManagerRegistry $registry)
+    {
+        parent::__construct($registry, NotificationUser::class);
+    }
+}