mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
423 lines
9.7 KiB
PHP
423 lines
9.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* Chill is a software for social workers
|
|
*
|
|
* For the full copyright and license information, please view
|
|
* the LICENSE file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Chill\MainBundle\Entity;
|
|
|
|
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
|
|
use DateTimeImmutable;
|
|
use DateTimeInterface;
|
|
use Doctrine\Common\Collections\ArrayCollection;
|
|
use Doctrine\Common\Collections\Collection;
|
|
use Doctrine\ORM\Mapping as ORM;
|
|
use Symfony\Component\Validator\Constraints as Assert;
|
|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
|
use function count;
|
|
use function in_array;
|
|
|
|
/**
|
|
* @ORM\Entity
|
|
* @ORM\Table(
|
|
* name="chill_main_notification",
|
|
* indexes={
|
|
* @ORM\Index(name="chill_main_notification_related_entity_idx", columns={"relatedentityclass", "relatedentityid"})
|
|
* }
|
|
* )
|
|
* @ORM\HasLifecycleCallbacks
|
|
*/
|
|
class Notification implements TrackUpdateInterface
|
|
{
|
|
/**
|
|
* @ORM\Column(type="text", nullable=false)
|
|
*/
|
|
private string $accessKey;
|
|
|
|
private array $addedAddresses = [];
|
|
|
|
/**
|
|
* @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;
|
|
|
|
/**
|
|
* @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 = '';
|
|
|
|
/**
|
|
* @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;
|
|
}
|
|
}
|