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

Change image path by default image when folder doesn't exist #1473

Closed devcut closed 2 years ago

devcut commented 2 years ago

Hello,

In my database, all images has url (ex: /uploads/product/123/123.png) but sometimes the folder and the image doesn't exist in the server.

In this case, I know the server return 404 but I would like to replace the file path by a default image path (ex: replace /uploads/product/123/123.png by /images/default.png)

How it's possible to make that with this bundle ?

parameters:
    liip_imagine.pngquant.binary: "%env(PNGQUANT_BIN)%"

liip_imagine:
    default_image: "images/default.png"
    resolvers:
        default:
            web_path: ~

    loaders:
        default:
            filesystem:
                data_root:
                    - "%kernel.project_dir%/public"
                allow_unresolvable_data_roots: true

    filter_sets:
        cache: ~

        # the name of the "filter set"
        1920:
            filters:
                thumbnail: { size: [1920], mode: outbound }
            post_processors:
                pngquant: { quality: "65-75" }

        900:
            filters:
                thumbnail: { size: [900], mode: outbound }
            post_processors:
                pngquant: { quality: "65-75" }

        600:
            filters:
                thumbnail: { size: [600], mode: outbound }
            post_processors:
                pngquant: { quality: "65-75" }

        300:
            filters:
                thumbnail: { size: [300], mode: outbound }
            post_processors:
                pngquant: { quality: "65-75" }

        150:
            filters:
                thumbnail: { size: [150], mode: outbound }
            post_processors:
                pngquant: { quality: "65-75" }

        75:
            filters:
                thumbnail: { size: [75], mode: outbound }
            post_processors:
                pngquant: { quality: "65-75" }

Thanks

dbu commented 2 years ago

hi @devcut , this functionality is not built in. you have however two possibilities: you could register a custom error controller in symfony and check the request to detect that an image was requested. or you can write a custom data loader that always finds your fallback image regardless of what was requested, and register that as the last loader in the chain.

devcut commented 2 years ago

Yes I did use a custom data loader.

An example for futur dev's who would pass here

services.yaml

imagine.data.loader.ustom:
  class: App\Service\LiipImagine\CustomDataLoader
  arguments:
    - "@liip_imagine"
  tags:
    - { name: "liip_imagine.binary.loader", loader: customDataLoader }

liip_imagine.yaml

filter_sets:
    cache: ~

    # the name of the "filter set"
    1920:
        data_loader: customDataLoader
        filters:
            thumbnail: { size: [1920], mode: outbound }
        post_processors:
            pngquant: { quality: "65-75" }

CustomDataLoader.php

namespace App\Service\LiipImagine;

use Imagine\Image\ImagineInterface;
use Liip\ImagineBundle\Binary\Loader\LoaderInterface;

class CustomDataLoader implements LoaderInterface
{
    public function __construct(private readonly ImagineInterface $imagine, private readonly ChatterInterface $chatter) {}

    public function find($path)
    {
        if (!file_exists($path)) {
            $path = 'images/default.png';
        }

        return $this->imagine->load(file_get_contents($path));
    }
}