diff --git a/src/View/ImageViewBuilder.php b/src/View/ImageViewBuilder.php index 72761cf..671c693 100644 --- a/src/View/ImageViewBuilder.php +++ b/src/View/ImageViewBuilder.php @@ -44,41 +44,9 @@ class ImageViewBuilder { * A renderable array to represent the image. */ public function build(FileInterface $file, string $style = NULL, array $attributes = [], bool $responsive = FALSE, bool $check_access = TRUE): array { - $access = $check_access ? $file->access('view', NULL, TRUE) : AccessResult::allowed(); - $build = []; - if ($access->isAllowed()) { - $build['#uri'] = $file->getFileUri(); - $build['#attributes'] = $attributes; - if ($style) { - // If an image style is given, image module needs the original - // image dimensions to calculate image style's - // width and height and set the attributes. - // See https://www.drupal.org/project/twig_tweak/issues/3356042 - $uri = $file->getFileUri(); - $image = $this->imageFactory->get($uri); - if ($image->isValid()) { - $build['#width'] = $image->getWidth(); - $build['#height'] = $image->getHeight(); - } - else { - $build['#width'] = $build['#height'] = NULL; - } - - if ($responsive) { - $build['#type'] = 'responsive_image'; - $build['#responsive_image_style_id'] = $style; - } - else { - $build['#theme'] = 'image_style'; - $build['#style_name'] = $style; - } - } - else { - $build['#theme'] = 'image'; - } - } + $build = $access->isAllowed() ? $this->doBuild($file, $style, $attributes, $responsive) : []; CacheableMetadata::createFromRenderArray($build) ->addCacheableDependency($access) @@ -88,4 +56,43 @@ class ImageViewBuilder { return $build; } + /** + * Actually builds the image. + */ + private function doBuild(FileInterface $file, string $style = NULL, array $attributes = [], bool $responsive = FALSE): array { + $build['#uri'] = $file->getFileUri(); + $build['#attributes'] = $attributes; + + if (!$style) { + $build['#theme'] = 'image'; + return $build; + } + + $build['#width'] = $attributes['width'] ?? NULL; + $build['#height'] = $attributes['height'] ?? NULL; + + if (!$build['#width'] && !$build['#height']) { + // If an image style is given, image module needs the original image + // dimensions to calculate image style's width and height and set the + // attributes. + // @see https://www.drupal.org/project/twig_tweak/issues/3356042 + $image = $this->imageFactory->get($file->getFileUri()); + if ($image->isValid()) { + $build['#width'] = $image->getWidth(); + $build['#height'] = $image->getHeight(); + } + } + + if ($responsive) { + $build['#type'] = 'responsive_image'; + $build['#responsive_image_style_id'] = $style; + } + else { + $build['#theme'] = 'image_style'; + $build['#style_name'] = $style; + } + + return $build; + } + } diff --git a/tests/src/Kernel/ImageViewBuilderTest.php b/tests/src/Kernel/ImageViewBuilderTest.php index 3dab2ee..88226d7 100644 --- a/tests/src/Kernel/ImageViewBuilderTest.php +++ b/tests/src/Kernel/ImageViewBuilderTest.php @@ -32,28 +32,14 @@ final class ImageViewBuilderTest extends AbstractTestCase { ]; /** - * The ImageStyle. - * - * @var \Drupal\image\Entity\ImageStyle - */ - protected $imageStyle; - - /** - * The ResponsiveImageStyle. - * - * @var \Drupal\responsive_image\Entity\ResponsiveImageStyle - */ - protected $responsiveImageStyle; - - /** - * The public image uri. + * The public image URI. * * @var string */ protected string $publicImageUri; /** - * The private image uri. + * The private image URI. * * @var string */ @@ -82,20 +68,20 @@ final class ImageViewBuilderTest extends AbstractTestCase { $this->installEntitySchema('file'); $this->installSchema('file', 'file_usage'); - $fileSystemService = \Drupal::service('file_system'); + $file_system = $this->container->get('file_system'); + + $file_system->prepareDirectory($this->siteDirectory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS); + $private_directory = $this->siteDirectory . '/private'; - $fileSystemService->prepareDirectory($this->siteDirectory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS); - $privateFilesDirectory = $this->siteDirectory . '/private'; - $fileSystemService->prepareDirectory($privateFilesDirectory, FileSystemInterface::CREATE_DIRECTORY); - $this->setSetting('file_private_path', $privateFilesDirectory); + $file_system->prepareDirectory($private_directory, FileSystemInterface::CREATE_DIRECTORY); + $this->setSetting('file_private_path', $private_directory); - $this->imageStyle = ImageStyle::create([ + $image_style = ImageStyle::create([ 'name' => 'small', 'label' => 'Small', ]); - $this->imageStyle->save(); // Add a crop effect: - $this->imageStyle->addImageEffect([ + $image_style->addImageEffect([ 'id' => 'image_resize', 'data' => [ 'width' => 10, @@ -103,20 +89,19 @@ final class ImageViewBuilderTest extends AbstractTestCase { ], 'weight' => 0, ]); - $this->imageStyle->save(); + $image_style->save(); - $this->responsiveImageStyle = ResponsiveImageStyle::create([ + $responsive_image_style = ResponsiveImageStyle::create([ 'id' => 'wide', 'label' => 'Wide', 'breakpoint_group' => 'twig_tweak_image_view_builder', 'fallback_image_style' => 'small', ]); - $this->responsiveImageStyle->save(); + $responsive_image_style->save(); - // Create a copy of a test image file in root. - // Original sizes: 40x20px. + // Create a copy of a test image file in root. Original sizes: 40x20px. $this->publicImageUri = 'public://image-test-do.jpg'; - $fileSystemService->copy('core/tests/fixtures/files/image-test.jpg', $this->publicImageUri, FileSystemInterface::EXISTS_REPLACE); + $file_system->copy('core/tests/fixtures/files/image-test.jpg', $this->publicImageUri, FileSystemInterface::EXISTS_REPLACE); $this->assertFileExists($this->publicImageUri); $this->publicImage = File::create([ 'uri' => $this->publicImageUri, @@ -124,11 +109,9 @@ final class ImageViewBuilderTest extends AbstractTestCase { ]); $this->publicImage->save(); - // Create a copy of a test image file in root. - // Original sizes: 40x20px. + // Create a copy of a test image file in root. Original sizes: 40x20px. $this->privateImageUri = 'private://image-test-do.png'; - $fileSystemService - ->copy('core/tests/fixtures/files/image-test.png', $this->privateImageUri, FileSystemInterface::EXISTS_REPLACE); + $file_system->copy('core/tests/fixtures/files/image-test.png', $this->privateImageUri, FileSystemInterface::EXISTS_REPLACE); $this->assertFileExists($this->privateImageUri); $this->privateImage = File::create([ 'uri' => $this->privateImageUri,