vendor/liip/imagine-bundle/Service/FilterService.php line 222

  1. <?php
  2. /*
  3.  * This file is part of the `liip/LiipImagineBundle` project.
  4.  *
  5.  * (c) https://github.com/liip/LiipImagineBundle/graphs/contributors
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE.md
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Liip\ImagineBundle\Service;
  11. use Liip\ImagineBundle\Binary\BinaryInterface;
  12. use Liip\ImagineBundle\Exception\Imagine\Filter\NonExistingFilterException;
  13. use Liip\ImagineBundle\Imagine\Cache\CacheManager;
  14. use Liip\ImagineBundle\Imagine\Data\DataManager;
  15. use Liip\ImagineBundle\Imagine\Filter\FilterManager;
  16. use Psr\Log\LoggerInterface;
  17. use Psr\Log\NullLogger;
  18. class FilterService
  19. {
  20.     /**
  21.      * @var DataManager
  22.      */
  23.     private $dataManager;
  24.     /**
  25.      * @var FilterManager
  26.      */
  27.     private $filterManager;
  28.     /**
  29.      * @var CacheManager
  30.      */
  31.     private $cacheManager;
  32.     /**
  33.      * @var LoggerInterface
  34.      */
  35.     private $logger;
  36.     /**
  37.      * @var bool
  38.      */
  39.     private $webpGenerate;
  40.     /**
  41.      * @var mixed[]
  42.      */
  43.     private $webpOptions;
  44.     public function __construct(
  45.         DataManager $dataManager,
  46.         FilterManager $filterManager,
  47.         CacheManager $cacheManager,
  48.         bool $webpGenerate,
  49.         array $webpOptions,
  50.         ?LoggerInterface $logger null
  51.     ) {
  52.         $this->dataManager $dataManager;
  53.         $this->filterManager $filterManager;
  54.         $this->cacheManager $cacheManager;
  55.         $this->webpGenerate $webpGenerate;
  56.         $this->webpOptions $webpOptions;
  57.         $this->logger $logger ?: new NullLogger();
  58.     }
  59.     /**
  60.      * @param string $path
  61.      * @param string $filter
  62.      *
  63.      * @return bool Returns true if we removed at least one cached image
  64.      */
  65.     public function bustCache($path$filter)
  66.     {
  67.         $busted false;
  68.         foreach ($this->buildFilterPathContainers($path) as $filterPathContainer) {
  69.             if ($this->cacheManager->isStored($filterPathContainer->getTarget(), $filter)) {
  70.                 $this->cacheManager->remove($filterPathContainer->getTarget(), $filter);
  71.                 $busted true;
  72.             }
  73.         }
  74.         return $busted;
  75.     }
  76.     /**
  77.      * @param bool $forced Force warm up cache
  78.      *
  79.      * @return bool Returns true if the cache is warmed up
  80.      */
  81.     public function warmUpCache(
  82.         string $path,
  83.         string $filter,
  84.         ?string $resolver null,
  85.         bool $forced false
  86.     ): bool {
  87.         $warmedUp false;
  88.         foreach ($this->buildFilterPathContainers($path) as $filterPathContainer) {
  89.             if ($this->warmUpCacheFilterPathContainer($filterPathContainer$filter$resolver$forced)) {
  90.                 $warmedUp true;
  91.             }
  92.         }
  93.         return $warmedUp;
  94.     }
  95.     /**
  96.      * @param string      $path
  97.      * @param string      $filter
  98.      * @param string|null $resolver
  99.      *
  100.      * @return string
  101.      */
  102.     public function getUrlOfFilteredImage($path$filter$resolver nullbool $webpSupported false)
  103.     {
  104.         foreach ($this->buildFilterPathContainers($path) as $filterPathContainer) {
  105.             $this->warmUpCacheFilterPathContainer($filterPathContainer$filter$resolver);
  106.         }
  107.         return $this->resolveFilterPathContainer(new FilterPathContainer($path), $filter$resolver$webpSupported);
  108.     }
  109.     /**
  110.      * @param string      $path
  111.      * @param string      $filter
  112.      * @param string|null $resolver
  113.      *
  114.      * @return string
  115.      */
  116.     public function getUrlOfFilteredImageWithRuntimeFilters(
  117.         $path,
  118.         $filter,
  119.         array $runtimeFilters = [],
  120.         $resolver null,
  121.         bool $webpSupported false
  122.     ) {
  123.         $runtimePath $this->cacheManager->getRuntimePath($path$runtimeFilters);
  124.         $runtimeOptions = [
  125.             'filters' => $runtimeFilters,
  126.         ];
  127.         foreach ($this->buildFilterPathContainers($path$runtimePath$runtimeOptions) as $filterPathContainer) {
  128.             $this->warmUpCacheFilterPathContainer($filterPathContainer$filter$resolver);
  129.         }
  130.         return $this->resolveFilterPathContainer(
  131.             new FilterPathContainer($path$runtimePath$runtimeOptions),
  132.             $filter,
  133.             $resolver,
  134.             $webpSupported
  135.         );
  136.     }
  137.     /**
  138.      * @param mixed[] $options
  139.      *
  140.      * @return FilterPathContainer[]
  141.      */
  142.     private function buildFilterPathContainers(string $sourcestring $target '', array $options = []): array
  143.     {
  144.         $basePathContainer = new FilterPathContainer($source$target$options);
  145.         $filterPathContainers = [$basePathContainer];
  146.         if ($this->webpGenerate) {
  147.             $filterPathContainers[] = $basePathContainer->createWebp($this->webpOptions);
  148.         }
  149.         return $filterPathContainers;
  150.     }
  151.     private function resolveFilterPathContainer(
  152.         FilterPathContainer $filterPathContainer,
  153.         string $filter,
  154.         ?string $resolver null,
  155.         bool $webpSupported false
  156.     ): string {
  157.         $path $filterPathContainer->getTarget();
  158.         if ($this->webpGenerate && $webpSupported) {
  159.             $path $filterPathContainer->createWebp($this->webpOptions)->getTarget();
  160.         }
  161.         return $this->cacheManager->resolve($path$filter$resolver);
  162.     }
  163.     /**
  164.      * @param bool $forced Force warm up cache
  165.      *
  166.      * @return bool Returns true if the cache is warmed up
  167.      */
  168.     private function warmUpCacheFilterPathContainer(
  169.         FilterPathContainer $filterPathContainer,
  170.         string $filter,
  171.         ?string $resolver null,
  172.         bool $forced false
  173.     ): bool {
  174.         if ($forced || !$this->cacheManager->isStored($filterPathContainer->getTarget(), $filter$resolver)) {
  175.             $this->cacheManager->store(
  176.                 $this->createFilteredBinary($filterPathContainer$filter),
  177.                 $filterPathContainer->getTarget(),
  178.                 $filter,
  179.                 $resolver
  180.             );
  181.             return true;
  182.         }
  183.         return false;
  184.     }
  185.     /**
  186.      * @throws NonExistingFilterException
  187.      */
  188.     private function createFilteredBinary(FilterPathContainer $filterPathContainerstring $filter): BinaryInterface
  189.     {
  190.         $binary $this->dataManager->find($filter$filterPathContainer->getSource());
  191.         try {
  192.             return $this->filterManager->applyFilter($binary$filter$filterPathContainer->getOptions());
  193.         } catch (NonExistingFilterException $e) {
  194.             $this->logger->debug(sprintf(
  195.                 'Could not locate filter "%s" for path "%s". Message was "%s"',
  196.                 $filter,
  197.                 $filterPathContainer->getSource(),
  198.                 $e->getMessage()
  199.             ));
  200.             throw $e;
  201.         }
  202.     }
  203. }