From 39e3dfe83b4fb4b7d9a9a300f0dccbb6b0871ae9 Mon Sep 17 00:00:00 2001 From: smiley Date: Sat, 25 Nov 2023 12:49:56 +0100 Subject: [PATCH] :fire: v6.0 first pass: PHP 8.2, remove deprecated elements, add type hints --- .phan/config.php | 17 +- composer.json | 10 +- examples/custom_output.php | 10 +- examples/eps.php | 4 +- examples/fpdf.php | 4 +- examples/html.php | 10 +- examples/image.php | 4 +- examples/imageWithRoundedShapes.php | 4 +- examples/imageWithText.php | 4 +- examples/imagick.php | 4 +- examples/imagickConvertSVGtoPNG.php | 2 - examples/imagickImageAsBackground.php | 2 - examples/imagickWithLogo.php | 3 +- examples/reflectance.php | 4 +- examples/svg.php | 4 +- examples/svgConvertViaCanvas.php | 4 +- examples/svgMeltedModules.php | 3 +- examples/svgRandomColoredDots.php | 3 +- examples/svgRoundQuietzone.php | 3 +- examples/svgWithLogo.php | 3 +- examples/svgWithLogoAndCustomShapes.php | 3 +- examples/text.php | 14 +- src/Common/EccLevel.php | 3 - src/Common/GDLuminanceSource.php | 36 ++-- src/Common/IMagickLuminanceSource.php | 13 +- src/Common/LuminanceSourceAbstract.php | 5 +- src/Common/LuminanceSourceInterface.php | 4 +- src/Data/AlphaNum.php | 2 +- src/Data/Byte.php | 2 +- src/Data/ECI.php | 2 +- src/Data/Hanzi.php | 2 +- src/Data/Kanji.php | 2 +- src/Data/Number.php | 2 +- src/Data/QRData.php | 7 +- src/Data/QRDataModeInterface.php | 2 +- src/Data/QRMatrix.php | 81 ++------- src/Decoder/BitMatrix.php | 12 +- src/Detector/AlignmentPattern.php | 2 +- src/Detector/FinderPattern.php | 2 +- src/Output/QREps.php | 10 +- src/Output/QRFpdf.php | 15 +- src/Output/QRGdImage.php | 87 +++------ src/Output/QRGdImageBMP.php | 2 +- src/Output/QRGdImageGIF.php | 2 +- src/Output/QRGdImageJPEG.php | 2 +- src/Output/QRGdImagePNG.php | 2 +- src/Output/QRGdImageWEBP.php | 2 +- src/Output/QRImage.php | 19 -- src/Output/QRImagick.php | 11 +- src/Output/QRMarkup.php | 4 +- src/Output/QRMarkupHTML.php | 2 +- src/Output/QRMarkupSVG.php | 6 +- src/Output/QROutputAbstract.php | 30 ++-- src/Output/QROutputInterface.php | 128 ++------------ src/Output/QRString.php | 111 ------------ src/Output/QRStringJSON.php | 6 +- src/Output/QRStringText.php | 8 +- src/QRCode.php | 224 ++---------------------- src/QROptionsTrait.php | 204 ++++----------------- tests/Data/QRDataTest.php | 6 +- tests/Data/QRMatrixTest.php | 43 +++-- tests/Output/QREpsTest.php | 4 +- tests/Output/QRFpdfTest.php | 5 +- tests/Output/QRGdImageBMPTest.php | 4 +- tests/Output/QRGdImageGIFTest.php | 4 +- tests/Output/QRGdImageJPGTest.php | 2 - tests/Output/QRGdImagePNGTest.php | 2 - tests/Output/QRGdImageWEBPTest.php | 4 +- tests/Output/QRImagickTest.php | 5 +- tests/Output/QRMarkupHTMLTest.php | 5 +- tests/Output/QRMarkupSVGTest.php | 5 +- tests/Output/QROutputTestAbstract.php | 6 +- tests/Output/QRStringJSONTest.php | 4 +- tests/Output/QRStringTEXTTest.php | 4 +- tests/Performance/output.php | 7 +- tests/Performance/qrcode.php | 8 +- tests/QRCodeReaderTestAbstract.php | 8 +- tests/QRCodeTest.php | 17 +- tests/QRMaxLengthTrait.php | 10 +- tests/QROptionsTest.php | 35 ++++ 80 files changed, 332 insertions(+), 1029 deletions(-) delete mode 100644 src/Output/QRImage.php delete mode 100644 src/Output/QRString.php diff --git a/.phan/config.php b/.phan/config.php index 72b796fa2..cb6554b66 100644 --- a/.phan/config.php +++ b/.phan/config.php @@ -14,8 +14,8 @@ return [ // Note that the **only** effect of choosing `'5.6'` is to infer // that functions removed in php 7.0 exist. // (See `backward_compatibility_checks` for additional options) - 'target_php_version' => null, - 'minimum_target_php_version' => '7.4', + 'target_php_version' => null, + 'minimum_target_php_version' => '8.2', // A list of directories that should be parsed for class and // method information. After excluding the directories @@ -24,19 +24,19 @@ return [ // // Thus, both first-party and third-party code being used by // your application should be included in this list. - 'directory_list' => [ + 'directory_list' => [ 'examples', 'src', 'tests', 'vendor', - '.phan/stubs' + '.phan/stubs', ], // A regex used to match every file name that you want to // exclude from parsing. Actual value will exclude every // "test", "tests", "Test" and "Tests" folders found in // "vendor/" directory. - 'exclude_file_regex' => '@^vendor/.*/(tests?|Tests?)/@', + 'exclude_file_regex' => '@^vendor/.*/(tests?|Tests?)/@', // A directory list that defines files that will be excluded // from static analysis, but whose class and method @@ -51,12 +51,9 @@ return [ // and `exclude_analysis_directory_list` arrays. 'exclude_analysis_directory_list' => [ 'vendor/', - '.phan/stubs' + '.phan/stubs', ], - 'suppress_issue_types' => [ + 'suppress_issue_types' => [ 'PhanAccessMethodInternal', - 'PhanAccessOverridesFinalConstant', - 'PhanDeprecatedClass', - 'PhanDeprecatedClassConstant', ], ]; diff --git a/composer.json b/composer.json index 169acd4db..b68cf35c0 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "chillerlan/php-qrcode", - "description": "A QR code generator and reader with a user friendly API. PHP 7.4+", + "description": "A QR code generator and reader with a user friendly API. PHP 8.2+", "homepage": "https://github.com/chillerlan/php-qrcode", "license": [ "MIT", "Apache-2.0" @@ -40,15 +40,15 @@ "minimum-stability": "stable", "prefer-stable": true, "require": { - "php": "^7.4 || ^8.0", + "php": "^8.2", "ext-mbstring": "*", - "chillerlan/php-settings-container": "^2.1.4 || ^3.1" + "chillerlan/php-settings-container": "^3.1" }, "require-dev": { - "chillerlan/php-authenticator": "^4.0 || ^5.0", + "chillerlan/php-authenticator": "^5.0", "phan/phan": "^5.4", "phpunit/phpunit": "^9.6", - "phpmd/phpmd": "^2.13", + "phpmd/phpmd": "^2.14", "setasign/fpdf": "^1.8.2", "squizlabs/php_codesniffer": "^3.7" }, diff --git a/examples/custom_output.php b/examples/custom_output.php index 48f20aa37..a6e581417 100644 --- a/examples/custom_output.php +++ b/examples/custom_output.php @@ -11,8 +11,7 @@ */ use chillerlan\QRCode\{QRCode, QROptions}; -use chillerlan\QRCode\Common\EccLevel; -use chillerlan\QRCode\Output\{QROutputAbstract, QROutputInterface}; +use chillerlan\QRCode\Output\QROutputAbstract; require_once __DIR__.'/../vendor/autoload.php'; @@ -25,7 +24,7 @@ class MyCustomOutput extends QROutputAbstract{ /** * @inheritDoc */ - public static function moduleValueIsValid($value):bool{ + public static function moduleValueIsValid(mixed $value):bool{ // TODO: Implement moduleValueIsValid() method. (interface) return false; } @@ -33,7 +32,7 @@ class MyCustomOutput extends QROutputAbstract{ /** * @inheritDoc */ - protected function prepareModuleValue($value){ + protected function prepareModuleValue(mixed $value):mixed{ // TODO: Implement prepareModuleValue() method. (abstract) return null; } @@ -73,7 +72,7 @@ class MyCustomOutput extends QROutputAbstract{ $options = new QROptions; $options->version = 5; -$options->eccLevel = EccLevel::L; +$options->eccLevel = 'L'; $data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s'; @@ -89,7 +88,6 @@ $qrOutputInterface = new MyCustomOutput($options, $qrcode->getQRMatrix()); var_dump($qrOutputInterface->dump()); // or just via the options -$options->outputType = QROutputInterface::CUSTOM; $options->outputInterface = MyCustomOutput::class; var_dump((new QRCode($options))->render($data)); diff --git a/examples/eps.php b/examples/eps.php index 3a29dc2fb..d68b18423 100644 --- a/examples/eps.php +++ b/examples/eps.php @@ -10,14 +10,14 @@ use chillerlan\QRCode\{QRCode, QROptions}; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\QROutputInterface; +use chillerlan\QRCode\Output\QREps; require_once __DIR__.'/../vendor/autoload.php'; $options = new QROptions; $options->version = 7; -$options->outputType = QROutputInterface::EPS; +$options->outputInterface = QREps::class; $options->scale = 5; $options->drawLightModules = false; // colors can be specified either as [R, G, B] or [C, M, Y, K] (0-255) diff --git a/examples/fpdf.php b/examples/fpdf.php index 465b284da..f4f30fa11 100644 --- a/examples/fpdf.php +++ b/examples/fpdf.php @@ -9,14 +9,14 @@ use chillerlan\QRCode\{QRCode, QROptions}; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\QROutputInterface; +use chillerlan\QRCode\Output\QRFpdf; require_once __DIR__ . '/../vendor/autoload.php'; $options = new QROptions; $options->version = 7; -$options->outputType = QROutputInterface::FPDF; +$options->outputInterface = QRFpdf::class; $options->scale = 5; $options->fpdfMeasureUnit = 'mm'; $options->bgColor = [222, 222, 222]; diff --git a/examples/html.php b/examples/html.php index 38d4b7fbe..c381e331d 100644 --- a/examples/html.php +++ b/examples/html.php @@ -10,16 +10,16 @@ use chillerlan\QRCode\{QRCode, QROptions}; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\QROutputInterface; +use chillerlan\QRCode\Output\QRMarkupHTML; require_once '../vendor/autoload.php'; $options = new QROptions; -$options->version = 5; -$options->outputType = QROutputInterface::MARKUP_HTML; -$options->cssClass = 'qrcode'; -$options->moduleValues = [ +$options->version = 5; +$options->outputInterface = QRMarkupHTML::class; +$options->cssClass = 'qrcode'; +$options->moduleValues = [ // finder QRMatrix::M_FINDER_DARK => '#A71111', // dark (true) QRMatrix::M_FINDER_DOT => '#A71111', // finder dot, dark (true) diff --git a/examples/image.php b/examples/image.php index 7dcb00f72..428437347 100644 --- a/examples/image.php +++ b/examples/image.php @@ -10,14 +10,14 @@ use chillerlan\QRCode\{QRCode, QROptions}; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\QROutputInterface; +use chillerlan\QRCode\Output\QRGdImagePNG; require_once __DIR__.'/../vendor/autoload.php'; $options = new QROptions; $options->version = 7; -$options->outputType = QROutputInterface::GDIMAGE_PNG; +$options->outputInterface = QRGdImagePNG::class; $options->scale = 20; $options->outputBase64 = false; $options->bgColor = [200, 150, 200]; diff --git a/examples/imageWithRoundedShapes.php b/examples/imageWithRoundedShapes.php index 687ca7d0d..f387d870c 100644 --- a/examples/imageWithRoundedShapes.php +++ b/examples/imageWithRoundedShapes.php @@ -16,7 +16,6 @@ use chillerlan\QRCode\Common\EccLevel; use chillerlan\QRCode\Data\QRMatrix; use chillerlan\QRCode\Output\QRGdImagePNG; -use chillerlan\QRCode\Output\QROutputInterface; use chillerlan\QRCode\QRCode; use chillerlan\QRCode\QROptions; use chillerlan\Settings\SettingsContainerInterface; @@ -30,7 +29,7 @@ require_once __DIR__ . '/../vendor/autoload.php'; class QRGdRounded extends QRGdImagePNG{ /** @inheritDoc */ - public function __construct(SettingsContainerInterface $options, QRMatrix $matrix){ + public function __construct(SettingsContainerInterface|QROptions $options, QRMatrix $matrix){ // enable the internal scaling for better rounding results at scale < 20 $options->drawCircularModules = true; @@ -137,7 +136,6 @@ class QRGdRounded extends QRGdImagePNG{ $options = new QROptions([ 'version' => 7, 'eccLevel' => EccLevel::H, - 'outputType' => QROutputInterface::CUSTOM, 'outputInterface' => QRGdRounded::class, 'outputBase64' => false, 'scale' => 30, diff --git a/examples/imageWithText.php b/examples/imageWithText.php index 79a3ed326..0f68870c5 100644 --- a/examples/imageWithText.php +++ b/examples/imageWithText.php @@ -13,7 +13,7 @@ */ use chillerlan\QRCode\{QRCode, QROptions}; -use chillerlan\QRCode\Output\{QROutputInterface, QRGdImagePNG}; +use chillerlan\QRCode\Output\QRGdImagePNG; require_once __DIR__.'/../vendor/autoload.php'; @@ -66,7 +66,7 @@ class QRImageWithText extends QRGdImagePNG{ $background = imagecolorallocate($this->image, ...$textBG); // allow transparency - if($this->options->imageTransparent && $this->options->outputType !== QROutputInterface::GDIMAGE_JPG){ + if($this->options->imageTransparent){ imagecolortransparent($this->image, $background); } diff --git a/examples/imagick.php b/examples/imagick.php index 6f73f2f40..8a00960b6 100644 --- a/examples/imagick.php +++ b/examples/imagick.php @@ -10,14 +10,14 @@ use chillerlan\QRCode\{QRCode, QROptions}; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\QROutputInterface; +use chillerlan\QRCode\Output\QRImagick; require_once __DIR__.'/../vendor/autoload.php'; $options = new QROptions; $options->version = 7; -$options->outputType = QROutputInterface::IMAGICK; +$options->outputInterface = QRImagick::class; $options->imagickFormat = 'webp'; $options->quality = 90; $options->scale = 20; diff --git a/examples/imagickConvertSVGtoPNG.php b/examples/imagickConvertSVGtoPNG.php index c5759caed..ba2e036db 100644 --- a/examples/imagickConvertSVGtoPNG.php +++ b/examples/imagickConvertSVGtoPNG.php @@ -18,7 +18,6 @@ use chillerlan\QRCode\Data\QRMatrix; use chillerlan\QRCode\Output\QRMarkupSVG; -use chillerlan\QRCode\Output\QROutputInterface; use chillerlan\QRCode\QRCode; use chillerlan\QRCode\QROptions; @@ -85,7 +84,6 @@ class SVGConvert extends QRMarkupSVG{ $options = new QROptions; $options->version = 7; -$options->outputType = QROutputInterface::CUSTOM; $options->outputInterface = SVGConvert::class; $options->imagickFormat = 'png32'; $options->scale = 20; diff --git a/examples/imagickImageAsBackground.php b/examples/imagickImageAsBackground.php index 10a4be3ad..951e93f21 100644 --- a/examples/imagickImageAsBackground.php +++ b/examples/imagickImageAsBackground.php @@ -10,7 +10,6 @@ use chillerlan\QRCode\Common\EccLevel; use chillerlan\QRCode\Output\QRImagick; -use chillerlan\QRCode\Output\QROutputInterface; use chillerlan\QRCode\QRCode; use chillerlan\QRCode\QRCodeException; use chillerlan\QRCode\QROptions; @@ -91,7 +90,6 @@ $options = new ImageAsBackgroundOptions; $options->background = __DIR__.'/background.jpg'; // setting from the augmented options $options->version = 5; -$options->outputType = QROutputInterface::CUSTOM; $options->outputInterface = QRImagickImageAsBackground::class; // use the custom output class $options->eccLevel = EccLevel::H; $options->outputBase64 = false; diff --git a/examples/imagickWithLogo.php b/examples/imagickWithLogo.php index 0fd7f1986..9c8611e5f 100644 --- a/examples/imagickWithLogo.php +++ b/examples/imagickWithLogo.php @@ -13,7 +13,7 @@ use chillerlan\QRCode\{QRCode, QRCodeException, QROptions}; use chillerlan\QRCode\Common\EccLevel; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\{QRImagick, QROutputInterface}; +use chillerlan\QRCode\Output\QRImagick; require_once __DIR__.'/../vendor/autoload.php'; @@ -98,7 +98,6 @@ $options = new ImagickWithLogoOptions; $options->pngLogo = __DIR__.'/octocat.png'; // setting from the augmented options $options->version = 5; -$options->outputType = QROutputInterface::CUSTOM; $options->outputInterface = QRImagickWithLogo::class; // use the custom output class $options->eccLevel = EccLevel::H; $options->outputBase64 = false; diff --git a/examples/reflectance.php b/examples/reflectance.php index 80c8dbba4..95ba2f8a1 100644 --- a/examples/reflectance.php +++ b/examples/reflectance.php @@ -10,7 +10,7 @@ use chillerlan\QRCode\Common\EccLevel; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\QROutputInterface; +use chillerlan\QRCode\Output\QRMarkupSVG; use chillerlan\QRCode\QRCode; use chillerlan\QRCode\QROptions; @@ -18,7 +18,7 @@ require_once __DIR__.'/../vendor/autoload.php'; $options = new QROptions; -$options->outputType = QROutputInterface::MARKUP_SVG; +$options->outputInterface = QRMarkupSVG::class; $options->outputBase64 = false; $options->svgAddXmlHeader = false; $options->connectPaths = true; diff --git a/examples/svg.php b/examples/svg.php index b0f221d8e..e60561d2a 100644 --- a/examples/svg.php +++ b/examples/svg.php @@ -12,14 +12,14 @@ use chillerlan\QRCode\{QRCode, QROptions}; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\QROutputInterface; +use chillerlan\QRCode\Output\QRMarkupSVG; require_once __DIR__.'/../vendor/autoload.php'; $options = new QROptions; $options->version = 7; -$options->outputType = QROutputInterface::MARKUP_SVG; +$options->outputInterface = QRMarkupSVG::class; $options->outputBase64 = false; // if set to false, the light modules won't be rendered $options->drawLightModules = true; diff --git a/examples/svgConvertViaCanvas.php b/examples/svgConvertViaCanvas.php index 530e7a284..78fc8de46 100644 --- a/examples/svgConvertViaCanvas.php +++ b/examples/svgConvertViaCanvas.php @@ -10,7 +10,7 @@ use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\QROutputInterface; +use chillerlan\QRCode\Output\QRMarkupSVG; use chillerlan\QRCode\QRCode; use chillerlan\QRCode\QROptions; @@ -19,7 +19,7 @@ require_once __DIR__.'/../vendor/autoload.php'; $options = new QROptions; $options->version = 7; -$options->outputType = QROutputInterface::MARKUP_SVG; +$options->outputInterface = QRMarkupSVG::class; $options->outputBase64 = false; $options->svgAddXmlHeader = false; $options->svgUseFillAttributes = false; diff --git a/examples/svgMeltedModules.php b/examples/svgMeltedModules.php index 3cc0ea139..f9bdaa408 100644 --- a/examples/svgMeltedModules.php +++ b/examples/svgMeltedModules.php @@ -13,7 +13,7 @@ use chillerlan\QRCode\{QRCode, QROptions}; use chillerlan\QRCode\Common\EccLevel; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\{QROutputInterface, QRMarkupSVG}; +use chillerlan\QRCode\Output\QRMarkupSVG; require_once __DIR__.'/../vendor/autoload.php'; @@ -256,7 +256,6 @@ $options->inverseMelt = true; $options->meltRadius = 0.4; $options->version = 7; -$options->outputType = QROutputInterface::CUSTOM; $options->outputInterface = MeltedSVGQRCodeOutput::class; $options->outputBase64 = false; $options->addQuietzone = true; diff --git a/examples/svgRandomColoredDots.php b/examples/svgRandomColoredDots.php index 4e89746e8..0883b7782 100644 --- a/examples/svgRandomColoredDots.php +++ b/examples/svgRandomColoredDots.php @@ -15,7 +15,7 @@ use chillerlan\QRCode\{QRCode, QROptions}; use chillerlan\QRCode\Common\EccLevel; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\{QROutputInterface, QRMarkupSVG}; +use chillerlan\QRCode\Output\QRMarkupSVG; require_once __DIR__.'/../vendor/autoload.php'; @@ -126,7 +126,6 @@ $options->svgDefs = ' ]]>'; // set the custom output interface -$options->outputType = QROutputInterface::CUSTOM; $options->outputInterface = RandomDotsSVGOutput::class; // common qrcode options diff --git a/examples/svgRoundQuietzone.php b/examples/svgRoundQuietzone.php index 1ca58d7c6..aa0597f02 100644 --- a/examples/svgRoundQuietzone.php +++ b/examples/svgRoundQuietzone.php @@ -14,7 +14,7 @@ use chillerlan\QRCode\Common\EccLevel; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\{QROutputInterface, QRMarkupSVG}; +use chillerlan\QRCode\Output\QRMarkupSVG; use chillerlan\QRCode\{QRCode, QRCodeException, QROptions}; require_once __DIR__.'/../vendor/autoload.php'; @@ -326,7 +326,6 @@ $options->version = 7; $options->eccLevel = EccLevel::H; $options->addQuietzone = false; // we're not adding a quiet zone, this is done internally in our own module $options->outputBase64 = false; // avoid base64 URI output for the example -$options->outputType = QROutputInterface::CUSTOM; $options->outputInterface = RoundQuietzoneSVGoutput::class; // load our own output class $options->drawLightModules = false; // set to true to add the light modules // common SVG options diff --git a/examples/svgWithLogo.php b/examples/svgWithLogo.php index 87a041413..1a8eb96d6 100644 --- a/examples/svgWithLogo.php +++ b/examples/svgWithLogo.php @@ -13,7 +13,7 @@ use chillerlan\QRCode\{QRCode, QRCodeException, QROptions}; use chillerlan\QRCode\Common\EccLevel; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\{QROutputInterface, QRMarkupSVG}; +use chillerlan\QRCode\Output\QRMarkupSVG; require_once __DIR__.'/../vendor/autoload.php'; @@ -113,7 +113,6 @@ $options->svgLogoScale = 0.25; $options->svgLogoCssClass = 'dark'; // QROptions $options->version = 5; -$options->outputType = QROutputInterface::CUSTOM; $options->outputInterface = QRSvgWithLogo::class; $options->outputBase64 = false; $options->eccLevel = EccLevel::H; // ECC level H is necessary when using logos diff --git a/examples/svgWithLogoAndCustomShapes.php b/examples/svgWithLogoAndCustomShapes.php index d639257ba..3b079bf8b 100644 --- a/examples/svgWithLogoAndCustomShapes.php +++ b/examples/svgWithLogoAndCustomShapes.php @@ -15,7 +15,7 @@ use chillerlan\QRCode\{QRCode, QRCodeException, QROptions}; use chillerlan\QRCode\Common\EccLevel; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\{QROutputInterface, QRMarkupSVG}; +use chillerlan\QRCode\Output\QRMarkupSVG; require_once __DIR__.'/../vendor/autoload.php'; @@ -174,7 +174,6 @@ $options->svgLogoCssClass = 'qr-logo dark'; // QROptions $options->version = 5; $options->quietzoneSize = 4; -$options->outputType = QROutputInterface::CUSTOM; $options->outputInterface = QRSvgWithLogoAndCustomShapes::class; $options->outputBase64 = false; $options->eccLevel = EccLevel::H; // ECC level H is required when using logos diff --git a/examples/text.php b/examples/text.php index 837e32f83..1aa83ec88 100644 --- a/examples/text.php +++ b/examples/text.php @@ -10,18 +10,18 @@ use chillerlan\QRCode\{QRCode, QROptions}; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\{QROutputInterface, QRStringText}; +use chillerlan\QRCode\Output\QRStringText; require_once __DIR__.'/../vendor/autoload.php'; $options = new QROptions; -$options->version = 3; -$options->quietzoneSize = 2; -$options->outputType = QROutputInterface::STRING_TEXT; -$options->eol = "\n"; -$options->textLineStart = str_repeat(' ', 6); -$options->moduleValues = [ +$options->version = 3; +$options->quietzoneSize = 2; +$options->outputInterface = QRStringText::class; +$options->eol = "\n"; +$options->textLineStart = str_repeat(' ', 6); +$options->moduleValues = [ QRMatrix::M_FINDER_DARK => QRStringText::ansi8('██', 124), QRMatrix::M_FINDER => QRStringText::ansi8('░░', 124), QRMatrix::M_FINDER_DOT => QRStringText::ansi8('██', 124), diff --git a/src/Common/EccLevel.php b/src/Common/EccLevel.php index 101785220..ecba012c0 100644 --- a/src/Common/EccLevel.php +++ b/src/Common/EccLevel.php @@ -143,9 +143,6 @@ final class EccLevel{ /** * @param int $eccLevel containing the two bits encoding a QR Code's error correction level * - * @todo: accept string values (PHP8+) - * @see https://github.com/chillerlan/php-qrcode/discussions/160 - * * @throws \chillerlan\QRCode\QRCodeException */ public function __construct(int $eccLevel){ diff --git a/src/Common/GDLuminanceSource.php b/src/Common/GDLuminanceSource.php index 027466f3e..d669ed176 100644 --- a/src/Common/GDLuminanceSource.php +++ b/src/Common/GDLuminanceSource.php @@ -13,41 +13,27 @@ namespace chillerlan\QRCode\Common; -use chillerlan\QRCode\Decoder\QRCodeDecoderException; +use chillerlan\QRCode\QROptions; use chillerlan\Settings\SettingsContainerInterface; -use function file_get_contents, get_resource_type, imagecolorat, imagecolorsforindex, - imagecreatefromstring, imagefilter, imagesx, imagesy, is_resource; -use const IMG_FILTER_BRIGHTNESS, IMG_FILTER_CONTRAST, IMG_FILTER_GRAYSCALE, IMG_FILTER_NEGATE, PHP_MAJOR_VERSION; +use GdImage; +use function file_get_contents, imagecolorat, imagecolorsforindex, + imagecreatefromstring, imagefilter, imagesx, imagesy; +use const IMG_FILTER_BRIGHTNESS, IMG_FILTER_CONTRAST, IMG_FILTER_GRAYSCALE, IMG_FILTER_NEGATE; /** * This class is used to help decode images from files which arrive as GD Resource * It does not support rotation. */ -class GDLuminanceSource extends LuminanceSourceAbstract{ +final class GDLuminanceSource extends LuminanceSourceAbstract{ - /** - * @var resource|\GdImage - */ - protected $gdImage; + private GdImage $gdImage; /** * GDLuminanceSource constructor. * - * @param resource|\GdImage $gdImage - * @param \chillerlan\Settings\SettingsContainerInterface|null $options - * * @throws \chillerlan\QRCode\Decoder\QRCodeDecoderException */ - public function __construct($gdImage, SettingsContainerInterface $options = null){ - - /** @noinspection PhpFullyQualifiedNameUsageInspection */ - if( - (PHP_MAJOR_VERSION >= 8 && !$gdImage instanceof \GdImage) // @todo: remove version check in v6 - || (PHP_MAJOR_VERSION < 8 && (!is_resource($gdImage) || get_resource_type($gdImage) !== 'gd')) - ){ - throw new QRCodeDecoderException('Invalid GD image source.'); // @codeCoverageIgnore - } - + public function __construct(GdImage $gdImage, SettingsContainerInterface|QROptions $options = null){ parent::__construct(imagesx($gdImage), imagesy($gdImage), $options); $this->gdImage = $gdImage; @@ -71,7 +57,7 @@ class GDLuminanceSource extends LuminanceSourceAbstract{ /** * */ - protected function setLuminancePixels():void{ + private function setLuminancePixels():void{ for($j = 0; $j < $this->height; $j++){ for($i = 0; $i < $this->width; $i++){ @@ -85,12 +71,12 @@ class GDLuminanceSource extends LuminanceSourceAbstract{ } /** @inheritDoc */ - public static function fromFile(string $path, SettingsContainerInterface $options = null):self{ + public static function fromFile(string $path, SettingsContainerInterface $options = null):static{ return new self(imagecreatefromstring(file_get_contents(self::checkFile($path))), $options); } /** @inheritDoc */ - public static function fromBlob(string $blob, SettingsContainerInterface $options = null):self{ + public static function fromBlob(string $blob, SettingsContainerInterface $options = null):static{ return new self(imagecreatefromstring($blob), $options); } diff --git a/src/Common/IMagickLuminanceSource.php b/src/Common/IMagickLuminanceSource.php index d4f66c5c2..d9518280e 100644 --- a/src/Common/IMagickLuminanceSource.php +++ b/src/Common/IMagickLuminanceSource.php @@ -13,6 +13,7 @@ namespace chillerlan\QRCode\Common; +use chillerlan\QRCode\QROptions; use chillerlan\Settings\SettingsContainerInterface; use Imagick; use function count; @@ -21,14 +22,14 @@ use function count; * This class is used to help decode images from files which arrive as Imagick Resource * It does not support rotation. */ -class IMagickLuminanceSource extends LuminanceSourceAbstract{ +final class IMagickLuminanceSource extends LuminanceSourceAbstract{ - protected Imagick $imagick; + private Imagick $imagick; /** * IMagickLuminanceSource constructor. */ - public function __construct(Imagick $imagick, SettingsContainerInterface $options = null){ + public function __construct(Imagick $imagick, SettingsContainerInterface|QROptions $options = null){ parent::__construct($imagick->getImageWidth(), $imagick->getImageHeight(), $options); $this->imagick = $imagick; @@ -53,7 +54,7 @@ class IMagickLuminanceSource extends LuminanceSourceAbstract{ /** * */ - protected function setLuminancePixels():void{ + private function setLuminancePixels():void{ $pixels = $this->imagick->exportImagePixels(1, 1, $this->width, $this->height, 'RGB', Imagick::PIXEL_CHAR); $count = count($pixels); @@ -63,12 +64,12 @@ class IMagickLuminanceSource extends LuminanceSourceAbstract{ } /** @inheritDoc */ - public static function fromFile(string $path, SettingsContainerInterface $options = null):self{ + public static function fromFile(string $path, SettingsContainerInterface $options = null):static{ return new self(new Imagick(self::checkFile($path)), $options); } /** @inheritDoc */ - public static function fromBlob(string $blob, SettingsContainerInterface $options = null):self{ + public static function fromBlob(string $blob, SettingsContainerInterface $options = null):static{ $im = new Imagick; $im->readImageBlob($blob); diff --git a/src/Common/LuminanceSourceAbstract.php b/src/Common/LuminanceSourceAbstract.php index 432a6e0d4..e74c8f7b1 100644 --- a/src/Common/LuminanceSourceAbstract.php +++ b/src/Common/LuminanceSourceAbstract.php @@ -25,8 +25,7 @@ use function array_slice, array_splice, file_exists, is_file, is_readable, realp */ abstract class LuminanceSourceAbstract implements LuminanceSourceInterface{ - /** @var \chillerlan\QRCode\QROptions|\chillerlan\Settings\SettingsContainerInterface */ - protected SettingsContainerInterface $options; + protected SettingsContainerInterface|QROptions $options; protected array $luminances; protected int $width; protected int $height; @@ -34,7 +33,7 @@ abstract class LuminanceSourceAbstract implements LuminanceSourceInterface{ /** * */ - public function __construct(int $width, int $height, SettingsContainerInterface $options = null){ + public function __construct(int $width, int $height, SettingsContainerInterface|QROptions $options = null){ $this->width = $width; $this->height = $height; $this->options = ($options ?? new QROptions); diff --git a/src/Common/LuminanceSourceInterface.php b/src/Common/LuminanceSourceInterface.php index 64409e36a..05e9ae596 100644 --- a/src/Common/LuminanceSourceInterface.php +++ b/src/Common/LuminanceSourceInterface.php @@ -51,11 +51,11 @@ interface LuminanceSourceInterface{ /** * Creates a LuminanceSource instance from the given file */ - public static function fromFile(string $path):self; + public static function fromFile(string $path):static; /** * Creates a LuminanceSource instance from the given data blob */ - public static function fromBlob(string $blob):self; + public static function fromBlob(string $blob):static; } diff --git a/src/Data/AlphaNum.php b/src/Data/AlphaNum.php index 81d0ff3f3..c1c8cb36b 100644 --- a/src/Data/AlphaNum.php +++ b/src/Data/AlphaNum.php @@ -69,7 +69,7 @@ final class AlphaNum extends QRDataModeAbstract{ /** * @inheritDoc */ - public function write(BitBuffer $bitBuffer, int $versionNumber):QRDataModeInterface{ + public function write(BitBuffer $bitBuffer, int $versionNumber):static{ $len = $this->getCharCount(); $bitBuffer diff --git a/src/Data/Byte.php b/src/Data/Byte.php index a86522602..b51ac254b 100644 --- a/src/Data/Byte.php +++ b/src/Data/Byte.php @@ -44,7 +44,7 @@ final class Byte extends QRDataModeAbstract{ /** * @inheritDoc */ - public function write(BitBuffer $bitBuffer, int $versionNumber):QRDataModeInterface{ + public function write(BitBuffer $bitBuffer, int $versionNumber):static{ $len = $this->getCharCount(); $bitBuffer diff --git a/src/Data/ECI.php b/src/Data/ECI.php index 3029e8373..396d5bbf7 100644 --- a/src/Data/ECI.php +++ b/src/Data/ECI.php @@ -67,7 +67,7 @@ final class ECI extends QRDataModeAbstract{ * @inheritDoc * @throws \chillerlan\QRCode\Data\QRCodeDataException */ - public function write(BitBuffer $bitBuffer, int $versionNumber):QRDataModeInterface{ + public function write(BitBuffer $bitBuffer, int $versionNumber):static{ $bitBuffer->put(self::DATAMODE, 4); if($this->encoding < 128){ diff --git a/src/Data/Hanzi.php b/src/Data/Hanzi.php index e11a81d9d..a40c97154 100644 --- a/src/Data/Hanzi.php +++ b/src/Data/Hanzi.php @@ -130,7 +130,7 @@ final class Hanzi extends QRDataModeAbstract{ * * @throws \chillerlan\QRCode\Data\QRCodeDataException on an illegal character occurence */ - public function write(BitBuffer $bitBuffer, int $versionNumber):QRDataModeInterface{ + public function write(BitBuffer $bitBuffer, int $versionNumber):static{ $bitBuffer ->put(self::DATAMODE, 4) diff --git a/src/Data/Kanji.php b/src/Data/Kanji.php index d6b6de5f7..fb6e27aab 100644 --- a/src/Data/Kanji.php +++ b/src/Data/Kanji.php @@ -123,7 +123,7 @@ final class Kanji extends QRDataModeAbstract{ * * @throws \chillerlan\QRCode\Data\QRCodeDataException on an illegal character occurence */ - public function write(BitBuffer $bitBuffer, int $versionNumber):QRDataModeInterface{ + public function write(BitBuffer $bitBuffer, int $versionNumber):static{ $bitBuffer ->put(self::DATAMODE, 4) diff --git a/src/Data/Number.php b/src/Data/Number.php index a2a7cee18..3fe564571 100644 --- a/src/Data/Number.php +++ b/src/Data/Number.php @@ -62,7 +62,7 @@ final class Number extends QRDataModeAbstract{ /** * @inheritDoc */ - public function write(BitBuffer $bitBuffer, int $versionNumber):QRDataModeInterface{ + public function write(BitBuffer $bitBuffer, int $versionNumber):static{ $len = $this->getCharCount(); $bitBuffer diff --git a/src/Data/QRData.php b/src/Data/QRData.php index e16dedb4f..7b7996c32 100644 --- a/src/Data/QRData.php +++ b/src/Data/QRData.php @@ -11,6 +11,7 @@ namespace chillerlan\QRCode\Data; use chillerlan\QRCode\Common\{BitBuffer, EccLevel, Mode, Version}; +use chillerlan\QRCode\QROptions; use chillerlan\Settings\SettingsContainerInterface; use function count; @@ -23,10 +24,8 @@ final class QRData{ /** * the options instance - * - * @var \chillerlan\Settings\SettingsContainerInterface|\chillerlan\QRCode\QROptions */ - private SettingsContainerInterface $options; + private SettingsContainerInterface|QROptions $options; /** * a BitBuffer instance @@ -58,7 +57,7 @@ final class QRData{ /** * QRData constructor. */ - public function __construct(SettingsContainerInterface $options, array $dataSegments = []){ + public function __construct(SettingsContainerInterface|QROptions $options, array $dataSegments = []){ $this->options = $options; $this->bitBuffer = new BitBuffer; $this->eccLevel = new EccLevel($this->options->eccLevel); diff --git a/src/Data/QRDataModeInterface.php b/src/Data/QRDataModeInterface.php index 321cf60b6..2cc346896 100644 --- a/src/Data/QRDataModeInterface.php +++ b/src/Data/QRDataModeInterface.php @@ -53,7 +53,7 @@ interface QRDataModeInterface{ * * @see \chillerlan\QRCode\Data\QRData::writeBitBuffer() */ - public function write(BitBuffer $bitBuffer, int $versionNumber):QRDataModeInterface; + public function write(BitBuffer $bitBuffer, int $versionNumber):static; /** * reads a segment from the BitBuffer and decodes in the current data mode diff --git a/src/Data/QRMatrix.php b/src/Data/QRMatrix.php index 6d1c13a7b..fb9584463 100755 --- a/src/Data/QRMatrix.php +++ b/src/Data/QRMatrix.php @@ -158,7 +158,7 @@ class QRMatrix{ /** * shortcut to initialize the functional patterns */ - public function initFunctionalPatterns():self{ + public function initFunctionalPatterns():static{ return $this ->setFinderPattern() ->setSeparators() @@ -184,21 +184,12 @@ class QRMatrix{ $matrix = $this->matrix; foreach($matrix as &$row){ - $row = array_map([$this, 'isDark'], $row); + $row = array_map($this->isDark(...), $row); } return $matrix; } - /** - * @deprecated 5.0.0 use QRMatrix::getMatrix() instead - * @see \chillerlan\QRCode\Data\QRMatrix::getMatrix() - * @codeCoverageIgnore - */ - public function matrix(bool $boolean = null):array{ - return $this->getMatrix($boolean); - } - /** * Returns the current version number */ @@ -206,15 +197,6 @@ class QRMatrix{ return $this->version; } - /** - * @deprecated 5.0.0 use QRMatrix::getVersion() instead - * @see \chillerlan\QRCode\Data\QRMatrix::getVersion() - * @codeCoverageIgnore - */ - public function version():?Version{ - return $this->getVersion(); - } - /** * Returns the current ECC level */ @@ -222,15 +204,6 @@ class QRMatrix{ return $this->eccLevel; } - /** - * @deprecated 5.0.0 use QRMatrix::getEccLevel() instead - * @see \chillerlan\QRCode\Data\QRMatrix::getEccLevel() - * @codeCoverageIgnore - */ - public function eccLevel():?EccLevel{ - return $this->getEccLevel(); - } - /** * Returns the current mask pattern */ @@ -238,15 +211,6 @@ class QRMatrix{ return $this->maskPattern; } - /** - * @deprecated 5.0.0 use QRMatrix::getMaskPattern() instead - * @see \chillerlan\QRCode\Data\QRMatrix::getMaskPattern() - * @codeCoverageIgnore - */ - public function maskPattern():?MaskPattern{ - return $this->getMaskPattern(); - } - /** * Returns the absoulute size of the matrix, including quiet zone (after setting it). * @@ -256,15 +220,6 @@ class QRMatrix{ return $this->moduleCount; } - /** - * @deprecated 5.0.0 use QRMatrix::getSize() instead - * @see \chillerlan\QRCode\Data\QRMatrix::getSize() - * @codeCoverageIgnore - */ - public function size():int{ - return $this->getSize(); - } - /** * Returns the value of the module at position [$x, $y] or -1 if the coordinate is outside the matrix */ @@ -283,7 +238,7 @@ class QRMatrix{ * true => $M_TYPE | 0x800 * false => $M_TYPE */ - public function set(int $x, int $y, bool $value, int $M_TYPE):self{ + public function set(int $x, int $y, bool $value, int $M_TYPE):static{ if(isset($this->matrix[$y][$x])){ $this->matrix[$y][$x] = (($M_TYPE & ~$this::IS_DARK) | (($value) ? $this::IS_DARK : 0)); @@ -295,7 +250,7 @@ class QRMatrix{ /** * Fills an area of $width * $height, from the given starting point [$startX, $startY] (top left) with $value for $M_TYPE. */ - public function setArea(int $startX, int $startY, int $width, int $height, bool $value, int $M_TYPE):self{ + public function setArea(int $startX, int $startY, int $width, int $height, bool $value, int $M_TYPE):static{ for($y = $startY; $y < ($startY + $height); $y++){ for($x = $startX; $x < ($startX + $width); $x++){ @@ -309,7 +264,7 @@ class QRMatrix{ /** * Flips the value of the module at ($x, $y) */ - public function flip(int $x, int $y):self{ + public function flip(int $x, int $y):static{ if(isset($this->matrix[$y][$x])){ $this->matrix[$y][$x] ^= $this::IS_DARK; @@ -402,7 +357,7 @@ class QRMatrix{ * * 4 * version + 9 or moduleCount - 8 */ - public function setDarkModule():self{ + public function setDarkModule():static{ $this->set(8, ($this->moduleCount - 8), true, $this::M_DARKMODULE); return $this; @@ -413,7 +368,7 @@ class QRMatrix{ * * ISO/IEC 18004:2000 Section 7.3.2 */ - public function setFinderPattern():self{ + public function setFinderPattern():static{ $pos = [ [0, 0], // top left @@ -437,7 +392,7 @@ class QRMatrix{ * * ISO/IEC 18004:2000 Section 7.3.3 */ - public function setSeparators():self{ + public function setSeparators():static{ $h = [ [7, 0], @@ -467,7 +422,7 @@ class QRMatrix{ * * ISO/IEC 18004:2000 Section 7.3.5 */ - public function setAlignmentPattern():self{ + public function setAlignmentPattern():static{ $alignmentPattern = $this->version->getAlignmentPattern(); foreach($alignmentPattern as $y){ @@ -496,7 +451,7 @@ class QRMatrix{ * * ISO/IEC 18004:2000 Section 7.3.4 */ - public function setTimingPattern():self{ + public function setTimingPattern():static{ for($i = 8; $i < ($this->moduleCount - 8); $i++){ @@ -518,7 +473,7 @@ class QRMatrix{ * * ISO/IEC 18004:2000 Section 8.10 */ - public function setVersionNumber():self{ + public function setVersionNumber():static{ $bits = $this->version->getVersionPattern(); if($bits !== null){ @@ -542,7 +497,7 @@ class QRMatrix{ * * ISO/IEC 18004:2000 Section 8.9 */ - public function setFormatInfo(MaskPattern $maskPattern = null):self{ + public function setFormatInfo(MaskPattern $maskPattern = null):static{ $this->maskPattern = $maskPattern; $bits = 0; // sets all format fields to false (test mode) @@ -585,7 +540,7 @@ class QRMatrix{ * * @throws \chillerlan\QRCode\Data\QRCodeDataException */ - public function setQuietZone(int $quietZoneSize):self{ + public function setQuietZone(int $quietZoneSize):static{ // early exit if there's nothing to add if($quietZoneSize < 1){ @@ -617,7 +572,7 @@ class QRMatrix{ /** * Rotates the matrix by 90 degrees clock wise */ - public function rotate90():self{ + public function rotate90():static{ /** @phan-suppress-next-line PhanParamTooFewInternalUnpack */ $this->matrix = array_map((fn(int ...$a):array => array_reverse($a)), ...$this->matrix); @@ -629,7 +584,7 @@ class QRMatrix{ * * ISO/IEC 18004:2015 Section 6.2 - Reflectance reversal */ - public function invert():self{ + public function invert():static{ foreach($this->matrix as $y => $row){ foreach($row as $x => $val){ @@ -668,7 +623,7 @@ class QRMatrix{ * * @throws \chillerlan\QRCode\Data\QRCodeDataException */ - public function setLogoSpace(int $width, int $height = null, int $startX = null, int $startY = null):self{ + public function setLogoSpace(int $width, int $height = null, int $startX = null, int $startY = null):static{ $height ??= $width; // if width and height happen to be negative or 0 (default value), just return - nothing to do @@ -730,7 +685,7 @@ class QRMatrix{ /** * Maps the interleaved binary $data on the matrix */ - public function writeCodewords(BitBuffer $bitBuffer):self{ + public function writeCodewords(BitBuffer $bitBuffer):static{ $data = (new ReedSolomonEncoder($this->version, $this->eccLevel))->interleaveEcBytes($bitBuffer); $byteCount = count($data); $iByte = 0; @@ -785,7 +740,7 @@ class QRMatrix{ * * ISO/IEC 18004:2000 Section 8.8.1 */ - public function mask(MaskPattern $maskPattern):self{ + public function mask(MaskPattern $maskPattern):static{ $this->maskPattern = $maskPattern; $mask = $this->maskPattern->getMask(); diff --git a/src/Decoder/BitMatrix.php b/src/Decoder/BitMatrix.php index ea2e321b5..3fc55e8d7 100644 --- a/src/Decoder/BitMatrix.php +++ b/src/Decoder/BitMatrix.php @@ -80,7 +80,7 @@ final class BitMatrix extends QRMatrix{ /** * Resets the current version info in order to attempt another reading */ - public function resetVersionInfo():self{ + public function resetVersionInfo():static{ $this->version = null; $this->eccLevel = null; $this->maskPattern = null; @@ -91,7 +91,7 @@ final class BitMatrix extends QRMatrix{ /** * Mirror the bit matrix diagonally in order to attempt a second reading. */ - public function mirrorDiagonal():self{ + public function mirrorDiagonal():static{ $this->mirror = !$this->mirror; // mirror vertically @@ -179,7 +179,7 @@ final class BitMatrix extends QRMatrix{ * * @throws \chillerlan\QRCode\Decoder\QRCodeDecoderException */ - private function readFormatInformation():self{ + private function readFormatInformation():static{ if($this->eccLevel !== null && $this->maskPattern !== null){ return $this; @@ -296,7 +296,7 @@ final class BitMatrix extends QRMatrix{ * @throws \chillerlan\QRCode\Decoder\QRCodeDecoderException * @noinspection DuplicatedCode */ - private function readVersion():self{ + private function readVersion():static{ if($this->version !== null){ return $this; @@ -415,7 +415,7 @@ final class BitMatrix extends QRMatrix{ * @codeCoverageIgnore * @throws \chillerlan\QRCode\Data\QRCodeDataException */ - public function setQuietZone(int $quietZoneSize = null):self{ + public function setQuietZone(int $quietZoneSize = null):static{ throw new QRCodeDataException('not supported'); } @@ -423,7 +423,7 @@ final class BitMatrix extends QRMatrix{ * @codeCoverageIgnore * @throws \chillerlan\QRCode\Data\QRCodeDataException */ - public function setLogoSpace(int $width, int $height = null, int $startX = null, int $startY = null):self{ + public function setLogoSpace(int $width, int $height = null, int $startX = null, int $startY = null):static{ throw new QRCodeDataException('not supported'); } diff --git a/src/Detector/AlignmentPattern.php b/src/Detector/AlignmentPattern.php index 72feafdfa..b405ec711 100644 --- a/src/Detector/AlignmentPattern.php +++ b/src/Detector/AlignmentPattern.php @@ -23,7 +23,7 @@ final class AlignmentPattern extends ResultPoint{ * Combines this object's current estimate of a finder pattern position and module size * with a new estimate. It returns a new FinderPattern containing an average of the two. */ - public function combineEstimate(float $i, float $j, float $newModuleSize):self{ + public function combineEstimate(float $i, float $j, float $newModuleSize):static{ return new self( (($this->x + $j) / 2.0), (($this->y + $i) / 2.0), diff --git a/src/Detector/FinderPattern.php b/src/Detector/FinderPattern.php index 1f799e87e..79e13e9c6 100644 --- a/src/Detector/FinderPattern.php +++ b/src/Detector/FinderPattern.php @@ -61,7 +61,7 @@ final class FinderPattern extends ResultPoint{ * with a new estimate. It returns a new FinderPattern containing a weighted average * based on count. */ - public function combineEstimate(float $i, float $j, float $newModuleSize):self{ + public function combineEstimate(float $i, float $j, float $newModuleSize):static{ $combinedCount = ($this->count + 1); return new self( diff --git a/src/Output/QREps.php b/src/Output/QREps.php index a04f20d5b..d60f1c22c 100644 --- a/src/Output/QREps.php +++ b/src/Output/QREps.php @@ -22,12 +22,12 @@ use function array_values, count, date, implode, is_array, is_numeric, max, min, */ class QREps extends QROutputAbstract{ - public const MIME_TYPE = 'application/postscript'; + final public const MIME_TYPE = 'application/postscript'; /** * @inheritDoc */ - public static function moduleValueIsValid($value):bool{ + public static function moduleValueIsValid(mixed $value):bool{ if(!is_array($value) || count($value) < 3){ return false; @@ -50,11 +50,9 @@ class QREps extends QROutputAbstract{ } /** - * @param array $value - * * @inheritDoc */ - protected function prepareModuleValue($value):string{ + protected function prepareModuleValue(mixed $value):string{ $values = []; foreach(array_values($value) as $i => $val){ @@ -130,7 +128,7 @@ class QREps extends QROutputAbstract{ } // create the path elements - $paths = $this->collectModules(fn(int $x, int $y, int $M_TYPE):string => $this->module($x, $y, $M_TYPE)); + $paths = $this->collectModules($this->module(...)); foreach($paths as $M_TYPE => $path){ diff --git a/src/Output/QRFpdf.php b/src/Output/QRFpdf.php index a80295411..9e03287a0 100644 --- a/src/Output/QRFpdf.php +++ b/src/Output/QRFpdf.php @@ -12,6 +12,7 @@ namespace chillerlan\QRCode\Output; use chillerlan\QRCode\Data\QRMatrix; +use chillerlan\QRCode\QROptions; use chillerlan\Settings\SettingsContainerInterface; use FPDF; @@ -25,7 +26,7 @@ use function array_values, class_exists, count, intval, is_array, is_numeric, ma */ class QRFpdf extends QROutputAbstract{ - public const MIME_TYPE = 'application/pdf'; + final public const MIME_TYPE = 'application/pdf'; protected FPDF $fpdf; protected ?array $prevColor = null; @@ -35,7 +36,7 @@ class QRFpdf extends QROutputAbstract{ * * @throws \chillerlan\QRCode\Output\QRCodeOutputException */ - public function __construct(SettingsContainerInterface $options, QRMatrix $matrix){ + public function __construct(SettingsContainerInterface|QROptions $options, QRMatrix $matrix){ if(!class_exists(FPDF::class)){ // @codeCoverageIgnoreStart @@ -52,7 +53,7 @@ class QRFpdf extends QROutputAbstract{ /** * @inheritDoc */ - public static function moduleValueIsValid($value):bool{ + public static function moduleValueIsValid(mixed $value):bool{ if(!is_array($value) || count($value) < 3){ return false; @@ -75,12 +76,10 @@ class QRFpdf extends QROutputAbstract{ } /** - * @param array $value - * * @inheritDoc * @throws \chillerlan\QRCode\Output\QRCodeOutputException */ - protected function prepareModuleValue($value):array{ + protected function prepareModuleValue(mixed $value):array{ $values = []; foreach(array_values($value) as $i => $val){ @@ -115,10 +114,8 @@ class QRFpdf extends QROutputAbstract{ /** * @inheritDoc - * - * @return string|\FPDF */ - public function dump(string $file = null){ + public function dump(string $file = null):string|FPDF{ $this->fpdf = $this->initFPDF(); $this->fpdf->AddPage(); diff --git a/src/Output/QRGdImage.php b/src/Output/QRGdImage.php index 8158a419d..2bb9c18c6 100644 --- a/src/Output/QRGdImage.php +++ b/src/Output/QRGdImage.php @@ -13,34 +13,28 @@ namespace chillerlan\QRCode\Output; use chillerlan\QRCode\Data\QRMatrix; +use chillerlan\QRCode\QROptions; use chillerlan\Settings\SettingsContainerInterface; -use ErrorException; -use Throwable; -use function array_values, count, extension_loaded, gd_info, imagebmp, imagecolorallocate, imagecolortransparent, - imagecreatetruecolor, imagedestroy, imagefilledellipse, imagefilledrectangle, imagegif, imagejpeg, imagepng, - imagescale, imagewebp, intdiv, intval, is_array, is_numeric, max, min, ob_end_clean, ob_get_contents, ob_start, +use ErrorException, GdImage, Throwable; +use function array_values, count, extension_loaded, gd_info, imagecolorallocate, imagecolortransparent, + imagecreatetruecolor, imagedestroy, imagefilledellipse, imagefilledrectangle, + imagescale, intdiv, intval, is_array, is_numeric, max, min, ob_end_clean, ob_get_contents, ob_start, restore_error_handler, set_error_handler, sprintf; /** * Converts the matrix into GD images, raw or base64 output (requires ext-gd) * * @see https://php.net/manual/book.image.php - * - * @deprecated 5.0.0 this class will be made abstract in future versions, - * calling it directly is deprecated - use one of the child classes instead * @see https://github.com/chillerlan/php-qrcode/issues/223 */ -class QRGdImage extends QROutputAbstract{ +abstract class QRGdImage extends QROutputAbstract{ /** * The GD image resource * * @see imagecreatetruecolor() - * @var resource|\GdImage - * - * @todo: add \GdImage type in v6 */ - protected $image; + protected GdImage $image; /** * The allocated background color @@ -62,7 +56,7 @@ class QRGdImage extends QROutputAbstract{ * @throws \chillerlan\QRCode\Output\QRCodeOutputException * @noinspection PhpMissingParentConstructorInspection */ - public function __construct(SettingsContainerInterface $options, QRMatrix $matrix){ + public function __construct(SettingsContainerInterface|QROptions $options, QRMatrix $matrix){ $this->options = $options; $this->matrix = $matrix; @@ -79,7 +73,6 @@ class QRGdImage extends QROutputAbstract{ /** * Checks whether GD is installed and if the given mode is supported * - * @return void * @throws \chillerlan\QRCode\Output\QRCodeOutputException * @codeCoverageIgnore */ @@ -90,23 +83,23 @@ class QRGdImage extends QROutputAbstract{ } $modes = [ - self::GDIMAGE_BMP => 'BMP Support', - self::GDIMAGE_GIF => 'GIF Create Support', - self::GDIMAGE_JPG => 'JPEG Support', - self::GDIMAGE_PNG => 'PNG Support', - self::GDIMAGE_WEBP => 'WebP Support', + QRGdImageBMP::class => 'BMP Support', + QRGdImageGIF::class => 'GIF Create Support', + QRGdImageJPEG::class => 'JPEG Support', + QRGdImagePNG::class => 'PNG Support', + QRGdImageWEBP::class => 'WebP Support', ]; // likely using default or custom output - if(!isset($modes[$this->options->outputType])){ + if(!isset($modes[$this->options->outputInterface])){ return; } $info = gd_info(); - $mode = $modes[$this->options->outputType]; + $mode = $modes[$this->options->outputInterface]; if(!isset($info[$mode]) || $info[$mode] !== true){ - throw new QRCodeOutputException(sprintf('output mode "%s" not supported', $this->options->outputType)); + throw new QRCodeOutputException(sprintf('output mode "%s" not supported', $this->options->outputInterface)); } } @@ -114,7 +107,7 @@ class QRGdImage extends QROutputAbstract{ /** * @inheritDoc */ - public static function moduleValueIsValid($value):bool{ + public static function moduleValueIsValid(mixed $value):bool{ if(!is_array($value) || count($value) < 3){ return false; @@ -137,12 +130,10 @@ class QRGdImage extends QROutputAbstract{ } /** - * @param array $value - * * @inheritDoc * @throws \chillerlan\QRCode\Output\QRCodeOutputException */ - protected function prepareModuleValue($value):int{ + protected function prepareModuleValue(mixed $value):int{ $values = []; foreach(array_values($value) as $i => $val){ @@ -174,12 +165,9 @@ class QRGdImage extends QROutputAbstract{ /** * @inheritDoc * - * @return string|resource|\GdImage - * - * @phan-suppress PhanUndeclaredTypeReturnType, PhanTypeMismatchReturn * @throws \ErrorException */ - public function dump(string $file = null){ + public function dump(string $file = null):string|GdImage{ set_error_handler(function(int $errno, string $errstr):bool{ throw new ErrorException($errstr, $errno); @@ -215,8 +203,7 @@ class QRGdImage extends QROutputAbstract{ $this->saveToFile($imageData, $file); if($this->options->outputBase64){ - // @todo: remove mime parameter in v6 - $imageData = $this->toBase64DataURI($imageData, 'image/'.$this->options->outputType); + $imageData = $this->toBase64DataURI($imageData); } restore_error_handler(); @@ -268,8 +255,7 @@ class QRGdImage extends QROutputAbstract{ */ protected function setTransparencyColor():void{ - // @todo: the jpg skip can be removed in v6 - if($this->options->outputType === QROutputInterface::GDIMAGE_JPG || !$this->options->imageTransparent){ + if(!$this->options->imageTransparent){ return; } @@ -330,38 +316,9 @@ class QRGdImage extends QROutputAbstract{ /** * Renders the image with the gdimage function for the desired output * - * @see \imagebmp() - * @see \imagegif() - * @see \imagejpeg() - * @see \imagepng() - * @see \imagewebp() - * - * @todo: v6.0: make abstract and call from child classes * @see https://github.com/chillerlan/php-qrcode/issues/223 - * @codeCoverageIgnore */ - protected function renderImage():void{ - - switch($this->options->outputType){ - case QROutputInterface::GDIMAGE_BMP: - imagebmp($this->image, null, ($this->options->quality > 0)); - break; - case QROutputInterface::GDIMAGE_GIF: - imagegif($this->image); - break; - case QROutputInterface::GDIMAGE_JPG: - imagejpeg($this->image, null, max(-1, min(100, $this->options->quality))); - break; - case QROutputInterface::GDIMAGE_WEBP: - imagewebp($this->image, null, max(-1, min(100, $this->options->quality))); - break; - // silently default to png output - case QROutputInterface::GDIMAGE_PNG: - default: - imagepng($this->image, null, max(-1, min(9, $this->options->quality))); - } - - } + abstract protected function renderImage():void; /** * Creates the final image by calling the desired GD output function diff --git a/src/Output/QRGdImageBMP.php b/src/Output/QRGdImageBMP.php index 268ebe7c2..3a4568b12 100644 --- a/src/Output/QRGdImageBMP.php +++ b/src/Output/QRGdImageBMP.php @@ -21,7 +21,7 @@ use function imagebmp; */ class QRGdImageBMP extends QRGdImage{ - public const MIME_TYPE = 'image/bmp'; + final public const MIME_TYPE = 'image/bmp'; /** * @inheritDoc diff --git a/src/Output/QRGdImageGIF.php b/src/Output/QRGdImageGIF.php index a02130907..751b381a6 100644 --- a/src/Output/QRGdImageGIF.php +++ b/src/Output/QRGdImageGIF.php @@ -21,7 +21,7 @@ use function imagegif; */ class QRGdImageGIF extends QRGdImage{ - public const MIME_TYPE = 'image/gif'; + final public const MIME_TYPE = 'image/gif'; /** * @inheritDoc diff --git a/src/Output/QRGdImageJPEG.php b/src/Output/QRGdImageJPEG.php index aa60f473e..c2b301e5b 100644 --- a/src/Output/QRGdImageJPEG.php +++ b/src/Output/QRGdImageJPEG.php @@ -23,7 +23,7 @@ use function min; */ class QRGdImageJPEG extends QRGdImage{ - public const MIME_TYPE = 'image/jpg'; + final public const MIME_TYPE = 'image/jpg'; /** * @inheritDoc diff --git a/src/Output/QRGdImagePNG.php b/src/Output/QRGdImagePNG.php index c97a868ee..4fa62dd82 100644 --- a/src/Output/QRGdImagePNG.php +++ b/src/Output/QRGdImagePNG.php @@ -23,7 +23,7 @@ use function min; */ class QRGdImagePNG extends QRGdImage{ - public const MIME_TYPE = 'image/png'; + final public const MIME_TYPE = 'image/png'; /** * @inheritDoc diff --git a/src/Output/QRGdImageWEBP.php b/src/Output/QRGdImageWEBP.php index 4f00e3cb9..6c305cf4b 100644 --- a/src/Output/QRGdImageWEBP.php +++ b/src/Output/QRGdImageWEBP.php @@ -23,7 +23,7 @@ use function min; */ class QRGdImageWEBP extends QRGdImage{ - public const MIME_TYPE = 'image/webp'; + final public const MIME_TYPE = 'image/webp'; /** * @inheritDoc diff --git a/src/Output/QRImage.php b/src/Output/QRImage.php deleted file mode 100644 index cda496d36..000000000 --- a/src/Output/QRImage.php +++ /dev/null @@ -1,19 +0,0 @@ - - * @copyright 2021 smiley - * @license MIT - */ - -namespace chillerlan\QRCode\Output; - -/** - * @deprecated 5.0.0 backward compatibility, use QRGdImage instead - * @see \chillerlan\QRCode\Output\QRGdImage - */ -class QRImage extends QRGdImage{ - -} diff --git a/src/Output/QRImagick.php b/src/Output/QRImagick.php index b28c00abd..294408bd0 100644 --- a/src/Output/QRImagick.php +++ b/src/Output/QRImagick.php @@ -13,6 +13,7 @@ namespace chillerlan\QRCode\Output; use chillerlan\QRCode\Data\QRMatrix; +use chillerlan\QRCode\QROptions; use chillerlan\Settings\SettingsContainerInterface; use finfo, Imagick, ImagickDraw, ImagickPixel; use function extension_loaded, in_array, is_string, max, min, preg_match, strlen; @@ -46,7 +47,7 @@ class QRImagick extends QROutputAbstract{ * * @throws \chillerlan\QRCode\Output\QRCodeOutputException */ - public function __construct(SettingsContainerInterface $options, QRMatrix $matrix){ + public function __construct(SettingsContainerInterface|QROptions $options, QRMatrix $matrix){ if(!extension_loaded('imagick')){ throw new QRCodeOutputException('ext-imagick not loaded'); // @codeCoverageIgnore @@ -65,7 +66,7 @@ class QRImagick extends QROutputAbstract{ * @see https://www.php.net/manual/imagickpixel.construct.php * @inheritDoc */ - public static function moduleValueIsValid($value):bool{ + public static function moduleValueIsValid(mixed $value):bool{ if(!is_string($value)){ return false; @@ -98,7 +99,7 @@ class QRImagick extends QROutputAbstract{ /** * @inheritDoc */ - protected function prepareModuleValue($value):ImagickPixel{ + protected function prepareModuleValue(mixed $value):ImagickPixel{ return new ImagickPixel($value); } @@ -111,10 +112,8 @@ class QRImagick extends QROutputAbstract{ /** * @inheritDoc - * - * @return string|\Imagick */ - public function dump(string $file = null){ + public function dump(string $file = null):string|Imagick{ $this->setBgColor(); $this->imagick = $this->createImage(); diff --git a/src/Output/QRMarkup.php b/src/Output/QRMarkup.php index 22551e3e6..06fb53728 100644 --- a/src/Output/QRMarkup.php +++ b/src/Output/QRMarkup.php @@ -26,7 +26,7 @@ abstract class QRMarkup extends QROutputAbstract{ * @see https://developer.mozilla.org/en-US/docs/Web/CSS/color_value * @inheritDoc */ - public static function moduleValueIsValid($value):bool{ + public static function moduleValueIsValid(mixed $value):bool{ if(!is_string($value)){ return false; @@ -57,7 +57,7 @@ abstract class QRMarkup extends QROutputAbstract{ /** * @inheritDoc */ - protected function prepareModuleValue($value):string{ + protected function prepareModuleValue(mixed $value):string{ return trim(strip_tags($value), " '\"\r\n\t"); } diff --git a/src/Output/QRMarkupHTML.php b/src/Output/QRMarkupHTML.php index 65dc49a8a..8a37d5511 100644 --- a/src/Output/QRMarkupHTML.php +++ b/src/Output/QRMarkupHTML.php @@ -17,7 +17,7 @@ use function implode, sprintf; */ class QRMarkupHTML extends QRMarkup{ - public const MIME_TYPE = 'text/html'; + final public const MIME_TYPE = 'text/html'; /** * @inheritDoc diff --git a/src/Output/QRMarkupSVG.php b/src/Output/QRMarkupSVG.php index a7f85d49b..124c3a684 100644 --- a/src/Output/QRMarkupSVG.php +++ b/src/Output/QRMarkupSVG.php @@ -22,7 +22,7 @@ use function array_chunk, implode, is_string, preg_match, sprintf, trim; */ class QRMarkupSVG extends QRMarkup{ - public const MIME_TYPE = 'image/svg+xml'; + final public const MIME_TYPE = 'image/svg+xml'; /** * @todo: XSS proof @@ -30,7 +30,7 @@ class QRMarkupSVG extends QRMarkup{ * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill * @inheritDoc */ - public static function moduleValueIsValid($value):bool{ + public static function moduleValueIsValid(mixed $value):bool{ if(!is_string($value)){ return false; @@ -115,7 +115,7 @@ class QRMarkupSVG extends QRMarkup{ * returns one or more SVG elements */ protected function paths():string{ - $paths = $this->collectModules(fn(int $x, int $y, int $M_TYPE):string => $this->module($x, $y, $M_TYPE)); + $paths = $this->collectModules($this->module(...)); $svg = []; // create the path elements diff --git a/src/Output/QROutputAbstract.php b/src/Output/QROutputAbstract.php index d8c44cc9a..168d957da 100644 --- a/src/Output/QROutputAbstract.php +++ b/src/Output/QROutputAbstract.php @@ -11,6 +11,7 @@ namespace chillerlan\QRCode\Output; use chillerlan\QRCode\Data\QRMatrix; +use chillerlan\QRCode\QROptions; use chillerlan\Settings\SettingsContainerInterface; use Closure; use function base64_encode, dirname, file_put_contents, is_writable, ksort, sprintf; @@ -43,9 +44,9 @@ abstract class QROutputAbstract implements QROutputInterface{ protected QRMatrix $matrix; /** - * @var \chillerlan\Settings\SettingsContainerInterface|\chillerlan\QRCode\QROptions + * the options instance */ - protected SettingsContainerInterface $options; + protected SettingsContainerInterface|QROptions $options; /** @see \chillerlan\QRCode\QROptions::$scale */ protected int $scale; @@ -68,7 +69,7 @@ abstract class QROutputAbstract implements QROutputInterface{ /** * QROutputAbstract constructor. */ - public function __construct(SettingsContainerInterface $options, QRMatrix $matrix){ + public function __construct(SettingsContainerInterface|QROptions $options, QRMatrix $matrix){ $this->options = $options; $this->matrix = $matrix; @@ -148,10 +149,9 @@ abstract class QROutputAbstract implements QROutputInterface{ /** * Returns the prepared value for the given $M_TYPE * - * @return mixed return value depends on the output class * @throws \chillerlan\QRCode\Output\QRCodeOutputException if $moduleValues[$M_TYPE] doesn't exist */ - protected function getModuleValue(int $M_TYPE){ + protected function getModuleValue(int $M_TYPE):mixed{ if(!isset($this->moduleValues[$M_TYPE])){ throw new QRCodeOutputException(sprintf('$M_TYPE %012b not found in module values map', $M_TYPE)); @@ -162,34 +162,26 @@ abstract class QROutputAbstract implements QROutputInterface{ /** * Returns the prepared module value at the given coordinate [$x, $y] (convenience) - * - * @return mixed|null */ - protected function getModuleValueAt(int $x, int $y){ + protected function getModuleValueAt(int $x, int $y):mixed{ return $this->getModuleValue($this->matrix->get($x, $y)); } /** - * Prepares the value for the given input () - * - * @param mixed $value - * - * @return mixed|null return value depends on the output class + * Prepares the value for the given input (return value depends on the output class) */ - abstract protected function prepareModuleValue($value); + abstract protected function prepareModuleValue(mixed $value):mixed; /** - * Returns a default value for either dark or light modules - * - * @return mixed|null return value depends on the output class + * Returns a default value for either dark or light modules (return value depends on the output class) */ - abstract protected function getDefaultModuleValue(bool $isDark); + abstract protected function getDefaultModuleValue(bool $isDark):mixed; /** * Returns a base64 data URI for the given string and mime type */ protected function toBase64DataURI(string $data, string $mime = null):string{ - return sprintf('data:%s;base64,%s', ($mime ?? $this::MIME_TYPE), base64_encode($data)); + return sprintf('data:%s;base64,%s', ($mime ?? static::MIME_TYPE), base64_encode($data)); } /** diff --git a/src/Output/QROutputInterface.php b/src/Output/QROutputInterface.php index 919f1ba75..792e22678 100644 --- a/src/Output/QROutputInterface.php +++ b/src/Output/QROutputInterface.php @@ -18,116 +18,24 @@ use chillerlan\QRCode\Data\QRMatrix; interface QROutputInterface{ /** - * @var string - * @deprecated 5.0.0 - * @see https://github.com/chillerlan/php-qrcode/issues/223 - */ - public const MARKUP_HTML = 'html'; - - /** - * @var string - * @deprecated 5.0.0 - * @see https://github.com/chillerlan/php-qrcode/issues/223 - */ - public const MARKUP_SVG = 'svg'; - - /** - * @var string - * @deprecated 5.0.0 - * @see https://github.com/chillerlan/php-qrcode/issues/223 - */ - public const GDIMAGE_BMP = 'bmp'; - - /** - * @var string - * @deprecated 5.0.0 - * @see https://github.com/chillerlan/php-qrcode/issues/223 - */ - public const GDIMAGE_GIF = 'gif'; - - /** - * @var string - * @deprecated 5.0.0 - * @see https://github.com/chillerlan/php-qrcode/issues/223 - */ - public const GDIMAGE_JPG = 'jpg'; - - /** - * @var string - * @deprecated 5.0.0 - * @see https://github.com/chillerlan/php-qrcode/issues/223 - */ - public const GDIMAGE_PNG = 'png'; - - /** - * @var string - * @deprecated 5.0.0 - * @see https://github.com/chillerlan/php-qrcode/issues/223 - */ - public const GDIMAGE_WEBP = 'webp'; - - /** - * @var string - * @deprecated 5.0.0 - * @see https://github.com/chillerlan/php-qrcode/issues/223 - */ - public const STRING_JSON = 'json'; - - /** - * @var string - * @deprecated 5.0.0 - * @see https://github.com/chillerlan/php-qrcode/issues/223 - */ - public const STRING_TEXT = 'text'; - - /** - * @var string - * @deprecated 5.0.0 - * @see https://github.com/chillerlan/php-qrcode/issues/223 - */ - public const IMAGICK = 'imagick'; - - /** - * @var string - * @deprecated 5.0.0 - * @see https://github.com/chillerlan/php-qrcode/issues/223 - */ - public const FPDF = 'fpdf'; - - /** - * @var string - * @deprecated 5.0.0 - * @see https://github.com/chillerlan/php-qrcode/issues/223 - */ - public const EPS = 'eps'; - - /** - * @var string - * @deprecated 5.0.0 - * @see https://github.com/chillerlan/php-qrcode/issues/223 - */ - public const CUSTOM = 'custom'; - - /** - * Map of built-in output modes => class FQN + * Map of built-in output class FQN * * @var string[] - * @deprecated 5.0.0 - * @see https://github.com/chillerlan/php-qrcode/issues/223 + * @see https://github.com/chillerlan/php-qrcode/issues/223 */ public const MODES = [ - self::MARKUP_SVG => QRMarkupSVG::class, - self::MARKUP_HTML => QRMarkupHTML::class, - self::GDIMAGE_BMP => QRGdImageBMP::class, - self::GDIMAGE_GIF => QRGdImageGIF::class, - self::GDIMAGE_JPG => QRGdImageJPEG::class, - self::GDIMAGE_PNG => QRGdImagePNG::class, - self::GDIMAGE_WEBP => QRGdImageWEBP::class, - self::STRING_JSON => QRStringJSON::class, - self::STRING_TEXT => QRStringText::class, - self::IMAGICK => QRImagick::class, - self::FPDF => QRFpdf::class, - self::EPS => QREps::class, + QRMarkupSVG::class, + QRMarkupHTML::class, + QRGdImageBMP::class, + QRGdImageGIF::class, + QRGdImageJPEG::class, + QRGdImagePNG::class, + QRGdImageWEBP::class, + QRStringJSON::class, + QRStringText::class, + QRImagick::class, + QRFpdf::class, + QREps::class, ]; /** @@ -205,10 +113,8 @@ interface QROutputInterface{ /** * Determines whether the given value is valid - * - * @param mixed $value */ - public static function moduleValueIsValid($value):bool; + public static function moduleValueIsValid(mixed $value):bool; /** * Generates the output, optionally dumps it to a file, and returns it @@ -218,9 +124,7 @@ interface QROutputInterface{ * you need to supply the $file parameter here in that case (or handle the option value in your custom output module). * * @see \chillerlan\QRCode\QRCode::renderMatrix() - * - * @return mixed */ - public function dump(string $file = null); + public function dump(string $file = null):mixed; } diff --git a/src/Output/QRString.php b/src/Output/QRString.php deleted file mode 100644 index cb70a6cce..000000000 --- a/src/Output/QRString.php +++ /dev/null @@ -1,111 +0,0 @@ - - * @copyright 2015 Smiley - * @license MIT - * - * @noinspection PhpComposerExtensionStubsInspection - */ - -namespace chillerlan\QRCode\Output; - -use function implode, is_string, json_encode, max, min, sprintf; -use const JSON_THROW_ON_ERROR; - -/** - * Converts the matrix data into string types - * - * @deprecated 5.0.0 this class will be removed in future versions, use one of QRStringText or QRStringJSON instead - */ -class QRString extends QROutputAbstract{ - - /** - * @inheritDoc - */ - public static function moduleValueIsValid($value):bool{ - return is_string($value); - } - - /** - * @inheritDoc - */ - protected function prepareModuleValue($value):string{ - return $value; - } - - /** - * @inheritDoc - */ - protected function getDefaultModuleValue(bool $isDark):string{ - return ($isDark) ? '██' : '░░'; - } - - /** - * @inheritDoc - */ - public function dump(string $file = null):string{ - - switch($this->options->outputType){ - case QROutputInterface::STRING_TEXT: - $data = $this->text(); - break; - case QROutputInterface::STRING_JSON: - default: - $data = $this->json(); - } - - $this->saveToFile($data, $file); - - return $data; - } - - /** - * string output - */ - protected function text():string{ - $lines = []; - $linestart = $this->options->textLineStart; - - for($y = 0; $y < $this->moduleCount; $y++){ - $r = []; - - for($x = 0; $x < $this->moduleCount; $x++){ - $r[] = $this->getModuleValueAt($x, $y); - } - - $lines[] = $linestart.implode('', $r); - } - - return implode($this->eol, $lines); - } - - /** - * JSON output - * - * @throws \JsonException - */ - protected function json():string{ - return json_encode($this->matrix->getMatrix($this->options->jsonAsBooleans), JSON_THROW_ON_ERROR); - } - - // - - /** - * a little helper to create a proper ANSI 8-bit color escape sequence - * - * @see https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit - * @see https://en.wikipedia.org/wiki/Block_Elements - * - * @codeCoverageIgnore - */ - public static function ansi8(string $str, int $color, bool $background = null):string{ - $color = max(0, min($color, 255)); - $background = ($background === true) ? 48 : 38; - - return sprintf("\x1b[%s;5;%sm%s\x1b[0m", $background, $color, $str); - } - -} diff --git a/src/Output/QRStringJSON.php b/src/Output/QRStringJSON.php index cd942a74e..361aead62 100644 --- a/src/Output/QRStringJSON.php +++ b/src/Output/QRStringJSON.php @@ -19,7 +19,7 @@ use function json_encode; */ class QRStringJSON extends QROutputAbstract{ - public const MIME_TYPE = 'application/json'; + final public const MIME_TYPE = 'application/json'; /** * @inheritDoc @@ -39,7 +39,7 @@ class QRStringJSON extends QROutputAbstract{ * * @inheritDoc */ - protected function prepareModuleValue($value):string{ + protected function prepareModuleValue(mixed $value):string{ return ''; } @@ -57,7 +57,7 @@ class QRStringJSON extends QROutputAbstract{ * * @inheritDoc */ - public static function moduleValueIsValid($value):bool{ + public static function moduleValueIsValid(mixed $value):bool{ return true; } diff --git a/src/Output/QRStringText.php b/src/Output/QRStringText.php index 3de86f9de..e4526a5d5 100644 --- a/src/Output/QRStringText.php +++ b/src/Output/QRStringText.php @@ -22,19 +22,19 @@ use function sprintf; */ class QRStringText extends QROutputAbstract{ - public const MIME_TYPE = 'text/plain'; + final public const MIME_TYPE = 'text/plain'; /** * @inheritDoc */ - public static function moduleValueIsValid($value):bool{ + public static function moduleValueIsValid(mixed $value):bool{ return is_string($value); } /** * @inheritDoc */ - protected function prepareModuleValue($value):string{ + protected function prepareModuleValue(mixed $value):string{ return $value; } @@ -53,7 +53,7 @@ class QRStringText extends QROutputAbstract{ $linestart = $this->options->textLineStart; foreach($this->matrix->getMatrix() as $row){ - $lines[] = $linestart.implode('', array_map([$this, 'getModuleValue'], $row)); + $lines[] = $linestart.implode('', array_map($this->getModuleValue(...), $row)); } $data = implode($this->eol, $lines); diff --git a/src/QRCode.php b/src/QRCode.php index b5ccea9d3..4c427a29c 100755 --- a/src/QRCode.php +++ b/src/QRCode.php @@ -13,7 +13,7 @@ namespace chillerlan\QRCode; use chillerlan\QRCode\Common\{ - EccLevel, ECICharset, GDLuminanceSource, IMagickLuminanceSource, LuminanceSourceInterface, MaskPattern, Mode, Version + ECICharset, GDLuminanceSource, IMagickLuminanceSource, LuminanceSourceInterface, MaskPattern, Mode }; use chillerlan\QRCode\Data\{AlphaNum, Byte, ECI, Hanzi, Kanji, Number, QRData, QRDataModeInterface, QRMatrix}; use chillerlan\QRCode\Decoder\{Decoder, DecoderResult}; @@ -32,138 +32,10 @@ use function class_exists, class_implements, in_array, mb_convert_encoding, mb_i */ class QRCode{ - /** - * @deprecated 5.0.0 use Version::AUTO instead - * @see \chillerlan\QRCode\Common\Version::AUTO - * @var int - */ - public const VERSION_AUTO = Version::AUTO; - - /** - * @deprecated 5.0.0 use MaskPattern::AUTO instead - * @see \chillerlan\QRCode\Common\MaskPattern::AUTO - * @var int - */ - public const MASK_PATTERN_AUTO = MaskPattern::AUTO; - - /** - * @deprecated 5.0.0 use EccLevel::L instead - * @see \chillerlan\QRCode\Common\EccLevel::L - * @var int - */ - public const ECC_L = EccLevel::L; - - /** - * @deprecated 5.0.0 use EccLevel::M instead - * @see \chillerlan\QRCode\Common\EccLevel::M - * @var int - */ - public const ECC_M = EccLevel::M; - - /** - * @deprecated 5.0.0 use EccLevel::Q instead - * @see \chillerlan\QRCode\Common\EccLevel::Q - * @var int - */ - public const ECC_Q = EccLevel::Q; - - /** - * @deprecated 5.0.0 use EccLevel::H instead - * @see \chillerlan\QRCode\Common\EccLevel::H - * @var int - */ - public const ECC_H = EccLevel::H; - - /** - * @deprecated 5.0.0 use QROutputInterface::MARKUP_HTML instead - * @see \chillerlan\QRCode\Output\QROutputInterface::MARKUP_HTML - * @var string - */ - public const OUTPUT_MARKUP_HTML = QROutputInterface::MARKUP_HTML; - - /** - * @deprecated 5.0.0 use QROutputInterface::MARKUP_SVG instead - * @see \chillerlan\QRCode\Output\QROutputInterface::MARKUP_SVG - * @var string - */ - public const OUTPUT_MARKUP_SVG = QROutputInterface::MARKUP_SVG; - - /** - * @deprecated 5.0.0 use QROutputInterface::GDIMAGE_PNG instead - * @see \chillerlan\QRCode\Output\QROutputInterface::GDIMAGE_PNG - * @var string - */ - public const OUTPUT_IMAGE_PNG = QROutputInterface::GDIMAGE_PNG; - - /** - * @deprecated 5.0.0 use QROutputInterface::GDIMAGE_JPG instead - * @see \chillerlan\QRCode\Output\QROutputInterface::GDIMAGE_JPG - * @var string - */ - public const OUTPUT_IMAGE_JPG = QROutputInterface::GDIMAGE_JPG; - - /** - * @deprecated 5.0.0 use QROutputInterface::GDIMAGE_GIF instead - * @see \chillerlan\QRCode\Output\QROutputInterface::GDIMAGE_GIF - * @var string - */ - public const OUTPUT_IMAGE_GIF = QROutputInterface::GDIMAGE_GIF; - - /** - * @deprecated 5.0.0 use QROutputInterface::STRING_JSON instead - * @see \chillerlan\QRCode\Output\QROutputInterface::STRING_JSON - * @var string - */ - public const OUTPUT_STRING_JSON = QROutputInterface::STRING_JSON; - - /** - * @deprecated 5.0.0 use QROutputInterface::STRING_TEXT instead - * @see \chillerlan\QRCode\Output\QROutputInterface::STRING_TEXT - * @var string - */ - public const OUTPUT_STRING_TEXT = QROutputInterface::STRING_TEXT; - - /** - * @deprecated 5.0.0 use QROutputInterface::IMAGICK instead - * @see \chillerlan\QRCode\Output\QROutputInterface::IMAGICK - * @var string - */ - public const OUTPUT_IMAGICK = QROutputInterface::IMAGICK; - - /** - * @deprecated 5.0.0 use QROutputInterface::FPDF instead - * @see \chillerlan\QRCode\Output\QROutputInterface::FPDF - * @var string - */ - public const OUTPUT_FPDF = QROutputInterface::FPDF; - - /** - * @deprecated 5.0.0 use QROutputInterface::EPS instead - * @see \chillerlan\QRCode\Output\QROutputInterface::EPS - * @var string - */ - public const OUTPUT_EPS = QROutputInterface::EPS; - - /** - * @deprecated 5.0.0 use QROutputInterface::CUSTOM instead - * @see \chillerlan\QRCode\Output\QROutputInterface::CUSTOM - * @var string - */ - public const OUTPUT_CUSTOM = QROutputInterface::CUSTOM; - - /** - * @deprecated 5.0.0 use QROutputInterface::MODES instead - * @see \chillerlan\QRCode\Output\QROutputInterface::MODES - * @var string[] - */ - public const OUTPUT_MODES = QROutputInterface::MODES; - /** * The settings container - * - * @var \chillerlan\QRCode\QROptions|\chillerlan\Settings\SettingsContainerInterface */ - protected SettingsContainerInterface $options; + protected SettingsContainerInterface|QROptions $options; /** * A collection of one or more data segments of QRDataModeInterface instances to write @@ -182,14 +54,14 @@ class QRCode{ * * PHP8: accept iterable */ - public function __construct(SettingsContainerInterface $options = null){ + public function __construct(SettingsContainerInterface|QROptions $options = null){ $this->setOptions(($options ?? new QROptions)); } /** * Sets an options instance */ - public function setOptions(SettingsContainerInterface $options):self{ + public function setOptions(SettingsContainerInterface|QROptions $options):static{ $this->options = $options; if($this->options->readerUseImagickIfAvailable){ @@ -201,10 +73,8 @@ class QRCode{ /** * Renders a QR Code for the given $data and QROptions, saves $file optionally - * - * @return mixed */ - public function render(string $data = null, string $file = null){ + public function render(string $data = null, string $file = null):mixed{ if($data !== null){ /** @var \chillerlan\QRCode\Data\QRDataModeInterface $dataInterface */ @@ -223,10 +93,8 @@ class QRCode{ /** * Renders a QR Code for the given QRMatrix and QROptions, saves $file optionally - * - * @return mixed */ - public function renderMatrix(QRMatrix $matrix, string $file = null){ + public function renderMatrix(QRMatrix $matrix, string $file = null):mixed{ return $this->initOutputInterface($matrix)->dump($file ?? $this->options->cachefile); } @@ -277,29 +145,15 @@ class QRCode{ return $matrix; } - /** - * @deprecated 5.0.0 use QRCode::getQRMatrix() instead - * @see \chillerlan\QRCode\QRCode::getQRMatrix() - * @codeCoverageIgnore - */ - public function getMatrix():QRMatrix{ - return $this->getQRMatrix(); - } - /** * initializes a fresh built-in or custom QROutputInterface * * @throws \chillerlan\QRCode\Output\QRCodeOutputException */ protected function initOutputInterface(QRMatrix $matrix):QROutputInterface{ - // @todo: remove custom invocation in v6 - $outputInterface = (QROutputInterface::MODES[$this->options->outputType] ?? null); + $outputInterface = $this->options->outputInterface; - if($this->options->outputType === QROutputInterface::CUSTOM){ - $outputInterface = $this->options->outputInterface; - } - - if(!$outputInterface || !class_exists($outputInterface)){ + if(empty($outputInterface) || !class_exists($outputInterface)){ throw new QRCodeOutputException('invalid output module'); } @@ -310,57 +164,13 @@ class QRCode{ return new $outputInterface($this->options, $matrix); } - /** - * checks if a string qualifies as numeric (convenience method) - * - * @deprecated 5.0.0 use Number::validateString() instead - * @see \chillerlan\QRCode\Data\Number::validateString() - * @codeCoverageIgnore - */ - public function isNumber(string $string):bool{ - return Number::validateString($string); - } - - /** - * checks if a string qualifies as alphanumeric (convenience method) - * - * @deprecated 5.0.0 use AlphaNum::validateString() instead - * @see \chillerlan\QRCode\Data\AlphaNum::validateString() - * @codeCoverageIgnore - */ - public function isAlphaNum(string $string):bool{ - return AlphaNum::validateString($string); - } - - /** - * checks if a string qualifies as Kanji (convenience method) - * - * @deprecated 5.0.0 use Kanji::validateString() instead - * @see \chillerlan\QRCode\Data\Kanji::validateString() - * @codeCoverageIgnore - */ - public function isKanji(string $string):bool{ - return Kanji::validateString($string); - } - - /** - * a dummy (convenience method) - * - * @deprecated 5.0.0 use Byte::validateString() instead - * @see \chillerlan\QRCode\Data\Byte::validateString() - * @codeCoverageIgnore - */ - public function isByte(string $string):bool{ - return Byte::validateString($string); - } - /** * Adds a data segment * * ISO/IEC 18004:2000 8.3.6 - Mixing modes * ISO/IEC 18004:2000 Annex H - Optimisation of bit stream length */ - public function addSegment(QRDataModeInterface $segment):self{ + public function addSegment(QRDataModeInterface $segment):static{ $this->dataSegments[] = $segment; return $this; @@ -371,7 +181,7 @@ class QRCode{ * * @codeCoverageIgnore */ - public function clearSegments():self{ + public function clearSegments():static{ $this->dataSegments = []; return $this; @@ -382,7 +192,7 @@ class QRCode{ * * ISO/IEC 18004:2000 8.3.2 - Numeric Mode */ - public function addNumericSegment(string $data):self{ + public function addNumericSegment(string $data):static{ return $this->addSegment(new Number($data)); } @@ -391,7 +201,7 @@ class QRCode{ * * ISO/IEC 18004:2000 8.3.3 - Alphanumeric Mode */ - public function addAlphaNumSegment(string $data):self{ + public function addAlphaNumSegment(string $data):static{ return $this->addSegment(new AlphaNum($data)); } @@ -400,7 +210,7 @@ class QRCode{ * * ISO/IEC 18004:2000 8.3.5 - Kanji Mode */ - public function addKanjiSegment(string $data):self{ + public function addKanjiSegment(string $data):static{ return $this->addSegment(new Kanji($data)); } @@ -409,7 +219,7 @@ class QRCode{ * * GBT18284-2000 Hanzi Mode */ - public function addHanziSegment(string $data):self{ + public function addHanziSegment(string $data):static{ return $this->addSegment(new Hanzi($data)); } @@ -418,7 +228,7 @@ class QRCode{ * * ISO/IEC 18004:2000 8.3.4 - 8-bit Byte Mode */ - public function addByteSegment(string $data):self{ + public function addByteSegment(string $data):static{ return $this->addSegment(new Byte($data)); } @@ -429,7 +239,7 @@ class QRCode{ * * ISO/IEC 18004:2000 8.3.1 - Extended Channel Interpretation (ECI) Mode */ - public function addEciDesignator(int $encoding):self{ + public function addEciDesignator(int $encoding):static{ return $this->addSegment(new ECI($encoding)); } @@ -442,7 +252,7 @@ class QRCode{ * * @throws \chillerlan\QRCode\QRCodeException */ - public function addEciSegment(int $encoding, string $data):self{ + public function addEciSegment(int $encoding, string $data):static{ // validate the encoding id $eciCharset = new ECICharset($encoding); // get charset name diff --git a/src/QROptionsTrait.php b/src/QROptionsTrait.php index 3c93b9712..f570bd9f0 100644 --- a/src/QROptionsTrait.php +++ b/src/QROptionsTrait.php @@ -14,9 +14,9 @@ namespace chillerlan\QRCode; -use chillerlan\QRCode\Output\QROutputInterface; +use chillerlan\QRCode\Output\QRMarkupSVG; use chillerlan\QRCode\Common\{EccLevel, MaskPattern, Version}; -use function extension_loaded, in_array, max, min, strtolower; +use function constant, extension_loaded, in_array, is_string, max, min, sprintf, strtolower, strtoupper, trim; use const JSON_THROW_ON_ERROR, PHP_EOL; /** @@ -61,7 +61,6 @@ trait QROptionsTrait{ * - `Q` => 25% * - `H` => 30% * - * @todo: accept string values (PHP8+) * @see \chillerlan\QRCode\Common\EccLevel * @see https://github.com/chillerlan/php-qrcode/discussions/160 */ @@ -96,44 +95,9 @@ trait QROptionsTrait{ */ /** - * The built-in output type - * - * - `QROutputInterface::MARKUP_SVG` (default) - * - `QROutputInterface::MARKUP_HTML` - * - `QROutputInterface::GDIMAGE_BMP` - * - `QROutputInterface::GDIMAGE_GIF` - * - `QROutputInterface::GDIMAGE_JPG` - * - `QROutputInterface::GDIMAGE_PNG` - * - `QROutputInterface::GDIMAGE_WEBP` - * - `QROutputInterface::STRING_TEXT` - * - `QROutputInterface::STRING_JSON` - * - `QROutputInterface::IMAGICK` - * - `QROutputInterface::EPS` - * - `QROutputInterface::FPDF` - * - `QROutputInterface::CUSTOM` - * - * @see \chillerlan\QRCode\Output\QREps - * @see \chillerlan\QRCode\Output\QRFpdf - * @see \chillerlan\QRCode\Output\QRGdImage - * @see \chillerlan\QRCode\Output\QRImagick - * @see \chillerlan\QRCode\Output\QRMarkupHTML - * @see \chillerlan\QRCode\Output\QRMarkupSVG - * @see \chillerlan\QRCode\Output\QRString - * @see https://github.com/chillerlan/php-qrcode/issues/223 - * - * @deprecated 5.0.0 see issue #223 + * The FQCN of the `QROutputInterface` to use */ - protected string $outputType = QROutputInterface::MARKUP_SVG; - - /** - * The FQCN of the custom `QROutputInterface` - * - * if `QROptions::$outputType` is set to `QROutputInterface::CUSTOM` (default: `null`) - * - * @deprecated 5.0.0 the nullable type will be removed in future versions - * and the default value will be set to `QRMarkupSVG::class` - */ - protected ?string $outputInterface = null; + protected string $outputInterface = QRMarkupSVG::class; /** * Return the image resource instead of a render if applicable. @@ -186,10 +150,8 @@ trait QROptionsTrait{ * - `QRImagick`: defaults to `"white"` * - `QRGdImage`: defaults to `[255, 255, 255]` * - `QRFpdf`: defaults to blank internally (white page) - * - * @var mixed|null */ - protected $bgColor = null; + protected mixed $bgColor = null; /** * Whether to invert the matrix (reflectance reversal) @@ -324,7 +286,7 @@ trait QROptionsTrait{ * * @var mixed|null */ - protected $transparencyColor = null; + protected mixed $transparencyColor = null; /** * Compression quality @@ -511,6 +473,32 @@ trait QROptionsTrait{ $this->version = ($version !== Version::AUTO) ? max(1, min(40, $version)) : Version::AUTO; } + /** + * sets the ECC level + * + * @throws \chillerlan\QRCode\QRCodeException + */ + protected function set_eccLevel(int|string $eccLevel):void{ + + if(is_string($eccLevel)){ + $ecc = strtoupper(trim($eccLevel)); + + if(!in_array($ecc, ['L', 'M', 'Q', 'H'])){ + throw new QRCodeException(sprintf('Invalid ECC level: "%s"', $ecc)); + } + + // @todo: PHP 8.3+ + // $eccLevel = EccLevel::{$ecc}; + $eccLevel = constant(EccLevel::class.'::'.$ecc); + } + + if((0b11 & $eccLevel) !== $eccLevel){ + throw new QRCodeException(sprintf('Invalid ECC level: "%s"', $eccLevel)); + } + + $this->eccLevel = $eccLevel; + } + /** * sets/clamps the quiet zone size */ @@ -587,132 +575,4 @@ trait QROptionsTrait{ $this->circleRadius = max(0.1, min(0.75, $circleRadius)); } - /* - * redirect calls of deprecated variables to new/renamed property - */ - - /** - * @deprecated 5.0.0 use QROptions::$outputBase64 instead - * @see \chillerlan\QRCode\QROptions::$outputBase64 - */ - protected bool $imageBase64; - - /** - * redirect call to the new variable - * - * @deprecated 5.0.0 use QROptions::$outputBase64 instead - * @see \chillerlan\QRCode\QROptions::$outputBase64 - * @codeCoverageIgnore - */ - protected function set_imageBase64(bool $imageBase64):void{ - $this->outputBase64 = $imageBase64; - } - - /** - * redirect call to the new variable - * - * @deprecated 5.0.0 use QROptions::$outputBase64 instead - * @see \chillerlan\QRCode\QROptions::$outputBase64 - * @codeCoverageIgnore - */ - protected function get_imageBase64():bool{ - return $this->outputBase64; - } - - /** - * @deprecated 5.0.0 use QROptions::$quality instead - * @see \chillerlan\QRCode\QROptions::$quality - */ - protected int $jpegQuality; - - /** - * @deprecated 5.0.0 use QROptions::$quality instead - * @see \chillerlan\QRCode\QROptions::$quality - * @codeCoverageIgnore - */ - protected function set_jpegQuality(int $jpegQuality):void{ - $this->quality = $jpegQuality; - } - - /** - * @deprecated 5.0.0 use QROptions::$quality instead - * @see \chillerlan\QRCode\QROptions::$quality - * @codeCoverageIgnore - */ - protected function get_jpegQuality():int{ - return $this->quality; - } - - /** - * @deprecated 5.0.0 use QROptions::$quality instead - * @see \chillerlan\QRCode\QROptions::$quality - */ - protected int $pngCompression; - - /** - * @deprecated 5.0.0 use QROptions::$quality instead - * @see \chillerlan\QRCode\QROptions::$quality - * @codeCoverageIgnore - */ - protected function set_pngCompression(int $pngCompression):void{ - $this->quality = $pngCompression; - } - - /** - * @deprecated 5.0.0 use QROptions::$quality instead - * @see \chillerlan\QRCode\QROptions::$quality - * @codeCoverageIgnore - */ - protected function get_pngCompression():int{ - return $this->quality; - } - - /** - * @deprecated 5.0.0 use QROptions::$transparencyColor instead - * @see \chillerlan\QRCode\QROptions::$transparencyColor - */ - protected array $imageTransparencyBG; - - /** - * @deprecated 5.0.0 use QROptions::$transparencyColor instead - * @see \chillerlan\QRCode\QROptions::$transparencyColor - * @codeCoverageIgnore - */ - protected function set_imageTransparencyBG(?array $imageTransparencyBG):void{ - $this->transparencyColor = $imageTransparencyBG; - } - - /** - * @deprecated 5.0.0 use QROptions::$transparencyColor instead - * @see \chillerlan\QRCode\QROptions::$transparencyColor - * @codeCoverageIgnore - */ - protected function get_imageTransparencyBG():?array{ - return $this->transparencyColor; - } - - /** - * @deprecated 5.0.0 use QROptions::$bgColor instead - * @see \chillerlan\QRCode\QROptions::$bgColor - */ - protected string $imagickBG; - - /** - * @deprecated 5.0.0 use QROptions::$bgColor instead - * @see \chillerlan\QRCode\QROptions::$bgColor - * @codeCoverageIgnore - */ - protected function set_imagickBG(?string $imagickBG):void{ - $this->bgColor = $imagickBG; - } - - /** - * @deprecated 5.0.0 use QROptions::$bgColor instead - * @see \chillerlan\QRCode\QROptions::$bgColor - * @codeCoverageIgnore - */ - protected function get_imagickBG():?string{ - return $this->bgColor; - } - } diff --git a/tests/Data/QRDataTest.php b/tests/Data/QRDataTest.php index bd2984768..4bd0b50f4 100644 --- a/tests/Data/QRDataTest.php +++ b/tests/Data/QRDataTest.php @@ -13,8 +13,7 @@ namespace chillerlan\QRCodeTest\Data; use chillerlan\QRCode\Common\BitBuffer; use chillerlan\QRCode\Common\MaskPattern; use chillerlan\QRCode\Data\QRData; -use chillerlan\QRCode\Output\QRGdImage; -use chillerlan\QRCode\Output\QROutputInterface; +use chillerlan\QRCode\Output\QRGdImagePNG; use chillerlan\QRCode\QRCode; use chillerlan\QRCode\QROptions; use PHPUnit\Framework\TestCase; @@ -51,11 +50,10 @@ final class QRDataTest extends TestCase{ $this::assertSame(3, $matrix->getVersion()->getVersionNumber()); // attempt to read - $options->outputType = QROutputInterface::GDIMAGE_PNG; $options->outputBase64 = false; $options->readerUseImagickIfAvailable = false; - $output = new QRGdImage($options, $matrix); + $output = new QRGdImagePNG($options, $matrix); $decodeResult = (new QRCode($options))->readFromBlob($output->dump()); QRMatrixTest::debugMatrix($matrix); diff --git a/tests/Data/QRMatrixTest.php b/tests/Data/QRMatrixTest.php index 3bef65794..14bd72ff7 100755 --- a/tests/Data/QRMatrixTest.php +++ b/tests/Data/QRMatrixTest.php @@ -13,7 +13,7 @@ namespace chillerlan\QRCodeTest\Data; use chillerlan\QRCode\{QRCode, QROptions}; use chillerlan\QRCode\Common\{EccLevel, MaskPattern, Version}; use chillerlan\QRCode\Data\{QRCodeDataException, QRMatrix}; -use chillerlan\QRCode\Output\{QROutputInterface, QRString}; +use chillerlan\QRCode\Output\QRStringText; use PHPUnit\Framework\TestCase; use Generator; use function defined; @@ -47,41 +47,40 @@ final class QRMatrixTest extends TestCase{ } $opt = new QROptions; - $opt->outputType = QROutputInterface::STRING_TEXT; - $opt->eol = "\n"; + $opt->eol = "\n"; $opt->moduleValues = [ // finder - QRMatrix::M_FINDER_DARK => QRString::ansi8('██', 124), // dark (true) - QRMatrix::M_FINDER => QRString::ansi8('░░', 124), // light (false) - QRMatrix::M_FINDER_DOT => QRString::ansi8('██', 124), // finder dot, dark (true) + QRMatrix::M_FINDER_DARK => QRStringText::ansi8('██', 124), // dark (true) + QRMatrix::M_FINDER => QRStringText::ansi8('░░', 124), // light (false) + QRMatrix::M_FINDER_DOT => QRStringText::ansi8('██', 124), // finder dot, dark (true) // alignment - QRMatrix::M_ALIGNMENT_DARK => QRString::ansi8('██', 2), - QRMatrix::M_ALIGNMENT => QRString::ansi8('░░', 2), + QRMatrix::M_ALIGNMENT_DARK => QRStringText::ansi8('██', 2), + QRMatrix::M_ALIGNMENT => QRStringText::ansi8('░░', 2), // timing - QRMatrix::M_TIMING_DARK => QRString::ansi8('██', 184), - QRMatrix::M_TIMING => QRString::ansi8('░░', 184), + QRMatrix::M_TIMING_DARK => QRStringText::ansi8('██', 184), + QRMatrix::M_TIMING => QRStringText::ansi8('░░', 184), // format - QRMatrix::M_FORMAT_DARK => QRString::ansi8('██', 200), - QRMatrix::M_FORMAT => QRString::ansi8('░░', 200), + QRMatrix::M_FORMAT_DARK => QRStringText::ansi8('██', 200), + QRMatrix::M_FORMAT => QRStringText::ansi8('░░', 200), // version - QRMatrix::M_VERSION_DARK => QRString::ansi8('██', 21), - QRMatrix::M_VERSION => QRString::ansi8('░░', 21), + QRMatrix::M_VERSION_DARK => QRStringText::ansi8('██', 21), + QRMatrix::M_VERSION => QRStringText::ansi8('░░', 21), // data - QRMatrix::M_DATA_DARK => QRString::ansi8('██', 166), - QRMatrix::M_DATA => QRString::ansi8('░░', 166), + QRMatrix::M_DATA_DARK => QRStringText::ansi8('██', 166), + QRMatrix::M_DATA => QRStringText::ansi8('░░', 166), // dark module - QRMatrix::M_DARKMODULE => QRString::ansi8('██', 53), + QRMatrix::M_DARKMODULE => QRStringText::ansi8('██', 53), // separator - QRMatrix::M_SEPARATOR => QRString::ansi8('░░', 219), + QRMatrix::M_SEPARATOR => QRStringText::ansi8('░░', 219), // quiet zone - QRMatrix::M_QUIETZONE => QRString::ansi8('░░', 195), + QRMatrix::M_QUIETZONE => QRStringText::ansi8('░░', 195), // logo space - QRMatrix::M_LOGO => QRString::ansi8('░░', 105), + QRMatrix::M_LOGO => QRStringText::ansi8('░░', 105), // empty - QRMatrix::M_NULL => QRString::ansi8('░░', 231), + QRMatrix::M_NULL => QRStringText::ansi8('░░', 231), ]; - $out = (new QRString($opt, $matrix))->dump(); + $out = (new QRStringText($opt, $matrix))->dump(); echo "\n\n".$out."\n\n"; } diff --git a/tests/Output/QREpsTest.php b/tests/Output/QREpsTest.php index 96b518253..8b67a906c 100644 --- a/tests/Output/QREpsTest.php +++ b/tests/Output/QREpsTest.php @@ -12,12 +12,10 @@ namespace chillerlan\QRCodeTest\Output; use chillerlan\QRCode\Data\QRMatrix; use chillerlan\QRCode\Output\QREps; -use chillerlan\QRCode\Output\QROutputInterface; class QREpsTest extends QROutputTestAbstract{ - protected string $FQN = QREps::class; - protected string $type = QROutputInterface::EPS; + protected string $FQN = QREps::class; public static function moduleValueProvider():array{ return [ diff --git a/tests/Output/QRFpdfTest.php b/tests/Output/QRFpdfTest.php index a117a6259..caece49e9 100644 --- a/tests/Output/QRFpdfTest.php +++ b/tests/Output/QRFpdfTest.php @@ -12,7 +12,7 @@ namespace chillerlan\QRCodeTest\Output; use FPDF; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\{QRFpdf, QROutputInterface}; +use chillerlan\QRCode\Output\QRFpdf; use function class_exists; @@ -21,8 +21,7 @@ use function class_exists; */ final class QRFpdfTest extends QROutputTestAbstract{ - protected string $FQN = QRFpdf::class; - protected string $type = QROutputInterface::FPDF; + protected string $FQN = QRFpdf::class; /** * @inheritDoc diff --git a/tests/Output/QRGdImageBMPTest.php b/tests/Output/QRGdImageBMPTest.php index 44f58bd2f..09d56a657 100644 --- a/tests/Output/QRGdImageBMPTest.php +++ b/tests/Output/QRGdImageBMPTest.php @@ -11,14 +11,12 @@ namespace chillerlan\QRCodeTest\Output; use chillerlan\QRCode\Output\QRGdImageBMP; -use chillerlan\QRCode\Output\QROutputInterface; /** * */ final class QRGdImageBMPTest extends QRGdImageTestAbstract{ - protected string $type = QROutputInterface::GDIMAGE_BMP; - protected string $FQN = QRGdImageBMP::class; + protected string $FQN = QRGdImageBMP::class; } diff --git a/tests/Output/QRGdImageGIFTest.php b/tests/Output/QRGdImageGIFTest.php index 0ac561895..b6ab05a33 100644 --- a/tests/Output/QRGdImageGIFTest.php +++ b/tests/Output/QRGdImageGIFTest.php @@ -11,14 +11,12 @@ namespace chillerlan\QRCodeTest\Output; use chillerlan\QRCode\Output\QRGdImageGIF; -use chillerlan\QRCode\Output\QROutputInterface; /** * */ final class QRGdImageGIFTest extends QRGdImageTestAbstract{ - protected string $type = QROutputInterface::GDIMAGE_GIF; - protected string $FQN = QRGdImageGIF::class; + protected string $FQN = QRGdImageGIF::class; } diff --git a/tests/Output/QRGdImageJPGTest.php b/tests/Output/QRGdImageJPGTest.php index 5700d38df..76ada23df 100644 --- a/tests/Output/QRGdImageJPGTest.php +++ b/tests/Output/QRGdImageJPGTest.php @@ -11,14 +11,12 @@ namespace chillerlan\QRCodeTest\Output; use chillerlan\QRCode\Output\QRGdImageJPEG; -use chillerlan\QRCode\Output\QROutputInterface; /** * */ final class QRGdImageJPGTest extends QRGdImageTestAbstract{ - protected string $type = QROutputInterface::GDIMAGE_JPG; protected string $FQN = QRGdImageJPEG::class; } diff --git a/tests/Output/QRGdImagePNGTest.php b/tests/Output/QRGdImagePNGTest.php index 5fc07544f..0151d1bc8 100644 --- a/tests/Output/QRGdImagePNGTest.php +++ b/tests/Output/QRGdImagePNGTest.php @@ -11,14 +11,12 @@ namespace chillerlan\QRCodeTest\Output; use chillerlan\QRCode\Output\QRGdImagePNG; -use chillerlan\QRCode\Output\QROutputInterface; /** * */ final class QRGdImagePNGTest extends QRGdImageTestAbstract{ - protected string $type = QROutputInterface::GDIMAGE_PNG; protected string $FQN = QRGdImagePNG::class; } diff --git a/tests/Output/QRGdImageWEBPTest.php b/tests/Output/QRGdImageWEBPTest.php index 8c7b7866e..7a6a0d91f 100644 --- a/tests/Output/QRGdImageWEBPTest.php +++ b/tests/Output/QRGdImageWEBPTest.php @@ -11,14 +11,12 @@ namespace chillerlan\QRCodeTest\Output; use chillerlan\QRCode\Output\QRGdImageWEBP; -use chillerlan\QRCode\Output\QROutputInterface; /** * */ final class QRGdImageWEBPTest extends QRGdImageTestAbstract{ - protected string $type = QROutputInterface::GDIMAGE_WEBP; - protected string $FQN = QRGdImageWEBP::class; + protected string $FQN = QRGdImageWEBP::class; } diff --git a/tests/Output/QRImagickTest.php b/tests/Output/QRImagickTest.php index fcaf1e5e4..35d15cd1f 100644 --- a/tests/Output/QRImagickTest.php +++ b/tests/Output/QRImagickTest.php @@ -14,7 +14,7 @@ namespace chillerlan\QRCodeTest\Output; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\{QRImagick, QROutputInterface}; +use chillerlan\QRCode\Output\QRImagick; use Imagick; /** @@ -22,8 +22,7 @@ use Imagick; */ final class QRImagickTest extends QROutputTestAbstract{ - protected string $FQN = QRImagick::class; - protected string $type = QROutputInterface::IMAGICK; + protected string $FQN = QRImagick::class; /** * @inheritDoc diff --git a/tests/Output/QRMarkupHTMLTest.php b/tests/Output/QRMarkupHTMLTest.php index a35cd07c6..78cc4c630 100644 --- a/tests/Output/QRMarkupHTMLTest.php +++ b/tests/Output/QRMarkupHTMLTest.php @@ -10,14 +10,13 @@ namespace chillerlan\QRCodeTest\Output; -use chillerlan\QRCode\Output\{QRMarkupHTML, QROutputInterface}; +use chillerlan\QRCode\Output\QRMarkupHTML; /** * */ final class QRMarkupHTMLTest extends QRMarkupTestAbstract{ - protected string $FQN = QRMarkupHTML::class; - protected string $type = QROutputInterface::MARKUP_HTML; + protected string $FQN = QRMarkupHTML::class; } diff --git a/tests/Output/QRMarkupSVGTest.php b/tests/Output/QRMarkupSVGTest.php index 7f15ac6c6..87c29be99 100644 --- a/tests/Output/QRMarkupSVGTest.php +++ b/tests/Output/QRMarkupSVGTest.php @@ -10,15 +10,14 @@ namespace chillerlan\QRCodeTest\Output; -use chillerlan\QRCode\Output\{QRMarkupSVG, QROutputInterface}; +use chillerlan\QRCode\Output\QRMarkupSVG; /** * */ final class QRMarkupSVGTest extends QRMarkupTestAbstract{ - protected string $FQN = QRMarkupSVG::class; - protected string $type = QROutputInterface::MARKUP_SVG; + protected string $FQN = QRMarkupSVG::class; public static function moduleValueProvider():array{ return [ diff --git a/tests/Output/QROutputTestAbstract.php b/tests/Output/QROutputTestAbstract.php index 587a737d4..454096064 100644 --- a/tests/Output/QROutputTestAbstract.php +++ b/tests/Output/QROutputTestAbstract.php @@ -17,6 +17,7 @@ use chillerlan\QRCode\Output\{QRCodeOutputException, QROutputInterface}; use PHPUnit\Framework\TestCase; use function file_exists, mkdir; +use function str_replace; /** * Test abstract for the several (built-in) output modules, @@ -30,7 +31,6 @@ abstract class QROutputTestAbstract extends TestCase{ protected QRMatrix $matrix; protected string $builddir = __DIR__.'/../../.build/output_test'; protected string $FQN; - protected string $type; /** * Attempts to create a directory under /.build and instances several required objects @@ -42,7 +42,7 @@ abstract class QROutputTestAbstract extends TestCase{ } $this->options = new QROptions; - $this->options->outputType = $this->type; + $this->options->outputInterface = $this->FQN; $this->matrix = (new QRCode($this->options))->addByteSegment('testdata')->getQRMatrix(); $this->outputInterface = new $this->FQN($this->options, $this->matrix); } @@ -94,7 +94,7 @@ abstract class QROutputTestAbstract extends TestCase{ $this->options->outputBase64 = false; $this->outputInterface = new $this->FQN($this->options, $this->matrix); // create the cache file - $file = $this->builddir.'/test.output.'.$this->type; + $file = $this->builddir.'/test.output.'.str_replace('chillerlan\\QRCode\\Output\\', '', $this->FQN); $data = $this->outputInterface->dump($file); $this::assertSame($data, file_get_contents($file)); diff --git a/tests/Output/QRStringJSONTest.php b/tests/Output/QRStringJSONTest.php index 17aad2f16..507ccdbd8 100644 --- a/tests/Output/QRStringJSONTest.php +++ b/tests/Output/QRStringJSONTest.php @@ -10,7 +10,6 @@ namespace chillerlan\QRCodeTest\Output; -use chillerlan\QRCode\Output\QROutputInterface; use chillerlan\QRCode\Output\QRStringJSON; use function extension_loaded; @@ -19,8 +18,7 @@ use function extension_loaded; */ final class QRStringJSONTest extends QROutputTestAbstract{ - protected string $type = QROutputInterface::STRING_JSON; - protected string $FQN = QRStringJSON::class; + protected string $FQN = QRStringJSON::class; /** * @inheritDoc diff --git a/tests/Output/QRStringTEXTTest.php b/tests/Output/QRStringTEXTTest.php index 4bb3f0e48..37c6fad49 100644 --- a/tests/Output/QRStringTEXTTest.php +++ b/tests/Output/QRStringTEXTTest.php @@ -11,7 +11,6 @@ namespace chillerlan\QRCodeTest\Output; use chillerlan\QRCode\Data\QRMatrix; -use chillerlan\QRCode\Output\QROutputInterface; use chillerlan\QRCode\Output\QRStringText; /** @@ -19,8 +18,7 @@ use chillerlan\QRCode\Output\QRStringText; */ final class QRStringTEXTTest extends QROutputTestAbstract{ - protected string $type = QROutputInterface::STRING_TEXT; - protected string $FQN = QRStringText::class; + protected string $FQN = QRStringText::class; public static function moduleValueProvider():array{ return [ diff --git a/tests/Performance/output.php b/tests/Performance/output.php index 4d96b5177..98a0d9fe8 100644 --- a/tests/Performance/output.php +++ b/tests/Performance/output.php @@ -37,12 +37,11 @@ $generator = new class () { for($v = 5; $v <= 40; $v += 5){ $version = new Version($v); - foreach(QROutputInterface::MODES as $outputType => $FQN){ + foreach(QROutputInterface::MODES as $FQN){ $name = str_replace('chillerlan\\QRCode\\Output\\', '', $FQN); yield sprintf('version %2s: %-14s', $version, $name) => [ $version->getVersionNumber(), - $outputType, $FQN, substr($str, 0, self::getMaxLengthForMode(Mode::BYTE, $version, $eccLevel)), $name, @@ -57,11 +56,11 @@ $generator = new class () { $test = new PerformanceTest(100); $json = []; -foreach($generator->dataProvider() as $key => [$version, $outputType, $FQN, $data, $name]){ +foreach($generator->dataProvider() as $key => [$version, $FQN, $data, $name]){ $options = new QROptions([ 'version' => $version, - 'outputType' => $outputType, + 'outputInterface' => $FQN, 'connectPaths' => true, 'drawLightModules' => true, 'drawCircularModules' => true, diff --git a/tests/Performance/qrcode.php b/tests/Performance/qrcode.php index c796f80ac..e08e76121 100644 --- a/tests/Performance/qrcode.php +++ b/tests/Performance/qrcode.php @@ -12,7 +12,7 @@ namespace chillerlan\QRCodeTest\Performance; use chillerlan\QRCode\{QRCode, QROptions}; use chillerlan\QRCode\Common\{EccLevel, Mode, Version}; -use chillerlan\QRCode\Output\QROutputInterface; +use chillerlan\QRCode\Output\QRStringJSON; use chillerlan\QRCodeTest\QRMaxLengthTrait; use Generator; use function file_put_contents; @@ -70,9 +70,9 @@ $json = []; foreach($generator->dataProvider() as $key => [$version, $eccLevel, $dataModeInterface, $dataModeName, $data]){ $options = new QROptions([ - 'outputType' => QROutputInterface::STRING_JSON, - 'version' => $version, - 'eccLevel' => $eccLevel->getLevel(), + 'outputInterface' => QRStringJSON::class, + 'version' => $version, + 'eccLevel' => $eccLevel->getLevel(), ]); $test->run(fn() => (new QRCode($options))->addSegment(new $dataModeInterface($data))->render()); diff --git a/tests/QRCodeReaderTestAbstract.php b/tests/QRCodeReaderTestAbstract.php index 8cc3ade03..22192dffa 100644 --- a/tests/QRCodeReaderTestAbstract.php +++ b/tests/QRCodeReaderTestAbstract.php @@ -15,7 +15,7 @@ namespace chillerlan\QRCodeTest; use chillerlan\QRCodeTest\Data\QRMatrixTest; use chillerlan\QRCode\{QRCode, QROptions}; use chillerlan\QRCode\Common\{EccLevel, Mode, Version}; -use chillerlan\QRCode\Output\QROutputInterface; +use chillerlan\QRCode\Output\QRGdImagePNG; use chillerlan\Settings\SettingsContainerInterface; use PHPUnit\Framework\TestCase; use Exception, Generator; @@ -96,8 +96,8 @@ abstract class QRCodeReaderTestAbstract extends TestCase{ } public function testReaderMultiMode():void{ - $this->options->outputType = QROutputInterface::GDIMAGE_PNG; - $this->options->outputBase64 = false; + $this->options->outputInterface = QRGdImagePNG::class; + $this->options->outputBase64 = false; $numeric = '123456789012345678901234567890'; $alphanum = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 $%*+-./:'; @@ -145,7 +145,7 @@ abstract class QRCodeReaderTestAbstract extends TestCase{ * @dataProvider dataTestProvider */ public function testReadData(Version $version, EccLevel $ecc, string $expected):void{ - $this->options->outputType = QROutputInterface::GDIMAGE_PNG; + $this->options->outputInterface = QRGdImagePNG::class; $this->options->imageTransparent = false; $this->options->eccLevel = $ecc->getLevel(); $this->options->version = $version->getVersionNumber(); diff --git a/tests/QRCodeTest.php b/tests/QRCodeTest.php index a612d93e2..ff5cf262d 100755 --- a/tests/QRCodeTest.php +++ b/tests/QRCodeTest.php @@ -11,7 +11,7 @@ namespace chillerlan\QRCodeTest; use chillerlan\QRCode\{QROptions, QRCode}; -use chillerlan\QRCode\Output\{QRCodeOutputException, QROutputInterface}; +use chillerlan\QRCode\Output\QRCodeOutputException; use PHPUnit\Framework\TestCase; use stdClass; use function file_get_contents; @@ -33,18 +33,6 @@ final class QRCodeTest extends TestCase{ $this->options = new QROptions; } - /** - * tests if an exception is thrown when an invalid (built-in) output type is specified - */ - public function testInitOutputInterfaceException():void{ - $this->expectException(QRCodeOutputException::class); - $this->expectExceptionMessage('invalid output module'); - - $this->options->outputType = 'foo'; - - $this->qrcode->setOptions($this->options)->render('test'); - } - /** * tests if an exception is thrown if the given output class does not exist */ @@ -52,7 +40,7 @@ final class QRCodeTest extends TestCase{ $this->expectException(QRCodeOutputException::class); $this->expectExceptionMessage('invalid output module'); - $this->options->outputType = QROutputInterface::CUSTOM; + $this->options->outputInterface = 'foo'; $this->qrcode->setOptions($this->options)->render('test'); } @@ -64,7 +52,6 @@ final class QRCodeTest extends TestCase{ $this->expectException(QRCodeOutputException::class); $this->expectExceptionMessage('output module does not implement QROutputInterface'); - $this->options->outputType = QROutputInterface::CUSTOM; $this->options->outputInterface = stdClass::class; $this->qrcode->setOptions($this->options)->render('test'); diff --git a/tests/QRMaxLengthTrait.php b/tests/QRMaxLengthTrait.php index 7fe07ab5a..9d8239b2b 100644 --- a/tests/QRMaxLengthTrait.php +++ b/tests/QRMaxLengthTrait.php @@ -25,7 +25,7 @@ trait QRMaxLengthTrait{ * * @var int[][][] */ - private static array $MAX_LENGTH =[ + protected const MAX_LENGTH =[ // v => [NUMERIC => [L, M, Q, H ], ALPHANUM => [L, M, Q, H], BINARY => [L, M, Q, H ], KANJI => [L, M, Q, H ]] 1 => [[ 41, 34, 27, 17], [ 25, 20, 16, 10], [ 17, 14, 11, 7], [ 10, 8, 7, 4]], 2 => [[ 77, 63, 48, 34], [ 47, 38, 29, 20], [ 32, 26, 20, 14], [ 20, 16, 12, 8]], @@ -73,8 +73,6 @@ trait QRMaxLengthTrait{ /** * the maximum character count for the given $mode and $eccLevel * - * @todo: this methood is only used in unit tests (incl. MAX_LENGTH table) - * * @throws \chillerlan\QRCode\QRCodeException * @codeCoverageIgnore */ @@ -95,16 +93,16 @@ trait QRMaxLengthTrait{ $ver = $version->getVersionNumber(); $ecc = $eccLevel->getOrdinal(); - if(!isset(static::$MAX_LENGTH[$ver])){ + if(!isset(static::MAX_LENGTH[$ver])){ throw new QRCodeException('invalid $version'); } - if(!isset(static::$MAX_LENGTH[$ver][$dataMode][$ecc])){ + if(!isset(static::MAX_LENGTH[$ver][$dataMode][$ecc])){ throw new QRCodeException('invalid $ecc'); } /** @SuppressWarnings(PHPMD.UndefinedVariable) */ - $maxlength = static::$MAX_LENGTH[$ver][$dataMode][$ecc]; + $maxlength = static::MAX_LENGTH[$ver][$dataMode][$ecc]; // Hanzi mode sets an additional 4 bit long subset identifier if($mode === Mode::HANZI){ diff --git a/tests/QROptionsTest.php b/tests/QROptionsTest.php index 534db985c..ccab4cbba 100644 --- a/tests/QROptionsTest.php +++ b/tests/QROptionsTest.php @@ -12,6 +12,8 @@ namespace chillerlan\QRCodeTest; +use chillerlan\QRCode\Common\EccLevel; +use chillerlan\QRCode\QRCodeException; use chillerlan\QRCode\QROptions; use chillerlan\QRCode\Common\Version; use PHPUnit\Framework\TestCase; @@ -68,6 +70,39 @@ final class QROptionsTest extends TestCase{ $this::assertSame($expectedMax, $o->versionMax); } + /** + * Tests setting the ECC level from string or int + */ + public function testSetEccLevel():void{ + $o = new QROptions(['eccLevel' => EccLevel::H]); + + $this::assertSame(EccLevel::H, $o->eccLevel); + + $o->eccLevel = 'q'; + + $this::assertSame(EccLevel::Q, $o->eccLevel); + } + + /** + * Tests if an exception is thrown when attempting to set an invalid ECC level integer + */ + public function testSetEccLevelFromIntException():void{ + $this->expectException(QRCodeException::class); + $this->expectExceptionMessage('Invalid ECC level: "42"'); + /** @phan-suppress-next-line PhanNoopNew */ + new QROptions(['eccLevel' => 42]); + } + + /** + * Tests if an exception is thrown when attempting to set an invalid ECC level string + */ + public function testSetEccLevelFromStringException():void{ + $this->expectException(QRCodeException::class); + $this->expectExceptionMessage('Invalid ECC level: "FOO"'); + /** @phan-suppress-next-line PhanNoopNew */ + new QROptions(['eccLevel' => 'foo']); + } + /** * @return int[][][] */