Skip to content
Permalink
Browse files

EZP-29137: As a developer, I want to replace missing images with plac…

…eholders (ezsystems#2311)

* EZP-29137: As a developer, I want to replace missing images with placeholders

* EZP-29137: As a developer, I want to replace missing images with placeholders (impl. generic placeholder provider)

* EZP-29137: As a developer, I want to replace missing images with placeholders (impl. remote placeholder provider)

* EZP-29137: As a developer, I want to replace missing images with placeholders (configuration)
  • Loading branch information...
adamwojs authored and lserwatka committed May 24, 2018
1 parent 513898e commit 595f7b1312b642b063bbc130f56e5707f0c39591
Showing with 1,102 additions and 1 deletion.
  1. +41 −0 eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Compiler/PlaceholderProviderPass.php
  2. +26 −0 eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Configuration.php
  3. +14 −0 eZ/Bundle/EzPublishCoreBundle/DependencyInjection/EzPublishCoreExtension.php
  4. +2 −0 eZ/Bundle/EzPublishCoreBundle/EzPublishCoreBundle.php
  5. +103 −0 eZ/Bundle/EzPublishCoreBundle/Imagine/PlaceholderAliasGenerator.php
  6. +55 −0 eZ/Bundle/EzPublishCoreBundle/Imagine/PlaceholderAliasGeneratorConfigurator.php
  7. +22 −0 eZ/Bundle/EzPublishCoreBundle/Imagine/PlaceholderProvider.php
  8. +108 −0 eZ/Bundle/EzPublishCoreBundle/Imagine/PlaceholderProvider/GenericProvider.php
  9. +77 −0 eZ/Bundle/EzPublishCoreBundle/Imagine/PlaceholderProvider/RemoteProvider.php
  10. +48 −0 eZ/Bundle/EzPublishCoreBundle/Imagine/PlaceholderProviderRegistry.php
  11. +32 −0 eZ/Bundle/EzPublishCoreBundle/Resources/config/image.yml
  12. +2 −1 eZ/Bundle/EzPublishCoreBundle/Resources/config/templating.yml
  13. +60 −0 eZ/Bundle/EzPublishCoreBundle/Tests/DependencyInjection/Compiler/PlaceholderProviderPassTest.php
  14. +32 −0 eZ/Bundle/EzPublishCoreBundle/Tests/DependencyInjection/EzPublishCoreExtensionTest.php
  15. +66 −0 eZ/Bundle/EzPublishCoreBundle/Tests/Imagine/PlaceholderAliasGeneratorConfiguratorTest.php
  16. +233 −0 eZ/Bundle/EzPublishCoreBundle/Tests/Imagine/PlaceholderAliasGeneratorTest.php
  17. +105 −0 eZ/Bundle/EzPublishCoreBundle/Tests/Imagine/PlaceholderProvider/GenericProviderTest.php
  18. +76 −0 eZ/Bundle/EzPublishCoreBundle/Tests/Imagine/PlaceholderProviderRegistryTest.php
@@ -0,0 +1,41 @@
<?php
/**
* This file is part of the eZ Publish Kernel package.
*
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
namespace eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Compiler;
use LogicException;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
class PlaceholderProviderPass implements CompilerPassInterface
{
const TAG_NAME = 'ezpublish.placeholder_provider';
const REGISTRY_DEFINITION_ID = 'ezpublish.image_alias.imagine.placeholder_provider.registry';
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition(self::REGISTRY_DEFINITION_ID)) {
return;
}
$definition = $container->getDefinition(self::REGISTRY_DEFINITION_ID);
foreach ($container->findTaggedServiceIds(self::TAG_NAME) as $id => $attributes) {
foreach ($attributes as $attribute) {
if (!isset($attribute['type'])) {
throw new LogicException(self::TAG_NAME . ' service tag needs a "type" attribute to identify the placeholder provider type. None given.');
}
$definition->addMethodCall(
'addProvider',
[$attribute['type'], new Reference($id)]
);
}
}
}
}
@@ -63,6 +63,7 @@ public function getConfigTreeBuilder()
$this->addRouterSection($rootNode);
$this->addRichTextSection($rootNode);
$this->addUrlAliasSection($rootNode);
$this->addImagePlaceholderSection($rootNode);
// Delegate SiteAccess config to configuration parsers
$this->mainConfigParser->addSemanticConfig($this->generateScopeBaseNode($rootNode));
@@ -570,6 +571,31 @@ function ($v) {
;
}
/**
* Defines configuration the images placeholder generation.
*
* @param \Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition $rootNode
*/
private function addImagePlaceholderSection(ArrayNodeDefinition $rootNode)
{
$rootNode
->children()
->arrayNode('image_placeholder')
->info('Configuration for strategy of replacing missing images')
->useAttributeAsKey('name')
->arrayPrototype()
->children()
->scalarNode('provider')
->end()
->variableNode('options')
->defaultValue([])
->end()
->end()
->end()
->end()
->end();
}
/**
* Define Url Alias Slug converter Semantic Configuration.
*
@@ -16,6 +16,7 @@
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Security\PolicyProvider\PoliciesConfigBuilder;
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Security\PolicyProvider\PolicyProviderInterface;
use eZ\Bundle\EzPublishCoreBundle\SiteAccess\SiteAccessConfigurationFilter;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader;
@@ -476,6 +477,19 @@ private function handleSiteAccessesRelation(ContainerBuilder $container)
private function handleImage(array $config, ContainerBuilder $container, FileLoader $loader)
{
$loader->load('image.yml');
$providers = [];
if (isset($config['image_placeholder'])) {
foreach ($config['image_placeholder'] as $name => $value) {
if (isset($providers[$name])) {
throw new InvalidConfigurationException("A image_placeholder named $name already exists");
}
$providers[$name] = $value;
}
}
$container->setParameter('image_alias.placeholder_providers', $providers);
}
private function handleUrlChecker($config, ContainerBuilder $container, FileLoader $loader)
@@ -14,6 +14,7 @@
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Compiler\ConfigResolverParameterPass;
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Compiler\FieldTypeParameterProviderRegistryPass;
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Compiler\FragmentPass;
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Compiler\PlaceholderProviderPass;
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Compiler\ImaginePass;
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Compiler\QueryTypePass;
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Compiler\RegisterSearchEngineIndexerPass;
@@ -80,6 +81,7 @@ public function build(ContainerBuilder $container)
$container->addCompilerPass(new URLHandlerPass());
$container->addCompilerPass(new BinaryContentDownloadPass());
$container->addCompilerPass(new ViewProvidersPass());
$container->addCompilerPass(new PlaceholderProviderPass());
// Storage passes
$container->addCompilerPass(new ExternalStorageRegistryPass());
@@ -0,0 +1,103 @@
<?php
/**
* This file is part of the eZ Publish Kernel package.
*
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
namespace eZ\Bundle\EzPublishCoreBundle\Imagine;
use eZ\Publish\API\Repository\Values\Content\Field;
use eZ\Publish\API\Repository\Values\Content\VersionInfo;
use eZ\Publish\Core\FieldType\Image\Value as ImageValue;
use eZ\Publish\Core\FieldType\Value;
use eZ\Publish\Core\IO\IOServiceInterface;
use eZ\Publish\SPI\Variation\VariationHandler;
use InvalidArgumentException;
use Liip\ImagineBundle\Exception\Imagine\Cache\Resolver\NotResolvableException;
use Liip\ImagineBundle\Imagine\Cache\Resolver\ResolverInterface;
class PlaceholderAliasGenerator implements VariationHandler
{
/**
* @var \eZ\Publish\SPI\Variation\VariationHandler
*/
private $aliasGenerator;
/**
* @var \Liip\ImagineBundle\Imagine\Cache\Resolver\ResolverInterface
*/
private $ioResolver;
/**
* @var \eZ\Publish\Core\IO\IOServiceInterface
*/
private $ioService;
/**
* @var \eZ\Bundle\EzPublishCoreBundle\Imagine\PlaceholderProvider|null
*/
private $placeholderProvider;
/**
* @var array
*/
private $placeholderOptions = [];
/**
* PlaceholderAliasGenerator constructor.
*
* @param \eZ\Publish\SPI\Variation\VariationHandler $aliasGenerator
* @param \Liip\ImagineBundle\Imagine\Cache\Resolver\ResolverInterface $ioResolver
* @param \eZ\Publish\Core\IO\IOServiceInterface $ioService
*/
public function __construct(
VariationHandler $aliasGenerator,
ResolverInterface $ioResolver,
IOServiceInterface $ioService)
{
$this->aliasGenerator = $aliasGenerator;
$this->ioResolver = $ioResolver;
$this->ioService = $ioService;
}
/**
* {@inheritdoc}
*/
public function getVariation(Field $field, VersionInfo $versionInfo, $variationName, array $parameters = [])
{
if ($this->placeholderProvider !== null) {
/** @var \eZ\Publish\Core\FieldType\Image\Value $imageValue */
$imageValue = $field->value;
if (!$this->supportsValue($imageValue)) {
throw new InvalidArgumentException("Value for field #{$field->id} ($field->fieldDefIdentifier) cannot be used for image placeholder generation.");
}
try {
$this->ioResolver->resolve($imageValue->id, IORepositoryResolver::VARIATION_ORIGINAL);
} catch (NotResolvableException $e) {
// Generate placeholder for original image
$binary = $this->ioService->newBinaryCreateStructFromLocalFile(
$this->placeholderProvider->getPlaceholder($imageValue, $this->placeholderOptions)
);
$binary->id = $imageValue->id;
$this->ioService->createBinaryFile($binary);
}
}
return $this->aliasGenerator->getVariation($field, $versionInfo, $variationName, $parameters);
}
public function setPlaceholderProvider(PlaceholderProvider $provider, array $options = [])
{
$this->placeholderProvider = $provider;
$this->placeholderOptions = $options;
}
public function supportsValue(Value $value): bool
{
return $value instanceof ImageValue;
}
}
@@ -0,0 +1,55 @@
<?php
/**
* This file is part of the eZ Publish Kernel package.
*
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
namespace eZ\Bundle\EzPublishCoreBundle\Imagine;
use eZ\Publish\Core\MVC\ConfigResolverInterface;
class PlaceholderAliasGeneratorConfigurator
{
/**
* @var \eZ\Publish\Core\MVC\ConfigResolverInterface
*/
private $configResolver;
/**
* @var \eZ\Bundle\EzPublishCoreBundle\Imagine\PlaceholderProviderRegistry
*/
private $providerRegistry;
/**
* @var array
*/
private $providersConfig;
/**
* PlaceholderAliasGeneratorConfigurator constructor.
*
* @param \eZ\Publish\Core\MVC\ConfigResolverInterface $configResolver
* @param \eZ\Bundle\EzPublishCoreBundle\Imagine\PlaceholderProviderRegistry $providerRegistry
* @param array $providersConfig
*/
public function __construct(ConfigResolverInterface $configResolver, PlaceholderProviderRegistry $providerRegistry, array $providersConfig)
{
$this->configResolver = $configResolver;
$this->providerRegistry = $providerRegistry;
$this->providersConfig = $providersConfig;
}
public function configure(PlaceholderAliasGenerator $generator)
{
$binaryHandlerName = $this->configResolver->getParameter('io.binarydata_handler');
if (isset($this->providersConfig[$binaryHandlerName])) {
$providersConfig = $this->providersConfig[$binaryHandlerName];
$provider = $this->providerRegistry->getProvider($providersConfig['provider']);
$generator->setPlaceholderProvider($provider, $providersConfig['options']);
}
}
}
@@ -0,0 +1,22 @@
<?php
/**
* This file is part of the eZ Publish Kernel package.
*
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
namespace eZ\Bundle\EzPublishCoreBundle\Imagine;
use eZ\Publish\Core\FieldType\Image\Value as ImageValue;
interface PlaceholderProvider
{
/**
* Provides a placeholder image path for a given Image FieldType value.
*
* @param \eZ\Publish\Core\FieldType\Image\Value $value
* @param array $options
* @return string Path to placeholder
*/
public function getPlaceholder(ImageValue $value, array $options = []): string;
}
Oops, something went wrong.

0 comments on commit 595f7b1

Please sign in to comment.
You can’t perform that action at this time.