summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Roach <greg@subaqua.co.uk>2026-05-04 23:30:47 +0100
committerGreg Roach <greg@subaqua.co.uk>2026-05-04 23:30:47 +0100
commit930f9f88b7fa24a11defa490560ad2102adc0e04 (patch)
tree8f7ede37b32f7321204fa595c60820ec47a55f9c
parent4f8c0f4e7de78ed2e8e5b8d518ec43645bee67ab (diff)
downloadwebtrees-930f9f88b7fa24a11defa490560ad2102adc0e04.tar.gz
webtrees-930f9f88b7fa24a11defa490560ad2102adc0e04.tar.bz2
webtrees-930f9f88b7fa24a11defa490560ad2102adc0e04.zip
Fix: #5365 - upgrade from intervention/image v3 to v4
-rw-r--r--app/Factories/ImageFactory.php59
-rw-r--r--composer.json2
-rw-r--r--composer.lock151
-rw-r--r--tests/app/Factories/ImageFactoryTest.php2
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'),
);
}