Skip to content

Latest commit

 

History

History
121 lines (85 loc) · 2.88 KB

remove_files_asynchronously.md

File metadata and controls

121 lines (85 loc) · 2.88 KB

Remove files asynchronously

To remove files asynchronously, ensure you have the Messenger installed. The messenger allows you to run tasks asynchronously, in our example the file removal.

Note:

We recommend you to create a message and message handler for each mapping. Use getMappingName to send the right message in the event subscriber.

Important:

Do not transfer the whole object and mapping or the whole event in the message. The UploadedFile which will be stored in the object while uploading is not serializable.

Create a message containing the filename of the file to be deleted.

<?php

namespace App\Message;

class RemoveProductImageMessage
{
    private string $filename;

    public function __construct(string $filename)
    {
        $this->filename = $filename;
    }

    public function getFilename(): string
    {
        return $this->filename;
    }

}

Create a message handler that will do the actual removal.

<?php

namespace App\MessageHandler;

use App\Message\RemoveProductImageMessage;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;

class RemoveProductImageMessageHandler implements MessageHandlerInterface
{
    public function __invoke(RemoveProductImageMessage $message): void
    {
        $filename = $message->getFilename();

        // delete your file according to your mapping configuration
    }

}

Create an event subscriber that will cancel the remove request and dispatch a remove message.

<?php

namespace App\EventSubscriber;

use App\Message\RemoveProductImageMessage;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\MessageBusInterface;
use Vich\UploaderBundle\Event\Event;
use Vich\UploaderBundle\Event\Events;

class RemoveFileEventSubscriber implements EventSubscriberInterface
{

    private $messageBus;

    public function __construct(MessageBusInterface $messageBus)
    {
        $this->messageBus = $messageBus;
    }

    public static function getSubscribedEvents(): array
    {
        return [
            Events::PRE_REMOVE => ['onPreRemove'],
        ];
    }

    public function onPreRemove(Event $event): void
    {
        $mapping = $event->getMapping();
        $mappingName = $mapping->getMappingName();

        if ('products' === $mappingName) {
            $this->dispatch(RemoveProductImageMessage::class, $event);
        }
    }

    private function dispatch(string $messageClass, Event $event): void
    {
        $event->cancel();

        $object = $event->getObject();

        $mapping = $event->getMapping();
        $filename = $mapping->getFileName($object);

        $message = new $messageClass($filename);
        $this->messageBus->dispatch($message);
    }

}

That was it!

Check out the docs for information on how to use the bundle! Return to the index.