diff options
Diffstat (limited to 'vendor/chillerlan/php-qrcode/src')
21 files changed, 606 insertions, 685 deletions
diff --git a/vendor/chillerlan/php-qrcode/src/Data/AlphaNum.php b/vendor/chillerlan/php-qrcode/src/Data/AlphaNum.php index c6d34e76f..28d9d7563 100644 --- a/vendor/chillerlan/php-qrcode/src/Data/AlphaNum.php +++ b/vendor/chillerlan/php-qrcode/src/Data/AlphaNum.php @@ -14,22 +14,19 @@ namespace chillerlan\QRCode\Data; use chillerlan\QRCode\QRCode; -use function array_search, ord, sprintf; +use function ord, sprintf; /** * Alphanumeric mode: 0 to 9, A to Z, space, $ % * + - . / : + * + * ISO/IEC 18004:2000 Section 8.3.3 + * ISO/IEC 18004:2000 Section 8.4.3 */ -class AlphaNum extends QRDataAbstract{ +final class AlphaNum extends QRDataAbstract{ - /** - * @inheritdoc - */ - protected $datamode = QRCode::DATA_ALPHANUM; + protected int $datamode = QRCode::DATA_ALPHANUM; - /** - * @inheritdoc - */ - protected $lengthBits = [9, 11, 13]; + protected array $lengthBits = [9, 11, 13]; /** * @inheritdoc @@ -47,19 +44,17 @@ class AlphaNum extends QRDataAbstract{ } /** - * @param string $chr + * get the code for the given character * - * @return int - * @throws \chillerlan\QRCode\Data\QRCodeDataException + * @throws \chillerlan\QRCode\Data\QRCodeDataException on an illegal character occurence */ protected function getCharCode(string $chr):int{ - $i = array_search($chr, $this::ALPHANUM_CHAR_MAP); - if($i !== false){ - return $i; + if(!isset($this::CHAR_MAP_ALPHANUM[$chr])){ + throw new QRCodeDataException(sprintf('illegal char: "%s" [%d]', $chr, ord($chr))); } - throw new QRCodeDataException(sprintf('illegal char: "%s" [%d]', $chr, ord($chr))); + return $this::CHAR_MAP_ALPHANUM[$chr]; } } diff --git a/vendor/chillerlan/php-qrcode/src/Data/Byte.php b/vendor/chillerlan/php-qrcode/src/Data/Byte.php index f1955645a..02e76a639 100644 --- a/vendor/chillerlan/php-qrcode/src/Data/Byte.php +++ b/vendor/chillerlan/php-qrcode/src/Data/Byte.php @@ -18,18 +18,15 @@ use function ord; /** * Byte mode, ISO-8859-1 or UTF-8 + * + * ISO/IEC 18004:2000 Section 8.3.4 + * ISO/IEC 18004:2000 Section 8.4.4 */ -class Byte extends QRDataAbstract{ +final class Byte extends QRDataAbstract{ - /** - * @inheritdoc - */ - protected $datamode = QRCode::DATA_BYTE; + protected int $datamode = QRCode::DATA_BYTE; - /** - * @inheritdoc - */ - protected $lengthBits = [8, 16, 16]; + protected array $lengthBits = [8, 16, 16]; /** * @inheritdoc diff --git a/vendor/chillerlan/php-qrcode/src/Data/Kanji.php b/vendor/chillerlan/php-qrcode/src/Data/Kanji.php index ce600d4ff..e106c50f1 100644 --- a/vendor/chillerlan/php-qrcode/src/Data/Kanji.php +++ b/vendor/chillerlan/php-qrcode/src/Data/Kanji.php @@ -18,18 +18,15 @@ use function mb_strlen, ord, sprintf, strlen; /** * Kanji mode: double-byte characters from the Shift JIS character set + * + * ISO/IEC 18004:2000 Section 8.3.5 + * ISO/IEC 18004:2000 Section 8.4.5 */ -class Kanji extends QRDataAbstract{ +final class Kanji extends QRDataAbstract{ - /** - * @inheritdoc - */ - protected $datamode = QRCode::DATA_KANJI; + protected int $datamode = QRCode::DATA_KANJI; - /** - * @inheritdoc - */ - protected $lengthBits = [8, 10, 12]; + protected array $lengthBits = [8, 10, 12]; /** * @inheritdoc @@ -40,6 +37,8 @@ class Kanji extends QRDataAbstract{ /** * @inheritdoc + * + * @throws \chillerlan\QRCode\Data\QRCodeDataException on an illegal character occurence */ protected function write(string $data):void{ $len = strlen($data); @@ -47,17 +46,17 @@ class Kanji extends QRDataAbstract{ for($i = 0; $i + 1 < $len; $i += 2){ $c = ((0xff & ord($data[$i])) << 8) | (0xff & ord($data[$i + 1])); - if(0x8140 <= $c && $c <= 0x9FFC){ + if($c >= 0x8140 && $c <= 0x9FFC){ $c -= 0x8140; } - elseif(0xE040 <= $c && $c <= 0xEBBF){ + elseif($c >= 0xE040 && $c <= 0xEBBF){ $c -= 0xC140; } else{ throw new QRCodeDataException(sprintf('illegal char at %d [%d]', $i + 1, $c)); } - $this->bitBuffer->put((($c >> 8) & 0xff) * 0xC0 + ($c & 0xff), 13); + $this->bitBuffer->put(((($c >> 8) & 0xff) * 0xC0) + ($c & 0xff), 13); } diff --git a/vendor/chillerlan/php-qrcode/src/Data/MaskPatternTester.php b/vendor/chillerlan/php-qrcode/src/Data/MaskPatternTester.php index 8dfd24180..7874cb53d 100644 --- a/vendor/chillerlan/php-qrcode/src/Data/MaskPatternTester.php +++ b/vendor/chillerlan/php-qrcode/src/Data/MaskPatternTester.php @@ -8,41 +8,51 @@ * @author Smiley <[email protected]> * @copyright 2017 Smiley * @license MIT + * + * @noinspection PhpUnused */ namespace chillerlan\QRCode\Data; -use function abs, call_user_func_array; +use function abs, array_search, call_user_func_array, min; /** - * The sole purpose of this class is to receive a QRMatrix object and run the pattern tests on it. + * Receives a QRDataInterface object and runs the mask pattern tests on it. + * + * ISO/IEC 18004:2000 Section 8.8.2 - Evaluation of masking results * - * @link http://www.thonky.com/qr-code-tutorial/data-masking + * @see http://www.thonky.com/qr-code-tutorial/data-masking */ -class MaskPatternTester{ - - /** - * @var \chillerlan\QRCode\Data\QRMatrix - */ - protected $matrix; +final class MaskPatternTester{ /** - * @var int + * The data interface that contains the data matrix to test */ - protected $moduleCount; + protected QRDataInterface $dataInterface; /** - * Receives the matrix an sets the module count + * Receives the QRDataInterface * * @see \chillerlan\QRCode\QROptions::$maskPattern * @see \chillerlan\QRCode\Data\QRMatrix::$maskPattern - * @see \chillerlan\QRCode\QRCode::getBestMaskPattern() + */ + public function __construct(QRDataInterface $dataInterface){ + $this->dataInterface = $dataInterface; + } + + /** + * shoves a QRMatrix through the MaskPatternTester to find the lowest penalty mask pattern * - * @param \chillerlan\QRCode\Data\QRMatrix $matrix + * @see \chillerlan\QRCode\Data\MaskPatternTester */ - public function __construct(QRMatrix $matrix){ - $this->matrix = $matrix; - $this->moduleCount = $this->matrix->size(); + public function getBestMaskPattern():int{ + $penalties = []; + + for($pattern = 0; $pattern < 8; $pattern++){ + $penalties[$pattern] = $this->testPattern($pattern); + } + + return array_search(min($penalties), $penalties, true); } /** @@ -50,15 +60,13 @@ class MaskPatternTester{ * * @see \chillerlan\QRCode\QROptions::$maskPattern * @see \chillerlan\QRCode\Data\QRMatrix::$maskPattern - * @see \chillerlan\QRCode\QRCode::getBestMaskPattern() - * - * @return int */ - public function testPattern():int{ - $penalty = 0; + public function testPattern(int $pattern):int{ + $matrix = $this->dataInterface->initMatrix($pattern, true); + $penalty = 0; for($level = 1; $level <= 4; $level++){ - $penalty += call_user_func_array([$this, 'testLevel'.$level], [$this->matrix->matrix(true)]); + $penalty += call_user_func_array([$this, 'testLevel'.$level], [$matrix->matrix(true), $matrix->size()]); } return (int)$penalty; @@ -66,10 +74,8 @@ class MaskPatternTester{ /** * Checks for each group of five or more same-colored modules in a row (or column) - * - * @return int */ - protected function testLevel1(array $m):int{ + protected function testLevel1(array $m, int $size):int{ $penalty = 0; foreach($m as $y => $row){ @@ -78,13 +84,13 @@ class MaskPatternTester{ for($ry = -1; $ry <= 1; $ry++){ - if($y + $ry < 0 || $this->moduleCount <= $y + $ry){ + if($y + $ry < 0 || $size <= $y + $ry){ continue; } for($rx = -1; $rx <= 1; $rx++){ - if(($ry === 0 && $rx === 0) || (($x + $rx) < 0 || $this->moduleCount <= ($x + $rx))){ + if(($ry === 0 && $rx === 0) || (($x + $rx) < 0 || $size <= ($x + $rx))){ continue; } @@ -107,21 +113,19 @@ class MaskPatternTester{ /** * Checks for each 2x2 area of same-colored modules in the matrix - * - * @return int */ - protected function testLevel2(array $m):int{ + protected function testLevel2(array $m, int $size):int{ $penalty = 0; foreach($m as $y => $row){ - if($y > ($this->moduleCount - 2)){ + if($y > $size - 2){ break; } foreach($row as $x => $val){ - if($x > ($this->moduleCount - 2)){ + if($x > $size - 2){ break; } @@ -140,17 +144,15 @@ class MaskPatternTester{ /** * Checks if there are patterns that look similar to the finder patterns (1:1:3:1:1 ratio) - * - * @return int */ - protected function testLevel3(array $m):int{ + protected function testLevel3(array $m, int $size):int{ $penalties = 0; foreach($m as $y => $row){ foreach($row as $x => $val){ if( - ($x + 6) < $this->moduleCount + $x + 6 < $size && $val && !$m[$y][$x + 1] && $m[$y][$x + 2] @@ -163,7 +165,7 @@ class MaskPatternTester{ } if( - ($y + 6) < $this->moduleCount + $y + 6 < $size && $val && !$m[$y + 1][$x] && $m[$y + 2][$x] @@ -183,10 +185,8 @@ class MaskPatternTester{ /** * Checks if more than half of the modules are dark or light, with a larger penalty for a larger difference - * - * @return float */ - protected function testLevel4(array $m):float{ + protected function testLevel4(array $m, int $size):float{ $count = 0; foreach($m as $y => $row){ @@ -197,7 +197,7 @@ class MaskPatternTester{ } } - return (abs(100 * $count / $this->moduleCount / $this->moduleCount - 50) / 5) * 10; + return (abs(100 * $count / $size / $size - 50) / 5) * 10; } } diff --git a/vendor/chillerlan/php-qrcode/src/Data/Number.php b/vendor/chillerlan/php-qrcode/src/Data/Number.php index 3936d12c3..0a905b13e 100644 --- a/vendor/chillerlan/php-qrcode/src/Data/Number.php +++ b/vendor/chillerlan/php-qrcode/src/Data/Number.php @@ -4,7 +4,7 @@ * * @filesource Number.php * @created 26.11.2015 - * @package QRCode + * @package chillerlan\QRCode\Data * @author Smiley <[email protected]> * @copyright 2015 Smiley * @license MIT @@ -14,22 +14,19 @@ namespace chillerlan\QRCode\Data; use chillerlan\QRCode\QRCode; -use function ord, sprintf, substr; +use function ord, sprintf, str_split, substr; /** - * Numeric mode: decimal digits 0 through 9 + * Numeric mode: decimal digits 0 to 9 + * + * ISO/IEC 18004:2000 Section 8.3.2 + * ISO/IEC 18004:2000 Section 8.4.2 */ -class Number extends QRDataAbstract{ +final class Number extends QRDataAbstract{ - /** - * @inheritdoc - */ - protected $datamode = QRCode::DATA_NUMBER; + protected int $datamode = QRCode::DATA_NUMBER; - /** - * @inheritdoc - */ - protected $lengthBits = [10, 12, 14]; + protected array $lengthBits = [10, 12, 14]; /** * @inheritdoc @@ -56,20 +53,18 @@ class Number extends QRDataAbstract{ } /** - * @param string $string + * get the code for the given numeric string * - * @return int - * @throws \chillerlan\QRCode\Data\QRCodeDataException + * @throws \chillerlan\QRCode\Data\QRCodeDataException on an illegal character occurence */ protected function parseInt(string $string):int{ $num = 0; - $len = strlen($string); - for($i = 0; $i < $len; $i++){ - $c = ord($string[$i]); + foreach(str_split($string) as $chr){ + $c = ord($chr); - if(!in_array($string[$i], $this::NUMBER_CHAR_MAP, true)){ - throw new QRCodeDataException(sprintf('illegal char: "%s" [%d]', $string[$i], $c)); + if(!isset($this::CHAR_MAP_NUMBER[$chr])){ + throw new QRCodeDataException(sprintf('illegal char: "%s" [%d]', $chr, $c)); } $c = $c - 48; // ord('0') diff --git a/vendor/chillerlan/php-qrcode/src/Data/QRDataAbstract.php b/vendor/chillerlan/php-qrcode/src/Data/QRDataAbstract.php index f52767e38..72b67b7b9 100644 --- a/vendor/chillerlan/php-qrcode/src/Data/QRDataAbstract.php +++ b/vendor/chillerlan/php-qrcode/src/Data/QRDataAbstract.php @@ -12,7 +12,7 @@ namespace chillerlan\QRCode\Data; -use chillerlan\QRCode\{QRCode, QRCodeException}; +use chillerlan\QRCode\QRCode; use chillerlan\QRCode\Helpers\{BitBuffer, Polynomial}; use chillerlan\Settings\SettingsContainerInterface; @@ -25,68 +25,50 @@ abstract class QRDataAbstract implements QRDataInterface{ /** * the string byte count - * - * @var int */ - protected $strlen; + protected ?int $strlen = null; /** * the current data mode: Num, Alphanum, Kanji, Byte - * - * @var int */ - protected $datamode; + protected int $datamode; /** * mode length bits for the version breakpoints 1-9, 10-26 and 27-40 * - * @var array + * ISO/IEC 18004:2000 Table 3 - Number of bits in Character Count Indicator */ - protected $lengthBits = [0, 0, 0]; + protected array $lengthBits = [0, 0, 0]; /** * current QR Code version - * - * @var int */ - protected $version; - - /** - * the raw data that's being passed to QRMatrix::mapData() - * - * @var array - */ - protected $matrixdata; + protected int $version; /** * ECC temp data - * - * @var array */ - protected $ecdata; + protected array $ecdata; /** * ECC temp data - * - * @var array */ - protected $dcdata; + protected array $dcdata; /** - * @var \chillerlan\QRCode\QROptions + * the options instance + * + * @var \chillerlan\Settings\SettingsContainerInterface|\chillerlan\QRCode\QROptions */ - protected $options; + protected SettingsContainerInterface $options; /** - * @var \chillerlan\QRCode\Helpers\BitBuffer + * a BitBuffer instance */ - protected $bitBuffer; + protected BitBuffer $bitBuffer; /** * QRDataInterface constructor. - * - * @param \chillerlan\Settings\SettingsContainerInterface $options - * @param string|null $data */ public function __construct(SettingsContainerInterface $options, string $data = null){ $this->options = $options; @@ -110,10 +92,7 @@ abstract class QRDataAbstract implements QRDataInterface{ ? $this->getMinimumVersion() : $this->options->version; - $this->matrixdata = $this - ->writeBitBuffer($data) - ->maskECC() - ; + $this->writeBitBuffer($data); return $this; } @@ -123,21 +102,14 @@ abstract class QRDataAbstract implements QRDataInterface{ */ public function initMatrix(int $maskPattern, bool $test = null):QRMatrix{ return (new QRMatrix($this->version, $this->options->eccLevel)) - ->setFinderPattern() - ->setSeparators() - ->setAlignmentPattern() - ->setTimingPattern() - ->setVersionNumber($test) - ->setFormatInfo($maskPattern, $test) - ->setDarkModule() - ->mapData($this->matrixdata, $maskPattern) + ->init($maskPattern, $test) + ->mapData($this->maskECC(), $maskPattern) ; } /** * returns the length bits for the version breakpoints 1-9, 10-26 and 27-40 * - * @return int * @throws \chillerlan\QRCode\Data\QRCodeDataException * @codeCoverageIgnore */ @@ -154,10 +126,6 @@ abstract class QRDataAbstract implements QRDataInterface{ /** * returns the byte count of the $data string - * - * @param string $data - * - * @return int */ protected function getLength(string $data):int{ return strlen($data); @@ -166,15 +134,17 @@ abstract class QRDataAbstract implements QRDataInterface{ /** * returns the minimum version number for the given string * - * @return int * @throws \chillerlan\QRCode\Data\QRCodeDataException */ protected function getMinimumVersion():int{ $maxlength = 0; // guess the version number within the given range + $dataMode = QRCode::DATA_MODES[$this->datamode]; + $eccMode = QRCode::ECC_MODES[$this->options->eccLevel]; + foreach(range($this->options->versionMin, $this->options->versionMax) as $version){ - $maxlength = $this::MAX_LENGTH[$version][QRCode::DATA_MODES[$this->datamode]][QRCode::ECC_MODES[$this->options->eccLevel]]; + $maxlength = $this::MAX_LENGTH[$version][$dataMode][$eccMode]; if($this->strlen <= $maxlength){ return $version; @@ -188,81 +158,72 @@ abstract class QRDataAbstract implements QRDataInterface{ * writes the actual data string to the BitBuffer * * @see \chillerlan\QRCode\Data\QRDataAbstract::writeBitBuffer() - * - * @param string $data - * - * @return void */ abstract protected function write(string $data):void; /** * creates a BitBuffer and writes the string data to it * - * @param string $data - * - * @return \chillerlan\QRCode\Data\QRDataAbstract - * @throws \chillerlan\QRCode\QRCodeException + * @throws \chillerlan\QRCode\QRCodeException on data overflow */ - protected function writeBitBuffer(string $data):QRDataInterface{ + protected function writeBitBuffer(string $data):void{ $this->bitBuffer = new BitBuffer; $MAX_BITS = $this::MAX_BITS[$this->version][QRCode::ECC_MODES[$this->options->eccLevel]]; $this->bitBuffer - ->clear() ->put($this->datamode, 4) ->put($this->strlen, $this->getLengthBits()) ; $this->write($data); - // there was an error writing the BitBuffer data, which is... unlikely. - if($this->bitBuffer->length > $MAX_BITS){ - throw new QRCodeException(sprintf('code length overflow. (%d > %d bit)', $this->bitBuffer->length, $MAX_BITS)); // @codeCoverageIgnore + // overflow, likely caused due to invalid version setting + if($this->bitBuffer->getLength() > $MAX_BITS){ + throw new QRCodeDataException(sprintf('code length overflow. (%d > %d bit)', $this->bitBuffer->getLength(), $MAX_BITS)); } - // end code. - if($this->bitBuffer->length + 4 <= $MAX_BITS){ + // add terminator (ISO/IEC 18004:2000 Table 2) + if($this->bitBuffer->getLength() + 4 <= $MAX_BITS){ $this->bitBuffer->put(0, 4); } // padding - while($this->bitBuffer->length % 8 !== 0){ + while($this->bitBuffer->getLength() % 8 !== 0){ $this->bitBuffer->putBit(false); } // padding while(true){ - if($this->bitBuffer->length >= $MAX_BITS){ + if($this->bitBuffer->getLength() >= $MAX_BITS){ break; } $this->bitBuffer->put(0xEC, 8); - if($this->bitBuffer->length >= $MAX_BITS){ + if($this->bitBuffer->getLength() >= $MAX_BITS){ break; } $this->bitBuffer->put(0x11, 8); } - return $this; } /** * ECC masking * - * @link http://www.thonky.com/qr-code-tutorial/error-correction-coding + * ISO/IEC 18004:2000 Section 8.5 ff * - * @return array + * @see http://www.thonky.com/qr-code-tutorial/error-correction-coding */ protected function maskECC():array{ [$l1, $l2, $b1, $b2] = $this::RSBLOCKS[$this->version][QRCode::ECC_MODES[$this->options->eccLevel]]; $rsBlocks = array_fill(0, $l1, [$b1, $b2]); $rsCount = $l1 + $l2; - $this->ecdata = array_fill(0, $rsCount, null); + $this->ecdata = array_fill(0, $rsCount, []); $this->dcdata = $this->ecdata; if($l2 > 0){ @@ -274,6 +235,8 @@ abstract class QRDataAbstract implements QRDataInterface{ $maxEcCount = 0; $offset = 0; + $bitBuffer = $this->bitBuffer->getBuffer(); + foreach($rsBlocks as $key => $block){ [$rsBlockTotal, $dcCount] = $block; @@ -283,12 +246,12 @@ abstract class QRDataAbstract implements QRDataInterface{ $this->dcdata[$key] = array_fill(0, $dcCount, null); foreach($this->dcdata[$key] as $a => $_z){ - $this->dcdata[$key][$a] = 0xff & $this->bitBuffer->buffer[$a + $offset]; + $this->dcdata[$key][$a] = 0xff & $bitBuffer[$a + $offset]; } [$num, $add] = $this->poly($key, $ecCount); - foreach($this->ecdata[$key] as $c => $_z){ + foreach($this->ecdata[$key] as $c => $_){ $modIndex = $c + $add; $this->ecdata[$key][$c] = $modIndex >= 0 ? $num[$modIndex] : 0; } @@ -300,7 +263,7 @@ abstract class QRDataAbstract implements QRDataInterface{ $data = array_fill(0, $totalCodeCount, null); $index = 0; - $mask = function($arr, $count) use (&$data, &$index, $rsCount){ + $mask = function(array $arr, int $count) use (&$data, &$index, $rsCount):void{ for($x = 0; $x < $count; $x++){ for($y = 0; $y < $rsCount; $y++){ if($x < count($arr[$y])){ @@ -318,10 +281,7 @@ abstract class QRDataAbstract implements QRDataInterface{ } /** - * @param int $key - * @param int $count - * - * @return int[] + * helper method for the polynomial operations */ protected function poly(int $key, int $count):array{ $rsPoly = new Polynomial; diff --git a/vendor/chillerlan/php-qrcode/src/Data/QRDataInterface.php b/vendor/chillerlan/php-qrcode/src/Data/QRDataInterface.php index 653386222..93ad6221d 100644 --- a/vendor/chillerlan/php-qrcode/src/Data/QRDataInterface.php +++ b/vendor/chillerlan/php-qrcode/src/Data/QRDataInterface.php @@ -13,23 +13,38 @@ namespace chillerlan\QRCode\Data; /** - * + * Specifies the methods reqired for the data modules (Number, Alphanum, Byte and Kanji) + * and holds version information in several constants */ interface QRDataInterface{ - const NUMBER_CHAR_MAP = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; + /** + * @var int[] + */ + const CHAR_MAP_NUMBER = [ + '0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, '7' => 7, '8' => 8, '9' => 9, + ]; - const ALPHANUM_CHAR_MAP = [ - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', - 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', - 'W', 'X', 'Y', 'Z', ' ', '$', '%', '*', - '+', '-', '.', '/', ':', + /** + * ISO/IEC 18004:2000 Table 5 + * + * @var int[] + */ + const CHAR_MAP_ALPHANUM = [ + '0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, '7' => 7, + '8' => 8, '9' => 9, 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, 'E' => 14, 'F' => 15, + 'G' => 16, 'H' => 17, 'I' => 18, 'J' => 19, 'K' => 20, 'L' => 21, 'M' => 22, 'N' => 23, + 'O' => 24, 'P' => 25, 'Q' => 26, 'R' => 27, 'S' => 28, 'T' => 29, 'U' => 30, 'V' => 31, + 'W' => 32, 'X' => 33, 'Y' => 34, 'Z' => 35, ' ' => 36, '$' => 37, '%' => 38, '*' => 39, + '+' => 40, '-' => 41, '.' => 42, '/' => 43, ':' => 44, ]; /** - * @link http://www.qrcode.com/en/about/version.html + * ISO/IEC 18004:2000 Tables 7-11 - Number of symbol characters and input data capacity for versions 1 to 40 + * + * @see http://www.qrcode.com/en/about/version.html + * + * @var int [][][] */ const MAX_LENGTH =[ // v => [NUMERIC => [L, M, Q, H ], ALPHANUM => [L, M, Q, H], BINARY => [L, M, Q, H ], KANJI => [L, M, Q, H ]] // modules @@ -75,6 +90,11 @@ interface QRDataInterface{ 40 => [[7089, 5596, 3993, 3057], [4296, 3391, 2420, 1852], [2953, 2331, 1663, 1273], [1817, 1435, 1024, 784]], // 177 ]; + /** + * ISO/IEC 18004:2000 Tables 7-11 - Number of symbol characters and input data capacity for versions 1 to 40 + * + * @var int [][] + */ const MAX_BITS = [ // version => [L, M, Q, H ] 1 => [ 152, 128, 104, 72], @@ -120,7 +140,9 @@ interface QRDataInterface{ ]; /** - * @link http://www.thonky.com/qr-code-tutorial/error-correction-table + * @see http://www.thonky.com/qr-code-tutorial/error-correction-table + * + * @var int [][][] */ const RSBLOCKS = [ 1 => [[ 1, 0, 26, 19], [ 1, 0, 26, 16], [ 1, 0, 26, 13], [ 1, 0, 26, 9]], @@ -167,20 +189,11 @@ interface QRDataInterface{ /** * Sets the data string (internally called by the constructor) - * - * @param string $data - * - * @return \chillerlan\QRCode\Data\QRDataInterface */ public function setData(string $data):QRDataInterface; /** * returns a fresh matrix object with the data written for the given $maskPattern - * - * @param int $maskPattern - * @param bool|null $test - * - * @return \chillerlan\QRCode\Data\QRMatrix */ public function initMatrix(int $maskPattern, bool $test = null):QRMatrix; diff --git a/vendor/chillerlan/php-qrcode/src/Data/QRMatrix.php b/vendor/chillerlan/php-qrcode/src/Data/QRMatrix.php index 5b4487a40..05c8b9069 100644..100755 --- a/vendor/chillerlan/php-qrcode/src/Data/QRMatrix.php +++ b/vendor/chillerlan/php-qrcode/src/Data/QRMatrix.php @@ -18,29 +18,46 @@ use Closure; use function array_fill, array_key_exists, array_push, array_unshift, count, floor, in_array, max, min, range; /** - * @link http://www.thonky.com/qr-code-tutorial/format-version-information + * Holds a numerical representation of the final QR Code; + * maps the ECC coded binary data and applies the mask pattern + * + * @see http://www.thonky.com/qr-code-tutorial/format-version-information */ -class QRMatrix{ +final class QRMatrix{ + /** @var int */ public const M_NULL = 0x00; + /** @var int */ public const M_DARKMODULE = 0x02; + /** @var int */ public const M_DATA = 0x04; + /** @var int */ public const M_FINDER = 0x06; + /** @var int */ public const M_SEPARATOR = 0x08; + /** @var int */ public const M_ALIGNMENT = 0x0a; + /** @var int */ public const M_TIMING = 0x0c; + /** @var int */ public const M_FORMAT = 0x0e; + /** @var int */ public const M_VERSION = 0x10; + /** @var int */ public const M_QUIETZONE = 0x12; + /** @var int */ public const M_LOGO = 0x14; + /** @var int */ public const M_FINDER_DOT = 0x16; - + /** @var int */ public const M_TEST = 0xff; /** - * @link http://www.thonky.com/qr-code-tutorial/alignment-pattern-locations + * ISO/IEC 18004:2000 Annex E, Table E.1 - Row/column coordinates of center module of Alignment Patterns + * + * version -> pattern * - * version -> pattern + * @var int[][] */ protected const alignmentPattern = [ 1 => [], @@ -86,9 +103,11 @@ class QRMatrix{ ]; /** - * @link http://www.thonky.com/qr-code-tutorial/format-version-tables + * ISO/IEC 18004:2000 Annex D, Table D.1 - Version information bit stream for each version * * no version pattern for QR Codes < 7 + * + * @var int[] */ protected const versionPattern = [ 7 => 0b000111110010010100, @@ -127,7 +146,13 @@ class QRMatrix{ 40 => 0b101000110001101001, ]; - // ECC level -> mask pattern + /** + * ISO/IEC 18004:2000 Section 8.9 - Format Information + * + * ECC level -> mask pattern + * + * @var int[][] + */ protected const formatPattern = [ [ // L 0b111011111000100, @@ -172,36 +197,35 @@ class QRMatrix{ ]; /** - * @var int + * the current QR Code version number */ - protected $version; + protected int $version; /** - * @var int + * the current ECC level */ - protected $eclevel; + protected int $eclevel; /** - * @var int + * the used mask pattern, set via QRMatrix::mapData() */ - protected $maskPattern = QRCode::MASK_PATTERN_AUTO; + protected int $maskPattern = QRCode::MASK_PATTERN_AUTO; /** - * @var int + * the size (side length) of the matrix */ - protected $moduleCount; + protected int $moduleCount; /** - * @var mixed[] + * the actual matrix data array + * + * @var int[][] */ - protected $matrix; + protected array $matrix; /** * QRMatrix constructor. * - * @param int $version - * @param int $eclevel - * * @throws \chillerlan\QRCode\Data\QRCodeDataException */ public function __construct(int $version, int $eclevel){ @@ -221,6 +245,21 @@ class QRMatrix{ } /** + * shortcut to initialize the matrix + */ + public function init(int $maskPattern, bool $test = null):QRMatrix{ + return $this + ->setFinderPattern() + ->setSeparators() + ->setAlignmentPattern() + ->setTimingPattern() + ->setVersionNumber($test) + ->setFormatInfo($maskPattern, $test) + ->setDarkModule() + ; + } + + /** * Returns the data matrix, returns a pure boolean representation if $boolean is set to true * * @return int[][]|bool[][] @@ -245,21 +284,21 @@ class QRMatrix{ } /** - * @return int + * Returns the current version number */ public function version():int{ return $this->version; } /** - * @return int + * Returns the current ECC level */ public function eccLevel():int{ return $this->eclevel; } /** - * @return int + * Returns the current mask pattern */ public function maskPattern():int{ return $this->maskPattern; @@ -269,8 +308,6 @@ class QRMatrix{ * Returns the absoulute size of the matrix, including quiet zone (after setting it). * * size = version * 4 + 17 [ + 2 * quietzone size] - * - * @return int */ public function size():int{ return $this->moduleCount; @@ -278,11 +315,6 @@ class QRMatrix{ /** * Returns the value of the module at position [$x, $y] - * - * @param int $x - * @param int $y - * - * @return int */ public function get(int $x, int $y):int{ return $this->matrix[$y][$x]; @@ -293,13 +325,6 @@ class QRMatrix{ * * true => $M_TYPE << 8 * false => $M_TYPE - * - * @param int $x - * @param int $y - * @param int $M_TYPE - * @param bool $value - * - * @return \chillerlan\QRCode\Data\QRMatrix */ public function set(int $x, int $y, bool $value, int $M_TYPE):QRMatrix{ $this->matrix[$y][$x] = $M_TYPE << ($value ? 8 : 0); @@ -315,21 +340,14 @@ class QRMatrix{ * * false => $value === $M_TYPE * $value >> 8 === 0 - * - * @param int $x - * @param int $y - * - * @return bool */ public function check(int $x, int $y):bool{ - return $this->matrix[$y][$x] >> 8 > 0; + return ($this->matrix[$y][$x] >> 8) > 0; } /** * Sets the "dark module", that is always on the same position 1x1px away from the bottom left finder - * - * @return \chillerlan\QRCode\Data\QRMatrix */ public function setDarkModule():QRMatrix{ $this->set(8, 4 * $this->version + 9, true, $this::M_DARKMODULE); @@ -340,7 +358,7 @@ class QRMatrix{ /** * Draws the 7x7 finder patterns in the corners top left/right and bottom left * - * @return \chillerlan\QRCode\Data\QRMatrix + * ISO/IEC 18004:2000 Section 7.3.2 */ public function setFinderPattern():QRMatrix{ @@ -375,7 +393,7 @@ class QRMatrix{ /** * Draws the separator lines around the finder patterns * - * @return \chillerlan\QRCode\Data\QRMatrix + * ISO/IEC 18004:2000 Section 7.3.3 */ public function setSeparators():QRMatrix{ @@ -405,7 +423,7 @@ class QRMatrix{ /** * Draws the 5x5 alignment patterns * - * @return \chillerlan\QRCode\Data\QRMatrix + * ISO/IEC 18004:2000 Section 7.3.5 */ public function setAlignmentPattern():QRMatrix{ @@ -435,7 +453,7 @@ class QRMatrix{ /** * Draws the timing pattern (h/v checkered line between the finder patterns) * - * @return \chillerlan\QRCode\Data\QRMatrix + * ISO/IEC 18004:2000 Section 7.3.4 */ public function setTimingPattern():QRMatrix{ @@ -457,9 +475,7 @@ class QRMatrix{ /** * Draws the version information, 2x 3x6 pixel * - * @param bool|null $test - * - * @return \chillerlan\QRCode\Data\QRMatrix + * ISO/IEC 18004:2000 Section 8.10 */ public function setVersionNumber(bool $test = null):QRMatrix{ $bits = $this::versionPattern[$this->version] ?? false; @@ -483,10 +499,7 @@ class QRMatrix{ /** * Draws the format info along the finder patterns * - * @param int $maskPattern - * @param bool|null $test - * - * @return \chillerlan\QRCode\Data\QRMatrix + * ISO/IEC 18004:2000 Section 8.9 */ public function setFormatInfo(int $maskPattern, bool $test = null):QRMatrix{ $bits = $this::formatPattern[QRCode::ECC_MODES[$this->eclevel]][$maskPattern] ?? 0; @@ -524,9 +537,8 @@ class QRMatrix{ /** * Draws the "quiet zone" of $size around the matrix * - * @param int|null $size + * ISO/IEC 18004:2000 Section 7.3.7 * - * @return \chillerlan\QRCode\Data\QRMatrix * @throws \chillerlan\QRCode\Data\QRCodeDataException */ public function setQuietZone(int $size = null):QRMatrix{ @@ -574,18 +586,12 @@ class QRMatrix{ * * @link https://github.com/chillerlan/php-qrcode/issues/52 * - * @param int $width - * @param int $height - * @param int|null $startX - * @param int|null $startY - * - * @return \chillerlan\QRCode\Data\QRMatrix * @throws \chillerlan\QRCode\Data\QRCodeDataException */ public function setLogoSpace(int $width, int $height, int $startX = null, int $startY = null):QRMatrix{ // for logos we operate in ECC H (30%) only - if($this->eclevel !== 0b10){ + if($this->eclevel !== QRCode::ECC_H){ throw new QRCodeDataException('ECC level "H" required to add logo space'); } @@ -635,7 +641,8 @@ class QRMatrix{ } /** - * Maps the binary $data array from QRDataInterface::maskECC() on the matrix, using $maskPattern + * Maps the binary $data array from QRDataInterface::maskECC() on the matrix, + * masking the data using $maskPattern (ISO/IEC 18004:2000 Section 8.8) * * @see \chillerlan\QRCode\Data\QRDataAbstract::maskECC() * @@ -647,10 +654,13 @@ class QRMatrix{ public function mapData(array $data, int $maskPattern):QRMatrix{ $this->maskPattern = $maskPattern; $byteCount = count($data); - $size = $this->moduleCount - 1; + $y = $this->moduleCount - 1; + $inc = -1; + $byteIndex = 0; + $bitIndex = 7; $mask = $this->getMask($this->maskPattern); - for($i = $size, $y = $size, $inc = -1, $byteIndex = 0, $bitIndex = 7; $i > 0; $i -= 2){ + for($i = $y; $i > 0; $i -= 2){ if($i === 6){ $i--; @@ -707,9 +717,6 @@ class QRMatrix{ * * @internal * - * @param int $maskPattern - * - * @return \Closure * @throws \chillerlan\QRCode\Data\QRCodeDataException */ protected function getMask(int $maskPattern):Closure{ @@ -719,14 +726,14 @@ class QRMatrix{ } return [ - 0b000 => function($x, $y):int{ return ($x + $y) % 2; }, - 0b001 => function($x, $y):int{ return $y % 2; }, - 0b010 => function($x, $y):int{ return $x % 3; }, - 0b011 => function($x, $y):int{ return ($x + $y) % 3; }, - 0b100 => function($x, $y):int{ return ((int)($y / 2) + (int)($x / 3)) % 2; }, - 0b101 => function($x, $y):int{ return (($x * $y) % 2) + (($x * $y) % 3); }, - 0b110 => function($x, $y):int{ return ((($x * $y) % 2) + (($x * $y) % 3)) % 2; }, - 0b111 => function($x, $y):int{ return ((($x * $y) % 3) + (($x + $y) % 2)) % 2; }, + 0b000 => fn($x, $y):int => ($x + $y) % 2, + 0b001 => fn($x, $y):int => $y % 2, + 0b010 => fn($x, $y):int => $x % 3, + 0b011 => fn($x, $y):int => ($x + $y) % 3, + 0b100 => fn($x, $y):int => ((int)($y / 2) + (int)($x / 3)) % 2, + 0b101 => fn($x, $y):int => (($x * $y) % 2) + (($x * $y) % 3), + 0b110 => fn($x, $y):int => ((($x * $y) % 2) + (($x * $y) % 3)) % 2, + 0b111 => fn($x, $y):int => ((($x * $y) % 3) + (($x + $y) % 2)) % 2, ][$maskPattern]; } diff --git a/vendor/chillerlan/php-qrcode/src/Helpers/BitBuffer.php b/vendor/chillerlan/php-qrcode/src/Helpers/BitBuffer.php index 0b4ff6a77..de47f20f4 100644 --- a/vendor/chillerlan/php-qrcode/src/Helpers/BitBuffer.php +++ b/vendor/chillerlan/php-qrcode/src/Helpers/BitBuffer.php @@ -14,20 +14,25 @@ namespace chillerlan\QRCode\Helpers; use function count, floor; -class BitBuffer{ +/** + * Holds the raw binary data + */ +final class BitBuffer{ /** - * @var int[] + * The buffer content + * + * @var int[] */ - public $buffer = []; + protected array $buffer = []; /** - * @var int + * Length of the content (bits) */ - public $length = 0; + protected int $length = 0; /** - * @return \chillerlan\QRCode\Helpers\BitBuffer + * clears the buffer */ public function clear():BitBuffer{ $this->buffer = []; @@ -37,10 +42,7 @@ class BitBuffer{ } /** - * @param int $num - * @param int $length - * - * @return \chillerlan\QRCode\Helpers\BitBuffer + * appends a sequence of bits */ public function put(int $num, int $length):BitBuffer{ @@ -52,9 +54,7 @@ class BitBuffer{ } /** - * @param bool $bit - * - * @return \chillerlan\QRCode\Helpers\BitBuffer + * appends a single bit */ public function putBit(bool $bit):BitBuffer{ $bufIndex = floor($this->length / 8); @@ -72,4 +72,18 @@ class BitBuffer{ return $this; } + /** + * returns the current buffer length + */ + public function getLength():int{ + return $this->length; + } + + /** + * returns the buffer content + */ + public function getBuffer():array{ + return $this->buffer; + } + } diff --git a/vendor/chillerlan/php-qrcode/src/Helpers/Polynomial.php b/vendor/chillerlan/php-qrcode/src/Helpers/Polynomial.php index abe11d0cc..c42e0831c 100644 --- a/vendor/chillerlan/php-qrcode/src/Helpers/Polynomial.php +++ b/vendor/chillerlan/php-qrcode/src/Helpers/Polynomial.php @@ -17,12 +17,14 @@ use chillerlan\QRCode\QRCodeException; use function array_fill, count, sprintf; /** - * @link http://www.thonky.com/qr-code-tutorial/error-correction-coding + * Polynomial long division helpers + * + * @see http://www.thonky.com/qr-code-tutorial/error-correction-coding */ -class Polynomial{ +final class Polynomial{ /** - * @link http://www.thonky.com/qr-code-tutorial/log-antilog-table + * @see http://www.thonky.com/qr-code-tutorial/log-antilog-table */ protected const table = [ [ 1, 0], [ 2, 0], [ 4, 1], [ 8, 25], [ 16, 2], [ 32, 50], [ 64, 26], [128, 198], @@ -60,29 +62,26 @@ class Polynomial{ ]; /** - * @var array + * @var int[] */ - protected $num = []; + protected array $num = []; /** * Polynomial constructor. - * - * @param array|null $num - * @param int|null $shift */ public function __construct(array $num = null, int $shift = null){ $this->setNum($num ?? [1], $shift); } /** - * @return array + * */ public function getNum():array{ return $this->num; } /** - * @param array $num + * @param int[] $num * @param int|null $shift * * @return \chillerlan\QRCode\Helpers\Polynomial @@ -105,7 +104,7 @@ class Polynomial{ } /** - * @param array $e + * @param int[] $e * * @return \chillerlan\QRCode\Helpers\Polynomial */ @@ -127,7 +126,7 @@ class Polynomial{ } /** - * @param array $e + * @param int[] $e * * @return \chillerlan\QRCode\Helpers\Polynomial */ @@ -150,9 +149,6 @@ class Polynomial{ } /** - * @param int $n - * - * @return int * @throws \chillerlan\QRCode\QRCodeException */ public function glog(int $n):int{ @@ -165,9 +161,7 @@ class Polynomial{ } /** - * @param int $n * - * @return int */ public function gexp(int $n):int{ diff --git a/vendor/chillerlan/php-qrcode/src/Output/QRFpdf.php b/vendor/chillerlan/php-qrcode/src/Output/QRFpdf.php index a706685af..a15ae9ff3 100644 --- a/vendor/chillerlan/php-qrcode/src/Output/QRFpdf.php +++ b/vendor/chillerlan/php-qrcode/src/Output/QRFpdf.php @@ -69,7 +69,7 @@ class QRFpdf extends QROutputAbstract{ * @return string|\FPDF */ public function dump(string $file = null){ - $file = $file ?? $this->options->cachefile; + $file ??= $this->options->cachefile; $fpdf = new FPDF('P', $this->options->fpdfMeasureUnit, [$this->length, $this->length]); $fpdf->AddPage(); @@ -83,6 +83,7 @@ class QRFpdf extends QROutputAbstract{ $color = $this->moduleValues[$M_TYPE]; if($prevColor === null || $prevColor !== $color){ + /** @phan-suppress-next-line PhanParamTooFewUnpack */ $fpdf->SetFillColor(...$color); $prevColor = $color; } diff --git a/vendor/chillerlan/php-qrcode/src/Output/QRImage.php b/vendor/chillerlan/php-qrcode/src/Output/QRImage.php index 598948c94..8f533d341 100644 --- a/vendor/chillerlan/php-qrcode/src/Output/QRImage.php +++ b/vendor/chillerlan/php-qrcode/src/Output/QRImage.php @@ -19,30 +19,36 @@ use chillerlan\QRCode\{QRCode, QRCodeException}; use chillerlan\Settings\SettingsContainerInterface; use Exception; -use function array_values, base64_encode, call_user_func, count, imagecolorallocate, imagecolortransparent, +use function array_values, base64_encode, call_user_func, count, extension_loaded, imagecolorallocate, imagecolortransparent, imagecreatetruecolor, imagedestroy, imagefilledrectangle, imagegif, imagejpeg, imagepng, in_array, is_array, ob_end_clean, ob_get_contents, ob_start, range, sprintf; /** - * Converts the matrix into GD images, raw or base64 output - * requires ext-gd - * @link http://php.net/manual/book.image.php + * Converts the matrix into GD images, raw or base64 output (requires ext-gd) + * + * @see http://php.net/manual/book.image.php */ class QRImage extends QROutputAbstract{ + /** + * GD image types that support transparency + * + * @var string[] + */ protected const TRANSPARENCY_TYPES = [ QRCode::OUTPUT_IMAGE_PNG, QRCode::OUTPUT_IMAGE_GIF, ]; - /** - * @var string - */ - protected $defaultMode = QRCode::OUTPUT_IMAGE_PNG; + protected string $defaultMode = QRCode::OUTPUT_IMAGE_PNG; /** + * The GD image resource + * * @see imagecreatetruecolor() - * @var resource + * @var resource|\GdImage + * + * @phan-suppress PhanUndeclaredTypeProperty */ protected $image; @@ -84,15 +90,20 @@ class QRImage extends QROutputAbstract{ /** * @inheritDoc * - * @return string|resource + * @return string|resource|\GdImage + * + * @phan-suppress PhanUndeclaredTypeReturnType, PhanTypeMismatchReturn */ public function dump(string $file = null){ + $file ??= $this->options->cachefile; + $this->image = imagecreatetruecolor($this->length, $this->length); // avoid: Indirect modification of overloaded property $imageTransparencyBG has no effect // https://stackoverflow.com/a/10455217 - $tbg = $this->options->imageTransparencyBG; - $background = imagecolorallocate($this->image, ...$tbg); + $tbg = $this->options->imageTransparencyBG; + /** @phan-suppress-next-line PhanParamTooFewInternalUnpack */ + $background = imagecolorallocate($this->image, ...$tbg); if((bool)$this->options->imageTransparent && in_array($this->options->outputType, $this::TRANSPARENCY_TYPES, true)){ imagecolortransparent($this->image, $background); @@ -110,7 +121,11 @@ class QRImage extends QROutputAbstract{ return $this->image; } - $imageData = $this->dumpImage($file); + $imageData = $this->dumpImage(); + + if($file !== null){ + $this->saveToFile($imageData, $file); + } if($this->options->imageBase64){ $imageData = sprintf('data:image/%s;base64,%s', $this->options->outputType, base64_encode($imageData)); @@ -120,11 +135,7 @@ class QRImage extends QROutputAbstract{ } /** - * @param int $x - * @param int $y - * @param array $rgb - * - * @return void + * Creates a single QR pixel with the given settings */ protected function setPixel(int $x, int $y, array $rgb):void{ imagefilledrectangle( @@ -133,20 +144,17 @@ class QRImage extends QROutputAbstract{ $y * $this->scale, ($x + 1) * $this->scale, ($y + 1) * $this->scale, + /** @phan-suppress-next-line PhanParamTooFewInternalUnpack */ imagecolorallocate($this->image, ...$rgb) ); } /** - * @param string|null $file + * Creates the final image by calling the desired GD output function * - * @return string - * @throws \chillerlan\QRCode\Output\QRCodeOutputException */ - protected function dumpImage(string $file = null):string{ - $file = $file ?? $this->options->cachefile; - + protected function dumpImage():string{ ob_start(); try{ @@ -164,14 +172,12 @@ class QRImage extends QROutputAbstract{ ob_end_clean(); - if($file !== null){ - $this->saveToFile($imageData, $file); - } - return $imageData; } /** + * PNG output + * * @return void */ protected function png():void{ @@ -186,6 +192,7 @@ class QRImage extends QROutputAbstract{ /** * Jiff - like... JitHub! + * * @return void */ protected function gif():void{ @@ -193,6 +200,8 @@ class QRImage extends QROutputAbstract{ } /** + * JPG output + * * @return void */ protected function jpg():void{ diff --git a/vendor/chillerlan/php-qrcode/src/Output/QRImagick.php b/vendor/chillerlan/php-qrcode/src/Output/QRImagick.php index 03886cf3b..49516d30e 100644 --- a/vendor/chillerlan/php-qrcode/src/Output/QRImagick.php +++ b/vendor/chillerlan/php-qrcode/src/Output/QRImagick.php @@ -19,24 +19,20 @@ use chillerlan\QRCode\QRCodeException; use chillerlan\Settings\SettingsContainerInterface; use Imagick, ImagickDraw, ImagickPixel; -use function is_string; +use function extension_loaded, is_string; /** - * ImageMagick output module - * requires ext-imagick - * @link http://php.net/manual/book.imagick.php - * @link http://phpimagick.com + * ImageMagick output module (requires ext-imagick) + * + * @see http://php.net/manual/book.imagick.php + * @see http://phpimagick.com */ class QRImagick extends QROutputAbstract{ - /** - * @var \Imagick - */ - protected $imagick; + protected Imagick $imagick; /** * @inheritDoc - * @throws \chillerlan\QRCode\QRCodeException */ public function __construct(SettingsContainerInterface $options, QRMatrix $matrix){ @@ -72,7 +68,7 @@ class QRImagick extends QROutputAbstract{ * @return string|\Imagick */ public function dump(string $file = null){ - $file = $file ?? $this->options->cachefile; + $file ??= $this->options->cachefile; $this->imagick = new Imagick; $this->imagick->newImage( @@ -98,7 +94,7 @@ class QRImagick extends QROutputAbstract{ } /** - * @return void + * Creates the QR image via ImagickDraw */ protected function drawImage():void{ $draw = new ImagickDraw; diff --git a/vendor/chillerlan/php-qrcode/src/Output/QRMarkup.php b/vendor/chillerlan/php-qrcode/src/Output/QRMarkup.php index 15559dae0..06d6e88cb 100644 --- a/vendor/chillerlan/php-qrcode/src/Output/QRMarkup.php +++ b/vendor/chillerlan/php-qrcode/src/Output/QRMarkup.php @@ -21,17 +21,13 @@ use function is_string, sprintf, strip_tags, trim; */ class QRMarkup extends QROutputAbstract{ - /** - * @var string - */ - protected $defaultMode = QRCode::OUTPUT_MARKUP_SVG; + protected string $defaultMode = QRCode::OUTPUT_MARKUP_SVG; /** * @see \sprintf() - * - * @var string */ - protected $svgHeader = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="qr-svg %1$s" style="width: 100%%; height: auto;" viewBox="0 0 %2$d %2$d">'; + protected string $svgHeader = '<svg xmlns="http://www.w3.org/2000/svg" class="qr-svg %1$s" '. + 'style="width: 100%%; height: auto;" viewBox="0 0 %2$d %2$d">'; /** * @inheritDoc @@ -55,10 +51,15 @@ class QRMarkup extends QROutputAbstract{ } /** - * @return string + * HTML output */ - protected function html():string{ - $html = '<div class="'.$this->options->cssClass.'">'.$this->options->eol; + protected function html(string $file = null):string{ + + $html = empty($this->options->cssClass) + ? '<div>' + : '<div class="'.$this->options->cssClass.'">'; + + $html .= $this->options->eol; foreach($this->matrix->matrix() as $row){ $html .= '<div>'; @@ -72,19 +73,21 @@ class QRMarkup extends QROutputAbstract{ $html .= '</div>'.$this->options->eol; - if($this->options->cachefile){ - return '<!DOCTYPE html><head><meta charset="UTF-8"></head><body>'.$this->options->eol.$html.'</body>'; + if($file !== null){ + return '<!DOCTYPE html>'. + '<head><meta charset="UTF-8"><title>QR Code</title></head>'. + '<body>'.$this->options->eol.$html.'</body>'; } return $html; } /** - * @link https://github.com/codemasher/php-qrcode/pull/5 + * SVG output * - * @return string + * @see https://github.com/codemasher/php-qrcode/pull/5 */ - protected function svg():string{ + protected function svg(string $file = null):string{ $matrix = $this->matrix->matrix(); $svg = sprintf($this->svgHeader, $this->options->cssClass, $this->options->svgViewBoxSize ?? $this->moduleCount) @@ -115,7 +118,9 @@ class QRMarkup extends QROutputAbstract{ } if($count > 0){ - $len = $count; + $len = $count; + $start ??= 0; // avoid type coercion in sprintf() - phan happy + $path .= sprintf('M%s %s h%s v1 h-%sZ ', $start, $y, $len, $len); // reset count @@ -128,7 +133,10 @@ class QRMarkup extends QROutputAbstract{ } if(!empty($path)){ - $svg .= sprintf('<path class="qr-%s %s" stroke="transparent" fill="%s" fill-opacity="%s" d="%s" />', $M_TYPE, $this->options->cssClass, $value, $this->options->svgOpacity, $path); + $svg .= sprintf( + '<path class="qr-%s %s" stroke="transparent" fill="%s" fill-opacity="%s" d="%s" />', + $M_TYPE, $this->options->cssClass, $value, $this->options->svgOpacity, $path + ); } } @@ -137,8 +145,9 @@ class QRMarkup extends QROutputAbstract{ $svg .= '</svg>'.$this->options->eol; // if saving to file, append the correct headers - if($this->options->cachefile){ - return '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'.$this->options->eol.$svg; + if($file !== null){ + return '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'. + $this->options->eol.$svg; } if($this->options->imageBase64){ diff --git a/vendor/chillerlan/php-qrcode/src/Output/QROutputAbstract.php b/vendor/chillerlan/php-qrcode/src/Output/QROutputAbstract.php index 4ec47de24..d4ed3d0c9 100644 --- a/vendor/chillerlan/php-qrcode/src/Output/QROutputAbstract.php +++ b/vendor/chillerlan/php-qrcode/src/Output/QROutputAbstract.php @@ -15,7 +15,7 @@ namespace chillerlan\QRCode\Output; use chillerlan\QRCode\{Data\QRMatrix, QRCode}; use chillerlan\Settings\SettingsContainerInterface; -use function call_user_func, dirname, file_put_contents, get_called_class, in_array, is_writable, sprintf; +use function call_user_func_array, dirname, file_put_contents, get_called_class, in_array, is_writable, sprintf; /** * common output abstract @@ -23,50 +23,53 @@ use function call_user_func, dirname, file_put_contents, get_called_class, in_ar abstract class QROutputAbstract implements QROutputInterface{ /** - * @var int + * the current size of the QR matrix + * + * @see \chillerlan\QRCode\Data\QRMatrix::size() */ - protected $moduleCount; + protected int $moduleCount; /** - * @param \chillerlan\QRCode\Data\QRMatrix $matrix + * the current output mode + * + * @see \chillerlan\QRCode\QROptions::$outputType */ - protected $matrix; + protected string $outputMode; /** - * @var \chillerlan\QRCode\QROptions + * the default output mode of the current output module */ - protected $options; + protected string $defaultMode; /** - * @var string + * the current scaling for a QR pixel + * + * @see \chillerlan\QRCode\QROptions::$scale */ - protected $outputMode; + protected int $scale; /** - * @var string; + * the side length of the QR image (modules * scale) */ - protected $defaultMode; + protected int $length; /** - * @var int + * an (optional) array of color values for the several QR matrix parts */ - protected $scale; + protected array $moduleValues; /** - * @var int + * the (filled) data matrix object */ - protected $length; + protected QRMatrix $matrix; /** - * @var array + * @var \chillerlan\Settings\SettingsContainerInterface|\chillerlan\QRCode\QROptions */ - protected $moduleValues; + protected SettingsContainerInterface $options; /** * QROutputAbstract constructor. - * - * @param \chillerlan\Settings\SettingsContainerInterface $options - * @param \chillerlan\QRCode\Data\QRMatrix $matrix */ public function __construct(SettingsContainerInterface $options, QRMatrix $matrix){ $this->options = $options; @@ -86,8 +89,6 @@ abstract class QROutputAbstract implements QROutputInterface{ /** * Sets the initial module values (clean-up & defaults) - * - * @return void */ abstract protected function setModuleValues():void; @@ -97,10 +98,6 @@ abstract class QROutputAbstract implements QROutputInterface{ * @see file_put_contents() * @see \chillerlan\QRCode\QROptions::cachefile * - * @param string $data - * @param string $file - * - * @return bool * @throws \chillerlan\QRCode\Output\QRCodeOutputException */ protected function saveToFile(string $data, string $file):bool{ @@ -116,9 +113,11 @@ abstract class QROutputAbstract implements QROutputInterface{ * @inheritDoc */ public function dump(string $file = null){ - // call the built-in output method - $data = call_user_func([$this, $this->outputMode ?? $this->defaultMode]); - $file = $file ?? $this->options->cachefile; + $file ??= $this->options->cachefile; + + // call the built-in output method with the optional file path as parameter + // to make the called method aware if a cache file was given + $data = call_user_func_array([$this, $this->outputMode ?? $this->defaultMode], [$file]); if($file !== null){ $this->saveToFile($data, $file); diff --git a/vendor/chillerlan/php-qrcode/src/Output/QROutputInterface.php b/vendor/chillerlan/php-qrcode/src/Output/QROutputInterface.php index d9149b0f7..b07b8e7a5 100644 --- a/vendor/chillerlan/php-qrcode/src/Output/QROutputInterface.php +++ b/vendor/chillerlan/php-qrcode/src/Output/QROutputInterface.php @@ -21,6 +21,7 @@ interface QROutputInterface{ const DEFAULT_MODULE_VALUES = [ // light + QRMatrix::M_NULL => false, // 0 QRMatrix::M_DATA => false, // 4 QRMatrix::M_FINDER => false, // 6 QRMatrix::M_SEPARATOR => false, // 8 @@ -46,8 +47,6 @@ interface QROutputInterface{ /** * generates the output, optionally dumps it to a file, and returns it * - * @param string|null $file - * * @return mixed */ public function dump(string $file = null); diff --git a/vendor/chillerlan/php-qrcode/src/Output/QRString.php b/vendor/chillerlan/php-qrcode/src/Output/QRString.php index ba8d83675..3ed5153e1 100644 --- a/vendor/chillerlan/php-qrcode/src/Output/QRString.php +++ b/vendor/chillerlan/php-qrcode/src/Output/QRString.php @@ -8,6 +8,9 @@ * @author Smiley <[email protected]> * @copyright 2015 Smiley * @license MIT + * + * @noinspection PhpUnusedParameterInspection + * @noinspection PhpComposerExtensionStubsInspection */ namespace chillerlan\QRCode\Output; @@ -21,10 +24,7 @@ use function implode, is_string, json_encode; */ class QRString extends QROutputAbstract{ - /** - * @var string - */ - protected $defaultMode = QRCode::OUTPUT_STRING_TEXT; + protected string $defaultMode = QRCode::OUTPUT_STRING_TEXT; /** * @inheritDoc @@ -48,9 +48,9 @@ class QRString extends QROutputAbstract{ } /** - * @return string + * string output */ - protected function text():string{ + protected function text(string $file = null):string{ $str = []; foreach($this->matrix->matrix() as $row){ @@ -67,9 +67,9 @@ class QRString extends QROutputAbstract{ } /** - * @return string + * JSON output */ - protected function json():string{ + protected function json(string $file = null):string{ return json_encode($this->matrix->matrix()); } diff --git a/vendor/chillerlan/php-qrcode/src/QRCode.php b/vendor/chillerlan/php-qrcode/src/QRCode.php index 91f7aa0eb..908030feb 100644..100755 --- a/vendor/chillerlan/php-qrcode/src/QRCode.php +++ b/vendor/chillerlan/php-qrcode/src/QRCode.php @@ -13,51 +13,76 @@ namespace chillerlan\QRCode; use chillerlan\QRCode\Data\{ - MaskPatternTester, QRCodeDataException, QRDataInterface, QRMatrix + AlphaNum, Byte, Kanji, MaskPatternTester, Number, QRCodeDataException, QRDataInterface, QRMatrix }; use chillerlan\QRCode\Output\{ QRCodeOutputException, QRFpdf, QRImage, QRImagick, QRMarkup, QROutputInterface, QRString }; use chillerlan\Settings\SettingsContainerInterface; -use function array_search, call_user_func_array, class_exists, in_array, min, ord, strlen; +use function call_user_func_array, class_exists, in_array, ord, strlen, strtolower, str_split; /** * Turns a text string into a Model 2 QR Code * - * @link https://github.com/kazuhikoarase/qrcode-generator/tree/master/php - * @link http://www.qrcode.com/en/codes/model12.html - * @link http://www.thonky.com/qr-code-tutorial/ + * @see https://github.com/kazuhikoarase/qrcode-generator/tree/master/php + * @see http://www.qrcode.com/en/codes/model12.html + * @see https://www.swisseduc.ch/informatik/theoretische_informatik/qr_codes/docs/qr_standard.pdf + * @see https://en.wikipedia.org/wiki/QR_code + * @see http://www.thonky.com/qr-code-tutorial/ */ class QRCode{ - /** - * API constants - */ - public const OUTPUT_MARKUP_HTML = 'html'; - public const OUTPUT_MARKUP_SVG = 'svg'; - public const OUTPUT_IMAGE_PNG = 'png'; - public const OUTPUT_IMAGE_JPG = 'jpg'; - public const OUTPUT_IMAGE_GIF = 'gif'; - public const OUTPUT_STRING_JSON = 'json'; - public const OUTPUT_STRING_TEXT = 'text'; - public const OUTPUT_IMAGICK = 'imagick'; - public const OUTPUT_FPDF = 'fpdf'; - public const OUTPUT_CUSTOM = 'custom'; - + /** @var int */ public const VERSION_AUTO = -1; + /** @var int */ public const MASK_PATTERN_AUTO = -1; - public const ECC_L = 0b01; // 7%. - public const ECC_M = 0b00; // 15%. - public const ECC_Q = 0b11; // 25%. - public const ECC_H = 0b10; // 30%. + // ISO/IEC 18004:2000 Table 2 + /** @var int */ public const DATA_NUMBER = 0b0001; + /** @var int */ public const DATA_ALPHANUM = 0b0010; + /** @var int */ public const DATA_BYTE = 0b0100; + /** @var int */ public const DATA_KANJI = 0b1000; + /** + * References to the keys of the following tables: + * + * @see \chillerlan\QRCode\Data\QRDataInterface::MAX_LENGTH + * + * @var int[] + */ + public const DATA_MODES = [ + self::DATA_NUMBER => 0, + self::DATA_ALPHANUM => 1, + self::DATA_BYTE => 2, + self::DATA_KANJI => 3, + ]; + + // ISO/IEC 18004:2000 Tables 12, 25 + + /** @var int */ + public const ECC_L = 0b01; // 7%. + /** @var int */ + public const ECC_M = 0b00; // 15%. + /** @var int */ + public const ECC_Q = 0b11; // 25%. + /** @var int */ + public const ECC_H = 0b10; // 30%. + + /** + * References to the keys of the following tables: + * + * @see \chillerlan\QRCode\Data\QRDataInterface::MAX_BITS + * @see \chillerlan\QRCode\Data\QRDataInterface::RSBLOCKS + * @see \chillerlan\QRCode\Data\QRMatrix::formatPattern + * + * @var int[] + */ public const ECC_MODES = [ self::ECC_L => 0, self::ECC_M => 1, @@ -65,13 +90,32 @@ class QRCode{ self::ECC_H => 3, ]; - public const DATA_MODES = [ - self::DATA_NUMBER => 0, - self::DATA_ALPHANUM => 1, - self::DATA_BYTE => 2, - self::DATA_KANJI => 3, - ]; + /** @var string */ + public const OUTPUT_MARKUP_HTML = 'html'; + /** @var string */ + public const OUTPUT_MARKUP_SVG = 'svg'; + /** @var string */ + public const OUTPUT_IMAGE_PNG = 'png'; + /** @var string */ + public const OUTPUT_IMAGE_JPG = 'jpg'; + /** @var string */ + public const OUTPUT_IMAGE_GIF = 'gif'; + /** @var string */ + public const OUTPUT_STRING_JSON = 'json'; + /** @var string */ + public const OUTPUT_STRING_TEXT = 'text'; + /** @var string */ + public const OUTPUT_IMAGICK = 'imagick'; + /** @var string */ + public const OUTPUT_FPDF = 'fpdf'; + /** @var string */ + public const OUTPUT_CUSTOM = 'custom'; + /** + * Map of built-in output modules => capabilities + * + * @var string[][] + */ public const OUTPUT_MODES = [ QRMarkup::class => [ self::OUTPUT_MARKUP_SVG, @@ -95,19 +139,33 @@ class QRCode{ ]; /** + * Map of data mode => interface + * + * @var string[] + */ + protected const DATA_INTERFACES = [ + 'number' => Number::class, + 'alphanum' => AlphaNum::class, + 'kanji' => Kanji::class, + 'byte' => Byte::class, + ]; + + /** + * The settings container + * * @var \chillerlan\QRCode\QROptions|\chillerlan\Settings\SettingsContainerInterface */ - protected $options; + protected SettingsContainerInterface $options; /** - * @var \chillerlan\QRCode\Data\QRDataInterface + * The selected data interface (Number, AlphaNum, Kanji, Byte) */ - protected $dataInterface; + protected QRDataInterface $dataInterface; /** * QRCode constructor. * - * @param \chillerlan\Settings\SettingsContainerInterface|null $options + * Sets the options instance, determines the current mb-encoding and sets it to UTF-8 */ public function __construct(SettingsContainerInterface $options = null){ $this->options = $options ?? new QROptions; @@ -116,9 +174,6 @@ class QRCode{ /** * Renders a QR Code for the given $data and QROptions * - * @param string $data - * @param string|null $file - * * @return mixed */ public function render(string $data, string $file = null){ @@ -128,9 +183,6 @@ class QRCode{ /** * Returns a QRMatrix object for the given $data and current QROptions * - * @param string $data - * - * @return \chillerlan\QRCode\Data\QRMatrix * @throws \chillerlan\QRCode\Data\QRCodeDataException */ public function getMatrix(string $data):QRMatrix{ @@ -142,7 +194,7 @@ class QRCode{ $this->dataInterface = $this->initDataInterface($data); $maskPattern = $this->options->maskPattern === $this::MASK_PATTERN_AUTO - ? $this->getBestMaskPattern() + ? (new MaskPatternTester($this->dataInterface))->getBestMaskPattern() : $this->options->maskPattern; $matrix = $this->dataInterface->initMatrix($maskPattern); @@ -155,48 +207,23 @@ class QRCode{ } /** - * shoves a QRMatrix through the MaskPatternTester to find the lowest penalty mask pattern - * - * @see \chillerlan\QRCode\Data\MaskPatternTester - * - * @return int - */ - protected function getBestMaskPattern():int{ - $penalties = []; - - for($pattern = 0; $pattern < 8; $pattern++){ - $tester = new MaskPatternTester($this->dataInterface->initMatrix($pattern, true)); - - $penalties[$pattern] = $tester->testPattern(); - } - - return array_search(min($penalties), $penalties, true); - } - - /** * returns a fresh QRDataInterface for the given $data * - * @param string $data - * - * @return \chillerlan\QRCode\Data\QRDataInterface * @throws \chillerlan\QRCode\Data\QRCodeDataException */ public function initDataInterface(string $data):QRDataInterface{ - $dataModes = ['Number', 'AlphaNum', 'Kanji', 'Byte']; - $dataNamespace = __NAMESPACE__.'\\Data\\'; // allow forcing the data mode // see https://github.com/chillerlan/php-qrcode/issues/39 - if(in_array($this->options->dataMode, $dataModes, true)){ - $dataInterface = $dataNamespace.$this->options->dataMode; + $interface = $this::DATA_INTERFACES[strtolower($this->options->dataModeOverride)] ?? null; - return new $dataInterface($this->options, $data); + if($interface !== null){ + return new $interface($this->options, $data); } - foreach($dataModes as $mode){ - $dataInterface = $dataNamespace.$mode; + foreach($this::DATA_INTERFACES as $mode => $dataInterface){ - if(call_user_func_array([$this, 'is'.$mode], [$data]) && class_exists($dataInterface)){ + if(call_user_func_array([$this, 'is'.$mode], [$data])){ return new $dataInterface($this->options, $data); } @@ -208,14 +235,12 @@ class QRCode{ /** * returns a fresh (built-in) QROutputInterface * - * @param string $data - * - * @return \chillerlan\QRCode\Output\QROutputInterface * @throws \chillerlan\QRCode\Output\QRCodeOutputException */ protected function initOutputInterface(string $data):QROutputInterface{ if($this->options->outputType === $this::OUTPUT_CUSTOM && class_exists($this->options->outputInterface)){ + /** @phan-suppress-next-line PhanTypeExpectedObjectOrClassName */ return new $this->options->outputInterface($this->options, $this->getMatrix($data)); } @@ -232,39 +257,25 @@ class QRCode{ /** * checks if a string qualifies as numeric - * - * @param string $string - * - * @return bool */ public function isNumber(string $string):bool{ - return $this->checkString($string, QRDataInterface::NUMBER_CHAR_MAP); + return $this->checkString($string, QRDataInterface::CHAR_MAP_NUMBER); } /** * checks if a string qualifies as alphanumeric - * - * @param string $string - * - * @return bool */ public function isAlphaNum(string $string):bool{ - return $this->checkString($string, QRDataInterface::ALPHANUM_CHAR_MAP); + return $this->checkString($string, QRDataInterface::CHAR_MAP_ALPHANUM); } /** * checks is a given $string matches the characters of a given $charmap, returns false on the first invalid occurence. - * - * @param string $string - * @param array $charmap - * - * @return bool */ protected function checkString(string $string, array $charmap):bool{ - $len = strlen($string); - for($i = 0; $i < $len; $i++){ - if(!in_array($string[$i], $charmap, true)){ + foreach(str_split($string) as $chr){ + if(!isset($charmap[$chr])){ return false; } } @@ -274,10 +285,6 @@ class QRCode{ /** * checks if a string qualifies as Kanji - * - * @param string $string - * - * @return bool */ public function isKanji(string $string):bool{ $i = 0; @@ -298,13 +305,9 @@ class QRCode{ /** * a dummy - * - * @param $data - * - * @return bool */ - protected function isByte(string $data):bool{ - return !empty($data); + public function isByte(string $data):bool{ + return $data !== ''; } } diff --git a/vendor/chillerlan/php-qrcode/src/QRCodeException.php b/vendor/chillerlan/php-qrcode/src/QRCodeException.php index 68af380ff..737a0803e 100644 --- a/vendor/chillerlan/php-qrcode/src/QRCodeException.php +++ b/vendor/chillerlan/php-qrcode/src/QRCodeException.php @@ -12,4 +12,9 @@ namespace chillerlan\QRCode; -class QRCodeException extends \Exception{} +use Exception; + +/** + * An exception container + */ +class QRCodeException extends Exception{} diff --git a/vendor/chillerlan/php-qrcode/src/QROptions.php b/vendor/chillerlan/php-qrcode/src/QROptions.php index 778ae0407..e36f6701a 100644 --- a/vendor/chillerlan/php-qrcode/src/QROptions.php +++ b/vendor/chillerlan/php-qrcode/src/QROptions.php @@ -15,46 +15,39 @@ namespace chillerlan\QRCode; use chillerlan\Settings\SettingsContainerAbstract; /** - * @property int $version - * @property int $versionMin - * @property int $versionMax - * @property int $eccLevel - * @property int $maskPattern - * @property bool $addQuietzone - * @property bool $quietzoneSize - * - * @property string $dataMode - * @property string $outputType - * @property string $outputInterface - * @property string $cachefile - * - * @property string $eol - * @property int $scale - * - * @property string $cssClass - * @property string $svgOpacity - * @property string $svgDefs - * @property int $svgViewBoxSize - * - * @property string $textDark - * @property string $textLight - * - * @property string $markupDark - * @property string $markupLight - * - * @property bool $returnResource - * @property bool $imageBase64 - * @property bool $imageTransparent - * @property array $imageTransparencyBG - * @property int $pngCompression - * @property int $jpegQuality - * - * @property string $imagickFormat - * @property string $imagickBG - * - * @property string $fpdfMeasureUnit - * - * @property array $moduleValues + * The QRCode settings container + * + * @property int $version + * @property int $versionMin + * @property int $versionMax + * @property int $eccLevel + * @property int $maskPattern + * @property bool $addQuietzone + * @property int $quietzoneSize + * @property string|null $dataModeOverride + * @property string $outputType + * @property string|null $outputInterface + * @property string|null $cachefile + * @property string $eol + * @property int $scale + * @property string $cssClass + * @property float $svgOpacity + * @property string $svgDefs + * @property int $svgViewBoxSize + * @property string $textDark + * @property string $textLight + * @property string $markupDark + * @property string $markupLight + * @property bool $returnResource + * @property bool $imageBase64 + * @property bool $imageTransparent + * @property array $imageTransparencyBG + * @property int $pngCompression + * @property int $jpegQuality + * @property string $imagickFormat + * @property string|null $imagickBG + * @property string $fpdfMeasureUnit + * @property array|null $moduleValues */ class QROptions extends SettingsContainerAbstract{ use QROptionsTrait; diff --git a/vendor/chillerlan/php-qrcode/src/QROptionsTrait.php b/vendor/chillerlan/php-qrcode/src/QROptionsTrait.php index 45d4cb415..74c384b13 100644 --- a/vendor/chillerlan/php-qrcode/src/QROptionsTrait.php +++ b/vendor/chillerlan/php-qrcode/src/QROptionsTrait.php @@ -8,146 +8,125 @@ * @author smiley <[email protected]> * @copyright 2018 smiley * @license MIT + * + * @noinspection PhpUnused */ namespace chillerlan\QRCode; -use function array_values, count, in_array, is_array, is_numeric, max, min, sprintf, strtolower; +use function array_values, count, in_array, is_numeric, max, min, sprintf, strtolower; +/** + * The QRCode plug-in settings & setter functionality + */ trait QROptionsTrait{ /** * QR Code version number * - * [1 ... 40] or QRCode::VERSION_AUTO - * - * @var int + * [1 ... 40] or QRCode::VERSION_AUTO */ - protected $version = QRCode::VERSION_AUTO; + protected int $version = QRCode::VERSION_AUTO; /** - * Minimum QR version (if $version = QRCode::VERSION_AUTO) + * Minimum QR version * - * @var int + * if $version = QRCode::VERSION_AUTO */ - protected $versionMin = 1; + protected int $versionMin = 1; /** * Maximum QR version - * - * @var int */ - protected $versionMax = 40; + protected int $versionMax = 40; /** * Error correct level * - * QRCode::ECC_X where X is - * L => 7% - * M => 15% - * Q => 25% - * H => 30% + * QRCode::ECC_X where X is: * - * @var int + * - L => 7% + * - M => 15% + * - Q => 25% + * - H => 30% */ - protected $eccLevel = QRCode::ECC_L; + protected int $eccLevel = QRCode::ECC_L; /** * Mask Pattern to use * - * [0...7] or QRCode::MASK_PATTERN_AUTO - * - * @var int + * [0...7] or QRCode::MASK_PATTERN_AUTO */ - protected $maskPattern = QRCode::MASK_PATTERN_AUTO; + protected int $maskPattern = QRCode::MASK_PATTERN_AUTO; /** * Add a "quiet zone" (margin) according to the QR code spec - * - * @var bool */ - protected $addQuietzone = true; + protected bool $addQuietzone = true; /** * Size of the quiet zone * - * internally clamped to [0 ... $moduleCount / 2], defaults to 4 modules - * - * @var int + * internally clamped to [0 ... $moduleCount / 2], defaults to 4 modules */ - protected $quietzoneSize = 4; + protected int $quietzoneSize = 4; /** * Use this to circumvent the data mode detection and force the usage of the given mode. - * valid modes are: Number, AlphaNum, Kanji, Byte * - * @see https://github.com/chillerlan/php-qrcode/issues/39 + * valid modes are: Number, AlphaNum, Kanji, Byte (case insensitive) * - * @var string|null + * @see https://github.com/chillerlan/php-qrcode/issues/39 + * @see https://github.com/chillerlan/php-qrcode/issues/97 (changed default value to '') */ - protected $dataMode = null; + protected string $dataModeOverride = ''; /** - * QRCode::OUTPUT_MARKUP_XXXX where XXXX = HTML, SVG - * QRCode::OUTPUT_IMAGE_XXX where XXX = PNG, GIF, JPG - * QRCode::OUTPUT_STRING_XXXX where XXXX = TEXT, JSON - * QRCode::OUTPUT_CUSTOM + * The output type * - * @var string + * - QRCode::OUTPUT_MARKUP_XXXX where XXXX = HTML, SVG + * - QRCode::OUTPUT_IMAGE_XXX where XXX = PNG, GIF, JPG + * - QRCode::OUTPUT_STRING_XXXX where XXXX = TEXT, JSON + * - QRCode::OUTPUT_CUSTOM */ - protected $outputType = QRCode::OUTPUT_IMAGE_PNG; + protected string $outputType = QRCode::OUTPUT_IMAGE_PNG; /** * the FQCN of the custom QROutputInterface if $outputType is set to QRCode::OUTPUT_CUSTOM - * - * @var string|null */ - protected $outputInterface = null; + protected ?string $outputInterface = null; /** * /path/to/cache.file - * - * @var string|null */ - protected $cachefile = null; + protected ?string $cachefile = null; /** * newline string [HTML, SVG, TEXT] - * - * @var string */ - protected $eol = PHP_EOL; + protected string $eol = PHP_EOL; /** - * size of a QR code pixel [SVG, IMAGE_*] - * HTML -> via CSS - * - * @var int + * size of a QR code pixel [SVG, IMAGE_*], HTML via CSS */ - protected $scale = 5; + protected int $scale = 5; /** * a common css class - * - * @var string */ - protected $cssClass = ''; + protected string $cssClass = ''; /** * SVG opacity - * - * @var float */ - protected $svgOpacity = 1.0; + protected float $svgOpacity = 1.0; /** * anything between <defs> * * @see https://developer.mozilla.org/docs/Web/SVG/Element/defs - * - * @var string */ - protected $svgDefs = '<style>rect{shape-rendering:crispEdges}</style>'; + protected string $svgDefs = '<style>rect{shape-rendering:crispEdges}</style>'; /** * SVG viewBox size. a single integer number which defines width/height of the viewBox attribute. @@ -155,38 +134,28 @@ trait QROptionsTrait{ * viewBox="0 0 x x" * * @see https://css-tricks.com/scale-svg/#article-header-id-3 - * - * @var int|null */ - protected $svgViewBoxSize = null; + protected ?int $svgViewBoxSize = null; /** * string substitute for dark - * - * @var string */ - protected $textDark = '🔴'; + protected string $textDark = '🔴'; /** * string substitute for light - * - * @var string */ - protected $textLight = 'â•'; + protected string $textLight = 'â•'; /** * markup substitute for dark (CSS value) - * - * @var string */ - protected $markupDark = '#000'; + protected string $markupDark = '#000'; /** * markup substitute for light (CSS value) - * - * @var string */ - protected $markupLight = '#fff'; + protected string $markupLight = '#fff'; /** * Return the image resource instead of a render if applicable. @@ -194,7 +163,7 @@ trait QROptionsTrait{ * * Supported by the following modules: * - * - QRImage: resource + * - QRImage: resource (PHP < 8), GdImage * - QRImagick: Imagick * - QRFpdf: FPDF * @@ -202,85 +171,66 @@ trait QROptionsTrait{ * * @var bool */ - protected $returnResource = false; + protected bool $returnResource = false; /** * toggle base64 or raw image data - * - * @var bool */ - protected $imageBase64 = true; + protected bool $imageBase64 = true; /** * toggle transparency, not supported by jpg - * - * @var bool */ - protected $imageTransparent = true; + protected bool $imageTransparent = true; /** * @see imagecolortransparent() * - * @var array [R, G, B] + * [R, G, B] */ - protected $imageTransparencyBG = [255, 255, 255]; + protected array $imageTransparencyBG = [255, 255, 255]; /** * @see imagepng() - * - * @var int */ - protected $pngCompression = -1; + protected int $pngCompression = -1; /** * @see imagejpeg() - * - * @var int */ - protected $jpegQuality = 85; + protected int $jpegQuality = 85; /** * Imagick output format * - * @see Imagick::setType() - * - * @var string + * @see \Imagick::setType() */ - protected $imagickFormat = 'png'; + protected string $imagickFormat = 'png'; /** * Imagick background color (defaults to "transparent") * * @see \ImagickPixel::__construct() - * - * @var string|null */ - protected $imagickBG = null; + protected ?string $imagickBG = null; /** * Measurement unit for FPDF output: pt, mm, cm, in (defaults to "pt") * * @see \FPDF::__construct() */ - protected $fpdfMeasureUnit = 'pt'; + protected string $fpdfMeasureUnit = 'pt'; /** * Module values map * - * HTML, IMAGICK: #ABCDEF, cssname, rgb(), rgba()... - * IMAGE: [63, 127, 255] // R, G, B - * - * @var array|null + * - HTML, IMAGICK: #ABCDEF, cssname, rgb(), rgba()... + * - IMAGE: [63, 127, 255] // R, G, B */ - protected $moduleValues = null; + protected ?array $moduleValues = null; /** * clamp min/max version number - * - * @param int $versionMin - * @param int $versionMax - * - * @return void */ protected function setMinMaxVersion(int $versionMin, int $versionMax):void{ $min = max(1, min(40, $versionMin)); @@ -292,10 +242,6 @@ trait QROptionsTrait{ /** * sets the minimum version number - * - * @param int $version - * - * @return void */ protected function set_versionMin(int $version):void{ $this->setMinMaxVersion($version, $this->versionMax); @@ -303,10 +249,6 @@ trait QROptionsTrait{ /** * sets the maximum version number - * - * @param int $version - * - * @return void */ protected function set_versionMax(int $version):void{ $this->setMinMaxVersion($this->versionMin, $version); @@ -315,9 +257,6 @@ trait QROptionsTrait{ /** * sets the error correction level * - * @param int $eccLevel - * - * @return void * @throws \chillerlan\QRCode\QRCodeException */ protected function set_eccLevel(int $eccLevel):void{ @@ -331,10 +270,6 @@ trait QROptionsTrait{ /** * sets/clamps the mask pattern - * - * @param int $maskPattern - * - * @return void */ protected function set_maskPattern(int $maskPattern):void{ @@ -347,15 +282,12 @@ trait QROptionsTrait{ /** * sets the transparency background color * - * @param mixed $imageTransparencyBG - * - * @return void * @throws \chillerlan\QRCode\QRCodeException */ - protected function set_imageTransparencyBG($imageTransparencyBG):void{ + protected function set_imageTransparencyBG(array $imageTransparencyBG):void{ // invalid value - set to white as default - if(!is_array($imageTransparencyBG) || count($imageTransparencyBG) < 3){ + if(count($imageTransparencyBG) < 3){ $this->imageTransparencyBG = [255, 255, 255]; return; @@ -363,6 +295,11 @@ trait QROptionsTrait{ foreach($imageTransparencyBG as $k => $v){ + // cut off exceeding items + if($k > 2){ + break; + } + if(!is_numeric($v)){ throw new QRCodeException('Invalid RGB value.'); } @@ -377,10 +314,6 @@ trait QROptionsTrait{ /** * sets/clamps the version number - * - * @param int $version - * - * @return void */ protected function set_version(int $version):void{ |