vendor/contao/core-bundle/src/Image/LegacyResizer.php line 98

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4.  * This file is part of Contao.
  5.  *
  6.  * (c) Leo Feyer
  7.  *
  8.  * @license LGPL-3.0-or-later
  9.  */
  10. namespace Contao\CoreBundle\Image;
  11. use Contao\Config;
  12. use Contao\CoreBundle\Framework\FrameworkAwareInterface;
  13. use Contao\CoreBundle\Framework\FrameworkAwareTrait;
  14. use Contao\File;
  15. use Contao\Image as LegacyImage;
  16. use Contao\Image\DeferredImageInterface;
  17. use Contao\Image\DeferredResizer as ImageResizer;
  18. use Contao\Image\ImageInterface;
  19. use Contao\Image\ResizeConfiguration;
  20. use Contao\Image\ResizeCoordinates;
  21. use Contao\Image\ResizeOptions;
  22. use Contao\System;
  23. use Imagine\Exception\RuntimeException as ImagineRuntimeException;
  24. use Imagine\Gd\Imagine as GdImagine;
  25. use Imagine\Image\Box;
  26. use Imagine\Image\ImagineInterface;
  27. use Symfony\Component\Filesystem\Path;
  28. /**
  29.  * Resizes image objects and executes the legacy hooks.
  30.  */
  31. class LegacyResizer extends ImageResizer implements FrameworkAwareInterface
  32. {
  33.     use FrameworkAwareTrait;
  34.     private ?LegacyImage $legacyImage null;
  35.     public function resize(ImageInterface $imageResizeConfiguration $configResizeOptions $options): ImageInterface
  36.     {
  37.         $this->framework->initialize(true);
  38.         $projectDir = (string) System::getContainer()->getParameter('kernel.project_dir');
  39.         if ($this->hasExecuteResizeHook() || $this->hasGetImageHook()) {
  40.             trigger_deprecation('contao/core-bundle''4.0''Using the "executeResize" and "getImage" hooks has been deprecated and will no longer work in Contao 5.0. Replace the "contao.image.legacy_resizer" service instead.');
  41.             $this->legacyImage null;
  42.             $legacyPath $image->getPath();
  43.             if (Path::isBasePath($projectDir$legacyPath)) {
  44.                 $legacyPath Path::makeRelative($legacyPath$projectDir);
  45.                 $this->legacyImage = new LegacyImage(new File($legacyPath));
  46.                 $this->legacyImage->setTargetWidth($config->getWidth());
  47.                 $this->legacyImage->setTargetHeight($config->getHeight());
  48.                 $this->legacyImage->setResizeMode($config->getMode());
  49.                 $this->legacyImage->setZoomLevel($config->getZoomLevel());
  50.                 if (($targetPath $options->getTargetPath()) && Path::isBasePath($projectDir$targetPath)) {
  51.                     $this->legacyImage->setTargetPath(Path::makeRelative($targetPath$projectDir));
  52.                 }
  53.                 $importantPart $image->getImportantPart();
  54.                 $imageSize $image->getDimensions()->getSize();
  55.                 $this->legacyImage->setImportantPart([
  56.                     'x' => $importantPart->getX() * $imageSize->getWidth(),
  57.                     'y' => $importantPart->getY() * $imageSize->getHeight(),
  58.                     'width' => $importantPart->getWidth() * $imageSize->getWidth(),
  59.                     'height' => $importantPart->getHeight() * $imageSize->getHeight(),
  60.                 ]);
  61.             }
  62.         }
  63.         if ($this->legacyImage && $this->hasExecuteResizeHook()) {
  64.             foreach ($GLOBALS['TL_HOOKS']['executeResize'] as $callback) {
  65.                 $return System::importStatic($callback[0])->{$callback[1]}($this->legacyImage);
  66.                 if (\is_string($return)) {
  67.                     return $this->createImage($imagePath::join($projectDir$return));
  68.                 }
  69.             }
  70.         }
  71.         try {
  72.             return parent::resize($image$config$options);
  73.         } catch (ImagineRuntimeException $exception) {
  74.             throw $this->enhanceImagineException($exception$image);
  75.         }
  76.     }
  77.     public function resizeDeferredImage(DeferredImageInterface $imagebool $blocking true): ?ImageInterface
  78.     {
  79.         try {
  80.             return parent::resizeDeferredImage($image$blocking);
  81.         } catch (ImagineRuntimeException $exception) {
  82.             throw $this->enhanceImagineException($exception$image);
  83.         }
  84.     }
  85.     protected function executeResize(ImageInterface $imageResizeCoordinates $coordinatesstring $pathResizeOptions $options): ImageInterface
  86.     {
  87.         if ($this->legacyImage && $this->hasGetImageHook()) {
  88.             $projectDir System::getContainer()->getParameter('kernel.project_dir');
  89.             foreach ($GLOBALS['TL_HOOKS']['getImage'] as $callback) {
  90.                 $return System::importStatic($callback[0])->{$callback[1]}(
  91.                     $this->legacyImage->getOriginalPath(),
  92.                     $this->legacyImage->getTargetWidth(),
  93.                     $this->legacyImage->getTargetHeight(),
  94.                     $this->legacyImage->getResizeMode(),
  95.                     $this->legacyImage->getCacheName(),
  96.                     new File($this->legacyImage->getOriginalPath()),
  97.                     $this->legacyImage->getTargetPath(),
  98.                     $this->legacyImage
  99.                 );
  100.                 if (\is_string($return)) {
  101.                     return $this->createImage($imagePath::join($projectDir$return));
  102.                 }
  103.             }
  104.         }
  105.         if ($image->getImagine() instanceof GdImagine) {
  106.             $dimensions $image->getDimensions();
  107.             $config $this->framework->getAdapter(Config::class);
  108.             $gdMaxImgWidth $config->get('gdMaxImgWidth');
  109.             $gdMaxImgHeight $config->get('gdMaxImgHeight');
  110.             // Return the path to the original image if it cannot be handled
  111.             if (
  112.                 $dimensions->getSize()->getWidth() > $gdMaxImgWidth
  113.                 || $dimensions->getSize()->getHeight() > $gdMaxImgHeight
  114.                 || $coordinates->getSize()->getWidth() > $gdMaxImgWidth
  115.                 || $coordinates->getSize()->getHeight() > $gdMaxImgHeight
  116.             ) {
  117.                 return $this->createImage($image$image->getPath());
  118.             }
  119.         }
  120.         return parent::executeResize($image$coordinates$path$options);
  121.     }
  122.     private function hasExecuteResizeHook(): bool
  123.     {
  124.         return !empty($GLOBALS['TL_HOOKS']['executeResize']) && \is_array($GLOBALS['TL_HOOKS']['executeResize']);
  125.     }
  126.     private function hasGetImageHook(): bool
  127.     {
  128.         return !empty($GLOBALS['TL_HOOKS']['getImage']) && \is_array($GLOBALS['TL_HOOKS']['getImage']);
  129.     }
  130.     private function enhanceImagineException(ImagineRuntimeException $exceptionImageInterface $image): \Throwable
  131.     {
  132.         $format Path::getExtension($image->getPath(), true);
  133.         if (!$this->formatIsSupported($format$image->getImagine())) {
  134.             return new \RuntimeException(sprintf('Image format "%s" is not supported in %s on this environment. Consider removing this format from contao.image.valid_extensions or switch the contao.image.imagine_service to an implementation that supports it.'$format, \get_class($image->getImagine())), $exception->getCode(), $exception);
  135.         }
  136.         return $exception;
  137.     }
  138.     private function formatIsSupported(string $formatImagineInterface $imagine): bool
  139.     {
  140.         if ('' === $format) {
  141.             return false;
  142.         }
  143.         try {
  144.             $imagine->create(new Box(11))->get($format);
  145.         } catch (\Throwable $e) {
  146.             return false;
  147.         }
  148.         return true;
  149.     }
  150. }