* * @ORM\ManyToMany(targetEntity=User::class) * * @ORM\JoinTable(name="chill_main_notification_addresses_user") */ private Collection $addressees; /** * a list of destinee which will receive notifications. * * @var array|string[] * * @ORM\Column(type="json") */ private array $addressesEmails = []; /** * a list of emails adresses which were added to the notification. * * @var array|string[] */ private array $addressesEmailsAdded = []; private ?ArrayCollection $addressesOnLoad = null; /** * @var Collection * * @ORM\OneToMany(targetEntity=NotificationComment::class, mappedBy="notification", orphanRemoval=true) * * @ORM\OrderBy({"createdAt": "ASC"}) */ private Collection $comments; /** * @ORM\Column(type="datetime_immutable") */ private \DateTimeImmutable $date; /** * @ORM\Id * * @ORM\GeneratedValue * * @ORM\Column(type="integer") */ private ?int $id = null; /** * @ORM\Column(type="text") */ private string $message = ''; /** * @ORM\Column(type="string", length=255) */ private string $relatedEntityClass = ''; /** * @ORM\Column(type="integer") */ private int $relatedEntityId; private array $removedAddresses = []; /** * @ORM\ManyToOne(targetEntity=User::class) * * @ORM\JoinColumn(nullable=true) */ private ?User $sender = null; /** * @ORM\Column(type="text", options={"default": ""}) * * @Assert\NotBlank(message="notification.Title must be defined") */ private string $title = ''; /** * @var Collection * * @ORM\ManyToMany(targetEntity=User::class) * * @ORM\JoinTable(name="chill_main_notification_addresses_unread") */ private Collection $unreadBy; /** * @ORM\Column(type="datetime_immutable") */ private ?\DateTimeImmutable $updatedAt = null; /** * @ORM\ManyToOne(targetEntity=User::class) */ private ?User $updatedBy = null; public function __construct() { $this->addressees = new ArrayCollection(); $this->unreadBy = new ArrayCollection(); $this->comments = new ArrayCollection(); $this->setDate(new \DateTimeImmutable()); $this->accessKey = bin2hex(openssl_random_pseudo_bytes(24)); } public function addAddressee(User $addressee): self { if (!$this->addressees->contains($addressee)) { $this->addressees[] = $addressee; $this->addedAddresses[] = $addressee; } return $this; } public function addAddressesEmail(string $email) { if (!\in_array($email, $this->addressesEmails, true)) { $this->addressesEmails[] = $email; $this->addressesEmailsAdded[] = $email; } } public function addComment(NotificationComment $comment): self { if (!$this->comments->contains($comment)) { $this->comments[] = $comment; $comment->setNotification($this); } return $this; } public function addUnreadBy(User $user): self { if (!$this->unreadBy->contains($user)) { $this->unreadBy[] = $user; } return $this; } /** * @Assert\Callback * * @param array $payload */ public function assertCountAddresses(ExecutionContextInterface $context, $payload): void { if (0 === (\count($this->getAddressesEmails()) + \count($this->getAddressees()))) { $context->buildViolation('notification.At least one addressee') ->atPath('addressees') ->addViolation(); } } public function getAccessKey(): string { return $this->accessKey; } public function getAddedAddresses(): array { return $this->addedAddresses; } /** * @return Collection|User[] */ public function getAddressees(): Collection { // keep a copy to compute changes later if (null === $this->addressesOnLoad) { $this->addressesOnLoad = new ArrayCollection($this->addressees->toArray()); } return $this->addressees; } /** * @return array|string[] */ public function getAddressesEmails(): array { return $this->addressesEmails; } /** * @return array|string[] */ public function getAddressesEmailsAdded(): array { return $this->addressesEmailsAdded; } public function getComments(): Collection { return $this->comments; } public function getDate(): ?\DateTimeImmutable { return $this->date; } public function getId(): ?int { return $this->id; } public function getMessage(): ?string { return $this->message; } public function getRelatedEntityClass(): ?string { return $this->relatedEntityClass; } public function getRelatedEntityId(): ?int { return $this->relatedEntityId; } public function getSender(): ?User { return $this->sender; } public function getTitle(): string { return $this->title; } public function getUnreadBy(): Collection { return $this->unreadBy; } public function getUpdatedAt(): ?\DateTimeImmutable { return $this->updatedAt; } public function getUpdatedBy(): ?User { return $this->updatedBy; } public function isReadBy(User $user): bool { return !$this->unreadBy->contains($user); } public function isSystem(): bool { return null === $this->sender; } public function markAsReadBy(User $user): self { return $this->removeUnreadBy($user); } public function markAsUnreadBy(User $user): self { return $this->addUnreadBy($user); } /** * @ORM\PreFlush */ public function registerUnread() { foreach ($this->addedAddresses as $addressee) { $this->addUnreadBy($addressee); } foreach ($this->removedAddresses as $addressee) { $this->removeAddressee($addressee); } if (null !== $this->addressesOnLoad) { foreach ($this->addressees as $existingAddresse) { if (!$this->addressesOnLoad->contains($existingAddresse)) { $this->addUnreadBy($existingAddresse); } } foreach ($this->addressesOnLoad as $onLoadAddressee) { if (!$this->addressees->contains($onLoadAddressee)) { $this->removeUnreadBy($onLoadAddressee); } } } $this->removedAddresses = []; $this->addedAddresses = []; $this->addressesOnLoad = null; } public function removeAddressee(User $addressee): self { if ($this->addressees->removeElement($addressee)) { $this->removedAddresses[] = $addressee; } return $this; } public function removeAddressesEmail(string $email) { if (\in_array($email, $this->addressesEmails, true)) { $this->addressesEmails = array_filter($this->addressesEmails, static fn ($e) => $e !== $email); $this->addressesEmailsAdded = array_filter($this->addressesEmailsAdded, static fn ($e) => $e !== $email); } } public function removeComment(NotificationComment $comment): self { $this->comments->removeElement($comment); return $this; } public function removeUnreadBy(User $user): self { $this->unreadBy->removeElement($user); return $this; } public function setDate(\DateTimeImmutable $date): self { $this->date = $date; return $this; } public function setMessage(?string $message): self { $this->message = (string) $message; return $this; } public function setRelatedEntityClass(string $relatedEntityClass): self { $this->relatedEntityClass = $relatedEntityClass; return $this; } public function setRelatedEntityId(int $relatedEntityId): self { $this->relatedEntityId = $relatedEntityId; return $this; } public function setSender(?User $sender): self { $this->sender = $sender; return $this; } public function setTitle(?string $title): Notification { $this->title = (string) $title; return $this; } public function setUpdatedAt(\DateTimeInterface $datetime): self { $this->updatedAt = $datetime; return $this; } public function setUpdatedBy(User $user): self { $this->updatedBy = $user; return $this; } }