Skip to content
90 changes: 90 additions & 0 deletions Command/WarmCacheCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php

namespace Liip\ImagineBundle\Command;

use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use Liip\ImagineBundle\Imagine\Cache\CacheWarmer;
use Liip\ImagineBundle\Imagine\Data\DataManager;
use Liip\ImagineBundle\Imagine\Filter\FilterManager;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

/**
* A command to warm up images cache (i.e. pre-generate thumbnails)
*
* @author Konstantin Tjuterev <[email protected]>
*/
class WarmCacheCommand extends ContainerAwareCommand
{
protected function configure()
{
$this
->setName('liip:imagine:cache:warm')
->setDescription('Warms cache for paths provided by given warmers (or all warmers, if run w/o params)')
->addOption('chunk-size', 'c', InputOption::VALUE_REQUIRED, 'Chunk size', 100)
->addOption('force', 'f', InputOption::VALUE_NONE, 'Force cache warm up for already cached images')
->addArgument('warmers', InputArgument::OPTIONAL|InputArgument::IS_ARRAY, 'Warmers names')
->setHelp(<<<EOF
The <info>%command.name%</info> command warms up cache by specified parameters.

A warmer can be configured for one or more filter set. A warmer should return a list of paths.
This command gets the paths from warmer and create cache (i.e. filtered image) for each filter configured for given warmer.

Warmers should be separated by spaces:
<info>php app/console %command.name% warmer1 warmer2</info>
All cache for a given `warmers` will be warmed up

<info>php app/console %command.name%</info>
Cache for all warmers will be warmed up when executing this command without parameters.

Note, that <info>--force</info> option will force regeneration of the cache only if warmer returns the path.
Generally, there should be NO need to use this option, instead, use <info>liip:imagine:cache:remove</info> command to clear cache.
Then run this command to warm-up the cache
EOF
);
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$warmers = $input->getArgument('warmers');

/** @var CacheWarmer $cacheWarmer */
$cacheWarmer = $this->getContainer()->get('liip_imagine.cache.warmer');
$cacheWarmer->setLoggerClosure($this->getLoggerClosure($output));

if ($chunkSize = $input->getOption('chunk-size')) {
$cacheWarmer->setChunkSize($chunkSize);
}

$force = false;
if ($input->getOption('force')) {
$force = true;
}

$cacheWarmer->warm($force, $warmers);
}

/**
* Returns Logger Closure
*
* @return callable
*/
protected function getLoggerClosure(OutputInterface $output)
{
$loggerClosure = function ($message, $msgType = 'info') use ($output) {
$time = date('Y-m-d G:i:s');
$message = sprintf(
'<comment>%s | Mem cur/peak: %dm/%dm </comment> | <' . $msgType . '>%s</' . $msgType . '>',
$time,
round(memory_get_usage(true) / 1024 / 1024, 1),
round(memory_get_peak_usage(true) / 1024 / 1024, 1),
$message
);
$output->writeln($message);
};
return $loggerClosure;
}
}
26 changes: 26 additions & 0 deletions DependencyInjection/Compiler/CacheWarmersCompilerPass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Liip\ImagineBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

class CacheWarmersCompilerPass implements CompilerPassInterface
{
/**
* {@inheritDoc}
*/
public function process(ContainerBuilder $container)
{
$tags = $container->findTaggedServiceIds('liip_imagine.cache.warmer');

if (count($tags) > 0 && $container->hasDefinition('liip_imagine.cache.warmer')) {
$warmer = $container->getDefinition('liip_imagine.cache.warmer');

foreach ($tags as $id => $tag) {
$warmer->addMethodCall('addWarmer', array($tag[0]['warmer'], new Reference($id)));
}
}
}
}
6 changes: 6 additions & 0 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,12 @@ public function getConfigTreeBuilder()
->useAttributeAsKey('name')
->prototype('variable')->end()
->end()
->end()
->arrayNode('warmers')
->defaultValue(array())
->useAttributeAsKey('name')
->prototype('scalar')
->end()
->end()
->end()
->end()
Expand Down
42 changes: 42 additions & 0 deletions DependencyInjection/Factory/Resolver/FormatResolverFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace Liip\ImagineBundle\DependencyInjection\Factory\Resolver;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\DefinitionDecorator;

/**
* Class FormatResolverFactory
*
* @copyright 2017 IntechSystems, SIA
* @package Liip\ImagineBundle\DependencyInjection\Factory\Resolver
* @author Mihail Savluga
*/
class FormatResolverFactory extends WebPathResolverFactory
{
/**
* {@inheritDoc}
*/
public function create(ContainerBuilder $container, $resolverName, array $config)
{
$resolverDefinition = new DefinitionDecorator('liip_imagine.cache.resolver.prototype.format');
$resolverDefinition->replaceArgument(2, $config['web_root']);
$resolverDefinition->replaceArgument(3, $config['cache_prefix']);
$resolverDefinition->addTag('liip_imagine.cache.resolver', array(
'resolver' => $resolverName
));
$resolverId = 'liip_imagine.cache.resolver.'.$resolverName;

$container->setDefinition($resolverId, $resolverDefinition);

return $resolverId;
}

/**
* {@inheritDoc}
*/
public function getName()
{
return 'format';
}
}
19 changes: 19 additions & 0 deletions Imagine/Cache/CacheManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ class CacheManager
*/
protected $defaultResolver;

/**
* @var CacheWarmer
*/
protected $cacheWarmer;

/**
* @var bool
*/
Expand Down Expand Up @@ -95,6 +100,18 @@ public function addResolver($filter, ResolverInterface $resolver)
}
}

/**
* @param \Liip\ImagineBundle\Imagine\Cache\CacheWarmer $cacheWarmer
*
* @return CacheManager
*/
public function setCacheWarmer($cacheWarmer)
{
$this->cacheWarmer = $cacheWarmer;

return $this;
}

/**
* Gets filtered path for rendering in the browser.
* It could be the cached one or an url of filter action.
Expand Down Expand Up @@ -238,6 +255,8 @@ public function remove($paths = null, $filters = null)
$paths = array_filter($paths);
$filters = array_filter($filters);

$this->cacheWarmer->clearWarmed($paths, $filters);

$mapping = new \SplObjectStorage();
foreach ($filters as $filter) {
$resolver = $this->getResolver($filter, null);
Expand Down
Loading