diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 000000000..1e846f0de --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,68 @@ +# https://help.github.com/en/categories/automating-your-workflow-with-github-actions +# https://github.com/localheinz/php-library-template/blob/master/.github/workflows/continuous-integration.yml +# https://github.com/sebastianbergmann/phpunit/blob/master/.github/workflows/ci.yml + +on: + pull_request: + push: + branches: + - master + tags: + - "**" + +name: "Continuous Integration" + +jobs: + + tests: + name: "Unit Tests" + runs-on: ubuntu-latest + + strategy: + matrix: + php-binary: + - php7.2 + - php7.3 + - php7.4 + + dependencies: + - lowest + - highest + + steps: + - name: "Checkout" + uses: actions/checkout@v1.1.0 + + - name: "Install lowest dependencies with composer" + if: matrix.dependencies == 'lowest' + run: ${{ matrix.php-binary }} $(which composer) update --no-interaction --no-progress --no-suggest --prefer-lowest + + - name: "Install highest dependencies with composer" + if: matrix.dependencies == 'highest' + run: ${{ matrix.php-binary }} $(which composer) update --no-interaction --no-progress --no-suggest + + - name: "Run unit tests with phpunit" + run: ${{ matrix.php-binary }} vendor/bin/phpunit --configuration=phpunit.xml --no-coverage + + + code-coverage: + name: "Code Coverage" + runs-on: ubuntu-latest + + steps: + - name: "Checkout" + uses: actions/checkout@v1.1.0 + + - name: "Install locked dependencies with composer" + run: php7.4 $(which composer) install --no-interaction --no-progress --no-suggest + + - name: "Dump Xdebug filter with phpunit/phpunit" + run: php7.4 vendor/bin/phpunit --configuration=phpunit.xml --dump-xdebug-filter=.build/phpunit/xdebug-filter.php + + - name: "Collect code coverage with Xdebug and phpunit/phpunit" + run: php7.4 vendor/bin/phpunit --configuration=phpunit.xml --prepend=.build/phpunit/xdebug-filter.php + + - name: "Send code coverage report to Codecov.io" + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + run: bash <(curl -s https://codecov.io/bash) diff --git a/README.md b/README.md index c3d1abee6..20967477f 100644 --- a/README.md +++ b/README.md @@ -30,12 +30,6 @@ namespaced, cleaned up, improved and other stuff. [gh-action-badge]: https://github.com/chillerlan/php-qrcode/workflows/Continuous%20Integration/badge.svg [gh-action]: https://github.com/chillerlan/php-qrcode/actions -Hi, please check out my other projects that are way cooler than qrcodes! - -- [php-oauth-core](https://github.com/chillerlan/php-oauth-core) - an OAuth 1/2 client library along with a bunch of [providers](https://github.com/chillerlan/php-oauth-providers) -- [php-httpinterface](https://github.com/chillerlan/php-httpinterface) - a PSR-7/15/17/18 implemetation -- [php-database](https://github.com/chillerlan/php-database) - a database client & querybuilder for MySQL, Postgres, SQLite, MSSQL, Firebird - ## Documentation ### Requirements @@ -46,7 +40,9 @@ Hi, please check out my other projects that are way cooler than qrcodes! ### Installation **requires [composer](https://getcomposer.org)** -*composer.json* (note: replace `dev-master` with a [version boundary](https://getcomposer.org/doc/articles/versions.md)) +via terminal: `composer require chillerlan/php-qrcode` + +*composer.json* (note: replace `dev-master` with a [version boundary](https://getcomposer.org/doc/articles/versions.md), e.g. `^3.2`) ```json { "require": { @@ -56,23 +52,6 @@ Hi, please check out my other projects that are way cooler than qrcodes! } ``` -#### Manual installation -Download the desired version of the package from [master](https://github.com/chillerlan/php-qrcode/archive/master.zip) or -[release](https://github.com/chillerlan/php-qrcode/releases) and extract the contents to your project folder. After that: -- run `composer install` to install the required dependencies and generate `/vendor/autoload.php`. -- if you use a custom autoloader, point the namespace `chillerlan\QRCode` to the folder `src` of the package - -Profit! - -#### Framework Integration -- Drupal [Google Authenticator Login `ga_login`](https://www.drupal.org/project/ga_login) -- WordPress [`wp-two-factor-auth`](https://github.com/sjinks/wp-two-factor-auth) -- WordPress [Simple 2FA `simple-2fa`](https://wordpress.org/plugins/simple-2fa/) -- WoltLab Suite [two-step-verification](http://pluginstore.woltlab.com/file/3007-two-step-verification/) -- [Cachet](https://github.com/CachetHQ/Cachet) -- [slack-qrcode](https://github.com/sameyasu/slack-qrcode) -- [gaara 嘎啦](https://github.com/xutengx/gaara) - ### Usage We want to encode this URI for a mobile authenticator into a QRcode image: ```php @@ -390,3 +369,18 @@ I don't take responsibility for molten CPUs, misled applications, failed log-ins The word "QR Code" is registered trademark of *DENSO WAVE INCORPORATED*
http://www.denso-wave.com/qrcode/faqpatent-e.html +### Framework Integration +- Drupal [Google Authenticator Login `ga_login`](https://www.drupal.org/project/ga_login) +- WordPress [`wp-two-factor-auth`](https://github.com/sjinks/wp-two-factor-auth) +- WordPress [Simple 2FA `simple-2fa`](https://wordpress.org/plugins/simple-2fa/) +- WoltLab Suite [two-step-verification](http://pluginstore.woltlab.com/file/3007-two-step-verification/) +- [Cachet](https://github.com/CachetHQ/Cachet) +- other uses: [dependents](https://github.com/chillerlan/php-qrcode/network/dependents) / [packages](https://github.com/chillerlan/php-qrcode/network/dependents?dependent_type=PACKAGE) + + +Hi, please check out my other projects that are way cooler than qrcodes! + +- [php-oauth-core](https://github.com/chillerlan/php-oauth-core) - an OAuth 1/2 client library along with a bunch of [providers](https://github.com/chillerlan/php-oauth-providers) +- [php-httpinterface](https://github.com/chillerlan/php-httpinterface) - a PSR-7/15/17/18 implemetation +- [php-database](https://github.com/chillerlan/php-database) - a database client & querybuilder for MySQL, Postgres, SQLite, MSSQL, Firebird + diff --git a/composer.json b/composer.json index 17bed0700..95eaec2db 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "chillerlan/php-settings-container": "^1.2" }, "require-dev": { - "phpunit/phpunit": "^8.4" + "phpunit/phpunit": "^8.5" }, "suggest": { "chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps." diff --git a/src/Data/Kanji.php b/src/Data/Kanji.php index 5636047cb..9a1b3787a 100644 --- a/src/Data/Kanji.php +++ b/src/Data/Kanji.php @@ -33,7 +33,7 @@ class Kanji extends QRDataAbstract{ } /** - * @throws \chillerlan\QRCode\Data\QRCodeDataException + * @inheritdoc */ protected function write(string $data):void{ $len = strlen($data); diff --git a/src/Data/Number.php b/src/Data/Number.php index 2e922dd7d..d0b33619a 100644 --- a/src/Data/Number.php +++ b/src/Data/Number.php @@ -41,11 +41,9 @@ class Number extends QRDataAbstract{ if($this->strlen - $i === 1){ $this->bitBuffer->put($this->parseInt(substr($data, $i, $i + 1)), 4); } - // @codeCoverageIgnoreStart elseif($this->strlen - $i === 2){ $this->bitBuffer->put($this->parseInt(substr($data, $i, $i + 2)), 7); } - // @codeCoverageIgnoreEnd } diff --git a/src/Data/QRDataAbstract.php b/src/Data/QRDataAbstract.php index 1dceb62ab..51b374204 100644 --- a/src/Data/QRDataAbstract.php +++ b/src/Data/QRDataAbstract.php @@ -75,7 +75,7 @@ abstract class QRDataAbstract implements QRDataInterface{ } /** - * Sets the data string (internally called by the constructor) + * @inheritDoc */ public function setData(string $data):QRDataInterface{ @@ -97,12 +97,10 @@ abstract class QRDataAbstract implements QRDataInterface{ } /** - * returns a fresh matrix object with the data written for the given $maskPattern + * @inheritDoc */ public function initMatrix(int $maskPattern, bool $test = null):QRMatrix{ - $matrix = new QRMatrix($this->version, $this->options->eccLevel); - - return $matrix + return (new QRMatrix($this->version, $this->options->eccLevel)) ->setFinderPattern() ->setSeparators() ->setAlignmentPattern() @@ -159,12 +157,14 @@ abstract class QRDataAbstract implements QRDataInterface{ } /** + * writes the actual data string to the BitBuffer + * * @see \chillerlan\QRCode\Data\QRDataAbstract::writeBitBuffer() */ abstract protected function write(string $data):void; /** - * writes the string data to the BitBuffer + * creates a BitBuffer and writes the string data to it * * @throws \chillerlan\QRCode\QRCodeException */ @@ -218,8 +218,6 @@ abstract class QRDataAbstract implements QRDataInterface{ /** * ECC masking * - * @see \chillerlan\QRCode\Data\QRDataAbstract::writeBitBuffer() - * * @link http://www.thonky.com/qr-code-tutorial/error-correction-coding */ protected function maskECC():array{ diff --git a/src/Data/QRDataInterface.php b/src/Data/QRDataInterface.php index 5e1759edd..936374a4f 100644 --- a/src/Data/QRDataInterface.php +++ b/src/Data/QRDataInterface.php @@ -166,12 +166,12 @@ interface QRDataInterface{ ]; /** - * + * Sets the data string (internally called by the constructor) */ public function setData(string $data):QRDataInterface; /** - * + * returns a fresh matrix object with the data written for the given $maskPattern */ public function initMatrix(int $maskPattern, bool $test = null):QRMatrix; diff --git a/src/Helpers/BitBuffer.php b/src/Helpers/BitBuffer.php index dcea3a124..84652929b 100644 --- a/src/Helpers/BitBuffer.php +++ b/src/Helpers/BitBuffer.php @@ -37,7 +37,7 @@ class BitBuffer{ public function put(int $num, int $length):BitBuffer{ for($i = 0; $i < $length; $i++){ - $this->putBit(($num >> ($length - $i - 1))&1 === 1); + $this->putBit((($num >> ($length - $i - 1)) & 1) === 1); } return $this; diff --git a/src/Output/QRImage.php b/src/Output/QRImage.php index f7a181967..f0c7a3f75 100644 --- a/src/Output/QRImage.php +++ b/src/Output/QRImage.php @@ -40,7 +40,7 @@ class QRImage extends QROutputAbstract{ protected $image; /** - * + * @inheritDoc */ protected function setModuleValues():void{ @@ -61,7 +61,7 @@ class QRImage extends QROutputAbstract{ } /** - * + * @inheritDoc */ public function dump(string $file = null):string{ $this->image = imagecreatetruecolor($this->length, $this->length); diff --git a/src/Output/QRImagick.php b/src/Output/QRImagick.php index bd41a678c..0a31b3169 100644 --- a/src/Output/QRImagick.php +++ b/src/Output/QRImagick.php @@ -25,7 +25,7 @@ use function is_string; class QRImagick extends QROutputAbstract{ /** - * + * @inheritDoc */ protected function setModuleValues():void{ @@ -44,7 +44,7 @@ class QRImagick extends QROutputAbstract{ } /** - * + * @inheritDoc */ public function dump(string $file = null):string{ $file ??= $this->options->cachefile; diff --git a/src/Output/QRMarkup.php b/src/Output/QRMarkup.php index e5ef9e04c..ed10aa66b 100644 --- a/src/Output/QRMarkup.php +++ b/src/Output/QRMarkup.php @@ -29,7 +29,7 @@ class QRMarkup extends QROutputAbstract{ protected string $svgHeader = ''; /** - * + * @inheritDoc */ protected function setModuleValues():void{ diff --git a/src/Output/QROutputAbstract.php b/src/Output/QROutputAbstract.php index ecda397d0..77e51dd4d 100644 --- a/src/Output/QROutputAbstract.php +++ b/src/Output/QROutputAbstract.php @@ -63,7 +63,10 @@ abstract class QROutputAbstract implements QROutputInterface{ abstract protected function setModuleValues():void; /** + * saves the qr data to a file + * * @see file_put_contents() + * @see \chillerlan\QRCode\QROptions::cachefile * * @throws \chillerlan\QRCode\Output\QRCodeOutputException */ @@ -77,9 +80,10 @@ 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 ??= $this->options->cachefile; diff --git a/src/Output/QROutputInterface.php b/src/Output/QROutputInterface.php index b485bb660..7bbb64300 100644 --- a/src/Output/QROutputInterface.php +++ b/src/Output/QROutputInterface.php @@ -42,6 +42,8 @@ interface QROutputInterface{ ]; /** + * generates the output, optionally dumps it to a file, and returns it + * * @return mixed */ public function dump(string $file = null); diff --git a/src/Output/QRString.php b/src/Output/QRString.php index bd0ad285d..036978984 100644 --- a/src/Output/QRString.php +++ b/src/Output/QRString.php @@ -24,7 +24,7 @@ class QRString extends QROutputAbstract{ protected string $defaultMode = QRCode::OUTPUT_STRING_TEXT; /** - * + * @inheritDoc */ protected function setModuleValues():void{ diff --git a/src/QRCode.php b/src/QRCode.php index e98bf4e20..ae0efef59 100755 --- a/src/QRCode.php +++ b/src/QRCode.php @@ -90,7 +90,10 @@ class QRCode{ ], ]; - protected QROptions $options; + /** + * @var \chillerlan\QRCode\QROptions|\chillerlan\Settings\SettingsContainerInterface + */ + protected SettingsContainerInterface $options; protected QRDataInterface $dataInterface; @@ -237,7 +240,7 @@ class QRCode{ } /** - * checks is a given $string matches the characters of a given charmap, returns false on the first invalid occurence. + * checks is a given $string matches the characters of a given $charmap, returns false on the first invalid occurence. */ protected function checkString(string $string, array $charmap):bool{ $len = strlen($string); diff --git a/src/QROptionsTrait.php b/src/QROptionsTrait.php index 10b690989..16090a0ec 100644 --- a/src/QROptionsTrait.php +++ b/src/QROptionsTrait.php @@ -19,7 +19,7 @@ trait QROptionsTrait{ /** * QR Code version number * - * [1 ... 40] or QRCode::VERSION_AUTO + * [1 ... 40] or QRCode::VERSION_AUTO */ protected int $version = QRCode::VERSION_AUTO; @@ -47,7 +47,7 @@ trait QROptionsTrait{ /** * 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; @@ -57,7 +57,7 @@ trait QROptionsTrait{ protected bool $addQuietzone = true; /** - * Size of the quiet zone + * Size of the quiet zone * * internally clamped to [0 ... $moduleCount / 2], defaults to 4 modules */ @@ -207,20 +207,22 @@ trait QROptionsTrait{ } /** - * + * sets the minimum version number */ protected function set_versionMin(int $version):void{ $this->setMinMaxVersion($version, $this->versionMax); } /** - * + * sets the maximum version number */ protected function set_versionMax(int $version):void{ $this->setMinMaxVersion($this->versionMin, $version); } /** + * sets the error correction level + * * @throws \chillerlan\QRCode\QRCodeException */ protected function set_eccLevel(int $eccLevel):void{ @@ -233,7 +235,7 @@ trait QROptionsTrait{ } /** - * + * sets/clamps the mask pattern */ protected function set_maskPattern(int $maskPattern):void{ @@ -244,6 +246,8 @@ trait QROptionsTrait{ } /** + * sets the transparency background color + * * @throws \chillerlan\QRCode\QRCodeException */ protected function set_imageTransparencyBG($imageTransparencyBG):void{ @@ -270,7 +274,7 @@ trait QROptionsTrait{ } /** - * + * sets/clamps the version number */ protected function set_version(int $version):void{