From 1bf8afd88ef98a7d314114b8f2d78fd51f9b94c0 Mon Sep 17 00:00:00 2001 From: thibaud-leclere Date: Sun, 29 Mar 2026 10:16:29 +0200 Subject: [PATCH] feat: add Notification entity --- migrations/Version20260329000003.php | 35 ++++++++++ src/Entity/Notification.php | 78 +++++++++++++++++++++++ src/Repository/NotificationRepository.php | 54 ++++++++++++++++ 3 files changed, 167 insertions(+) create mode 100644 migrations/Version20260329000003.php create mode 100644 src/Entity/Notification.php create mode 100644 src/Repository/NotificationRepository.php diff --git a/migrations/Version20260329000003.php b/migrations/Version20260329000003.php new file mode 100644 index 0000000..92517ff --- /dev/null +++ b/migrations/Version20260329000003.php @@ -0,0 +1,35 @@ +addSql('CREATE TABLE notification (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, user_id INT NOT NULL, message VARCHAR(255) NOT NULL, read BOOLEAN NOT NULL DEFAULT false, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY (id))'); + $this->addSql('CREATE INDEX IDX_BF5476CAA76ED395 ON notification (user_id)'); + $this->addSql('COMMENT ON COLUMN notification.created_at IS \'(DC2Type:datetime_immutable)\''); + $this->addSql('ALTER TABLE notification ADD CONSTRAINT FK_BF5476CAA76ED395 FOREIGN KEY (user_id) REFERENCES "user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE notification DROP CONSTRAINT FK_BF5476CAA76ED395'); + $this->addSql('DROP TABLE notification'); + } +} diff --git a/src/Entity/Notification.php b/src/Entity/Notification.php new file mode 100644 index 0000000..66bdc32 --- /dev/null +++ b/src/Entity/Notification.php @@ -0,0 +1,78 @@ +createdAt = new \DateTimeImmutable(); + } + + public function getId(): ?int + { + return $this->id; + } + + public function getUser(): ?User + { + return $this->user; + } + + public function setUser(?User $user): static + { + $this->user = $user; + return $this; + } + + public function getMessage(): ?string + { + return $this->message; + } + + public function setMessage(string $message): static + { + $this->message = $message; + return $this; + } + + public function isRead(): bool + { + return $this->read; + } + + public function setRead(bool $read): static + { + $this->read = $read; + return $this; + } + + public function getCreatedAt(): \DateTimeImmutable + { + return $this->createdAt; + } +} diff --git a/src/Repository/NotificationRepository.php b/src/Repository/NotificationRepository.php new file mode 100644 index 0000000..ccc1e66 --- /dev/null +++ b/src/Repository/NotificationRepository.php @@ -0,0 +1,54 @@ + + */ +class NotificationRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Notification::class); + } + + /** + * @return Notification[] + */ + public function findRecentForUser(User $user, int $limit = 20): array + { + return $this->createQueryBuilder('n') + ->andWhere('n.user = :user') + ->setParameter('user', $user) + ->orderBy('n.createdAt', 'DESC') + ->setMaxResults($limit) + ->getQuery() + ->getResult(); + } + + public function countUnreadForUser(User $user): int + { + return $this->count(['user' => $user, 'read' => false]); + } + + public function markAllReadForUser(User $user): void + { + $this->createQueryBuilder('n') + ->update() + ->set('n.read', ':true') + ->where('n.user = :user') + ->andWhere('n.read = :false') + ->setParameter('true', true) + ->setParameter('false', false) + ->setParameter('user', $user) + ->getQuery() + ->execute(); + } +}