diff --git a/src/CoreBundle/Controller/Api/CreateMessageAttachmentAction.php b/src/CoreBundle/Controller/Api/CreateMessageAttachmentAction.php deleted file mode 100644 index e8dd2de2a2..0000000000 --- a/src/CoreBundle/Controller/Api/CreateMessageAttachmentAction.php +++ /dev/null @@ -1,55 +0,0 @@ -files->get('file'); - - if (empty($uploadedFile)) { - throw new BadRequestHttpException('file is required'); - } - - $messageRepo = $em->getRepository(Message::class); - - $message = $messageRepo->find($request->get('messageId')); - - $attachment = (new MessageAttachment()) - ->setFilename($uploadedFile->getFilename()) - ->setMessage($message) - ->setParent($message->getSender()) - ->setCreator($message->getSender()) - ; - - foreach ($message->getReceivers() as $receiver) { - $attachment->addUserLink($receiver->getReceiver()); - } - - $message->addAttachment($attachment); - - $em->persist($attachment); - $repo->addFile($attachment, $uploadedFile); - $em->flush(); - - return $attachment; - } -} diff --git a/src/CoreBundle/Entity/Message.php b/src/CoreBundle/Entity/Message.php index efbbc4bd91..55fe3f879a 100644 --- a/src/CoreBundle/Entity/Message.php +++ b/src/CoreBundle/Entity/Message.php @@ -157,8 +157,14 @@ class Message /** * @var Collection */ - #[Groups(['message:read'])] - #[ORM\OneToMany(mappedBy: 'message', targetEntity: MessageAttachment::class, cascade: ['remove', 'persist'])] + #[Assert\Valid] + #[Groups(['message:read', 'message:write'])] + #[ORM\OneToMany( + mappedBy: 'message', + targetEntity: MessageAttachment::class, + cascade: ['persist'], + orphanRemoval: true, + )] protected Collection $attachments; #[ORM\OneToMany(mappedBy: 'message', targetEntity: MessageFeedback::class, orphanRemoval: true)] @@ -374,10 +380,27 @@ class Message return $this->attachments; } - public function addAttachment(MessageAttachment $attachment): self + 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 { - $this->attachments->add($attachment); - $attachment->setMessage($this); + if ($this->attachments->removeElement($attachment)) { + if ($attachment->getMessage() === $this) { + $attachment->setMessage(null); + } + } return $this; } diff --git a/src/CoreBundle/Entity/MessageAttachment.php b/src/CoreBundle/Entity/MessageAttachment.php index d439d905f0..324ed03a8b 100644 --- a/src/CoreBundle/Entity/MessageAttachment.php +++ b/src/CoreBundle/Entity/MessageAttachment.php @@ -8,9 +8,6 @@ namespace Chamilo\CoreBundle\Entity; use ApiPlatform\Metadata\ApiResource; use ApiPlatform\Metadata\Get; -use ApiPlatform\Metadata\GetCollection; -use ApiPlatform\Metadata\Post; -use Chamilo\CoreBundle\Controller\Api\CreateMessageAttachmentAction; use Chamilo\CoreBundle\Repository\Node\MessageAttachmentRepository; use Doctrine\ORM\Mapping as ORM; use Stringable; @@ -20,38 +17,6 @@ use Symfony\Component\Serializer\Annotation\Groups; types: ['http://schema.org/MediaObject'], operations: [ new Get(), - new GetCollection(), - new Post( - controller: CreateMessageAttachmentAction::class, - openapiContext: [ - 'requestBody' => [ - 'content' => [ - 'multipart/form-data' => [ - 'schema' => [ - 'type' => 'object', - 'properties' => [ - 'file' => [ - 'type' => 'string', - 'format' => 'binary', - ], - 'messageId' => [ - 'type' => 'integer', - ], - ], - ], - ], - ], - ], - ], - security: 'is_granted(\'ROLE_USER\')', - validationContext: [ - 'groups' => [ - 'Default', - 'message_attachment:create', - ], - ], - deserialize: false - ), ], normalizationContext: [ 'groups' => ['message:read'], @@ -68,20 +33,24 @@ class MessageAttachment extends AbstractResource implements ResourceInterface, S #[ORM\Column(name: 'path', type: 'string', length: 255, nullable: false)] protected string $path; - #[Groups(['message:read'])] + + #[Groups(['message:read', 'message:write'])] #[ORM\Column(name: 'comment', type: 'text', nullable: true)] protected ?string $comment = null; #[ORM\Column(name: 'size', type: 'integer', nullable: false)] protected int $size; - #[ORM\ManyToOne(targetEntity: Message::class, cascade: ['persist'], inversedBy: 'attachments')] + #[ORM\ManyToOne(targetEntity: Message::class, inversedBy: 'attachments')] #[ORM\JoinColumn(name: 'message_id', referencedColumnName: 'id', nullable: false)] protected Message $message; #[ORM\Column(name: 'filename', type: 'string', length: 255, nullable: false)] protected string $filename; + #[Groups(['message:write'])] + protected ResourceFile $resourceFileToAttach; + public function __construct() { $this->size = 0; @@ -152,12 +121,12 @@ class MessageAttachment extends AbstractResource implements ResourceInterface, S return $this; } - public function getMessage(): Message + public function getMessage(): ?Message { return $this->message; } - public function setMessage(Message $message): self + public function setMessage(?Message $message): static { $this->message = $message; @@ -188,4 +157,22 @@ class MessageAttachment extends AbstractResource implements ResourceInterface, S { return $this->setFilename($name); } + + public function getResourceFileToAttach(): ResourceFile + { + return $this->resourceFileToAttach; + } + + public function setResourceFileToAttach(ResourceFile $resourceFileToAttach): self + { + $this + ->setFilename($resourceFileToAttach->getOriginalName()) + ->setSize($resourceFileToAttach->getSize()) + ->setPath($resourceFileToAttach->getTitle()) + ; + + $this->resourceFileToAttach = $resourceFileToAttach; + + return $this; + } } diff --git a/src/CoreBundle/State/MessageProcessor.php b/src/CoreBundle/State/MessageProcessor.php index 3c630ef904..1575599310 100644 --- a/src/CoreBundle/State/MessageProcessor.php +++ b/src/CoreBundle/State/MessageProcessor.php @@ -11,14 +11,21 @@ use ApiPlatform\Metadata\Operation; use ApiPlatform\Metadata\Post; use ApiPlatform\State\ProcessorInterface; use Chamilo\CoreBundle\Entity\Message; +use Chamilo\CoreBundle\Entity\MessageAttachment; use Chamilo\CoreBundle\Entity\MessageRelUser; +use Chamilo\CoreBundle\Repository\ResourceNodeRepository; +use Doctrine\ORM\EntityManagerInterface; use Notification; +use Vich\UploaderBundle\Storage\FlysystemStorage; final class MessageProcessor implements ProcessorInterface { public function __construct( private readonly ProcessorInterface $persistProcessor, private readonly ProcessorInterface $removeProcessor, + private readonly FlysystemStorage $storage, + private readonly EntityManagerInterface $entityManager, + private readonly ResourceNodeRepository $resourceNodeRepository, ) {} public function process($data, Operation $operation, array $uriVariables = [], array $context = []) @@ -27,9 +34,20 @@ final class MessageProcessor implements ProcessorInterface return $this->removeProcessor->process($data, $operation, $uriVariables, $context); } + /** @var Message $message */ $message = $this->persistProcessor->process($data, $operation, $uriVariables, $context); - \assert($message instanceof Message); + foreach ($message->getAttachments() as $attachment) { + $attachment->resourceNode->setResourceFile( + $attachment->getResourceFileToAttach() + ); + + foreach ($message->getReceivers() as $receiver) { + $attachment->addUserLink($receiver->getReceiver()); + } + } + + $this->entityManager->flush(); if ($operation instanceof Post) { if (Message::MESSAGE_TYPE_INBOX === $message->getMsgType()) { @@ -52,6 +70,20 @@ final class MessageProcessor implements ProcessorInterface ->getValues() ; + $attachmentList = []; + + /** @var MessageAttachment $messageAttachment */ + foreach ($message->getAttachments() as $messageAttachment) { + $stream = $this->resourceNodeRepository->getResourceNodeFileStream( + $messageAttachment->resourceNode + ); + + $attachmentList[] = [ + 'stream' => $stream, + 'filename' => $messageAttachment->getFilename(), + ]; + } + (new Notification()) ->saveNotification( $message->getId(), @@ -60,6 +92,7 @@ final class MessageProcessor implements ProcessorInterface $message->getTitle(), $message->getContent(), $sender_info, + $attachmentList, ) ; }