diff --git a/composer.json b/composer.json index 4d092ae..7b9ea43 100755 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "nelson/resizer", "description": "Resizer Extension for Nette Framework & Latte", "require": { - "php": "^8.0", + "php": "^8.1", "ext-fileinfo": "*", "latte/latte": "^2.11.0 || ^3.0.0", "nette/application": "^3.1", diff --git a/src/DI/ResizerConfigDTO.php b/src/DI/ResizerConfigDTO.php index 67a9356..5a1e595 100644 --- a/src/DI/ResizerConfigDTO.php +++ b/src/DI/ResizerConfigDTO.php @@ -11,12 +11,15 @@ final class ResizerConfigDTO public string $wwwDir; public string $tempDir; public string $cache = '/resizer/'; + public bool $upgradeJpg2Webp = true; public bool $upgradePng2Webp = true; public bool $upgradeJpg2Avif = true; public bool $upgradePng2Avif = true; + public bool $isWebpSupportedByServer = false; public bool $isAvifSupportedByServer = false; + public bool $strip = true; /** @var int<0, 100> */ diff --git a/src/Dimensions.php b/src/Dimensions.php index 17b3afb..b96f6d8 100755 --- a/src/Dimensions.php +++ b/src/Dimensions.php @@ -10,8 +10,8 @@ class Dimensions * @param positive-int $height */ public function __construct( - private int $width, - private int $height + private readonly int $width, + private readonly int $height ) { } diff --git a/src/OutputFormat.php b/src/OutputFormat.php index 11e22a7..0c170dc 100644 --- a/src/OutputFormat.php +++ b/src/OutputFormat.php @@ -16,8 +16,8 @@ final class OutputFormat public function __construct( - private Request $request, - private ResizerConfig $config, + private readonly Request $request, + private readonly ResizerConfig $config, ) { $this->browserSupportsAvif = $this->browserSupports(Resizer::MIME_TYPE_AVIF); @@ -33,6 +33,8 @@ public function getOutputFormat(string $file, ?string $format = null): ?string $format = match ($suffix) { Resizer::FORMAT_SUFFIX_JPG => $this->getOutputFormatForJpg(), Resizer::FORMAT_SUFFIX_PNG => $this->getOutputFormatForPng(), + Resizer::FORMAT_SUFFIX_WEBP => $this->getOutputFormatForWebp(), + Resizer::FORMAT_SUFFIX_AVIF => $this->getOutputFormatForAvif(), default => $suffix, }; } @@ -42,6 +44,26 @@ public function getOutputFormat(string $file, ?string $format = null): ?string } + private function getOutputFormatForWebp(): string + { + return match (true) { + $this->canServeWebp() => Resizer::FORMAT_SUFFIX_WEBP, + $this->canServeAvif() => Resizer::FORMAT_SUFFIX_AVIF, + default => Resizer::FORMAT_SUFFIX_JPG, + }; + } + + + private function getOutputFormatForAvif(): string + { + return match (true) { + $this->canServeAvif() => Resizer::FORMAT_SUFFIX_AVIF, + $this->canServeWebp() => Resizer::FORMAT_SUFFIX_WEBP, + default => Resizer::FORMAT_SUFFIX_JPG, + }; + } + + private function getOutputFormatForJpg(): string { return match (true) { @@ -64,7 +86,6 @@ private function getOutputFormatForPng(): string private function canServeWebp(): bool { - dump($this->config->isWebpSupportedByServer()); return $this->config->isWebpSupportedByServer() && $this->browserSupportsWebp; } @@ -77,10 +98,10 @@ private function canServeAvif(): bool private function isFormatSupported(string $format): void { - if (!in_array(strtolower($format), Resizer::SUPPORTED_FORMATS, true)) { + if (!in_array(strtolower($format), $this->config->getSupportedFormats(), true)) { throw new Exception(sprintf( "Format '%s' not supported (%s).", - $format, implode(', ', Resizer::SUPPORTED_FORMATS), + $format, implode(', ', $this->config->getSupportedFormats()), )); } } @@ -111,17 +132,10 @@ private function isFileJpg(string $path): bool } - private function isFilePng(string $path): bool - { - return $this->isFileOfFormat($path, Resizer::FORMAT_SUFFIX_PNG); - } - - private function getFileFormat(string $file): string { return match (true) { $this->isFileJpg($file) => Resizer::FORMAT_SUFFIX_JPG, - $this->isFilePng($file) => Resizer::FORMAT_SUFFIX_PNG, default => pathinfo($file, PATHINFO_EXTENSION), }; } diff --git a/src/Presenters/ResizePresenter.php b/src/Presenters/ResizePresenter.php index e3013cc..60b9ea2 100644 --- a/src/Presenters/ResizePresenter.php +++ b/src/Presenters/ResizePresenter.php @@ -20,7 +20,7 @@ final class ResizePresenter extends Presenter public function __construct( - private IResizer $resizer, + private readonly IResizer $resizer, ) { parent::__construct(); diff --git a/src/Resizer.php b/src/Resizer.php index 8cb6cc3..8937a49 100644 --- a/src/Resizer.php +++ b/src/Resizer.php @@ -30,25 +30,13 @@ final class Resizer implements IResizer public const MIME_TYPE_WEBP = 'image/webp'; public const MIME_TYPE_AVIF = 'image/avif'; - public const SUPPORTED_FORMATS = [ - 'jpeg', - 'jpg', - 'gif', - 'png', - 'wbmp', - 'xbm', - 'webp', - 'avif', - 'bmp', - ]; - private AbstractImagine $imagine; private string $cacheDir; public function __construct( - private ResizerConfig $config, - private OutputFormat $outputFormat, + private readonly ResizerConfig $config, + private readonly OutputFormat $outputFormat, ) { $this->cacheDir = $config->getTempDir() . $config->getCache(); diff --git a/src/ResizerConfig.php b/src/ResizerConfig.php index d76d984..d82e685 100644 --- a/src/ResizerConfig.php +++ b/src/ResizerConfig.php @@ -11,10 +11,26 @@ final class ResizerConfig use SmartObject; + /** @var array */ + private array $supportedFormats = [ + 'jpeg', + 'jpg', + 'gif', + 'png', + ]; + + public function __construct( - private ResizerConfigDTO $config, + private readonly ResizerConfigDTO $config, ) { + if ($config->isWebpSupportedByServer) { + $this->supportedFormats[] = Resizer::FORMAT_SUFFIX_WEBP; + } + + if ($config->isAvifSupportedByServer) { + $this->supportedFormats[] = Resizer::FORMAT_SUFFIX_AVIF; + } } @@ -137,4 +153,11 @@ public function getOptions(): array ]; } + + /** @return array */ + public function getSupportedFormats(): array + { + return $this->supportedFormats; + } + } diff --git a/src/ResizerParams.php b/src/ResizerParams.php index e193d99..390ca9d 100755 --- a/src/ResizerParams.php +++ b/src/ResizerParams.php @@ -11,14 +11,14 @@ class ResizerParams * @param positive-int|null $height */ public function __construct( - private bool $ifresize, - private ?string $horizontal, - private ?string $vertical, - private bool $forceDimensions, - private ?string $horizontalMargin, - private ?string $verticalMargin, - private ?int $width, - private ?int $height + private readonly bool $ifresize, + private readonly ?string $horizontal, + private readonly ?string $vertical, + private readonly bool $forceDimensions, + private readonly ?string $horizontalMargin, + private readonly ?string $verticalMargin, + private readonly ?int $width, + private readonly ?int $height ) { } diff --git a/tests/OutputFormatTest.php b/tests/OutputFormatTest.php index ddcb4aa..889a256 100644 --- a/tests/OutputFormatTest.php +++ b/tests/OutputFormatTest.php @@ -21,7 +21,10 @@ public static function setUpBeforeClass(): void public function testJpg(): void { $httpRequest = new Request(new UrlScript); - $outputFormat = new OutputFormat($httpRequest, $this->getConfig()); + $outputFormat = new OutputFormat( + $httpRequest, + $this->getConfig(), + ); $this->assertSame( $outputFormat->getOutputFormat('test.jpg'), @@ -40,12 +43,102 @@ public function testJpg(): void } + public function testAvif(): void + { + $httpRequest = new Request(new UrlScript, headers: ['accept' => 'image/avif,image/webp']); + $outputFormat = new OutputFormat( + $httpRequest, + $this->getConfig(true, true), + ); + + $this->assertSame( + $outputFormat->getOutputFormat('test.avif'), + 'avif', + ); + } + + + public function testAvif2Jpg(): void + { + $httpRequest = new Request(new UrlScript); + $outputFormat = new OutputFormat( + $httpRequest, + $this->getConfig(), + ); + + $this->assertSame( + $outputFormat->getOutputFormat('test.avif'), + 'jpg', + ); + } + + + public function testAvif2Webp(): void + { + $httpRequest = new Request(new UrlScript, headers: ['accept' => 'image/webp']); + $outputFormat = new OutputFormat( + $httpRequest, + $this->getConfig(true), + ); + + $this->assertSame( + $outputFormat->getOutputFormat('test.avif'), + 'webp', + ); + } + + + public function testWebp(): void + { + $httpRequest = new Request(new UrlScript, headers: ['accept' => 'image/avif,image/webp']); + $outputFormat = new OutputFormat( + $httpRequest, + $this->getConfig(true, true), + ); + + $this->assertSame( + $outputFormat->getOutputFormat('test.webp'), + 'webp', + ); + } + + + public function testWebp2Jpg(): void + { + $httpRequest = new Request(new UrlScript); + $outputFormat = new OutputFormat( + $httpRequest, + $this->getConfig(), + ); + + $this->assertSame( + $outputFormat->getOutputFormat('test.webp'), + 'jpg', + ); + } + + + public function testWebp2Avif(): void + { + $httpRequest = new Request(new UrlScript, headers: ['accept' => 'image/avif']); + $outputFormat = new OutputFormat( + $httpRequest, + $this->getConfig(false, true), + ); + + $this->assertSame( + $outputFormat->getOutputFormat('test.webp'), + 'avif', + ); + } + + public function testJpg2Avif(): void { $httpRequest = new Request(new UrlScript, headers: ['accept' => 'image/avif,image/webp']); $outputFormat = new OutputFormat( $httpRequest, - $this->getConfig(true, true) + $this->getConfig(true, true), ); $this->assertSame( @@ -60,7 +153,7 @@ public function testJpg2Webp(): void $httpRequest = new Request(new UrlScript, headers: ['accept' => 'image/webp']); $outputFormat = new OutputFormat( $httpRequest, - $this->getConfig(true, true) + $this->getConfig(true, true), ); $this->assertSame( @@ -75,7 +168,7 @@ public function testPng2Avif(): void $httpRequest = new Request(new UrlScript, headers: ['accept' => 'image/avif,image/webp']); $outputFormat = new OutputFormat( $httpRequest, - $this->getConfig(true, true) + $this->getConfig(true, true), ); $this->assertSame( @@ -90,7 +183,7 @@ public function testPng2Webp(): void $httpRequest = new Request(new UrlScript, headers: ['accept' => 'image/webp']); $outputFormat = new OutputFormat( $httpRequest, - $this->getConfig(true, true) + $this->getConfig(true, true), ); $this->assertSame( @@ -109,11 +202,9 @@ public function testPng(): void $outputFormat->getOutputFormat('test.png'), 'png', ); - } - private function getConfig(bool $webpSupported = false, bool $avifSupported = false): ResizerConfig { $config = new ResizerConfigDTO; @@ -132,5 +223,4 @@ private function getConfig(bool $webpSupported = false, bool $avifSupported = fa return new ResizerConfig($config); } - }