Reputation: 2379
I am working on a Symfony application where users can crop images with. After someone has downloaded the cropped image I want the application to remove it from the server.
I currently have this controller action:
/**
* @Route(
* "/download/{crop_id}",
* name="download_cropped",
* options={"expose"=true}
* )
*
* @ParamConverter(
* "crop",
* class="WebwijsCropperBundle:Crop",
* options={"id" = "crop_id"}
* )
*
*/
public function downloadAction(Crop $crop)
{
$dir = $this->container->getParameter('image.cropped.dir');
return new BinaryFileResponse($dir . '/' . $crop->getCroppedFile());
}
I created this EventListener where I want to remove the image after the response is sent. This Listener will be triggered after every response.
So how do I get the information that I need to know if the response comes from the correct controller action. And how can I get the crop_id parameter so I know which file to remove?
class FileRemovalListener
{
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function onKernelTerminate(PostResponseEvent $event)
{
$response = $event->getResponse();
$request = $event->getRequest();
// what do i have to do here to know
// from which controller action the response comes?
}
}
This is the service definition in services.yml
WebwijsCropperBundle\EventListener\FileRemovalListener:
tags:
- { name: kernel.event_listener, event: kernel.terminate, method: onKernelTerminate }
Upvotes: 7
Views: 5089
Reputation: 1
Just a precision about the function "deleteFileAfterSend(bool $bool)". As symfony documentation said "(...)note that this will not work when the X-Sendfile header is set.". See : https://symfony.com/doc/current/components/http_foundation.html#serving-files. Then you can do something like this for delete a file after response sending :
$zipName = 'downloads/' . uniqid().'.zip';
$response = new StreamedResponse();
$response->headers->set(...);
return $response->setCallBack(function () use($zipName) {
readfile($zipName);
$filesystem = new Filesystem();
try {
$filesystem->remove($zipName);
} catch (IOExceptionInterface $exception) {
echo "Cannot delete the zip file : ". $zipName;
}
});
Upvotes: 0
Reputation: 428
Use
deleteFileAfterSend(bool $shouldDelete)
If this is set to true, the file will be unlinked after the request is sent. Note: If the X-Sendfile header is used, the deleteFileAfterSend setting will not be used.
Upvotes: 1
Reputation: 974
If you only want to remove the file, try this:
public function downloadAction(Crop $crop)
{
$dir = $this->container->getParameter('image.cropped.dir');
$response = new BinaryFileResponse($dir . '/' . $crop->getCroppedFile());
$response->deleteFileAfterSend(true);
return $response;
}
Upvotes: 23