From 930f9f88b7fa24a11defa490560ad2102adc0e04 Mon Sep 17 00:00:00 2001 From: Greg Roach Date: Mon, 4 May 2026 23:30:47 +0100 Subject: Fix: #5365 - upgrade from intervention/image v3 to v4 --- app/Factories/ImageFactory.php | 59 ++++++------ composer.json | 2 +- composer.lock | 151 ++++++++++++++++--------------- tests/app/Factories/ImageFactoryTest.php | 2 +- 4 files changed, 106 insertions(+), 108 deletions(-) diff --git a/app/Factories/ImageFactory.php b/app/Factories/ImageFactory.php index 9f5394d8f0..9ef76f9c38 100644 --- a/app/Factories/ImageFactory.php +++ b/app/Factories/ImageFactory.php @@ -31,15 +31,14 @@ use Fisharebest\Webtrees\Registry; use Fisharebest\Webtrees\Services\PhpService; use Fisharebest\Webtrees\Webtrees; use Imagick; -use Intervention\Gif\Exceptions\NotReadableException; use Intervention\Image\Drivers\Gd\Driver as GdDriver; use Intervention\Image\Drivers\Imagick\Driver as ImagickDriver; +use Intervention\Image\Exceptions\ImageException; use Intervention\Image\ImageManager; use Intervention\Image\Interfaces\ImageInterface; use InvalidArgumentException; use League\Flysystem\FilesystemException; use League\Flysystem\FilesystemOperator; -use League\Flysystem\UnableToReadFile; use League\Flysystem\UnableToRetrieveMetadata; use Psr\Http\Message\ResponseInterface; use RuntimeException; @@ -55,7 +54,6 @@ use function pathinfo; use function preg_replace; use function response; use function str_starts_with; -use function stripos; use function strtolower; use function view; @@ -106,9 +104,9 @@ class ImageFactory implements ImageFactoryInterface $filename = $download ? addcslashes(string: basename(path: $path), characters: '"') : ''; return $this->imageResponse(data: $filesystem->read(location: $path), mime_type: $mime_type, filename: $filename); - } catch (UnableToReadFile | FilesystemException $ex) { + } catch (FilesystemException $ex) { return $this->replacementImageResponse(text: (string) StatusCodeInterface::STATUS_NOT_FOUND) - ->withHeader('x-thumbnail-exception', get_class(object: $ex) . ': ' . $ex->getMessage()); + ->withHeader('x-file-exception', get_class(object: $ex) . ': ' . $ex->getMessage()); } } @@ -121,17 +119,17 @@ class ImageFactory implements ImageFactoryInterface ): ResponseInterface { try { $mime_type = $filesystem->mimeType(path: $path); - $image = $this->imageManager()->read(input: $filesystem->readStream($path)); + $image = $this->imageManager()->decodeBinary(binary: $filesystem->read(location: $path)); $image = $this->resizeImage(image: $image, width: $width, height: $height, fit: $fit); $quality = $this->extractImageQuality(image: $image, default: static::GD_DEFAULT_THUMBNAIL_QUALITY); - $data = $image->encodeByMediaType(type: $mime_type, quality: $quality)->toString(); + $data = $image->encodeUsingMediaType(mediaType: $mime_type, quality: $quality)->toString(); return $this->imageResponse(data: $data, mime_type: $mime_type, filename: ''); - } catch (FilesystemException | UnableToReadFile $ex) { + } catch (FilesystemException $ex) { return $this ->replacementImageResponse(text: (string) StatusCodeInterface::STATUS_NOT_FOUND) ->withHeader('x-thumbnail-exception', get_class(object: $ex) . ': ' . $ex->getMessage()); - } catch (RuntimeException $ex) { + } catch (ImageException $ex) { return $this ->replacementImageResponse(text: '.' . pathinfo(path: $path, flags: PATHINFO_EXTENSION)) ->withHeader('x-thumbnail-exception', get_class(object: $ex) . ': ' . $ex->getMessage()); @@ -153,20 +151,20 @@ class ImageFactory implements ImageFactoryInterface try { $mime_type = $media_file->mimeType(); - $image = $this->imageManager()->read(input: $filesystem->readStream($path)); + $image = $this->imageManager()->decodeBinary(binary: $filesystem->read(location: $path)); $watermark = $this->createWatermark(width: $image->width(), height: $image->height(), media_file: $media_file); $image = $this->addWatermark(image: $image, watermark: $watermark); $filename = $download ? basename(path: $path) : ''; $quality = $this->extractImageQuality(image: $image, default: static::GD_DEFAULT_IMAGE_QUALITY); - $data = $image->encodeByMediaType(type: $mime_type, quality: $quality)->toString(); + $data = $image->encodeUsingMediaType(mediaType: $mime_type, quality: $quality)->toString(); return $this->imageResponse(data: $data, mime_type: $mime_type, filename: $filename); - } catch (NotReadableException $ex) { + } catch (ImageException $ex) { return $this->replacementImageResponse(text: pathinfo(path: $path, flags: PATHINFO_EXTENSION)) ->withHeader('x-image-exception', $ex->getMessage()); - } catch (FilesystemException | UnableToReadFile $ex) { + } catch (FilesystemException $ex) { return $this->replacementImageResponse(text: (string) StatusCodeInterface::STATUS_NOT_FOUND) - ->withHeader('x-thumbnail-exception', get_class(object: $ex) . ': ' . $ex->getMessage()); + ->withHeader('x-image-exception', get_class(object: $ex) . ': ' . $ex->getMessage()); } catch (Throwable $ex) { return $this->replacementImageResponse(text: (string) StatusCodeInterface::STATUS_INTERNAL_SERVER_ERROR) ->withHeader('x-image-exception', $ex->getMessage()); @@ -180,10 +178,10 @@ class ImageFactory implements ImageFactoryInterface string $fit, bool $add_watermark ): string { - // Where are the images stored. + // Where are the images stored? $filesystem = $media_file->media()->tree()->mediaFilesystem(); - // Where is the image stored in the filesystem. + // Where is the image stored in the filesystem? $path = $media_file->filename(); $key = implode(separator: ':', array: [ @@ -197,7 +195,7 @@ class ImageFactory implements ImageFactoryInterface ]); $closure = function () use ($filesystem, $path, $width, $height, $fit, $add_watermark, $media_file): string { - $image = $this->imageManager()->read(input: $filesystem->readStream($path)); + $image = $this->imageManager()->decodeBinary(binary: $filesystem->read(location: $path)); $image = $this->resizeImage(image: $image, width: $width, height: $height, fit: $fit); if ($add_watermark) { @@ -205,9 +203,9 @@ class ImageFactory implements ImageFactoryInterface $image = $this->addWatermark(image: $image, watermark: $watermark); } - $quality = $this->extractImageQuality(image: $image, default: static::GD_DEFAULT_THUMBNAIL_QUALITY); + $quality = $this->extractImageQuality(image: $image, default: static::GD_DEFAULT_THUMBNAIL_QUALITY); - return $image->encodeByMediaType(type: $media_file->mimeType(), quality: $quality)->toString(); + return $image->encodeUsingMediaType(mediaType: $media_file->mimeType(), quality: $quality)->toString(); }; return Registry::cache()->file()->remember(key: $key, closure: $closure, ttl: static::THUMBNAIL_CACHE_TTL); @@ -220,10 +218,10 @@ class ImageFactory implements ImageFactoryInterface string $fit, bool $add_watermark ): ResponseInterface { - // Where are the images stored. + // Where are the images stored? $filesystem = $media_file->media()->tree()->mediaFilesystem(); - // Where is the image stored in the filesystem. + // Where is the image stored in the filesystem? $path = $media_file->filename(); try { @@ -231,12 +229,8 @@ class ImageFactory implements ImageFactoryInterface $data = $this->mediaFileThumbnail($media_file, $width, $height, $fit, $add_watermark); - return $this->imageResponse(data: $data, mime_type: $mime_type, filename: ''); - } catch (NotReadableException $ex) { - return $this - ->replacementImageResponse(text: '.' . pathinfo(path: $path, flags: PATHINFO_EXTENSION)) - ->withHeader('x-thumbnail-exception', get_class(object: $ex) . ': ' . $ex->getMessage()); - } catch (FilesystemException | UnableToReadFile $ex) { + return $this->imageResponse(data: $data, mime_type: $mime_type, filename: ''); + } catch (FilesystemException $ex) { return $this ->replacementImageResponse(text: (string) StatusCodeInterface::STATUS_NOT_FOUND) ->withHeader('x-thumbnail-exception', get_class(object: $ex) . ': ' . $ex->getMessage()); @@ -256,19 +250,19 @@ class ImageFactory implements ImageFactoryInterface public function thumbnailNeedsWatermark(MediaFile $media_file, UserInterface $user): bool { - return $this->fileNeedsWatermark(media_file: $media_file, user: $user); + return $this->fileNeedsWatermark(media_file: $media_file, user: $user); } public function createWatermark(int $width, int $height, MediaFile $media_file): ImageInterface { return $this->imageManager() - ->read(input: Webtrees::ROOT_DIR . static::WATERMARK_FILE) + ->decodePath(path: Webtrees::ROOT_DIR . static::WATERMARK_FILE) ->scale(width: $width, height: $height); } public function addWatermark(ImageInterface $image, ImageInterface $watermark): ImageInterface { - return $image->place(element: $watermark, position: 'center'); + return $image->insert(image: $watermark, alignment: 'center'); } public function replacementImageResponse(string $text): ResponseInterface @@ -305,8 +299,9 @@ class ImageFactory implements ImageFactoryInterface return $response; } - return $response - ->withHeader('content-disposition', 'attachment; filename="' . addcslashes(string: basename(path: $filename), characters: '"') . '"'); + $filename = addcslashes(string: basename(path: $filename), characters: '"'); + + return $response->withHeader('content-disposition', 'attachment; filename="' . $filename . '"'); } /** diff --git a/composer.json b/composer.json index 3a0fb05e12..8ebb147ba1 100644 --- a/composer.json +++ b/composer.json @@ -53,7 +53,7 @@ "guzzlehttp/guzzle": "7.10.0", "illuminate/database": "12.58.0", "illuminate/support": "12.58.0", - "intervention/image": "3.11.7", + "intervention/image": "4.0.3", "league/commonmark": "2.8.2", "league/flysystem": "3.33.0", "league/flysystem-path-prefixing": "3.31.0", diff --git a/composer.lock b/composer.lock index df6be2fb67..136c41432e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "796ea38dabad4d5cdfb935edce714686", + "content-hash": "9808ac7944bdfc0a1d7a3d93b3cd818b", "packages": [ { "name": "aura/router", @@ -1589,26 +1589,26 @@ }, { "name": "intervention/gif", - "version": "4.2.4", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/Intervention/gif.git", - "reference": "c3598a16ebe7690cd55640c44144a9df383ea73c" + "reference": "d856f59205aec768059d837148d755c079cdb94a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Intervention/gif/zipball/c3598a16ebe7690cd55640c44144a9df383ea73c", - "reference": "c3598a16ebe7690cd55640c44144a9df383ea73c", + "url": "https://api.github.com/repos/Intervention/gif/zipball/d856f59205aec768059d837148d755c079cdb94a", + "reference": "d856f59205aec768059d837148d755c079cdb94a", "shasum": "" }, "require": { - "php": "^8.1" + "php": "^8.3" }, "require-dev": { "phpstan/phpstan": "^2.1", - "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0", + "phpunit/phpunit": "^12.0", "slevomat/coding-standard": "~8.0", - "squizlabs/php_codesniffer": "^3.8" + "squizlabs/php_codesniffer": "^4" }, "type": "library", "autoload": { @@ -1627,7 +1627,7 @@ "homepage": "https://intervention.io/" } ], - "description": "Native PHP GIF Encoder/Decoder", + "description": "PHP GIF Encoder/Decoder", "homepage": "https://github.com/intervention/gif", "keywords": [ "animation", @@ -1637,7 +1637,7 @@ ], "support": { "issues": "https://github.com/Intervention/gif/issues", - "source": "https://github.com/Intervention/gif/tree/4.2.4" + "source": "https://github.com/Intervention/gif/tree/5.0.0" }, "funding": [ { @@ -1653,33 +1653,33 @@ "type": "ko_fi" } ], - "time": "2026-01-04T09:27:23+00:00" + "time": "2026-03-21T05:08:17+00:00" }, { "name": "intervention/image", - "version": "3.11.7", + "version": "4.0.3", "source": { "type": "git", "url": "https://github.com/Intervention/image.git", - "reference": "2159bcccff18f09d2a392679b81a82c5a003f9bb" + "reference": "76d4e5a48b78f7b48f84d90160e6973b1e800832" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Intervention/image/zipball/2159bcccff18f09d2a392679b81a82c5a003f9bb", - "reference": "2159bcccff18f09d2a392679b81a82c5a003f9bb", + "url": "https://api.github.com/repos/Intervention/image/zipball/76d4e5a48b78f7b48f84d90160e6973b1e800832", + "reference": "76d4e5a48b78f7b48f84d90160e6973b1e800832", "shasum": "" }, "require": { "ext-mbstring": "*", - "intervention/gif": "^4.2", - "php": "^8.1" + "intervention/gif": "^5", + "php": "^8.3" }, "require-dev": { "mockery/mockery": "^1.6", "phpstan/phpstan": "^2.1", - "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0", + "phpunit/phpunit": "^12.0", "slevomat/coding-standard": "~8.0", - "squizlabs/php_codesniffer": "^3.8" + "squizlabs/php_codesniffer": "^4" }, "suggest": { "ext-exif": "Recommended to be able to read EXIF data properly." @@ -1713,7 +1713,7 @@ ], "support": { "issues": "https://github.com/Intervention/image/issues", - "source": "https://github.com/Intervention/image/tree/3.11.7" + "source": "https://github.com/Intervention/image/tree/4.0.3" }, "funding": [ { @@ -1729,20 +1729,20 @@ "type": "ko_fi" } ], - "time": "2026-02-19T13:11:17+00:00" + "time": "2026-05-01T08:19:10+00:00" }, { "name": "laravel/serializable-closure", - "version": "v2.0.12", + "version": "v2.0.13", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "a6abb4e54f6fcd3138120b9ad497f0bd146f9919" + "reference": "b566ee0dd251f3c4078bed003a7ce015f5ea6dce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/a6abb4e54f6fcd3138120b9ad497f0bd146f9919", - "reference": "a6abb4e54f6fcd3138120b9ad497f0bd146f9919", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/b566ee0dd251f3c4078bed003a7ce015f5ea6dce", + "reference": "b566ee0dd251f3c4078bed003a7ce015f5ea6dce", "shasum": "" }, "require": { @@ -1790,7 +1790,7 @@ "issues": "https://github.com/laravel/serializable-closure/issues", "source": "https://github.com/laravel/serializable-closure" }, - "time": "2026-04-14T13:33:34+00:00" + "time": "2026-04-16T14:03:50+00:00" }, { "name": "league/commonmark", @@ -3569,29 +3569,29 @@ }, { "name": "sabre/uri", - "version": "3.0.3", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sabre-io/uri.git", - "reference": "4fa0b2049e06a4fbe4aea4f0aa69e7b8410a13bc" + "reference": "a926c749dddfb289b8a9b5218d16ac06affdc631" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/uri/zipball/4fa0b2049e06a4fbe4aea4f0aa69e7b8410a13bc", - "reference": "4fa0b2049e06a4fbe4aea4f0aa69e7b8410a13bc", + "url": "https://api.github.com/repos/sabre-io/uri/zipball/a926c749dddfb289b8a9b5218d16ac06affdc631", + "reference": "a926c749dddfb289b8a9b5218d16ac06affdc631", "shasum": "" }, "require": { - "php": "^7.4 || ^8.0" + "php": "^8.2" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.94", + "friendsofphp/php-cs-fixer": "^3.95", "phpstan/extension-installer": "^1.4", "phpstan/phpstan": "^2.1", "phpstan/phpstan-phpunit": "^2.0", "phpstan/phpstan-strict-rules": "^2.0", - "phpunit/phpunit": "^9.6", - "rector/rector": "^2.3" + "phpunit/phpunit": "^10.5", + "rector/rector": "^2.4" }, "type": "library", "autoload": { @@ -3626,7 +3626,7 @@ "issues": "https://github.com/sabre-io/uri/issues", "source": "https://github.com/fruux/sabre-uri" }, - "time": "2026-04-01T08:19:11+00:00" + "time": "2026-04-26T04:19:03+00:00" }, { "name": "sabre/vobject", @@ -3734,16 +3734,16 @@ }, { "name": "sabre/xml", - "version": "4.0.7", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/sabre-io/xml.git", - "reference": "53db7bad0953949fb61037fbf9b13b421492395c" + "reference": "bec83cbe2f4e1e1ca4254ed8d7caa7e32cc74b05" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/xml/zipball/53db7bad0953949fb61037fbf9b13b421492395c", - "reference": "53db7bad0953949fb61037fbf9b13b421492395c", + "url": "https://api.github.com/repos/sabre-io/xml/zipball/bec83cbe2f4e1e1ca4254ed8d7caa7e32cc74b05", + "reference": "bec83cbe2f4e1e1ca4254ed8d7caa7e32cc74b05", "shasum": "" }, "require": { @@ -3751,14 +3751,17 @@ "ext-xmlreader": "*", "ext-xmlwriter": "*", "lib-libxml": ">=2.6.20", - "php": "^7.4 || ^8.0", + "php": "^8.2", "sabre/uri": ">=2.0,<4.0.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.94", + "friendsofphp/php-cs-fixer": "^3.95", + "phpstan/extension-installer": "^1.4", "phpstan/phpstan": "^2.1", - "phpunit/phpunit": "^9.6", - "rector/rector": "^2.3" + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^10.5", + "rector/rector": "^2.4" }, "type": "library", "autoload": { @@ -3800,7 +3803,7 @@ "issues": "https://github.com/sabre-io/xml/issues", "source": "https://github.com/fruux/sabre-xml" }, - "time": "2026-04-02T11:40:41+00:00" + "time": "2026-04-27T10:56:01+00:00" }, { "name": "symfony/cache", @@ -4227,16 +4230,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "f57b899fa736fd71121168ef268f23c206083f0a" + "reference": "e4a2e29753c7801f7a8340e066cfa788f3bc8101" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f57b899fa736fd71121168ef268f23c206083f0a", - "reference": "f57b899fa736fd71121168ef268f23c206083f0a", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/e4a2e29753c7801f7a8340e066cfa788f3bc8101", + "reference": "e4a2e29753c7801f7a8340e066cfa788f3bc8101", "shasum": "" }, "require": { @@ -4288,7 +4291,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.8" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.9" }, "funding": [ { @@ -4308,7 +4311,7 @@ "type": "tidelift" } ], - "time": "2026-03-30T13:54:39+00:00" + "time": "2026-04-18T13:18:21+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -4540,16 +4543,16 @@ }, { "name": "symfony/mime", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "6df02f99998081032da3407a8d6c4e1dcb5d4379" + "reference": "2d550c4758ba4c47519a6667c36553d535705b0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/6df02f99998081032da3407a8d6c4e1dcb5d4379", - "reference": "6df02f99998081032da3407a8d6c4e1dcb5d4379", + "url": "https://api.github.com/repos/symfony/mime/zipball/2d550c4758ba4c47519a6667c36553d535705b0c", + "reference": "2d550c4758ba4c47519a6667c36553d535705b0c", "shasum": "" }, "require": { @@ -4605,7 +4608,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.4.8" + "source": "https://github.com/symfony/mime/tree/v7.4.9" }, "funding": [ { @@ -4625,7 +4628,7 @@ "type": "tidelift" } ], - "time": "2026-03-30T14:11:46+00:00" + "time": "2026-04-29T13:21:53+00:00" }, { "name": "symfony/polyfill-ctype", @@ -5735,16 +5738,16 @@ }, { "name": "symfony/var-exporter", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "398907e89a2a56fe426f7955c6fa943ec0c77225" + "reference": "22e03a49c95ef054a43601cd159b222bfab1c701" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/398907e89a2a56fe426f7955c6fa943ec0c77225", - "reference": "398907e89a2a56fe426f7955c6fa943ec0c77225", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/22e03a49c95ef054a43601cd159b222bfab1c701", + "reference": "22e03a49c95ef054a43601cd159b222bfab1c701", "shasum": "" }, "require": { @@ -5792,7 +5795,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v7.4.8" + "source": "https://github.com/symfony/var-exporter/tree/v7.4.9" }, "funding": [ { @@ -5812,7 +5815,7 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-04-18T13:18:21+00:00" }, { "name": "tecnickcom/tcpdf", @@ -8006,16 +8009,16 @@ }, { "name": "symfony/config", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "2d19dde43fa2ff720b9a40763ace7226594f503b" + "reference": "d4a277b7a0f26487db16b264d935c617b7d994ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/2d19dde43fa2ff720b9a40763ace7226594f503b", - "reference": "2d19dde43fa2ff720b9a40763ace7226594f503b", + "url": "https://api.github.com/repos/symfony/config/zipball/d4a277b7a0f26487db16b264d935c617b7d994ea", + "reference": "d4a277b7a0f26487db16b264d935c617b7d994ea", "shasum": "" }, "require": { @@ -8061,7 +8064,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v7.4.8" + "source": "https://github.com/symfony/config/tree/v7.4.9" }, "funding": [ { @@ -8081,20 +8084,20 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-04-29T14:25:20+00:00" }, { "name": "symfony/filesystem", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "58b9790d12f9670b7f53a1c1738febd3108970a5" + "reference": "dcd8f96bcdc0f128ec406c765cc066c6035d1be3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/58b9790d12f9670b7f53a1c1738febd3108970a5", - "reference": "58b9790d12f9670b7f53a1c1738febd3108970a5", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/dcd8f96bcdc0f128ec406c765cc066c6035d1be3", + "reference": "dcd8f96bcdc0f128ec406c765cc066c6035d1be3", "shasum": "" }, "require": { @@ -8131,7 +8134,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.4.8" + "source": "https://github.com/symfony/filesystem/tree/v7.4.9" }, "funding": [ { @@ -8151,7 +8154,7 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-04-18T13:18:21+00:00" }, { "name": "symfony/stopwatch", diff --git a/tests/app/Factories/ImageFactoryTest.php b/tests/app/Factories/ImageFactoryTest.php index bfe43cfffd..470fae1486 100644 --- a/tests/app/Factories/ImageFactoryTest.php +++ b/tests/app/Factories/ImageFactoryTest.php @@ -122,7 +122,7 @@ class ImageFactoryTest extends TestCase self::assertSame('image/svg+xml', $response->getHeaderLine('content-type')); self::assertStringContainsString( 'UnableToReadFile', - $response->getHeaderLine('x-thumbnail-exception'), + $response->getHeaderLine('x-file-exception'), ); } -- cgit v1.3