diff --git a/src/View/ImageViewBuilder.php b/src/View/ImageViewBuilder.php index de1d6da..9f592c7 100644 --- a/src/View/ImageViewBuilder.php +++ b/src/View/ImageViewBuilder.php @@ -3,7 +3,9 @@ namespace Drupal\twig_tweak\View; use Drupal\Core\Access\AccessResult; +use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\CacheableMetadata; +use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\file\FileInterface; /** @@ -11,6 +13,34 @@ use Drupal\file\FileInterface; */ class ImageViewBuilder { + /** + * The responsive image style entity storage. + * + * @var \Drupal\Core\Entity\EntityStorageInterface + */ + protected $responsiveImageStyleStorage; + + /** + * The image style entity storage. + * + * @var \Drupal\Core\Entity\EntityStorageInterface + */ + protected $imageStyleStorage; + + /** + * Constructs an ImageViewBuilder object. + * + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager + * The entity type manager. + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + */ + public function __construct(EntityTypeManagerInterface $entity_type_manager) { + $this->responsiveImageStyleStorage = $entity_type_manager->getStorage('responsive_image_style'); + $this->imageStyleStorage = $entity_type_manager->getStorage('image_style'); + } + /** * Builds an image. * @@ -33,6 +63,8 @@ class ImageViewBuilder { $access = $check_access ? $file->access('view', NULL, TRUE) : AccessResult::allowed(); $build = []; + $image_styles_to_load = []; + $cache_tags = []; if ($access->isAllowed()) { $build['#uri'] = $file->getFileUri(); $build['#attributes'] = $attributes; @@ -40,10 +72,16 @@ class ImageViewBuilder { if ($responsive) { $build['#type'] = 'responsive_image'; $build['#responsive_image_style_id'] = $style; + + /** @var \Drupal\responsive_image\ResponsiveImageStyleInterface $responsive_image_style */ + $responsive_image_style = $this->responsiveImageStyleStorage->load($style); + $cache_tags = Cache::mergeTags($cache_tags, $responsive_image_style->getCacheTags()); + $image_styles_to_load = $responsive_image_style->getImageStyleIds(); } else { $build['#theme'] = 'image_style'; $build['#style_name'] = $style; + $image_styles_to_load[] = $style; } } else { @@ -51,9 +89,17 @@ class ImageViewBuilder { } } + if ($image_styles_to_load) { + $image_styles = $this->imageStyleStorage->loadMultiple($image_styles_to_load); + foreach ($image_styles as $image_style) { + $cache_tags = Cache::mergeTags($cache_tags, $image_style->getCacheTags()); + } + } + CacheableMetadata::createFromRenderArray($build) ->addCacheableDependency($access) ->addCacheableDependency($file) + ->addCacheTags($cache_tags) ->applyTo($build); return $build; diff --git a/tests/src/Kernel/ImageViewBuilderTest.php b/tests/src/Kernel/ImageViewBuilderTest.php index 53aa42b..e73dd07 100644 --- a/tests/src/Kernel/ImageViewBuilderTest.php +++ b/tests/src/Kernel/ImageViewBuilderTest.php @@ -106,6 +106,7 @@ final class ImageViewBuilderTest extends AbstractTestCase { 'user.permissions', ], 'tags' => [ + 'config:image.style.large', 'file:1', 'tag_for_public://ocean.jpg', ], @@ -128,6 +129,7 @@ final class ImageViewBuilderTest extends AbstractTestCase { 'user.permissions', ], 'tags' => [ + 'config:responsive_image.styles.wide', 'file:1', 'tag_for_public://ocean.jpg', ], diff --git a/twig_tweak.services.yml b/twig_tweak.services.yml index 6e33f41..d5aee96 100644 --- a/twig_tweak.services.yml +++ b/twig_tweak.services.yml @@ -31,6 +31,7 @@ services: twig_tweak.image_view_builder: class: Drupal\twig_tweak\View\ImageViewBuilder + arguments: ['@entity_type.manager'] twig_tweak.url_extractor: class: Drupal\twig_tweak\UrlExtractor