Skip to content

Commit

Permalink
EZP-32320: Fixed image placeholders generation on DFS
Browse files Browse the repository at this point in the history
  • Loading branch information
adamwojs committed Feb 15, 2021
1 parent fe9b584 commit 1e6de31
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,9 @@ private function addImagePlaceholderSection(ArrayNodeDefinition $rootNode)
->variableNode('options')
->defaultValue([])
->end()
->booleanNode('verify_binary_data_availability')
->defaultFalse()
->end()
->end()
->end()
->end()
Expand Down
53 changes: 40 additions & 13 deletions eZ/Bundle/EzPublishCoreBundle/Imagine/PlaceholderAliasGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

use eZ\Publish\API\Repository\Values\Content\Field;
use eZ\Publish\API\Repository\Values\Content\VersionInfo;
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
use eZ\Publish\API\Repository\Exceptions\InvalidArgumentException as APIInvalidArgumentException;
use eZ\Publish\Core\FieldType\Image\Value as ImageValue;
use eZ\Publish\Core\FieldType\Value;
use eZ\Publish\Core\IO\IOServiceInterface;
Expand All @@ -33,18 +35,14 @@ class PlaceholderAliasGenerator implements VariationHandler
/** @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
*/
/** @var bool */
private $verifyBinaryDataAvailability = false;

public function __construct(
VariationHandler $aliasGenerator,
ResolverInterface $ioResolver,
IOServiceInterface $ioService)
{
IOServiceInterface $ioService
) {
$this->aliasGenerator = $aliasGenerator;
$this->ioResolver = $ioResolver;
$this->ioService = $ioService;
Expand All @@ -62,10 +60,7 @@ public function getVariation(Field $field, VersionInfo $versionInfo, $variationN
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
if (!$this->isOriginalImageAvailable($imageValue)) {
$binary = $this->ioService->newBinaryCreateStructFromLocalFile(
$this->placeholderProvider->getPlaceholder($imageValue, $this->placeholderOptions)
);
Expand All @@ -84,8 +79,40 @@ public function setPlaceholderProvider(PlaceholderProvider $provider, array $opt
$this->placeholderOptions = $options;
}

/**
* Enable/disable binary data availability verification.
*
* If enabled then binary data storage will be used to check if original file exists. Required for DFS setup.
*
* @param bool $verifyBinaryDataAvailability
*/
public function setVerifyBinaryDataAvailability(bool $verifyBinaryDataAvailability): void
{
$this->verifyBinaryDataAvailability = $verifyBinaryDataAvailability;
}

public function supportsValue(Value $value): bool
{
return $value instanceof ImageValue;
}

private function isOriginalImageAvailable(ImageValue $imageValue): bool
{
try {
$this->ioResolver->resolve($imageValue->id, IORepositoryResolver::VARIATION_ORIGINAL);
} catch (NotResolvableException $e) {
return false;
}

if ($this->verifyBinaryDataAvailability) {
try {
// Try to open input stream to original file
$this->ioService->getFileInputStream($this->ioService->loadBinaryFile($imageValue->id));
} catch (NotFoundException | APIInvalidArgumentException $e) {
return false;
}
}

return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,11 @@ class PlaceholderAliasGeneratorConfigurator
/** @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)
{
public function __construct(
ConfigResolverInterface $configResolver,
PlaceholderProviderRegistry $providerRegistry,
array $providersConfig
) {
$this->configResolver = $configResolver;
$this->providerRegistry = $providerRegistry;
$this->providersConfig = $providersConfig;
Expand All @@ -38,10 +34,12 @@ public function configure(PlaceholderAliasGenerator $generator)
$binaryHandlerName = $this->configResolver->getParameter('io.binarydata_handler');

if (isset($this->providersConfig[$binaryHandlerName])) {
$providersConfig = $this->providersConfig[$binaryHandlerName];
$config = $this->providersConfig[$binaryHandlerName];

$provider = $this->providerRegistry->getProvider($config['provider']);

$provider = $this->providerRegistry->getProvider($providersConfig['provider']);
$generator->setPlaceholderProvider($provider, $providersConfig['options']);
$generator->setPlaceholderProvider($provider, $config['options']);
$generator->setVerifyBinaryDataAvailability($config['verify_binary_data_availability'] ?? false);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ public function testImagePlaceholderConfiguration()
'foo' => 'Foo',
'bar' => 'Bar',
],
'verify_binary_data_availability' => true,
],
'fancy' => [
'provider' => 'remote',
Expand All @@ -246,10 +247,12 @@ public function testImagePlaceholderConfiguration()
'foo' => 'Foo',
'bar' => 'Bar',
],
'verify_binary_data_availability' => true,
],
'fancy' => [
'provider' => 'remote',
'options' => [],
'verify_binary_data_availability' => false,
],
], $this->container->getParameter('image_alias.placeholder_providers'));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
use eZ\Bundle\EzPublishCoreBundle\Imagine\IORepositoryResolver;
use eZ\Bundle\EzPublishCoreBundle\Imagine\PlaceholderAliasGenerator;
use eZ\Bundle\EzPublishCoreBundle\Imagine\PlaceholderProvider;
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
use eZ\Publish\API\Repository\Values\Content\Field;
use eZ\Publish\API\Repository\Values\Content\VersionInfo as APIVersionInfo;
use eZ\Publish\Core\FieldType\Image\Value as ImageValue;
use eZ\Publish\Core\FieldType\Null\Value as NullValue;
use eZ\Publish\Core\FieldType\Value as FieldTypeValue;
use eZ\Publish\Core\FieldType\Value;
use eZ\Publish\Core\IO\IOServiceInterface;
use eZ\Publish\Core\IO\Values\BinaryFile;
use eZ\Publish\Core\IO\Values\BinaryFileCreateStruct;
use eZ\Publish\Core\Repository\Values\Content\VersionInfo;
use eZ\Publish\SPI\Variation\Values\ImageVariation;
Expand Down Expand Up @@ -188,6 +190,74 @@ public function testGetVariationOriginalNotFound(Field $field, APIVersionInfo $v
$this->assertEquals($expectedVariation, $actualVariation);
}

/**
* @dataProvider getVariationProvider
*/
public function testGetVariationReturnsPlaceholderIfBinaryDataIsNotAvailable(
Field $field,
APIVersionInfo $versionInfo,
string $variationName,
array $parameters
): void {
$this->aliasGenerator->setVerifyBinaryDataAvailability(true);

$placeholderPath = '/tmp/placeholder.jpg';
$binaryCreateStruct = new BinaryFileCreateStruct();
$expectedVariation = $this->createMock(ImageVariation::class);
$binaryFile = $this->createMock(BinaryFile::class);

$this->ioResolver
->expects($this->once())
->method('resolve')
->with($field->value->id, IORepositoryResolver::VARIATION_ORIGINAL)
->willReturn('/path/to/original/image.png');

$this->ioService
->method('loadBinaryFile')
->with($field->value->id)
->willReturn($binaryFile);

$this->ioService
->method('getFileInputStream')
->with($binaryFile)
->willThrowException($this->createMock(NotFoundException::class));

$this->placeholderProvider
->expects($this->once())
->method('getPlaceholder')
->with($field->value, $this->placeholderOptions)
->willReturn($placeholderPath);

$this->ioService
->expects($this->once())
->method('newBinaryCreateStructFromLocalFile')
->with($placeholderPath)
->willReturn($binaryCreateStruct);

$this->ioService
->expects($this->once())
->method('createBinaryFile')
->with($binaryCreateStruct);

$this->aliasGenerator->setPlaceholderProvider(
$this->placeholderProvider,
$this->placeholderOptions
);

$this->innerAliasGenerator
->expects($this->once())
->method('getVariation')
->with($field, $versionInfo, $variationName, $parameters)
->willReturn($expectedVariation);

$actualVariation = $this->aliasGenerator->getVariation(
$field, $versionInfo, $variationName, $parameters
);

$this->assertEquals($field->value->id, $binaryCreateStruct->id);
$this->assertEquals($expectedVariation, $actualVariation);
}

/**
* @dataProvider supportsValueProvider
*/
Expand Down

0 comments on commit 1e6de31

Please sign in to comment.