Skip to content

Commit

Permalink
Generate WebP in liip:imagine:cache:resolve CLI command and async res…
Browse files Browse the repository at this point in the history
…olve cache messages (#1347)
  • Loading branch information
peter-gribanov authored Oct 16, 2021
1 parent 7282ab2 commit 018394c
Show file tree
Hide file tree
Showing 9 changed files with 1,168 additions and 58 deletions.
5 changes: 2 additions & 3 deletions Async/ResolveCacheProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,9 @@ public function process(Message $psrMessage, Context $psrContext)
$filters = $message->getFilters() ?: array_keys($this->filterManager->getFilterConfiguration()->all());
$path = $message->getPath();
$results = [];

foreach ($filters as $filter) {
if ($message->isForce()) {
$this->filterService->bustCache($path, $filter);
}
$this->filterService->warmUpCache($path, $filter, null, $message->isForce());

$results[$filter] = $this->filterService->getUrlOfFilteredImage($path, $filter);
}
Expand Down
19 changes: 13 additions & 6 deletions Command/RemoveCacheCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use Liip\ImagineBundle\Imagine\Filter\FilterManager;
use Liip\ImagineBundle\Service\FilterService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
Expand All @@ -22,14 +23,21 @@
class RemoveCacheCommand extends Command
{
use CacheCommandTrait;

protected static $defaultName = 'liip:imagine:cache:remove';

public function __construct(CacheManager $cacheManager, FilterManager $filterManager)
/**
* @var FilterService
*/
private $filterService;

public function __construct(CacheManager $cacheManager, FilterManager $filterManager, FilterService $filterService)
{
parent::__construct();

$this->cacheManager = $cacheManager;
$this->filterManager = $filterManager;
$this->filterService = $filterService;
}

protected function configure(): void
Expand Down Expand Up @@ -79,9 +87,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
if (empty($images)) {
$this->cacheManager->remove(null, $filters);
} else {
foreach ($images as $i) {
foreach ($filters as $f) {
$this->runCacheImageRemove($i, $f);
foreach ($images as $image) {
foreach ($filters as $filter) {
$this->runCacheImageRemove($image, $filter);
}
}
}
Expand All @@ -99,8 +107,7 @@ private function runCacheImageRemove(string $image, string $filter): void

$this->io->group($image, $filter, 'blue');

if ($this->cacheManager->isStored($image, $filter)) {
$this->cacheManager->remove($image, $filter);
if ($this->filterService->bustCache($image, $filter)) {
$this->io->status('removed', 'green');
} else {
$this->io->status('skipped', 'yellow');
Expand Down
20 changes: 10 additions & 10 deletions Command/ResolveCacheCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
namespace Liip\ImagineBundle\Command;

use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use Liip\ImagineBundle\Imagine\Data\DataManager;
use Liip\ImagineBundle\Imagine\Filter\FilterManager;
use Liip\ImagineBundle\Service\FilterService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
Expand All @@ -23,20 +23,21 @@
class ResolveCacheCommand extends Command
{
use CacheCommandTrait;

protected static $defaultName = 'liip:imagine:cache:resolve';

/**
* @var DataManager
* @var FilterService
*/
private $dataManager;
private $filterService;

public function __construct(DataManager $dataManager, CacheManager $cacheManager, FilterManager $filterManager)
public function __construct(CacheManager $cacheManager, FilterManager $filterManager, FilterService $filterService)
{
parent::__construct();

$this->dataManager = $dataManager;
$this->cacheManager = $cacheManager;
$this->filterManager = $filterManager;
$this->filterService = $filterService;
}

protected function configure(): void
Expand Down Expand Up @@ -90,9 +91,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$forced = $input->getOption('force');
[$images, $filters] = $this->resolveInputFiltersAndPaths($input);

foreach ($images as $i) {
foreach ($filters as $f) {
$this->runCacheImageResolve($i, $f, $forced);
foreach ($images as $image) {
foreach ($filters as $filter) {
$this->runCacheImageResolve($image, $filter, $forced);
}
}

Expand All @@ -110,8 +111,7 @@ private function runCacheImageResolve(string $image, string $filter, bool $force
$this->io->group($image, $filter, 'blue');

try {
if ($forced || !$this->cacheManager->isStored($image, $filter)) {
$this->cacheManager->store($this->filterManager->applyFilter($this->dataManager->find($filter, $image), $filter), $image, $filter);
if ($this->filterService->warmUpCache($image, $filter, null, $forced)) {
$this->io->status('resolved', 'green');
} else {
$this->io->status('cached', 'white');
Expand Down
4 changes: 1 addition & 3 deletions Message/Handler/WarmupCacheHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,7 @@ public function __invoke(WarmupCache $message): void
$path = $message->getPath();

foreach ($filters as $filter) {
if ($message->isForce()) {
$this->filterService->bustCache($path, $filter);
}
$this->filterService->warmUpCache($path, $filter, null, $message->isForce());

$this->filterService->getUrlOfFilteredImage($path, $filter);
}
Expand Down
3 changes: 2 additions & 1 deletion Resources/config/commands.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
<service id="liip_imagine.command.cache_remove" class="Liip\ImagineBundle\Command\RemoveCacheCommand">
<argument type="service" id="liip_imagine.cache.manager" />
<argument type="service" id="liip_imagine.filter.manager" />
<argument type="service" id="liip_imagine.service.filter" />
<tag name="console.command" command="liip:imagine:cache:remove" alias="imagine:del" />
</service>

<service id="liip_imagine.command.cache_resolve" class="Liip\ImagineBundle\Command\ResolveCacheCommand">
<argument type="service" id="liip_imagine.data.manager" />
<argument type="service" id="liip_imagine.cache.manager" />
<argument type="service" id="liip_imagine.filter.manager" />
<argument type="service" id="liip_imagine.service.filter" />
<tag name="console.command" command="liip:imagine:cache:resolve" alias="imagine:get" />
</service>

Expand Down
124 changes: 92 additions & 32 deletions Service/FilterService.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class FilterService
private $webpGenerate;

/**
* @var array
* @var mixed[]
*/
private $webpOptions;

Expand All @@ -70,21 +70,44 @@ public function __construct(
/**
* @param string $path
* @param string $filter
*
* @return bool Returns true if we removed at least one cached image
*/
public function bustCache($path, $filter)
{
$basePathContainer = new FilterPathContainer($path);
$filterPathContainers = [$basePathContainer];

if ($this->webpGenerate) {
$filterPathContainers[] = $basePathContainer->createWebp($this->webpOptions);
}
$busted = false;

foreach ($filterPathContainers as $filterPathContainer) {
foreach ($this->buildFilterPathContainers($path) as $filterPathContainer) {
if ($this->cacheManager->isStored($filterPathContainer->getTarget(), $filter)) {
$this->cacheManager->remove($filterPathContainer->getTarget(), $filter);

$busted = true;
}
}

return $busted;
}

/**
* @param bool $forced Force warm up cache
*
* @return bool Returns true if the cache is warmed up
*/
public function warmUpCache(
string $path,
string $filter,
?string $resolver = null,
bool $forced = false
): bool {
$warmedUp = false;

foreach ($this->buildFilterPathContainers($path) as $filterPathContainer) {
if ($this->warmUpCacheFilterPathContainer($filterPathContainer, $filter, $resolver, $forced)) {
$warmedUp = true;
}
}

return $warmedUp;
}

/**
Expand All @@ -96,9 +119,11 @@ public function bustCache($path, $filter)
*/
public function getUrlOfFilteredImage($path, $filter, $resolver = null, bool $webpSupported = false)
{
$basePathContainer = new FilterPathContainer($path);
foreach ($this->buildFilterPathContainers($path) as $filterPathContainer) {
$this->warmUpCacheFilterPathContainer($filterPathContainer, $filter, $resolver);
}

return $this->getUrlOfFilteredImageByContainer($basePathContainer, $filter, $resolver, $webpSupported);
return $this->resolveFilterPathContainer(new FilterPathContainer($path), $filter, $resolver, $webpSupported);
}

/**
Expand All @@ -116,42 +141,77 @@ public function getUrlOfFilteredImageWithRuntimeFilters(
bool $webpSupported = false
) {
$runtimePath = $this->cacheManager->getRuntimePath($path, $runtimeFilters);
$basePathContainer = new FilterPathContainer($path, $runtimePath, [
$runtimeOptions = [
'filters' => $runtimeFilters,
]);
];

foreach ($this->buildFilterPathContainers($path, $runtimePath, $runtimeOptions) as $filterPathContainer) {
$this->warmUpCacheFilterPathContainer($filterPathContainer, $filter, $resolver);
}

return $this->resolveFilterPathContainer(
new FilterPathContainer($path, $runtimePath, $runtimeOptions),
$filter,
$resolver,
$webpSupported
);
}

/**
* @param mixed[] $options
*
* @return FilterPathContainer[]
*/
private function buildFilterPathContainers(string $source, string $target = '', array $options = []): array
{
$basePathContainer = new FilterPathContainer($source, $target, $options);
$filterPathContainers = [$basePathContainer];

if ($this->webpGenerate) {
$filterPathContainers[] = $basePathContainer->createWebp($this->webpOptions);
}

return $this->getUrlOfFilteredImageByContainer($basePathContainer, $filter, $resolver, $webpSupported);
return $filterPathContainers;
}

private function getUrlOfFilteredImageByContainer(
FilterPathContainer $basePathContainer,
private function resolveFilterPathContainer(
FilterPathContainer $filterPathContainer,
string $filter,
?string $resolver = null,
bool $webpSupported = false
): string {
$filterPathContainers = [$basePathContainer];
$path = $filterPathContainer->getTarget();

if ($this->webpGenerate) {
$webpPathContainer = $basePathContainer->createWebp($this->webpOptions);
$filterPathContainers[] = $webpPathContainer;
if ($webpSupported) {
$path = $filterPathContainer->createWebp($this->webpOptions)->getTarget();
}

foreach ($filterPathContainers as $filterPathContainer) {
if (!$this->cacheManager->isStored($filterPathContainer->getTarget(), $filter, $resolver)) {
$this->cacheManager->store(
$this->createFilteredBinary($filterPathContainer, $filter),
$filterPathContainer->getTarget(),
$filter,
$resolver
);
}
}
return $this->cacheManager->resolve($path, $filter, $resolver);
}

/**
* @param bool $forced Force warm up cache
*
* @return bool Returns true if the cache is warmed up
*/
private function warmUpCacheFilterPathContainer(
FilterPathContainer $filterPathContainer,
string $filter,
?string $resolver = null,
bool $forced = false
): bool {
if ($forced || !$this->cacheManager->isStored($filterPathContainer->getTarget(), $filter, $resolver)) {
$this->cacheManager->store(
$this->createFilteredBinary($filterPathContainer, $filter),
$filterPathContainer->getTarget(),
$filter,
$resolver
);

if ($webpSupported && isset($webpPathContainer)) {
return $this->cacheManager->resolve($webpPathContainer->getTarget(), $filter, $resolver);
return true;
}

return $this->cacheManager->resolve($basePathContainer->getTarget(), $filter, $resolver);
return false;
}

/**
Expand Down
7 changes: 4 additions & 3 deletions Tests/Async/ResolveCacheProcessorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ public function testShouldCreateOneImagePerRequestedFilter(): void

public function testShouldBurstCacheWhenResolvingForced(): void
{
$force = true;
$filterName = 'fooFilter';
$imagePath = 'theImagePath';

Expand All @@ -308,8 +309,8 @@ public function testShouldBurstCacheWhenResolvingForced(): void
$filterServiceMock = $this->createFilterServiceMock();
$filterServiceMock
->expects($this->once())
->method('bustCache')
->with($imagePath, $filterName);
->method('warmUpCache')
->with($imagePath, $filterName, null, $force);

$processor = new ResolveCacheProcessor(
$filterManagerMock,
Expand All @@ -318,7 +319,7 @@ public function testShouldBurstCacheWhenResolvingForced(): void
);

$message = new NullMessage();
$message->setBody(json_encode(['path' => $imagePath, 'force' => true]));
$message->setBody(json_encode(['path' => $imagePath, 'force' => $force]));

$result = $processor->process($message, new NullContext());

Expand Down
Loading

0 comments on commit 018394c

Please sign in to comment.