improvements-2.x-dev/src/Plugin/Filter/ImageStyleFilter.php
src/Plugin/Filter/ImageStyleFilter.php
<?php
namespace Drupal\improvements\Plugin\Filter;
use Drupal\Component\Utility\Html;
use Drupal\Core\StreamWrapper\PublicStream;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\filter\Attribute\Filter;
use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;
use Drupal\filter\Plugin\FilterInterface;
use Drupal\image\Entity\ImageStyle;
/**
* @TODO Add tests
*/
#[Filter(
id: 'image_style_filter',
title: new TranslatableMarkup('Image style'),
type: FilterInterface::TYPE_TRANSFORM_REVERSIBLE,
description: new TranslatableMarkup('Apply image style to images with data-image-style attribute.'),
weight: 20,
)]
class ImageStyleFilter extends FilterBase {
/**
* {@inheritDoc}
*/
public function process($text, $langcode): FilterProcessResult {
$result = new FilterProcessResult($text);
if (stripos($text, 'data-image-style=') !== FALSE) {
$text_dom = Html::load($text);
$text_xpath = new \DOMXPath($text_dom);
$images_nodes = $text_xpath->query('//img[@data-image-style]');
$file_url_generator = \Drupal::service('file_url_generator');
/** @var \DOMElement $image_node */
foreach ($images_nodes as $image_node) {
$image_src = $image_node->getAttribute('src');
if ($image_uri = $this->convertPathToUri($image_src)) {
$image_style_name = $image_node->getAttribute('data-image-style');
$image_style = ImageStyle::load($image_style_name); /** @var ImageStyle $image_style */
if ($image_style && $image_style->supportsUri($image_uri)) {
$image_new_src = $image_style->buildUrl($image_uri);
$image_new_src = $file_url_generator->transformRelative($image_new_src);
$image_node->setAttribute('src', $image_new_src);
}
}
}
$result->setProcessedText(Html::serialize($text_dom));
}
return $result;
}
/**
* Convert path "/sites/default/files/example.jpg" to uri "public://example.jpg".
*/
protected function convertPathToUri(string $path): ?string {
$public_path = base_path() . PublicStream::basePath();
if (str_starts_with($path, $public_path . '/')) {
return 'public://' . mb_substr($path, mb_strlen($public_path) + 1);
}
return NULL;
}
}
