Internal: API: Message: Allow to add attachments by create message endpoint - refs BT#21648

pull/5544/head
Angel Fernando Quiroz Campos 6 months ago
parent faf578c661
commit bf69c78e73
  1. 55
      src/CoreBundle/Controller/Api/CreateMessageAttachmentAction.php
  2. 31
      src/CoreBundle/Entity/Message.php
  3. 65
      src/CoreBundle/Entity/MessageAttachment.php
  4. 35
      src/CoreBundle/State/MessageProcessor.php

@ -1,55 +0,0 @@
<?php
/* For licensing terms, see /license.txt */
declare(strict_types=1);
namespace Chamilo\CoreBundle\Controller\Api;
use Chamilo\CoreBundle\Entity\Message;
use Chamilo\CoreBundle\Entity\MessageAttachment;
use Chamilo\CoreBundle\Repository\Node\MessageAttachmentRepository;
use Doctrine\ORM\EntityManager;
use Exception;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class CreateMessageAttachmentAction extends BaseResourceFileAction
{
/**
* @throws Exception
*/
public function __invoke(Request $request, MessageAttachmentRepository $repo, EntityManager $em): MessageAttachment
{
/** @var UploadedFile|null $uploadedFile */
$uploadedFile = $request->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;
}
}

@ -157,8 +157,14 @@ class Message
/**
* @var Collection<int, MessageAttachment>
*/
#[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);
$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;
}

@ -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;
}
}

@ -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,
)
;
}

Loading…
Cancel
Save