<?php
namespace App\Entity;
use App\Enum\Origin;
use App\Repository\MessageRepository;
use DateTimeZone;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity(repositoryClass: MessageRepository::class)]
#[ORM\Table(name: 'messages')]
class Message
{
#[ORM\Id]
#[ORM\Column(type: 'string', length: 22, unique: true)]
#[Groups(['message_read', 'mission_read', 'message_write'])]
private string $id;
#[ORM\Column(type: 'text', nullable: true)]
#[Groups(['message_read', 'mission_read', 'message_write'])]
private ?string $content = null;
#[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'messages')]
#[Groups(['message_read', 'mission_read', 'message_write'])]
private User $user;
#[ORM\ManyToMany(targetEntity: User::class)] // Relation unidirectionnelle
#[ORM\JoinTable(name: 'pinned_message_user')] // Nom de la table pivot
#[Groups(['message_read', 'mission_read', 'message_write'])]
private Collection $pinnedByUsers;
#[ORM\ManyToOne(targetEntity: Campaign::class, inversedBy: 'messages')]
private Campaign $campaign;
#[ORM\Column(type: 'datetime')]
#[Groups(['message_read', 'mission_read', 'message_write'])]
private \DateTimeInterface $createdAt;
#[ORM\OneToMany(mappedBy: 'messages', targetEntity: FileMessage::class, cascade: ["persist"])]
#[Groups(['message_read', 'mission_read'])]
private $fileMessages;
#[ORM\Column(type: 'array', nullable: true)]
#[Groups(['message_read', 'mission_read', 'message_write'])]
private $userListWhoRead = [];
#[ORM\ManyToOne(targetEntity: Mission::class, inversedBy: 'messages')]
private $mission;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
#[Groups(['message_read', 'mission_read'])]
private $origin;
#[ORM\Column(type: 'array', nullable: true)]
#[Groups(['message_read', 'mission_read'])]
private $replyTo = [];
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $originalContent = null;
#[ORM\OneToMany(mappedBy: 'message', targetEntity: MessageReaction::class)]
#[Groups(['message_read', 'mission_read', 'message_write'])]
private Collection $messageReactions;
#[ORM\Column(type: 'boolean', nullable: true)]
#[Groups(['message_read', 'mission_read', 'message_write'])]
private $isDeleted;
#[ORM\Column(type: 'datetime', nullable: true)]
private \DateTimeInterface $insertPinned;
#[ORM\Column(type: 'boolean', nullable: true)]
#[Groups(['message_read', 'mission_read', 'message_write'])]
private $isModified;
//For api
#[Groups(['message_read', 'mission_read', 'message_write'])]
private $reactionListApi = [];
#[ORM\ManyToOne(targetEntity: DiscussionGroup::class, inversedBy: 'messages')]
#[ORM\JoinColumn(nullable: true)]
#[Groups(['message_read', 'mission_read', 'message_write'])]
private ?DiscussionGroup $discussionGroup = null;
// for Api Only;
#[Groups(['message_read', 'mission_read', 'message_write'])]
private $createdAtTimestamp;
#[Groups(['message_read', 'mission_read', 'message_write'])]
private $createdAtCustom;
#[Groups(['message_read', 'mission_read', 'message_write'])]
private $lastMessageUread;
#[Groups(['message_read', 'mission_read', 'message_write'])]
private $userListWhoReadApi;
#[ORM\ManyToMany(targetEntity: User::class)]
#[ORM\JoinTable(name: 'message_shared_user')]
private Collection $sharedWithUsers;
#[ORM\Column(length: 255, nullable: true)]
private ?string $platform = null;
public function __construct()
{
$this->id = Uuid::v4()->toBase58();
// $date = new \DateTime('now');
// $utcTimeZone = new DateTimeZone("UTC");
//$utcTimeZone = new DateTimeZone("Europe/Paris");
// $date->setTimezone($utcTimeZone);
$date = new \DateTime("now", new DateTimeZone("UTC"));
$this->createdAt = $date;
$this->fileMessages = new ArrayCollection();
$this->userListWhoRead=[];
$this->origin = Origin::HUMAN->value;
$this->messageReactions = new ArrayCollection();
$this->isDeleted = false;
$this->pinnedByUsers = new ArrayCollection();
$this->sharedWithUsers = new ArrayCollection();
}
public function getId(): ?string
{
return $this->id;
}
public function getContent(): ?string
{
return $this->content;
}
public function setLastMessageUread(string $lastMessageUread){
$this->lastMessageUread = $lastMessageUread;;
}
public function getLastMessageUread(){
return $this->lastMessageUread;
}
public function setContent(?string $content, ?bool $replaceChar=true, ?bool $htmlspecialchars=true): self
{
// $this->setOriginalContent($content);
// $content = $htmlspecialchars ? htmlspecialchars($content) : $content;
if($replaceChar){
$pattern="/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}([-a-zA-Z0-9()@:%_\+.~#?&\/\/=;]*)/";
$content = preg_replace_callback($pattern, function ($matches) {
$url = $matches[0];
return '<a href="' . $url . '" target="_blank">' . $matches[0] . '</a>';
}, $content );
}
$content = str_replace(['<br />', '<br>','<br/>', '<br >'], '', $content);
$this->content =nl2br($content);
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
public function getCampaign(): ?Campaign
{
return $this->campaign;
}
public function setCampaign(?Campaign $campaign): self
{
$this->campaign = $campaign;
return $this;
}
public function getCreatedAtTimestamp(){
return $this->getCreatedAt()->getTimestamp();
}
public function getCreatedAtCustom(){
// $timezone = new \DateTimeZone(date_default_timezone_get());
// $now = new \DateTime('now', $timezone);
// $offsetInSeconds = $timezone->getOffset($now);
// $offsetInHours = $offsetInSeconds / 3600;
return $this->getCreatedAt()->format('Y-m-d\TH:i');
}
public function getCreatedAt(): ?\DateTimeInterface
{
// if ($this->createdAt) {
// // Convertit la date en UTC
// $this->createdAt->setTimezone(new \DateTimeZone('UTC'));
// }
return $this->createdAt;
}
public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
/**
* @return Collection|FileMessage[]
*/
public function getFileMessages(): Collection
{
return $this->fileMessages;
}
public function addFileMessage(FileMessage $fileMessage): self
{
if (!$this->fileMessages->contains($fileMessage)) {
$this->fileMessages[] = $fileMessage;
$fileMessage->setMessages($this);
}
return $this;
}
public function removeFileMessage(FileMessage $fileMessage): self
{
if ($this->fileMessages->removeElement($fileMessage)) {
// set the owning side to null (unless already changed)
if ($fileMessage->getMessages() === $this) {
$fileMessage->setMessages(null);
}
}
return $this;
}
public function getUserListWhoRead(): ?array
{
return $this->userListWhoRead;
}
public function getUserListWhoReadApi(): ?array
{
return $this->userListWhoReadApi;
}
public function setUserListWhoReadApi(?array $userListWhoReadApi): self
{
$this->userListWhoReadApi = $userListWhoReadApi;
return $this;
}
public function getReactionListApi(){
return $this->reactionListApi;
}
public function setReactionListApi(array $reactionListApi){
$this->reactionListApi = $reactionListApi;
}
public function setUserListWhoRead(?array $userListWhoRead): self
{
$this->userListWhoRead = $userListWhoRead;
return $this;
}
public function getMission(): ?Mission
{
return $this->mission;
}
public function setMission(?Mission $mission): self
{
$this->mission = $mission;
return $this;
}
public function getOrigin(): ?string
{
return $this->origin;
}
public function setOrigin(?string $origin): self
{
$this->origin = $origin;
return $this;
}
public function getReplyTo(): ?array
{
return $this->replyTo;
}
public function setReplyToWithMessage(?Message $message=null){
if($message!=null){
$this->setReplyTo([
'content'=>$message->getcontent(),
'id'=>$message->getId(),
'date'=>$message->getCreatedAt(),
'userFullname'=>$message->getUser()->getFullname()
]);
}
}
public function setReplyTo(?array $replyTo): self
{
$this->replyTo = $replyTo;
return $this;
}
private function addAtTheLine($content){
$pattern = "/\r/";
return preg_replace($pattern,'<br>',$content);
}
public function getOriginalContent(): ?string
{
return $this->originalContent;
}
public function setOriginalContent(?string $originalContent): static
{
$this->originalContent = $originalContent;
return $this;
}
private function putBoldUserMentioned($content){
return $content = preg_replace_callback('/(?:^|\s)@(\w+)[;,\.]?(?=\s|$)(?![\w.-]*@\w+\.\w+)/u', function($match) {
$user = [...explode('__', $match[0])];
if ("@tous" == $user[0]){
return '<strong data-origin="@tous">' . $match[0] . '</strong>';
}
else{
if(sizeof($user) == 2 ){
[$originFirstname, $originLastname] = $user;
$firstname= preg_replace('/_/u', " ", $originFirstname);
$lastname = preg_replace('/_/u', " ", $originLastname);
return "<strong data-origin='{$originFirstname}__{$originLastname}'>$firstname </strong>";
}
else{
return $match[0];
}
}
}, $content);
}
/**
* @return Collection<int, MessageReaction>
*/
public function getMessageReactions(): Collection
{
return $this->messageReactions;
}
public function addMessageReaction(MessageReaction $messageReaction): static
{
if (!$this->messageReactions->contains($messageReaction)) {
$this->messageReactions->add($messageReaction);
$messageReaction->setMessage($this);
}
return $this;
}
public function removeMessageReaction(MessageReaction $messageReaction): static
{
if ($this->messageReactions->removeElement($messageReaction)) {
// set the owning side to null (unless already changed)
if ($messageReaction->getMessage() === $this) {
$messageReaction->setMessage(null);
}
}
return $this;
}
public function isDeleted(): ?bool
{
return $this->isDeleted;
}
public function setIsDeleted(?bool $isDeleted): self
{
$this->isDeleted = $isDeleted;
return $this;
}
public function isModified(): ?bool
{
return $this->isModified;
}
public function setIsModified(?bool $isModified): self
{
$this->isModified = $isModified;
return $this;
}
public function isIsDeleted(): ?bool
{
return $this->isDeleted;
}
public function isIsModified(): ?bool
{
return $this->isModified;
}
public function getDiscussionGroup(): ?DiscussionGroup
{
return $this->discussionGroup;
}
public function setDiscussionGroup(?DiscussionGroup $discussionGroup): static
{
$this->discussionGroup = $discussionGroup;
return $this;
}
public function getInsertPinned(): ?\DateTimeInterface
{
return $this->insertPinned;
}
public function setInsertPinned(?\DateTimeInterface $insertPinned): static
{
$this->insertPinned = $insertPinned;
return $this;
}
public function getPinnedBy(): ?User
{
return $this->pinnedBy;
}
public function setPinnedBy(?User $pinnedBy): static
{
$this->pinnedBy = $pinnedBy;
return $this;
}
/**
* @return Collection<int, User>
*/
public function getPinnedByUsers(): Collection
{
return $this->pinnedByUsers;
}
public function addPinnedByUser(User $pinnedByUser): static
{
if (!$this->pinnedByUsers->contains($pinnedByUser)) {
$this->pinnedByUsers->add($pinnedByUser);
}
return $this;
}
public function removePinnedByUser(User $pinnedByUser): static
{
$this->pinnedByUsers->removeElement($pinnedByUser);
return $this;
}
public function isPinnedBy(User $user){
$pinned = false;
foreach ($this->getPinnedByUsers() as $userPinned) {
if ($user->getId() == $userPinned->getId()) {
$pinned = true;
break;
}
}
return $pinned;
}
/**
* @return Collection<int, User>
*/
public function getSharedWithUsers(): Collection
{
return $this->sharedWithUsers;
}
public function addSharedWithUser(User $sharedWithUser): static
{
if (!$this->sharedWithUsers->contains($sharedWithUser)) {
$this->sharedWithUsers->add($sharedWithUser);
}
return $this;
}
public function removeSharedWithUser(User $sharedWithUser): static
{
$this->sharedWithUsers->removeElement($sharedWithUser);
return $this;
}
public function getPlatform(): ?string
{
return $this->platform;
}
public function setPlatform(?string $platform): static
{
$this->platform = $platform;
return $this;
}
}