src/CoreBundle/Entity/Message.php
<?php
declare(strict_types=1);
/* For licensing terms, see /license.txt */
namespace Chamilo\CoreBundle\Entity;
use ApiPlatform\Doctrine\Orm\Filter\BooleanFilter;
use ApiPlatform\Doctrine\Orm\Filter\ExistsFilter;
use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Put;
use Chamilo\CoreBundle\Entity\Listener\MessageListener;
use Chamilo\CoreBundle\Filter\PartialSearchOrFilter;
use Chamilo\CoreBundle\Repository\MessageRepository;
use Chamilo\CoreBundle\State\MessageByGroupStateProvider;
use Chamilo\CoreBundle\State\MessageProcessor;
use Chamilo\CoreBundle\State\MessageStateProvider;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Table(name: 'message')]
#[ORM\Index(columns: ['user_sender_id'], name: 'idx_message_user_sender')]
#[ORM\Index(columns: ['group_id'], name: 'idx_message_group')]
#[ORM\Index(columns: ['msg_type'], name: 'idx_message_type')]
#[ORM\Entity(repositoryClass: MessageRepository::class)]
#[ORM\EntityListeners([MessageListener::class])]
#[ApiResource(
operations: [
new Get(security: "is_granted('VIEW', object)"),
new Put(security: "is_granted('EDIT', object)"),
new Delete(security: "is_granted('DELETE', object)"),
new GetCollection(
uriTemplate: '/messages',
security: "is_granted('ROLE_USER')",
name: 'get_all_messages',
provider: MessageStateProvider::class
),
new GetCollection(
uriTemplate: '/messages/by-group/list',
security: "is_granted('ROLE_USER')",
name: 'get_messages_by_social_group',
provider: MessageByGroupStateProvider::class
),
new Post(securityPostDenormalize: "is_granted('CREATE', object)"),
],
normalizationContext: [
'groups' => ['message:read'],
],
denormalizationContext: [
'groups' => ['message:write'],
],
security: "is_granted('ROLE_USER')",
processor: MessageProcessor::class,
)]
#[ApiFilter(filterClass: OrderFilter::class, properties: ['title', 'sendDate'])]
#[ApiFilter(SearchFilter::class, properties: [
'msgType' => 'exact',
'status' => 'exact',
'sender' => 'exact',
'receivers.receiver' => 'exact',
'receivers.receiverType' => 'exact',
'receivers.tags.tag' => 'exact',
'parent' => 'exact',
])]
#[ApiFilter(
BooleanFilter::class,
properties: ['receivers.read']
)]
#[ApiFilter(PartialSearchOrFilter::class, properties: ['title', 'content'])]
#[ApiFilter(ExistsFilter::class, properties: ['receivers.deletedAt'])]
class Message
{
public const MESSAGE_TYPE_INBOX = 1;
public const MESSAGE_TYPE_GROUP = 5;
public const MESSAGE_TYPE_INVITATION = 6;
public const MESSAGE_TYPE_CONVERSATION = 7;
// status
public const MESSAGE_STATUS_DELETED = 3;
public const MESSAGE_STATUS_DRAFT = 4;
public const MESSAGE_STATUS_INVITATION_PENDING = 5;
public const MESSAGE_STATUS_INVITATION_ACCEPTED = 6;
public const MESSAGE_STATUS_INVITATION_DENIED = 7;
#[ORM\Column(name: 'id', type: 'integer')]
#[ORM\Id]
#[ORM\GeneratedValue]
#[Groups(['message:read'])]
protected ?int $id = null;
#[Assert\NotBlank]
#[Groups(['message:read', 'message:write'])]
#[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'sentMessages')]
#[ORM\JoinColumn(name: 'user_sender_id', referencedColumnName: 'id', onDelete: 'SET NULL')]
protected ?User $sender = null;
/**
* @var Collection<int, MessageRelUser>
*/
#[ORM\OneToMany(mappedBy: 'message', targetEntity: MessageRelUser::class, cascade: ['persist', 'remove'])]
#[Groups(['message:write'])]
protected Collection $receivers;
#[Assert\NotBlank]
#[Groups(['message:read', 'message:write'])]
#[ORM\Column(name: 'msg_type', type: 'smallint', nullable: false)]
protected int $msgType;
#[Assert\NotBlank]
#[Groups(['message:read', 'message:write'])]
#[ORM\Column(name: 'status', type: 'smallint', nullable: false)]
protected int $status;
#[Groups(['message:read'])]
#[ORM\Column(name: 'send_date', type: 'datetime', nullable: false)]
protected DateTime $sendDate;
#[Assert\NotBlank]
#[Groups(['message:read', 'message:write'])]
#[ORM\Column(name: 'title', type: 'string', length: 255, nullable: false)]
protected string $title;
#[Assert\NotBlank]
#[Groups(['message:read', 'message:write'])]
#[ORM\Column(name: 'content', type: 'text', nullable: false)]
protected string $content;
#[Groups(['message:read', 'message:write'])]
#[ORM\ManyToOne(targetEntity: Usergroup::class)]
#[ORM\JoinColumn(name: 'group_id', referencedColumnName: 'id', onDelete: 'CASCADE')]
protected ?Usergroup $group = null;
/**
* @var Collection<int, Message>
*/
#[ORM\OneToMany(mappedBy: 'parent', targetEntity: self::class)]
protected Collection $children;
#[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'children')]
#[ORM\JoinColumn(name: 'parent_id', referencedColumnName: 'id')]
protected ?Message $parent = null;
#[Gedmo\Timestampable(on: 'update')]
#[ORM\Column(name: 'update_date', type: 'datetime', nullable: true)]
protected ?DateTime $updateDate;
#[ORM\Column(name: 'votes', type: 'integer', nullable: true)]
protected ?int $votes;
/**
* @var Collection<int, MessageAttachment>
*/
#[Assert\Valid]
#[Groups(['message:read', 'message:write'])]
#[ORM\OneToMany(
mappedBy: 'message',
targetEntity: MessageAttachment::class,
cascade: ['persist'],
orphanRemoval: true,
)]
protected Collection $attachments;
public function __construct()
{
$this->sendDate = new DateTime('now');
$this->updateDate = $this->sendDate;
$this->msgType = self::MESSAGE_TYPE_INBOX;
$this->content = '';
$this->attachments = new ArrayCollection();
$this->children = new ArrayCollection();
$this->receivers = new ArrayCollection();
$this->votes = 0;
$this->status = 0;
}
/**
* @return Collection<int, MessageRelUser>
*/
public function getReceivers(): Collection
{
return $this->receivers;
}
public function setReceiversFromArray(array $receivers): self
{
$this->receivers = new ArrayCollection($receivers);
return $this;
}
#[Groups(['message:read'])]
public function getReceiversTo(): array
{
return $this->receivers
->filter(
fn (MessageRelUser $messageRelUser) => MessageRelUser::TYPE_TO === $messageRelUser->getReceiverType()
)->getValues()
;
}
#[Groups(['message:read'])]
public function getReceiversCc(): array
{
return $this->receivers
->filter(
fn (MessageRelUser $messageRelUser) => MessageRelUser::TYPE_CC === $messageRelUser->getReceiverType()
)
->getValues()
;
}
#[Groups(['message:read'])]
public function getReceiversSender(): array
{
return $this->receivers
->filter(
fn (MessageRelUser $messageRelUser) => MessageRelUser::TYPE_SENDER === $messageRelUser->getReceiverType()
)
->getValues()
;
}
#[Groups(['message:read'])]
public function getFirstReceiver(): ?MessageRelUser
{
if ($this->receivers->count() > 0) {
return $this->receivers->first();
}
return null;
}
public function hasUserReceiver(User $receiver): bool
{
if ($this->receivers->count()) {
$criteria = Criteria::create()
->where(
Criteria::expr()->eq('receiver', $receiver)
)
->andWhere(
Criteria::expr()->eq('message', $this)
)
;
return $this->receivers->matching($criteria)->count() > 0;
}
return false;
}
public function addReceiverTo(User $receiver): self
{
$messageRelUser = (new MessageRelUser())
->setReceiver($receiver)
->setReceiverType(MessageRelUser::TYPE_TO)
;
$this->addReceiver($messageRelUser);
return $this;
}
public function addReceiver(MessageRelUser $messageRelUser): self
{
if (!$this->receivers->contains($messageRelUser)) {
$this->receivers->add($messageRelUser);
$messageRelUser->setMessage($this);
}
return $this;
}
public function addReceiverCc(User $receiver): self
{
$messageRelUser = (new MessageRelUser())
->setReceiver($receiver)
->setReceiverType(MessageRelUser::TYPE_CC)
;
$this->addReceiver($messageRelUser);
return $this;
}
public function removeReceiver(MessageRelUser $messageRelUser): self
{
$this->receivers->removeElement($messageRelUser);
return $this;
}
public function getSender(): ?User
{
return $this->sender;
}
public function setSender(?User $sender): self
{
$this->sender = $sender;
return $this;
}
public function getMsgType(): int
{
return $this->msgType;
}
public function setMsgType(int $msgType): self
{
$this->msgType = $msgType;
return $this;
}
public function getSendDate(): DateTime
{
return $this->sendDate;
}
public function setSendDate(DateTime $sendDate): self
{
$this->sendDate = $sendDate;
return $this;
}
public function getTitle(): string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getContent(): string
{
return $this->content;
}
public function setContent(string $content): self
{
$this->content = $content;
return $this;
}
public function getUpdateDate(): ?DateTime
{
return $this->updateDate;
}
public function setUpdateDate(DateTime $updateDate): self
{
$this->updateDate = $updateDate;
return $this;
}
public function getId(): ?int
{
return $this->id;
}
public function getVotes(): int
{
return $this->votes;
}
public function setVotes(int $votes): self
{
$this->votes = $votes;
return $this;
}
/**
* @return Collection<int, MessageAttachment>
*/
public function getAttachments(): Collection
{
return $this->attachments;
}
public function addAttachment(MessageAttachment $attachment): static
{
if (!$this->attachments->contains($attachment)) {
$this->attachments->add($attachment);
$attachment
->setMessage($this)
->setParent($this->sender)
->setCreator($this->sender)
;
}
return $this;
}
public function removeAttachment(MessageAttachment $attachment): static
{
if ($this->attachments->removeElement($attachment)) {
if ($attachment->getMessage() === $this) {
$attachment->setMessage(null);
}
}
return $this;
}
public function getParent(): ?self
{
return $this->parent;
}
public function setParent(?self $parent): self
{
$this->parent = $parent;
return $this;
}
/**
* @return Collection<int, Message>
*/
public function getChildren(): Collection
{
return $this->children;
}
public function addChild(self $child): self
{
$this->children[] = $child;
$child->setParent($this);
return $this;
}
public function getGroup(): ?Usergroup
{
return $this->group;
}
public function setGroup(?Usergroup $group): self
{
// $this->msgType = self::MESSAGE_TYPE_GROUP;
$this->group = $group;
return $this;
}
public function getStatus(): int
{
return $this->status;
}
public function setStatus(int $status): self
{
$this->status = $status;
return $this;
}
}