Skip to content

Commit ce70865

Browse files
committed
Image: catches all errors during saving
1 parent 574a2d1 commit ce70865

File tree

2 files changed

+39
-36
lines changed

2 files changed

+39
-36
lines changed

src/Utils/Image.php

+21-36
Original file line numberDiff line numberDiff line change
@@ -718,42 +718,27 @@ public function send(int $type = ImageType::JPEG, ?int $quality = null): void
718718
*/
719719
private function output(int $type, ?int $quality, ?string $file = null): void
720720
{
721-
switch ($type) {
722-
case ImageType::JPEG:
723-
$quality = $quality === null ? 85 : max(0, min(100, $quality));
724-
$success = @imagejpeg($this->image, $file, $quality); // @ is escalated to exception
725-
break;
726-
727-
case ImageType::PNG:
728-
$quality = $quality === null ? 9 : max(0, min(9, $quality));
729-
$success = @imagepng($this->image, $file, $quality); // @ is escalated to exception
730-
break;
731-
732-
case ImageType::GIF:
733-
$success = @imagegif($this->image, $file); // @ is escalated to exception
734-
break;
735-
736-
case ImageType::WEBP:
737-
$quality = $quality === null ? 80 : max(0, min(100, $quality));
738-
$success = @imagewebp($this->image, $file, $quality); // @ is escalated to exception
739-
break;
740-
741-
case ImageType::AVIF:
742-
$quality = $quality === null ? 30 : max(0, min(100, $quality));
743-
$success = @imageavif($this->image, $file, $quality); // @ is escalated to exception
744-
break;
745-
746-
case ImageType::BMP:
747-
$success = @imagebmp($this->image, $file); // @ is escalated to exception
748-
break;
749-
750-
default:
751-
throw new Nette\InvalidArgumentException("Unsupported image type '$type'.");
752-
}
753-
754-
if (!$success) {
755-
throw new ImageException(Helpers::getLastError() ?: 'Unknown error');
756-
}
721+
[$defQuality, $min, $max] = match ($type) {
722+
ImageType::JPEG => [85, 0, 100],
723+
ImageType::PNG => [9, 0, 9],
724+
ImageType::GIF => [null, null, null],
725+
ImageType::WEBP => [80, 0, 100],
726+
ImageType::AVIF => [30, 0, 100],
727+
ImageType::BMP => [null, null, null],
728+
default => throw new Nette\InvalidArgumentException("Unsupported image type '$type'."),
729+
};
730+
731+
$args = [$this->image, $file];
732+
if ($defQuality !== null) {
733+
$args[] = $quality === null ? $defQuality : max($min, min($max, $quality));
734+
}
735+
736+
Callback::invokeSafe('image' . self::Formats[$type], $args, function (string $message) use ($file): void {
737+
if ($file !== null) {
738+
@unlink($file);
739+
}
740+
throw new ImageException($message);
741+
});
757742
}
758743

759744

tests/Utils/Image.save.phpt

+18
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,21 @@ Assert::exception(
8888
Nette\InvalidArgumentException::class,
8989
'Unsupported file extension \'psd\'.',
9090
);
91+
92+
93+
test('saving palette-based as WEBP should fail without creating file', function () {
94+
if (!Image::isTypeSupported(Image::WEBP) || PHP_VERSION_ID < 80200) {
95+
return;
96+
}
97+
98+
$paletteImage = Image::fromFile(__DIR__ . '/fixtures.images/logo.gif');
99+
$filename = getTempDir() . '/palette-test.webp';
100+
101+
Assert::exception(
102+
fn() => $paletteImage->save($filename),
103+
Nette\Utils\ImageException::class,
104+
'Palette %a%',
105+
);
106+
107+
Assert::false(is_file($filename));
108+
});

0 commit comments

Comments
 (0)