Contao-Camp 2024
Ergebnis 1 bis 4 von 4

Thema: Service überschreiben (contao.image.resizer)

  1. #1
    Contao-Nutzer
    Registriert seit
    21.08.2018.
    Beiträge
    8

    Standard Service überschreiben (contao.image.resizer)

    Hallo,

    ich versuche contao.image.resizer - Service zu überschreiben. (um Bilder nach dem resizen zu komprimieren)

    Ich gehe wie folgt vor:
    Im eigenen Bundle überschreibe ich den contao.image.resize-Service.

    config/services.yml
    Code:
    services:
        contao.image.resizer:
            class: Amahnert\CoreBundle\Image\ExtendedLegacyResizer
            arguments:
                - '%contao.image.target_dir%'
                - '@contao.image.resize_calculator'
                - '@filesystem'
                - '@contao.image.deferred_image_storage'
            public: true

    classes/ExtendedLegacyResizer.php
    Code:
    <?php
    
    namespace Amahnert\CoreBundle\Image;
    
    use Contao\CoreBundle\Image\LegacyResizer;
    use Contao\Image\ImageInterface;
    use Contao\Image\ResizeConfiguration;
    use Contao\Image\ResizeOptions;
    
    class ExtendedLegacyResizer extends LegacyResizer
    {
    
        public function resize(ImageInterface $image, ResizeConfiguration $config, ResizeOptions $options): ImageInterface
        {
            return parent::resize($image, $config, $options);
        }
    
    }
    und jetzt nach aufrufen einer beliebigen Seite bekomme ich den Fehler: "Call to a member function initialize() on null".
    ( in vendor/contao/core-bundle/src/Image/LegacyResizer.php (line 47) )

    Was mache ich falsch ?
    Komme leider seit 2 Tagen nicht weiter.

  2. #2
    Contao-Urgestein
    Registriert seit
    29.10.2009.
    Ort
    Magdeburg
    Beiträge
    2.020
    Partner-ID
    626
    User beschenken
    Wunschliste

    Standard

    Da du einen Service eines anderen Bundles überschreibst, greift vermutlich das automatische Injecten des Contao-Frameworks nicht mehr (Symfony/Contao geht davon aus, dass es schon erledigt wurde).

    Grundsätzlich ist das extenden hier nicht die saubere Lösung, vielmehr solltest du den Service dekorieren. Dies unterstützt der Symfony-Container auch: https://symfony.com/doc/current/serv...ecoration.html. Das sieht erstmal nach mehr Code aus, hat aber den entscheidenden Vorteil, dass dein Code völlig unabhängig ist von dem Resizer, den Contao (zukünftig) verwendet.


    config/service.yml
    Code:
    amehnert.image.resizer:
      decorates: contao.image.resizer
      arguments:
        - @amehnert.image.resizer.inner
      public: true

    PHP-Code:
    class CompressingImageResizer implements DeferredImageInterface
    {
        private 
    DeferredImageInterface $resizer;
        
        public function 
    __construct(DeferredImageInterface $resizer)
        {
            
    $this->resizer $resizer;
        }

        public function 
    getImagine(): ImagineInterface
        
    {
            return 
    $this->resizer->getImagine();
        }

        public function 
    getPath(): string
        
    {
            return 
    $this->resizer->getPath();
        }

        public function 
    getUrl(string $rootDirstring $prefix ''): string
        
    {
            return 
    $this->resizer->getUrl($rootDir$prefix);
        }

        public function 
    getDimensions(): ImageDimensions
        
    {
            return 
    $this->resizer->getDimensions();
        }

        public function 
    getImportantPart(): ImportantPart
        
    {
            return 
    $this->resizer->getImportantPart();
        }

        public function 
    setImportantPart(ImportantPart $importantPart null): ImageInterface
        
    {
            return 
    $this->resizer->setImportantPart($importantPart);
        }


  3. #3
    Contao-Nutzer
    Registriert seit
    21.08.2018.
    Beiträge
    8

    Standard

    Vielen Dank !
    Es funktioniert. Ich habe meinen Fehler verstanden :thumbs-up:

  4. #4
    Contao-Nutzer Avatar von rory_ch
    Registriert seit
    11.05.2016.
    Ort
    Schweiz
    Beiträge
    119

    Frage

    Hallo zusammen

    Ich würde gerne das gleiche machen und den contao.image.resizer Service dekorieren.
    Aktuell habe ich folgendes:

    services.yml
    PHP-Code:
    services:
        
    example.image.resizer:
            class: 
    Vendor\ExampleBundle\Classes\ImageResizer
            decorates
    contao.image.resizer
            arguments
    :
                - 
    '@example.image.resizer.inner'
            
    public: true 
    Classes\ImageResize.php
    PHP-Code:
    <?php

    namespace Vendor\ExampleBundle\Classes;

    use 
    Contao\Image\DeferredImageInterface;
    use 
    Contao\CoreBundle\Image\LegacyResizer;
    use 
    Contao\Image\ImageInterface;
    use 
    Contao\Image\ResizeConfiguration;
    use 
    Contao\Image\ResizeOptions;
    use 
    Imagine\Image\ImagineInterface;
    use 
    Contao\Image\ImageDimensions;
    use 
    Contao\Image\ImportantPart;

    class 
    ImageResizer implements DeferredImageInterface
    {
        private 
    DeferredImageInterface $resizer;
        
        public function 
    __construct(DeferredImageInterface $resizer)
        {
            
    $this->resizer $resizer;
        }

        public function 
    getImagine(): ImagineInterface
        
    {
            return 
    $this->resizer->getImagine();
        }

        public function 
    getPath(): string
        
    {
            return 
    $this->resizer->getPath();
        }

        public function 
    getUrl(string $rootDirstring $prefix ''): string
        
    {
            return 
    $this->resizer->getUrl($rootDir$prefix);
        }

        public function 
    getDimensions(): ImageDimensions
        
    {
            return 
    $this->resizer->getDimensions();
        }

        public function 
    getImportantPart(): ImportantPart
        
    {
            return 
    $this->resizer->getImportantPart();
        }

        public function 
    setImportantPart(ImportantPart $importantPart null): ImageInterface
        
    {
            return 
    $this->resizer->setImportantPart($importantPart);
        }
    }
    Dabei erhalte ich beim composer install / Cache leeren keine Fehlemeldung.
    Aber beim öffnen des Backends, erscheint sofort diese Meldung:
    Code:
    Argument 1 passed to Vendor\ExampleBundle\Classes\ImageResizer::__construct() must implement interface Contao\Image\DeferredImageInterface, instance of Contao\CoreBundle\Image\LegacyResizer given, called in /home/var/cache/dev/ContainerH9ro3X5/getVendor_Image_ResizerService.php on line 22
    Wenn ich nun die "DeferredImageInterface" Klasse bei der _construct Methode und dem typed Property entferne, erhalte ich einfach das nächste Problem:
    Code:
    Argument 1 passed to Contao\CoreBundle\Image\ImageFactory::__construct() must implement interface Contao\Image\ResizerInterface, instance of Vendor\ExampleBundle\Classes\ImageResizer given, called in /home/var/cache/dev/ContainerH9ro3X5/getContao_Image_ImageFactoryService.php on line 17
    Mache ich was grundsätzliches Falsch?
    Kenne mich mit dem dekorieren leider nicht aus.

    Danke im Voraus

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Lesezeichen

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •