diff --git a/src/Data/AlphaNum.php b/src/Data/AlphaNum.php index 6c06305f8..28d9d7563 100644 --- a/src/Data/AlphaNum.php +++ b/src/Data/AlphaNum.php @@ -18,6 +18,9 @@ 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 */ final class AlphaNum extends QRDataAbstract{ @@ -41,7 +44,9 @@ final class AlphaNum extends QRDataAbstract{ } /** - * @throws \chillerlan\QRCode\Data\QRCodeDataException + * get the code for the given character + * + * @throws \chillerlan\QRCode\Data\QRCodeDataException on an illegal character occurence */ protected function getCharCode(string $chr):int{ diff --git a/src/Data/Byte.php b/src/Data/Byte.php index b4fe4309c..02e76a639 100644 --- a/src/Data/Byte.php +++ b/src/Data/Byte.php @@ -18,6 +18,9 @@ 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 */ final class Byte extends QRDataAbstract{ diff --git a/src/Data/Kanji.php b/src/Data/Kanji.php index 12f7a6b7c..b08af0776 100644 --- a/src/Data/Kanji.php +++ b/src/Data/Kanji.php @@ -18,6 +18,9 @@ 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 */ final class Kanji extends QRDataAbstract{ @@ -34,6 +37,8 @@ final class Kanji extends QRDataAbstract{ /** * @inheritdoc + * + * @throws \chillerlan\QRCode\Data\QRCodeDataException on an illegal character occurence */ protected function write(string $data):void{ $len = strlen($data); diff --git a/src/Data/MaskPatternTester.php b/src/Data/MaskPatternTester.php index 963f62e21..ae8972b9a 100644 --- a/src/Data/MaskPatternTester.php +++ b/src/Data/MaskPatternTester.php @@ -17,12 +17,15 @@ use function abs, array_search, call_user_func_array, min; /** * Receives a QRDataInterface object and runs the mask pattern tests on it. * - * @link http://www.thonky.com/qr-code-tutorial/data-masking + * ISO/IEC 18004:2000 Section 8.8.2 - Evaluation of masking results + * + * @see http://www.thonky.com/qr-code-tutorial/data-masking */ final class MaskPatternTester{ - protected QRMatrix $matrix; - + /** + * The data interface that contains the data matrix to test + */ protected QRDataInterface $dataInterface; /** @@ -153,7 +156,7 @@ final class MaskPatternTester{ } /** - * Checks if there are patterns that look similar to the finder patterns + * Checks if there are patterns that look similar to the finder patterns (1:1:3:1:1 ratio) */ protected function testLevel3(QRMatrix $m, int $size):float{ $penalty = 0; diff --git a/src/Data/Number.php b/src/Data/Number.php index fa1107050..dedc54a39 100644 --- a/src/Data/Number.php +++ b/src/Data/Number.php @@ -4,7 +4,7 @@ * * @filesource Number.php * @created 26.11.2015 - * @package QRCode + * @package chillerlan\QRCode\Data * @author Smiley * @copyright 2015 Smiley * @license MIT @@ -17,7 +17,10 @@ use chillerlan\QRCode\QRCode; use function ord, sprintf, 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 */ final class Number extends QRDataAbstract{ @@ -50,12 +53,14 @@ final class Number extends QRDataAbstract{ } /** - * @throws \chillerlan\QRCode\Data\QRCodeDataException + * get the code for the given numeric string + * + * @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]); diff --git a/src/Data/QRDataAbstract.php b/src/Data/QRDataAbstract.php index 5c4e3f68f..6fda7dac2 100644 --- a/src/Data/QRDataAbstract.php +++ b/src/Data/QRDataAbstract.php @@ -35,6 +35,8 @@ abstract class QRDataAbstract implements QRDataInterface{ /** * mode length bits for the version breakpoints 1-9, 10-26 and 27-40 + * + * ISO/IEC 18004:2000 Table 3 - Number of bits in Character Count Indicator */ protected array $lengthBits = [0, 0, 0]; @@ -166,7 +168,7 @@ abstract class QRDataAbstract implements QRDataInterface{ /** * creates a BitBuffer and writes the string data to it * - * @throws \chillerlan\QRCode\QRCodeException + * @throws \chillerlan\QRCode\QRCodeException on data overflow */ protected function writeBitBuffer(string $data):void{ $this->bitBuffer = new BitBuffer; @@ -186,7 +188,7 @@ abstract class QRDataAbstract implements QRDataInterface{ throw new QRCodeDataException(sprintf('code length overflow. (%d > %d bit)', $this->bitBuffer->getLength(), $MAX_BITS)); } - // end code. + // add terminator (ISO/IEC 18004:2000 Table 2) if($this->bitBuffer->getLength() + 4 <= $MAX_BITS){ $this->bitBuffer->put(0, 4); } @@ -217,7 +219,9 @@ abstract class QRDataAbstract implements QRDataInterface{ /** * ECC masking * - * @link http://www.thonky.com/qr-code-tutorial/error-correction-coding + * ISO/IEC 18004:2000 Section 8.5 ff + * + * @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]]; @@ -282,7 +286,7 @@ abstract class QRDataAbstract implements QRDataInterface{ } /** - * + * helper method for the polynomial operations */ protected function poly(int $key, int $count):array{ $rsPoly = new Polynomial; diff --git a/src/Data/QRDataInterface.php b/src/Data/QRDataInterface.php index 8f99fbcdb..cc86f7cd6 100644 --- a/src/Data/QRDataInterface.php +++ b/src/Data/QRDataInterface.php @@ -13,16 +13,22 @@ 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{ + /** + * @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, ]; /** * 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, @@ -34,7 +40,11 @@ interface QRDataInterface{ ]; /** - * @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 @@ -80,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], @@ -125,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]], diff --git a/src/Data/QRMatrix.php b/src/Data/QRMatrix.php index 8fd056c8d..8a52e98de 100755 --- a/src/Data/QRMatrix.php +++ b/src/Data/QRMatrix.php @@ -18,28 +18,44 @@ 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 */ 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; -# public const M_LOGO = 0x14; // @todo +# public const M_LOGO = 0x14; // @todo + /** @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 => [], @@ -85,9 +101,11 @@ final 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, @@ -126,7 +144,13 @@ final 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, @@ -170,14 +194,31 @@ final class QRMatrix{ ], ]; + /** + * the current QR Code version number + */ protected int $version; + /** + * the current ECC level + */ protected int $eclevel; + /** + * the used mask pattern, set via QRMatrix::mapData() + */ protected int $maskPattern = QRCode::MASK_PATTERN_AUTO; + /** + * the size (side length) of the matrix + */ protected int $moduleCount; - /** @var mixed[] */ + + /** + * the actual matrix data array + * + * @var int[][] + */ protected array $matrix; /** @@ -217,6 +258,8 @@ final class QRMatrix{ } /** + * Returns the data matrix + * * @return int[][] */ public function matrix():array{ @@ -224,21 +267,21 @@ final class QRMatrix{ } /** - * + * Returns the current version number */ public function version():int{ return $this->version; } /** - * + * Returns the current ECC level */ public function eccLevel():int{ return $this->eclevel; } /** - * + * Returns the current mask pattern */ public function maskPattern():int{ return $this->maskPattern; @@ -297,6 +340,8 @@ final class QRMatrix{ /** * Draws the 7x7 finder patterns in the corners top left/right and bottom left + * + * ISO/IEC 18004:2000 Section 7.3.2 */ public function setFinderPattern():QRMatrix{ @@ -324,6 +369,8 @@ final class QRMatrix{ /** * Draws the separator lines around the finder patterns + * + * ISO/IEC 18004:2000 Section 7.3.3 */ public function setSeparators():QRMatrix{ @@ -352,6 +399,8 @@ final class QRMatrix{ /** * Draws the 5x5 alignment patterns + * + * ISO/IEC 18004:2000 Section 7.3.5 */ public function setAlignmentPattern():QRMatrix{ @@ -380,6 +429,8 @@ final class QRMatrix{ /** * Draws the timing pattern (h/v checkered line between the finder patterns) + * + * ISO/IEC 18004:2000 Section 7.3.4 */ public function setTimingPattern():QRMatrix{ @@ -400,6 +451,8 @@ final class QRMatrix{ /** * Draws the version information, 2x 3x6 pixel + * + * ISO/IEC 18004:2000 Section 8.10 */ public function setVersionNumber(bool $test = null):QRMatrix{ $bits = $this::versionPattern[$this->version] ?? false; @@ -422,6 +475,8 @@ final class QRMatrix{ /** * Draws the format info along the finder patterns + * + * 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; @@ -459,6 +514,8 @@ final class QRMatrix{ /** * Draws the "quiet zone" of $size around the matrix * + * ISO/IEC 18004:2000 Section 7.3.7 + * * @throws \chillerlan\QRCode\Data\QRCodeDataException */ public function setQuietZone(int $size = null):QRMatrix{ @@ -498,6 +555,8 @@ final class QRMatrix{ * * @param int[] $data * @param int $maskPattern + * + * @return \chillerlan\QRCode\Data\QRMatrix */ public function mapData(array $data, int $maskPattern):QRMatrix{ $this->maskPattern = $maskPattern; diff --git a/src/Helpers/BitBuffer.php b/src/Helpers/BitBuffer.php index c35abd31c..de47f20f4 100644 --- a/src/Helpers/BitBuffer.php +++ b/src/Helpers/BitBuffer.php @@ -14,15 +14,25 @@ namespace chillerlan\QRCode\Helpers; use function count, floor; +/** + * Holds the raw binary data + */ final class BitBuffer{ - /** @var int[] */ + /** + * The buffer content + * + * @var int[] + */ protected array $buffer = []; + /** + * Length of the content (bits) + */ protected int $length = 0; /** - * + * clears the buffer */ public function clear():BitBuffer{ $this->buffer = []; @@ -32,7 +42,7 @@ final class BitBuffer{ } /** - * + * appends a sequence of bits */ public function put(int $num, int $length):BitBuffer{ @@ -44,7 +54,7 @@ final class BitBuffer{ } /** - * + * appends a single bit */ public function putBit(bool $bit):BitBuffer{ $bufIndex = floor($this->length / 8); diff --git a/src/Helpers/Polynomial.php b/src/Helpers/Polynomial.php index 12c3f0078..c42e0831c 100644 --- a/src/Helpers/Polynomial.php +++ b/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 */ 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], @@ -79,7 +81,10 @@ final class Polynomial{ } /** + * @param int[] $num + * @param int|null $shift * + * @return \chillerlan\QRCode\Helpers\Polynomial */ public function setNum(array $num, int $shift = null):Polynomial{ $offset = 0; @@ -99,7 +104,9 @@ final class Polynomial{ } /** + * @param int[] $e * + * @return \chillerlan\QRCode\Helpers\Polynomial */ public function multiply(array $e):Polynomial{ $n = array_fill(0, count($this->num) + count($e) - 1, 0); @@ -119,7 +126,9 @@ final class Polynomial{ } /** + * @param int[] $e * + * @return \chillerlan\QRCode\Helpers\Polynomial */ public function mod(array $e):Polynomial{ $n = $this->num; diff --git a/src/Output/QRImage.php b/src/Output/QRImage.php index f64f64160..f30a87552 100644 --- a/src/Output/QRImage.php +++ b/src/Output/QRImage.php @@ -20,12 +20,17 @@ use function array_values, base64_encode, call_user_func, count, imagecoloralloc 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, @@ -34,6 +39,8 @@ class QRImage extends QROutputAbstract{ protected string $defaultMode = QRCode::OUTPUT_IMAGE_PNG; /** + * The GD image resource + * * @see imagecreatetruecolor() * @var resource */ @@ -70,8 +77,8 @@ class QRImage extends QROutputAbstract{ // 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; + $background = imagecolorallocate($this->image, ...$tbg); if((bool)$this->options->imageTransparent && in_array($this->options->outputType, $this::TRANSPARENCY_TYPES, true)){ imagecolortransparent($this->image, $background); @@ -99,7 +106,7 @@ class QRImage extends QROutputAbstract{ } /** - * + * Creates a single QR pixel with the given settings */ protected function setPixel(int $x, int $y, array $rgb):void{ imagefilledrectangle( @@ -113,7 +120,7 @@ class QRImage extends QROutputAbstract{ } /** - * @param string|null $file + * Creates the final image by calling the desired GD output function * * @throws \chillerlan\QRCode\Output\QRCodeOutputException */ @@ -139,6 +146,8 @@ class QRImage extends QROutputAbstract{ } /** + * PNG output + * * @return void */ protected function png():void{ @@ -153,6 +162,7 @@ class QRImage extends QROutputAbstract{ /** * Jiff - like... JitHub! + * * @return void */ protected function gif():void{ @@ -160,6 +170,8 @@ class QRImage extends QROutputAbstract{ } /** + * JPG output + * * @return void */ protected function jpg():void{ diff --git a/src/Output/QRImagick.php b/src/Output/QRImagick.php index 0a31b3169..9afd5df40 100644 --- a/src/Output/QRImagick.php +++ b/src/Output/QRImagick.php @@ -8,6 +8,8 @@ * @author smiley * @copyright 2018 smiley * @license MIT + * + * @noinspection PhpComposerExtensionStubsInspection */ namespace chillerlan\QRCode\Output; @@ -17,10 +19,10 @@ use Imagick, ImagickDraw, ImagickPixel; use function 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{ @@ -67,7 +69,7 @@ class QRImagick extends QROutputAbstract{ } /** - * + * Creates the QR image via ImagickDraw */ protected function drawImage(Imagick $imagick):string{ $draw = new ImagickDraw; diff --git a/src/Output/QRMarkup.php b/src/Output/QRMarkup.php index f7abeb6c5..8eb83e0ed 100644 --- a/src/Output/QRMarkup.php +++ b/src/Output/QRMarkup.php @@ -26,7 +26,8 @@ class QRMarkup extends QROutputAbstract{ /** * @see \sprintf() */ - protected string $svgHeader = ''; + protected string $svgHeader = ''; /** * @inheritDoc @@ -50,7 +51,7 @@ class QRMarkup extends QROutputAbstract{ } /** - * + * HTML output */ protected function html():string{ $html = '
'.$this->options->eol; @@ -68,14 +69,18 @@ class QRMarkup extends QROutputAbstract{ $html .= '
'.$this->options->eol; if($this->options->cachefile){ - return ''.$this->options->eol.$html.''; + return ''. + 'QR Code'. + ''.$this->options->eol.$html.''; } return $html; } /** - * @link https://github.com/codemasher/php-qrcode/pull/5 + * SVG output + * + * @see https://github.com/codemasher/php-qrcode/pull/5 */ protected function svg():string{ $matrix = $this->matrix->matrix(); @@ -123,7 +128,10 @@ class QRMarkup extends QROutputAbstract{ } if(!empty($path)){ - $svg .= sprintf('', $M_TYPE, $this->options->cssClass, $value, $this->options->svgOpacity, $path); + $svg .= sprintf( + '', + $M_TYPE, $this->options->cssClass, $value, $this->options->svgOpacity, $path + ); } } @@ -133,7 +141,8 @@ class QRMarkup extends QROutputAbstract{ // if saving to file, append the correct headers if($this->options->cachefile){ - return ''.$this->options->eol.$svg; + return ''. + $this->options->eol.$svg; } return $svg; diff --git a/src/Output/QRString.php b/src/Output/QRString.php index 036978984..3f668f80e 100644 --- a/src/Output/QRString.php +++ b/src/Output/QRString.php @@ -45,7 +45,7 @@ class QRString extends QROutputAbstract{ } /** - * + * string output */ protected function text():string{ $str = []; @@ -64,7 +64,7 @@ class QRString extends QROutputAbstract{ } /** - * + * JSON output */ protected function json():string{ return json_encode($this->matrix->matrix()); diff --git a/src/QRCode.php b/src/QRCode.php index c46a40371..12b0a76d3 100755 --- a/src/QRCode.php +++ b/src/QRCode.php @@ -25,45 +25,37 @@ use function call_user_func_array, class_exists, in_array, mb_internal_encoding, /** * 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_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; - public const ECC_MODES = [ - self::ECC_L => 0, - self::ECC_M => 1, - self::ECC_Q => 2, - self::ECC_H => 3, - ]; - + /** + * 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, @@ -71,6 +63,57 @@ class QRCode{ 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, + self::ECC_Q => 2, + self::ECC_H => 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_CUSTOM = 'custom'; + + /** + * Map of built-in output modules => capabilities + * + * @var string[][] + */ public const OUTPUT_MODES = [ QRMarkup::class => [ self::OUTPUT_MARKUP_SVG, @@ -103,22 +146,31 @@ class QRCode{ ]; /** + * The settings container + * * @var \chillerlan\QRCode\QROptions|\chillerlan\Settings\SettingsContainerInterface */ protected SettingsContainerInterface $options; + /** + * The selected data interface (Number, AlphaNum, Kanji, Byte) + */ protected QRDataInterface $dataInterface; /** - * @see http://php.net/manual/function.mb-internal-encoding.php + * The current encoding (before the QRCode instance was invoked) + * + * @see http://php.net/manual/function.mb-internal-encoding.php mb_internal_encoding() */ protected string $mbCurrentEncoding; /** * QRCode constructor. + * + * Sets the options instance, determines the current mb-encoding and sets it to UTF-8 */ public function __construct(SettingsContainerInterface $options = null){ - // save the current mb encoding (in case it differs from UTF-8) + // save the current mb-encoding (in case it differs from UTF-8) $this->mbCurrentEncoding = mb_internal_encoding(); // use UTF-8 from here on mb_internal_encoding('UTF-8'); @@ -127,10 +179,11 @@ class QRCode{ } /** + * Restores the previous mb-encoding setting, so that we don't mess up the rest of the script + * * @return void */ public function __destruct(){ - // restore the previous mb_internal_encoding, so that we don't mess up the rest of the script mb_internal_encoding($this->mbCurrentEncoding); } diff --git a/src/QRCodeException.php b/src/QRCodeException.php index 68af380ff..55bb1be4b 100644 --- a/src/QRCodeException.php +++ b/src/QRCodeException.php @@ -12,4 +12,7 @@ namespace chillerlan\QRCode; +/** + * An exception container + */ class QRCodeException extends \Exception{} diff --git a/src/QROptions.php b/src/QROptions.php index 8e20626c5..79242245d 100644 --- a/src/QROptions.php +++ b/src/QROptions.php @@ -15,43 +15,37 @@ 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 int $quietzoneSize + * The QRCode settings container * - * @property string $dataMode - * @property string $outputType - * @property string $outputInterface - * @property string $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 $imageBase64 - * @property bool $imageTransparent - * @property array $imageTransparencyBG - * @property int $pngCompression - * @property int $jpegQuality - * - * @property string $imagickFormat - * @property string $imagickBG - * - * @property array $moduleValues + * @property int $version + * @property int $versionMin + * @property int $versionMax + * @property int $eccLevel + * @property int $maskPattern + * @property bool $addQuietzone + * @property int $quietzoneSize + * @property string|null $dataMode + * @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 $imageBase64 + * @property bool $imageTransparent + * @property array $imageTransparencyBG + * @property int $pngCompression + * @property int $jpegQuality + * @property string $imagickFormat + * @property string|null $imagickBG + * @property array|null $moduleValues */ class QROptions extends SettingsContainerAbstract{ use QROptionsTrait; diff --git a/src/QROptionsTrait.php b/src/QROptionsTrait.php index cadc32877..fc29bb3f7 100644 --- a/src/QROptionsTrait.php +++ b/src/QROptionsTrait.php @@ -14,17 +14,22 @@ namespace chillerlan\QRCode; use function array_values, count, is_numeric, max, min, sprintf; +/** + * The QRCode plug-in settings & setter functionality + */ trait QROptionsTrait{ /** * QR Code version number * - * [1 ... 40] or QRCode::VERSION_AUTO + * [1 ... 40] or QRCode::VERSION_AUTO */ protected int $version = QRCode::VERSION_AUTO; /** - * Minimum QR version (if $version = QRCode::VERSION_AUTO) + * Minimum QR version + * + * if $version = QRCode::VERSION_AUTO */ protected int $versionMin = 1; @@ -36,18 +41,19 @@ trait QROptionsTrait{ /** * Error correct level * - * QRCode::ECC_X where X is - * L => 7% - * M => 15% - * Q => 25% - * H => 30% + * QRCode::ECC_X where X is: + * + * - L => 7% + * - M => 15% + * - Q => 25% + * - H => 30% */ protected int $eccLevel = QRCode::ECC_L; /** * Mask Pattern to use * - * [0...7] or QRCode::MASK_PATTERN_AUTO + * [0...7] or QRCode::MASK_PATTERN_AUTO */ protected int $maskPattern = QRCode::MASK_PATTERN_AUTO; @@ -59,12 +65,13 @@ trait QROptionsTrait{ /** * Size of the quiet zone * - * internally clamped to [0 ... $moduleCount / 2], defaults to 4 modules + * internally clamped to [0 ... $moduleCount / 2], defaults to 4 modules */ 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 @@ -72,10 +79,12 @@ trait QROptionsTrait{ protected ?string $dataMode = null; /** - * 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 + * + * - 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 string $outputType = QRCode::OUTPUT_IMAGE_PNG; @@ -95,8 +104,7 @@ trait QROptionsTrait{ protected string $eol = PHP_EOL; /** - * size of a QR code pixel [SVG, IMAGE_*] - * HTML -> via CSS + * size of a QR code pixel [SVG, IMAGE_*], HTML via CSS */ protected int $scale = 5; @@ -190,8 +198,8 @@ trait QROptionsTrait{ /** * Module values map * - * HTML, IMAGICK: #ABCDEF, cssname, rgb(), rgba()... - * IMAGE: [63, 127, 255] // R, G, B + * - HTML, IMAGICK: #ABCDEF, cssname, rgb(), rgba()... + * - IMAGE: [63, 127, 255] // R, G, B */ protected ?array $moduleValues = null;