picture_everywhere-1.0.0/src/Preprocess.php
src/Preprocess.php
<?php
namespace Drupal\picture_everywhere;
use Drupal\Core\Template\Attribute;
/**
* Preprocessing functionality for Picture Everywhere.
*/
class Preprocess {
/**
* A list of HTML attributes that should always go on the <img> element.
*
* @var string[]
*/
public const ALWAYS_IMG_TAG_ATTRS = [
'alt',
'crossorigin',
'decoding',
'height',
'loading',
'referrerpolicy',
'src',
'srcset',
'sizes',
'width',
];
/**
* Implements hook_preprocess_image().
*/
public static function preprocessImage(array &$variables): void {
if (!empty($variables['in_picture'])) {
return;
}
// We want to pull up all attributes passed to the filter to the <picture>
// element.
$variables['picture_attributes'] = static::splitAttributes($variables['attributes']);
if (
\Drupal::config('picture_everywhere.settings')->get('output.webp.auto_webp_source')
&& (
!empty($variables['attributes']['src'])
|| !empty($variables['attributes']['srcset'])
)
) {
$original_src = !empty($variables['attributes']['srcset']) ?
$variables['attributes']['srcset'] :
$variables['attributes']['src'];
$webp_src_value = explode('?', $original_src);
$webp_src_value = preg_replace('/\.(jpe?g|png)$/i', '.webp', $webp_src_value, -1, $replacement_count);
if ($replacement_count) {
$webp_src_value = implode('?', $webp_src_value);
$variables['sources']['attributes'] = new Attribute([
'srcset' => $webp_src_value,
'type' => 'image/webp',
]);
}
}
}
/**
* Implements hook_preprocess_responsive_image().
*/
public static function preprocessResponsiveImage(array &$variables): void {
if (empty($variables['output_image_tag'])) {
$variables['img_element']['#in_picture'] = TRUE;
}
}
/**
* Implements hook_preprocess_svg_image_field_formatter().
*/
public static function preprocessSvgImageFieldFormatter(array &$variables): void {
if (!empty($variables['inline'])) {
return;
}
// We want to pull up all attributes passed to the filter to the <picture>
// element.
$variables['picture_attributes'] = static::splitAttributes($variables['attributes']);
// SVG Image Field itself sets no loading attribute. We want to default to
// lazy unless specified otherwise.
if (!array_key_exists('loading', $variables['attributes'])) {
$variables['attributes']['loading'] = 'lazy';
}
}
/**
* Get the names of HTML attributes that should be on the <img> tag.
*
* @return string[]
* The HTML attribute names that should be on the <img> tag instead of
* <picture>.
*/
protected static function getImgTagAttributeNames(): array {
$tags = &drupal_static(__METHOD__);
if (!isset($tags)) {
$configured_names = \Drupal::config('picture_everywhere.settings')->get('output.img_tag_attributes') ?: [];
$tags = array_merge(static::ALWAYS_IMG_TAG_ATTRS, $configured_names);
}
return $tags;
}
/**
* Splits <img> tag attributes into two for <picture>/<img> tags.
*
* The picture tag attributes will be returned. Attributes "moved" to picture
* tag attributes will be unset on the passed attributes.
*
* @param array|null &$attributes
* The original attributes array.
*
* @return \Drupal\Core\Template\Attribute
* The <picture> tag attributes.
*/
protected static function splitAttributes(Attribute|array|null &$attributes = NULL): Attribute {
$picture_attributes = [];
if ($attributes) {
$img_attr_names = static::getImgTagAttributeNames();
foreach (array_keys($attributes) as $attribute_name) {
if (in_array($attribute_name, $img_attr_names, TRUE)) {
continue;
}
$picture_attributes[$attribute_name] = $attributes[$attribute_name];
unset($attributes[$attribute_name]);
}
}
return new Attribute($picture_attributes);
}
}
