diff --git a/src/bundle/DependencyInjection/EzEnhancedImageAssetExtension.php b/src/bundle/DependencyInjection/EzEnhancedImageAssetExtension.php index 7592d61..ff75a5e 100644 --- a/src/bundle/DependencyInjection/EzEnhancedImageAssetExtension.php +++ b/src/bundle/DependencyInjection/EzEnhancedImageAssetExtension.php @@ -84,5 +84,34 @@ public function prepend(ContainerBuilder $container): void $container->prependExtensionConfig($extensionName, $config); $container->addResource(new FileResource($configFile)); } + + $configs = $container->getExtensionConfig('ezpublish'); + $newConfig = []; + foreach ($configs as $config) { + if (!isset($config['system'])) { + continue; + } + + foreach ($config['system'] as $system => $systemConfig) { + if (!isset($systemConfig['image_variations'])) { + continue; + } + + foreach (array_keys($systemConfig['image_variations']) as $imageVariation) { + if (false !== strpos($imageVariation, '_retina')) { + $webpVariationName = preg_replace('/^(.+)(_retina)$/', '$1_webp$2', $imageVariation); + } else { + $webpVariationName = $imageVariation.'_webp'; + } + $newConfig['system'][$system]['image_variations'][$webpVariationName] = [ + 'reference' => $imageVariation, + 'filters' => [ + ['name' => 'toFormat', 'params' => ['format' => 'webp']], + ], + ]; + } + } + } + $container->prependExtensionConfig('ezpublish', $newConfig); } } diff --git a/src/bundle/Resources/config/services.yml b/src/bundle/Resources/config/services.yml index bf756a2..fd63308 100644 --- a/src/bundle/Resources/config/services.yml +++ b/src/bundle/Resources/config/services.yml @@ -28,7 +28,7 @@ services: Novactive\EzEnhancedImageAsset\Imagine\Filter\Loader\FocusedThumbnailFilterLoader: tags: - - {name: 'liip_imagine.filter.loader', loader: 'focusedThumbnail'} + - { name: 'liip_imagine.filter.loader', loader: 'focusedThumbnail' } Novactive\EzEnhancedImageAsset\Imagine\Filter\Loader\PlaceholderFilterLoader: tags: @@ -38,6 +38,11 @@ services: tags: - { name: "liip_imagine.filter.loader", loader: 'webOptimization' } + Novactive\EzEnhancedImageAsset\Imagine\Filter\Loader\ToFormatFilterLoader: + tags: + - { name: "liip_imagine.filter.loader", loader: 'toFormat' } + + Novactive\EzEnhancedImageAsset\Imagine\FocusedImageAliasGenerator: ezpublish.image_alias.imagine.alias_generator: @@ -51,9 +56,7 @@ services: decorates: 'liip_imagine.filter.configuration' arguments: $filterConfiguration: '@Novactive\EzEnhancedImageAsset\Imagine\Filter\FilterConfiguration.inner' - calls: - - [setDefaultPostProcessors, ['$image_default_post_processors;ez_enhanced_image_asset$']] - - [setDefaultConfig, ['$image_default_config;ez_enhanced_image_asset$']] + Novactive\EzEnhancedImageAsset\FieldValueConverter\ChainFieldValueConverter: arguments: @@ -70,3 +73,6 @@ services: Novactive\EzEnhancedImageAsset\Imagine\PlaceholderProvider\RemoteProvider: tags: - { name: 'ezpublish.placeholder_provider', type: 'enhanced_remote' } + + Novactive\EzEnhancedImageAsset\Imagine\AliasDirectoryVariationPathGenerator: + decorates: 'ezpublish.image_alias.variation_path_generator.alias_directory' diff --git a/src/bundle/Resources/views/themes/standard/enhanced_image_asset/content_fields.html.twig b/src/bundle/Resources/views/themes/standard/enhanced_image_asset/content_fields.html.twig index 8a9e959..468dba4 100644 --- a/src/bundle/Resources/views/themes/standard/enhanced_image_asset/content_fields.html.twig +++ b/src/bundle/Resources/views/themes/standard/enhanced_image_asset/content_fields.html.twig @@ -3,8 +3,10 @@ {% block enhancedimage_field %} {% spaceless %} {% set lazyLoad = parameters.lazyLoad is defined ? parameters.lazyLoad : lazy_load_images %} + {% set alias = parameters.alias|default( 'original' ) %} + {% set alternativeAliasList = parameters.alternativeAlias|default( [] ) %} {% if not ez_is_field_empty( content, field ) %} - {% set imageAttrs = ez_image_attrs( field, versionInfo, parameters.alias|default( 'original' ), { + {% set imageAttrs = ez_image_attrs( field, versionInfo, alias, { lazyLoad: lazyLoad, retina: parameters.retina|default( enable_retina_variations ), attrs: { @@ -12,18 +14,18 @@ 'alt': parameters.alternativeText|default(field.value.alternativeText) } }) %} - {% set alternativeAliasList = parameters.alternativeAlias|default( [] ) %} {% set attr = attr|merge({ 'class': (attr.class|default('') ~ ' enhancedimage--wrapper enhancedimage--focused-img--wrapper')|trim, }) %} + {% set alternativeAliasList = alternativeAliasList|merge([{'alias': alias ~ '_webp'}]) %} {% for alternativeAlias in alternativeAliasList %} {% set alternativeImageAttrs = ez_image_attrs( field, versionInfo, alternativeAlias.alias, { lazyLoad: lazyLoad, retina: parameters.retina|default( enable_retina_variations ), attrs: { - 'media': alternativeAlias.media, + 'media': alternativeAlias.media|default, 'data-name': alternativeAlias.alias, } }) %} @@ -35,7 +37,7 @@ {% if lazyLoad %} {% set placeholderAlias = ez_image_alias(field, versionInfo, 'placeholder') %} - + {{ field.value.alternativeText }} {% endif %} {% endif %} @@ -45,8 +47,10 @@ {% block ezimage_field %} {% spaceless %} {% set lazyLoad = parameters.lazyLoad is defined ? parameters.lazyLoad : lazy_load_images %} + {% set alias = parameters.alias|default( 'original' ) %} + {% set alternativeAliasList = parameters.alternativeAlias|default( [] ) %} {% if not ez_is_field_empty( content, field ) %} - {% set imageAttrs = ez_image_attrs( field, versionInfo, parameters.alias|default( 'original' ), { + {% set imageAttrs = ez_image_attrs( field, versionInfo, alias, { lazyLoad: lazyLoad, retina: parameters.retina|default( enable_retina_variations ), attrs: { @@ -54,18 +58,18 @@ 'alt': parameters.alternativeText|default(field.value.alternativeText) } }) %} - {% set alternativeAliasList = parameters.alternativeAlias|default( [] ) %} {% set attr = attr|merge({ 'class': (attr.class|default('') ~ ' enhancedimage--wrapper')|trim, }) %} + {% set alternativeAliasList = alternativeAliasList|merge([{'alias': alias ~ '_webp'}]) %} {% for alternativeAlias in alternativeAliasList %} {% set alternativeImageAttrs = ez_image_attrs( field, versionInfo, alternativeAlias.alias, { lazyLoad: lazyLoad, retina: parameters.retina|default( enable_retina_variations ), attrs: { - 'media': alternativeAlias.media, + 'media': alternativeAlias.media|default, 'data-name': alternativeAlias.alias, } }) %} @@ -77,7 +81,7 @@ {% if lazyLoad %} {% set placeholderAlias = ez_image_alias(field, versionInfo, 'placeholder') %} - + {{ field.value.alternativeText }} {% endif %} {% endif %} diff --git a/src/lib/Imagine/AliasDirectoryVariationPathGenerator.php b/src/lib/Imagine/AliasDirectoryVariationPathGenerator.php new file mode 100644 index 0000000..a8741dd --- /dev/null +++ b/src/lib/Imagine/AliasDirectoryVariationPathGenerator.php @@ -0,0 +1,47 @@ +filterConfiguration = $filterConfiguration; + } + + public function getVariationPath($originalPath, $filter) + { + $filterConfig = $this->filterConfiguration->get($filter); + $info = pathinfo($originalPath); + + $variationExtension = $filterConfig['format'] ?? $info['extension']; + + return sprintf( + '_aliases/%s/%s/%s%s', + $filter, + $info['dirname'], + $info['filename'], + empty($variationExtension) ? '' : '.' . $variationExtension + ); + } +} \ No newline at end of file diff --git a/src/lib/Imagine/Filter/FilterConfiguration.php b/src/lib/Imagine/Filter/FilterConfiguration.php index 717a715..6f22808 100644 --- a/src/lib/Imagine/Filter/FilterConfiguration.php +++ b/src/lib/Imagine/Filter/FilterConfiguration.php @@ -14,6 +14,7 @@ namespace Novactive\EzEnhancedImageAsset\Imagine\Filter; +use eZ\Publish\Core\MVC\ConfigResolverInterface; use Liip\ImagineBundle\Imagine\Filter\FilterConfiguration as BaseFilterConfiguration; /** @@ -26,38 +27,17 @@ class FilterConfiguration extends BaseFilterConfiguration /** @var BaseFilterConfiguration */ protected $filterConfiguration; - /** - * @var - */ - protected $defaultPostProcessors; - - /** - * @var - */ - protected $defaultConfig; + /** @var ConfigResolverInterface */ + protected $configResolver; /** * FilterConfiguration constructor. */ - public function __construct(BaseFilterConfiguration $filterConfiguration) + public function __construct(BaseFilterConfiguration $filterConfiguration, ConfigResolverInterface $configResolver) { $this->filterConfiguration = $filterConfiguration; - } - - /** - * @param $defaultPostProcessors - */ - public function setDefaultPostProcessors($defaultPostProcessors): void - { - $this->defaultPostProcessors = $defaultPostProcessors; - } - - /** - * @param $defaultConfig - */ - public function setDefaultConfig($defaultConfig): void - { - $this->defaultConfig = $defaultConfig; + $this->configResolver = $configResolver; + parent::__construct(); } /** @@ -65,25 +45,51 @@ public function setDefaultConfig($defaultConfig): void */ public function get($filter): array { + $defaultPostProcessors = $this->getDefaultPostProcessors(); + $defaultConfig = $this->getDefaultConfig(); $config = $this->filterConfiguration->get($filter); - if (!isset($config['jpeg_quality'])) { - $config['jpeg_quality'] = 70; + $config = array_merge( + [ + 'quality' => 70, + 'jpeg_quality' => 70, + 'webp_quality' => 70, + 'png_compression_level' => 6, + ], + $config + ); + + if ($defaultPostProcessors && (!isset($config['post_processors']) || empty($config['post_processors']))) { + $config['post_processors'] = $defaultPostProcessors; } - if (!isset($config['png_compression_level'])) { - $config['png_compression_level'] = 6; - } - if ($this->defaultPostProcessors && (!isset($config['post_processors']) || empty($config['post_processors']))) { - $config['post_processors'] = $this->defaultPostProcessors; + + if ($defaultConfig) { + $config += $defaultConfig; } - if ($this->defaultConfig) { - $config += $this->defaultConfig; + if (!isset($config['format']) && isset($config['filters']['toFormat'])) { + $config['format'] = $config['filters']['toFormat']['format']; } return $config; } + public function getDefaultPostProcessors(): ?array + { + return $this->configResolver->getParameter( + 'image_default_post_processors', + 'ez_enhanced_image_asset' + ); + } + + public function getDefaultConfig(): ?array + { + return $this->configResolver->getParameter( + 'image_default_config', + 'ez_enhanced_image_asset' + ); + } + /** * Sets a configuration on the given filter. * diff --git a/src/lib/Imagine/Filter/Loader/ToFormatFilterLoader.php b/src/lib/Imagine/Filter/Loader/ToFormatFilterLoader.php new file mode 100644 index 0000000..f7aa89e --- /dev/null +++ b/src/lib/Imagine/Filter/Loader/ToFormatFilterLoader.php @@ -0,0 +1,34 @@ + $this->configResolver->getParameter( + 'enable_lazy_load', + 'ez_enhanced_image_asset' + ), + 'enable_retina_variations' => $this->configResolver->getParameter( + 'enable_retina', + 'ez_enhanced_image_asset' + ), + ]; + } + /** * @required */ @@ -64,6 +83,14 @@ public function setAssetExtension(AssetExtension $assetExtension): void $this->assetExtension = $assetExtension; } + /** + * @required + */ + public function setConfigResolver(ConfigResolverInterface $configResolver): void + { + $this->configResolver = $configResolver; + } + /** * {@inheritdoc} */ @@ -95,15 +122,16 @@ public function getFunctions() * @param $variationName * @param array $parameters * + * @return array|mixed * @throws ReflectionException * - * @return array|mixed */ public function getImageAttributes(Field $field, VersionInfo $versionInfo, $variationName, $parameters = []) { - $lazyLoadEnabled = $parameters['lazyLoad'] ?? false; + $lazyLoadEnabled = $parameters['lazyLoad'] ?? false; $retinaSupportEnabled = $parameters['retina'] ?? false; - $attrs = $parameters['attrs'] ?? []; + $addMimeType = $parameters['addMimeType'] ?? false; + $attrs = $parameters['attrs'] ?? []; $this->initiateArrayAttribute($attrs, 'srcset'); $this->initiateArrayAttribute($attrs, 'class'); @@ -114,16 +142,21 @@ public function getImageAttributes(Field $field, VersionInfo $versionInfo, $vari $this->appendRetinaVariationAttrs($field, $versionInfo, $variationName, $defaultVariation, $attrs); } + if ($addMimeType && $defaultVariation) { + $attrs['type'] = $defaultVariation->mimeType; + } if (is_array($attrs['srcset'])) { $attrs['srcset'] = implode(', ', $attrs['srcset']); } if ($lazyLoadEnabled) { - $attrs['class'][] = 'has-placeholder'; + $attrs['class'][] = 'has-placeholder'; $attrs['data-srcset'] = is_array($attrs['srcset']) ? implode(', ', $attrs['srcset']) : $attrs['srcset']; unset($attrs['srcset']); } $attrs['class'] = implode(' ', $attrs['class']); + if (!isset($attrs["alt"])) + $attrs['alt'] = $field->value->alternativeText; return $attrs; } @@ -143,16 +176,17 @@ protected function initiateArrayAttribute(array &$attributes, string $attributeN * @param $variationName * @param array $attrs * + * @return ImageVariation|FocusedVariation|null * @throws ReflectionException * - * @return ImageVariation|FocusedVariation|null */ protected function appendDefaultVariationAttrs( - Field $field, + Field $field, VersionInfo $versionInfo, - $variationName, - &$attrs = [] - ) { + $variationName, + &$attrs = [] + ) + { $defaultVariation = $this->getImageVariation($field, $versionInfo, $variationName); if (!$defaultVariation) { return null; @@ -161,11 +195,13 @@ protected function appendDefaultVariationAttrs( if ($defaultVariation instanceof FocusedVariation && $defaultVariation->focusPoint) { $attrs['data-focus-x'] = $defaultVariation->focusPoint->getPosX(); $attrs['data-focus-y'] = $defaultVariation->focusPoint->getPosY(); - $attrs['class'][] = 'enhancedimage--focused-img'; + $attrs['class'][] = 'enhancedimage--focused-img'; } - $attrs['srcset'][] = str_replace(' ', '%20', $this->assetExtension->getAssetUrl($defaultVariation->uri)); - $attrs['data-width'] = $defaultVariation->width; + $attrs['srcset'][] = str_replace(' ', '%20', $this->assetExtension->getAssetUrl($defaultVariation->uri)); + $attrs['data-width'] = $defaultVariation->width; $attrs['data-height'] = $defaultVariation->height; + $attrs['width'] = $defaultVariation->width; + $attrs['height'] = $defaultVariation->height; return $defaultVariation; } @@ -173,17 +209,22 @@ protected function appendDefaultVariationAttrs( /** * Returns the image variation object for $field/$versionInfo. * + * @return ImageVariation|FocusedVariation|null * @throws ReflectionException * - * @return ImageVariation|FocusedVariation|null */ public function getImageVariation(Field $field, VersionInfo $versionInfo, string $variationName) { + if (!$this->isVariationsAvailable($variationName)) { + return null; + } try { return $this->focusedImageAliasGenerator->getVariation($field, $versionInfo, $variationName); } catch (InvalidVariationException $e) { if (isset($this->logger)) { - $this->logger->error("Couldn't get variation '{$variationName}' for image with id {$field->value->id}"); + $this->logger->error( + "Couldn't get variation '{$variationName}' for image with id {$field->value->id}" + ); } } catch (SourceImageNotFoundException $e) { if (isset($this->logger)) { @@ -204,21 +245,29 @@ public function getImageVariation(Field $field, VersionInfo $versionInfo, string return null; } + protected function isVariationsAvailable($variationName): bool + { + $configuredVariations = $this->configResolver->getParameter('image_variations'); + + return isset($configuredVariations[$variationName]); + } + /** * @param $variationName * @param array $attrs * + * @return ImageVariation|FocusedVariation|null * @throws ReflectionException * - * @return ImageVariation|FocusedVariation|null */ protected function appendRetinaVariationAttrs( - Field $field, - VersionInfo $versionInfo, - $variationName, + Field $field, + VersionInfo $versionInfo, + $variationName, ImageVariation $defaultVariation, - &$attrs = [] - ) { + &$attrs = [] + ) + { try { $retinaVariation = $this->getImageVariation( $field, @@ -242,4 +291,4 @@ protected function appendRetinaVariationAttrs( return null; } -} +} \ No newline at end of file