liip / LiipImagineBundle

Symfony Bundle to assist in image manipulation using the imagine library
http://liip.ch
MIT License
1.66k stars 378 forks source link

How is possible use LiiImagineBundle for private image files #1503

Open mardon opened 1 year ago

mardon commented 1 year ago

In my Symfony application, user can upload images but images are stored in non public directory, in my case I store this in /var/card-upload. For display images in templateI use this controller method with

<?php

namespace App\Controller;

use App\Entity\Card;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\Routing\Annotation\Route;

class ServePrivateImageController extends AbstractController
{
    /**
     * Returns a private image for card file for display.
     *
     * @Route("/serve-private-image/{id}", name="serve_private_image", methods="GET")
     * @param Card $card
     * @return BinaryFileResponse
     */
    #[Route(path: '/serve-private-image/{id}', name: 'serve_private_image')]
    public function privateImageServe(Card $card): BinaryFileResponse
    {
        return $this->fileServe($card->getImage());
    }
    /**
     * Returns a private file for display.
     *
     * @param string $path
     * @return BinaryFileResponse
     */
    private function fileServe(string $path): BinaryFileResponse
    {
        $absolutePath = $this->getParameter('card_directory') . '/' . $path;

        return new BinaryFileResponse($absolutePath);
    }
}

Now I dont how I can this BinaryFileResponse filter by using LiipImagineBundle. It is posiible?

dbu commented 1 year ago

i don't see the access control in this code. if all you need is storing the source images outside of the web root, you can configure a different data root: https://github.com/liip/LiipImagineBundle#data-roots

if you have additional logic to verify access, you could inject the filters as service into your controller, as illustrated in https://github.com/liip/LiipImagineBundle#use-as-a-service

mardon commented 1 year ago

I am trying use this code but this is no ok

<?php

namespace App\Service;

use Liip\ImagineBundle\Model\Binary;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\String\Slugger\SluggerInterface;

class ImageUploader
{
    private $targetDirectory;
    private SluggerInterface $slugger;
    private $container;

    public function __construct($targetDirectory, SluggerInterface $slugger,Container $container)
    {
        $this->targetDirectory = $targetDirectory;
        $this->slugger = $slugger;
        $this->container = $container;
    }

    public function upload(UploadedFile $file): string
    {
        $originalFilename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
        $safeFilename = $this->slugger->slug($originalFilename);
        $fileName = $safeFilename.'-'.uniqid().'.'.$file->guessExtension();

        try {
            $file->move($this->getTargetDirectory(), $fileName);
        } catch (FileException $e) {
            // ... handle exception if something happens during file upload
        }

                $fileName = md5(uniqid()) . '.' . $file->guessExtension();

                $contents = file_get_contents($file);

                $binary = new Binary(
                    $contents,
                    $file->getMimeType(),
                    $file->guessExtension()
                );

                $filterManager = $this->container->get('liip_imagine.filter.manager');    // the filter manager service
                $response = $filterManager->applyFilter($binary, 'my_thumb');

                $thumb = $response->getContent();                               // get the image from the response

                $f = fopen($this->targetDirectory .'/images_dir/' . $fileName, 'w');                                        // create thumbnail file
                fwrite($f, $thumb);                                             // write the thumbnail
                fclose($f);

        return $fileName;
    }

    public function getTargetDirectory()
    {
        return $this->targetDirectory;
    }
}
dbu commented 1 year ago

the github issues are intended to report bugs with the bundle. i am okay to help a bit more than that, but you need to be more specific. at which point do you get an error and what does the error say? when you look at it, it might already give you hints what you can do to solve the problem.

note that the intended usage pattern with LiipImagineBundle is to just store the source image file and then configure the filter when requesting the image. if you do that, you need a lot less code in your controller, and uploading the image will not be slowed down by scaling the image to all formats you need.