v1.0 Initial commit of project
This commit is contained in:
1
vendor/endroid/qr-code/.github/FUNDING.yml
vendored
Normal file
1
vendor/endroid/qr-code/.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
github: endroid
|
||||
68
vendor/endroid/qr-code/.github/workflows/CI.yml
vendored
Normal file
68
vendor/endroid/qr-code/.github/workflows/CI.yml
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
name: CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['7.3', '7.4', '8.0', '8.1']
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
extensions: gd, mbstring, pcov, zip
|
||||
ini-values: max_execution_time=600, memory_limit=-1
|
||||
tools: composer:v2
|
||||
coverage: pcov
|
||||
env:
|
||||
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composercache
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
|
||||
- name: Cache composer dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.composercache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
restore-keys: ${{ runner.os }}-composer-
|
||||
|
||||
- name: Setup problem matchers
|
||||
run: |
|
||||
echo "::add-matcher::${{ runner.tool_cache }}/php.json"
|
||||
echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
|
||||
|
||||
- name: Install Composer dependencies
|
||||
run: composer install --prefer-dist
|
||||
|
||||
- name: Check code quality
|
||||
run: vendor/bin/code-quality
|
||||
|
||||
- name: Test against highest versions
|
||||
run: |
|
||||
vendor/bin/unit-test
|
||||
vendor/bin/functional-test
|
||||
|
||||
- name: Test against lowest versions
|
||||
run: |
|
||||
composer update --prefer-lowest
|
||||
vendor/bin/unit-test
|
||||
vendor/bin/functional-test ^3.4
|
||||
|
||||
- name: Archive logs
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: logs
|
||||
path: vendor/endroid/quality/application/var/log
|
||||
|
||||
- name: Archive code coverage results
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: coverage
|
||||
path: tests/coverage
|
||||
4
vendor/endroid/qr-code/.gitignore
vendored
Normal file
4
vendor/endroid/qr-code/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/composer
|
||||
/composer.lock
|
||||
/tests/coverage/
|
||||
/vendor/
|
||||
19
vendor/endroid/qr-code/LICENSE
vendored
Normal file
19
vendor/endroid/qr-code/LICENSE
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright 2020 (c) Jeroen van den Enden
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
130
vendor/endroid/qr-code/README.md
vendored
Normal file
130
vendor/endroid/qr-code/README.md
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
# QR Code
|
||||
|
||||
*By [endroid](https://endroid.nl/)*
|
||||
|
||||
[](https://packagist.org/packages/endroid/qr-code)
|
||||
[](https://github.com/endroid/qr-code/actions)
|
||||
[](https://packagist.org/packages/endroid/qr-code)
|
||||
[](https://packagist.org/packages/endroid/qr-code)
|
||||
[](https://packagist.org/packages/endroid/qr-code)
|
||||
|
||||
This library helps you generate QR codes in a jiffy. Makes use of [bacon/bacon-qr-code](https://github.com/Bacon/BaconQrCode)
|
||||
to generate the matrix and [khanamiryan/qrcode-detector-decoder](https://github.com/khanamiryan/php-qrcode-detector-decoder)
|
||||
for validating generated QR codes. Further extended with Twig extensions, generation routes, a factory and a
|
||||
Symfony bundle for easy installation and configuration.
|
||||
|
||||
Different writers are provided to generate the QR code as PNG, SVG, EPS, PDF or in binary format.
|
||||
|
||||
## Installation
|
||||
|
||||
Use [Composer](https://getcomposer.org/) to install the library.
|
||||
|
||||
``` bash
|
||||
$ composer require endroid/qr-code
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```php
|
||||
use Endroid\QrCode\QrCode;
|
||||
|
||||
$qrCode = new QrCode('Life is too short to be generating QR codes');
|
||||
|
||||
header('Content-Type: '.$qrCode->getContentType());
|
||||
echo $qrCode->writeString();
|
||||
```
|
||||
|
||||
## Advanced usage
|
||||
|
||||
```php
|
||||
use Endroid\QrCode\ErrorCorrectionLevel;
|
||||
use Endroid\QrCode\LabelAlignment;
|
||||
use Endroid\QrCode\QrCode;
|
||||
use Endroid\QrCode\Response\QrCodeResponse;
|
||||
|
||||
// Create a basic QR code
|
||||
$qrCode = new QrCode('Life is too short to be generating QR codes');
|
||||
$qrCode->setSize(300);
|
||||
$qrCode->setMargin(10);
|
||||
|
||||
// Set advanced options
|
||||
$qrCode->setWriterByName('png');
|
||||
$qrCode->setEncoding('UTF-8');
|
||||
$qrCode->setErrorCorrectionLevel(ErrorCorrectionLevel::HIGH());
|
||||
$qrCode->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0, 'a' => 0]);
|
||||
$qrCode->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255, 'a' => 0]);
|
||||
$qrCode->setLabel('Scan the code', 16, __DIR__.'/../assets/fonts/noto_sans.otf', LabelAlignment::CENTER());
|
||||
$qrCode->setLogoPath(__DIR__.'/../assets/images/symfony.png');
|
||||
$qrCode->setLogoSize(150, 200);
|
||||
$qrCode->setValidateResult(false);
|
||||
|
||||
// Round block sizes to improve readability and make the blocks sharper in pixel based outputs (like png).
|
||||
// There are three approaches:
|
||||
$qrCode->setRoundBlockSize(true, QrCode::ROUND_BLOCK_SIZE_MODE_MARGIN); // The size of the qr code is shrinked, if necessary, but the size of the final image remains unchanged due to additional margin being added (default)
|
||||
$qrCode->setRoundBlockSize(true, QrCode::ROUND_BLOCK_SIZE_MODE_ENLARGE); // The size of the qr code and the final image is enlarged, if necessary
|
||||
$qrCode->setRoundBlockSize(true, QrCode::ROUND_BLOCK_SIZE_MODE_SHRINK); // The size of the qr code and the final image is shrinked, if necessary
|
||||
|
||||
// Set additional writer options (SvgWriter example)
|
||||
$qrCode->setWriterOptions(['exclude_xml_declaration' => true]);
|
||||
|
||||
// Directly output the QR code
|
||||
header('Content-Type: '.$qrCode->getContentType());
|
||||
echo $qrCode->writeString();
|
||||
|
||||
// Save it to a file
|
||||
$qrCode->writeFile(__DIR__.'/qrcode.png');
|
||||
|
||||
// Generate a data URI to include image data inline (i.e. inside an <img> tag)
|
||||
$dataUri = $qrCode->writeDataUri();
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Encoding
|
||||
You can pick one of these values for encoding:
|
||||
|
||||
`ISO-8859-1`, `ISO-8859-2`, `ISO-8859-3`, `ISO-8859-4`, `ISO-8859-5`, `ISO-8859-6`, `ISO-8859-7`, `ISO-8859-8`, `ISO-8859-9`, `ISO-8859-10`, `ISO-8859-11`, `ISO-8859-12`, `ISO-8859-13`, `ISO-8859-14`, `ISO-8859-15`, `ISO-8859-16`, `Shift_JIS`, `windows-1250`, `windows-1251`, `windows-1252`, `windows-1256`, `UTF-16BE`, `UTF-8`, `US-ASCII`, `GBK` `EUC-KR`
|
||||
|
||||
If you use a barcode scanner you can have some troubles while reading the generated QR codes. Depending on the encoding you chose you will have an extra amount of data corresponding to the ECI block. Some barcode scanner are not programmed to interpret this block of information. For exemple the ECI block for `UTF-8` is `000026` so the above exemple will produce : `\000026Life is too short to be generating QR codes`. To ensure a maximum compatibility you can use the `ISO-8859-1` encoding that is the default encoding used by barcode scanners.
|
||||
|
||||
## Readability
|
||||
|
||||
The readability of a QR code is primarily determined by the size, the input
|
||||
length, the error correction level and any possible logo over the image so you
|
||||
can tweak these parameters if you are looking for optimal results. You can also
|
||||
check $qrCode->getRoundBlockSize() value to see if block dimensions are rounded
|
||||
so that the image is more sharp and readable. Please note that rounding block
|
||||
size can result in additional padding to compensate for the rounding difference.
|
||||
|
||||
## Built-in validation reader
|
||||
|
||||
You can enable the built-in validation reader (disabled by default) by calling
|
||||
setValidateResult(true). This validation reader does not guarantee that the QR
|
||||
code will be readable by all readers but it helps you provide a minimum level
|
||||
of quality.
|
||||
|
||||
Take note that the validator can consume quite amount of additional resources.
|
||||
|
||||
## Symfony integration
|
||||
|
||||
The [endroid/qr-code-bundle](https://github.com/endroid/qr-code-bundle)
|
||||
integrates the QR code library in Symfony for an even better experience.
|
||||
|
||||
* Configure your defaults (like image size, default writer etc.)
|
||||
* Generate QR codes quickly from anywhere via the factory service
|
||||
* Generate QR codes directly by typing an URL like /qr-code/\<text>.png?size=300
|
||||
* Generate QR codes or URLs directly from Twig using dedicated functions
|
||||
|
||||
Read the [bundle documentation](https://github.com/endroid/qr-code-bundle)
|
||||
for more information.
|
||||
|
||||
## Versioning
|
||||
|
||||
Version numbers follow the MAJOR.MINOR.PATCH scheme. Backwards compatibility
|
||||
breaking changes will be kept to a minimum but be aware that these can occur.
|
||||
Lock your dependencies for production and test your code when upgrading.
|
||||
|
||||
## License
|
||||
|
||||
This bundle is under the MIT license. For the full copyright and license
|
||||
information please view the LICENSE file that was distributed with this source code.
|
||||
BIN
vendor/endroid/qr-code/assets/fonts/noto_sans.otf
vendored
Normal file
BIN
vendor/endroid/qr-code/assets/fonts/noto_sans.otf
vendored
Normal file
Binary file not shown.
BIN
vendor/endroid/qr-code/assets/fonts/open_sans.ttf
vendored
Normal file
BIN
vendor/endroid/qr-code/assets/fonts/open_sans.ttf
vendored
Normal file
Binary file not shown.
BIN
vendor/endroid/qr-code/assets/images/symfony.png
vendored
Normal file
BIN
vendor/endroid/qr-code/assets/images/symfony.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
42
vendor/endroid/qr-code/src/ErrorCorrectionLevel.php
vendored
Normal file
42
vendor/endroid/qr-code/src/ErrorCorrectionLevel.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode;
|
||||
|
||||
use BaconQrCode\Common\ErrorCorrectionLevel as BaconErrorCorrectionLevel;
|
||||
use MyCLabs\Enum\Enum;
|
||||
|
||||
/**
|
||||
* @method static ErrorCorrectionLevel LOW()
|
||||
* @method static ErrorCorrectionLevel MEDIUM()
|
||||
* @method static ErrorCorrectionLevel QUARTILE()
|
||||
* @method static ErrorCorrectionLevel HIGH()
|
||||
*
|
||||
* @extends Enum<string>
|
||||
* @psalm-immutable
|
||||
*/
|
||||
class ErrorCorrectionLevel extends Enum
|
||||
{
|
||||
const LOW = 'low';
|
||||
const MEDIUM = 'medium';
|
||||
const QUARTILE = 'quartile';
|
||||
const HIGH = 'high';
|
||||
|
||||
/**
|
||||
* @psalm-suppress ImpureMethodCall
|
||||
*/
|
||||
public function toBaconErrorCorrectionLevel(): BaconErrorCorrectionLevel
|
||||
{
|
||||
$name = strtoupper(substr($this->getValue(), 0, 1));
|
||||
|
||||
return BaconErrorCorrectionLevel::valueOf($name);
|
||||
}
|
||||
}
|
||||
16
vendor/endroid/qr-code/src/Exception/GenerateImageException.php
vendored
Normal file
16
vendor/endroid/qr-code/src/Exception/GenerateImageException.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Exception;
|
||||
|
||||
class GenerateImageException extends QrCodeException
|
||||
{
|
||||
}
|
||||
16
vendor/endroid/qr-code/src/Exception/InvalidFontException.php
vendored
Normal file
16
vendor/endroid/qr-code/src/Exception/InvalidFontException.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Exception;
|
||||
|
||||
class InvalidFontException extends QrCodeException
|
||||
{
|
||||
}
|
||||
16
vendor/endroid/qr-code/src/Exception/InvalidLogoException.php
vendored
Normal file
16
vendor/endroid/qr-code/src/Exception/InvalidLogoException.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Exception;
|
||||
|
||||
class InvalidLogoException extends QrCodeException
|
||||
{
|
||||
}
|
||||
16
vendor/endroid/qr-code/src/Exception/InvalidWriterException.php
vendored
Normal file
16
vendor/endroid/qr-code/src/Exception/InvalidWriterException.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Exception;
|
||||
|
||||
class InvalidWriterException extends QrCodeException
|
||||
{
|
||||
}
|
||||
16
vendor/endroid/qr-code/src/Exception/MissingExtensionException.php
vendored
Normal file
16
vendor/endroid/qr-code/src/Exception/MissingExtensionException.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Exception;
|
||||
|
||||
class MissingExtensionException extends QrCodeException
|
||||
{
|
||||
}
|
||||
16
vendor/endroid/qr-code/src/Exception/MissingFunctionException.php
vendored
Normal file
16
vendor/endroid/qr-code/src/Exception/MissingFunctionException.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Exception;
|
||||
|
||||
class MissingFunctionException extends QrCodeException
|
||||
{
|
||||
}
|
||||
16
vendor/endroid/qr-code/src/Exception/MissingLogoHeightException.php
vendored
Normal file
16
vendor/endroid/qr-code/src/Exception/MissingLogoHeightException.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Exception;
|
||||
|
||||
class MissingLogoHeightException extends QrCodeException
|
||||
{
|
||||
}
|
||||
18
vendor/endroid/qr-code/src/Exception/QrCodeException.php
vendored
Normal file
18
vendor/endroid/qr-code/src/Exception/QrCodeException.php
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Exception;
|
||||
|
||||
use Exception;
|
||||
|
||||
abstract class QrCodeException extends Exception
|
||||
{
|
||||
}
|
||||
16
vendor/endroid/qr-code/src/Exception/UnsupportedExtensionException.php
vendored
Normal file
16
vendor/endroid/qr-code/src/Exception/UnsupportedExtensionException.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Exception;
|
||||
|
||||
class UnsupportedExtensionException extends QrCodeException
|
||||
{
|
||||
}
|
||||
16
vendor/endroid/qr-code/src/Exception/ValidationException.php
vendored
Normal file
16
vendor/endroid/qr-code/src/Exception/ValidationException.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Exception;
|
||||
|
||||
class ValidationException extends QrCodeException
|
||||
{
|
||||
}
|
||||
112
vendor/endroid/qr-code/src/Factory/QrCodeFactory.php
vendored
Normal file
112
vendor/endroid/qr-code/src/Factory/QrCodeFactory.php
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Factory;
|
||||
|
||||
use Endroid\QrCode\ErrorCorrectionLevel;
|
||||
use Endroid\QrCode\Exception\ValidationException;
|
||||
use Endroid\QrCode\QrCode;
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
use Endroid\QrCode\WriterRegistryInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\PropertyAccess\PropertyAccess;
|
||||
|
||||
class QrCodeFactory implements QrCodeFactoryInterface
|
||||
{
|
||||
private $writerRegistry;
|
||||
|
||||
/** @var OptionsResolver */
|
||||
private $optionsResolver;
|
||||
|
||||
/** @var array<string, mixed> */
|
||||
private $defaultOptions;
|
||||
|
||||
/** @var array<int, string> */
|
||||
private $definedOptions = [
|
||||
'writer',
|
||||
'writer_options',
|
||||
'size',
|
||||
'margin',
|
||||
'foreground_color',
|
||||
'background_color',
|
||||
'encoding',
|
||||
'round_block_size',
|
||||
'round_block_size_mode',
|
||||
'error_correction_level',
|
||||
'logo_path',
|
||||
'logo_width',
|
||||
'logo_height',
|
||||
'label',
|
||||
'label_font_size',
|
||||
'label_font_path',
|
||||
'label_alignment',
|
||||
'label_margin',
|
||||
'validate_result',
|
||||
];
|
||||
|
||||
/** @param array<string, mixed> $defaultOptions */
|
||||
public function __construct(array $defaultOptions = [], WriterRegistryInterface $writerRegistry = null)
|
||||
{
|
||||
$this->defaultOptions = $defaultOptions;
|
||||
$this->writerRegistry = $writerRegistry;
|
||||
}
|
||||
|
||||
public function create(string $text = '', array $options = []): QrCodeInterface
|
||||
{
|
||||
$options = $this->getOptionsResolver()->resolve($options);
|
||||
$accessor = PropertyAccess::createPropertyAccessor();
|
||||
|
||||
$qrCode = new QrCode($text);
|
||||
|
||||
if ($this->writerRegistry instanceof WriterRegistryInterface) {
|
||||
$qrCode->setWriterRegistry($this->writerRegistry);
|
||||
}
|
||||
|
||||
foreach ($this->definedOptions as $option) {
|
||||
if (isset($options[$option])) {
|
||||
if ('writer' === $option) {
|
||||
$options['writer_by_name'] = $options[$option];
|
||||
$option = 'writer_by_name';
|
||||
}
|
||||
if ('error_correction_level' === $option) {
|
||||
$options[$option] = new ErrorCorrectionLevel($options[$option]);
|
||||
}
|
||||
$accessor->setValue($qrCode, $option, $options[$option]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$qrCode instanceof QrCodeInterface) {
|
||||
throw new ValidationException('QR Code was messed up by property accessor');
|
||||
}
|
||||
|
||||
return $qrCode;
|
||||
}
|
||||
|
||||
private function getOptionsResolver(): OptionsResolver
|
||||
{
|
||||
if (!$this->optionsResolver instanceof OptionsResolver) {
|
||||
$this->optionsResolver = $this->createOptionsResolver();
|
||||
}
|
||||
|
||||
return $this->optionsResolver;
|
||||
}
|
||||
|
||||
private function createOptionsResolver(): OptionsResolver
|
||||
{
|
||||
$optionsResolver = new OptionsResolver();
|
||||
$optionsResolver
|
||||
->setDefaults($this->defaultOptions)
|
||||
->setDefined($this->definedOptions)
|
||||
;
|
||||
|
||||
return $optionsResolver;
|
||||
}
|
||||
}
|
||||
20
vendor/endroid/qr-code/src/Factory/QrCodeFactoryInterface.php
vendored
Normal file
20
vendor/endroid/qr-code/src/Factory/QrCodeFactoryInterface.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Factory;
|
||||
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
|
||||
interface QrCodeFactoryInterface
|
||||
{
|
||||
/** @param array<string, mixed> $options */
|
||||
public function create(string $text = '', array $options = []): QrCodeInterface;
|
||||
}
|
||||
29
vendor/endroid/qr-code/src/LabelAlignment.php
vendored
Normal file
29
vendor/endroid/qr-code/src/LabelAlignment.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode;
|
||||
|
||||
use MyCLabs\Enum\Enum;
|
||||
|
||||
/**
|
||||
* @method static LabelAlignment LEFT()
|
||||
* @method static LabelAlignment CENTER()
|
||||
* @method static LabelAlignment RIGHT()
|
||||
*
|
||||
* @extends Enum<string>
|
||||
* @psalm-immutable
|
||||
*/
|
||||
class LabelAlignment extends Enum
|
||||
{
|
||||
const LEFT = 'left';
|
||||
const CENTER = 'center';
|
||||
const RIGHT = 'right';
|
||||
}
|
||||
478
vendor/endroid/qr-code/src/QrCode.php
vendored
Normal file
478
vendor/endroid/qr-code/src/QrCode.php
vendored
Normal file
@@ -0,0 +1,478 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode;
|
||||
|
||||
use BaconQrCode\Encoder\Encoder;
|
||||
use Endroid\QrCode\Exception\InvalidFontException;
|
||||
use Endroid\QrCode\Exception\UnsupportedExtensionException;
|
||||
use Endroid\QrCode\Exception\ValidationException;
|
||||
use Endroid\QrCode\Writer\WriterInterface;
|
||||
|
||||
class QrCode implements QrCodeInterface
|
||||
{
|
||||
const LABEL_FONT_PATH_DEFAULT = __DIR__.'/../assets/fonts/noto_sans.otf';
|
||||
|
||||
const ROUND_BLOCK_SIZE_MODE_MARGIN = 'margin';
|
||||
const ROUND_BLOCK_SIZE_MODE_SHRINK = 'shrink';
|
||||
const ROUND_BLOCK_SIZE_MODE_ENLARGE = 'enlarge';
|
||||
|
||||
private $text;
|
||||
|
||||
/** @var int */
|
||||
private $size = 300;
|
||||
|
||||
/** @var int */
|
||||
private $margin = 10;
|
||||
|
||||
/** @var array<int> */
|
||||
private $foregroundColor = [
|
||||
'r' => 0,
|
||||
'g' => 0,
|
||||
'b' => 0,
|
||||
'a' => 0,
|
||||
];
|
||||
|
||||
/** @var array<int> */
|
||||
private $backgroundColor = [
|
||||
'r' => 255,
|
||||
'g' => 255,
|
||||
'b' => 255,
|
||||
'a' => 0,
|
||||
];
|
||||
|
||||
/** @var string */
|
||||
private $encoding = 'UTF-8';
|
||||
|
||||
/** @var bool */
|
||||
private $roundBlockSize = true;
|
||||
|
||||
/** @var string */
|
||||
private $roundBlockSizeMode = self::ROUND_BLOCK_SIZE_MODE_MARGIN;
|
||||
|
||||
private $errorCorrectionLevel;
|
||||
|
||||
/** @var string */
|
||||
private $logoPath;
|
||||
|
||||
/** @var int|null */
|
||||
private $logoWidth;
|
||||
|
||||
/** @var int|null */
|
||||
private $logoHeight;
|
||||
|
||||
/** @var string */
|
||||
private $label;
|
||||
|
||||
/** @var int */
|
||||
private $labelFontSize = 16;
|
||||
|
||||
/** @var string */
|
||||
private $labelFontPath = self::LABEL_FONT_PATH_DEFAULT;
|
||||
|
||||
private $labelAlignment;
|
||||
|
||||
/** @var array<string, int> */
|
||||
private $labelMargin = [
|
||||
't' => 0,
|
||||
'r' => 10,
|
||||
'b' => 10,
|
||||
'l' => 10,
|
||||
];
|
||||
|
||||
/** @var WriterRegistryInterface */
|
||||
private $writerRegistry;
|
||||
|
||||
/** @var WriterInterface|null */
|
||||
private $writer;
|
||||
|
||||
/** @var array<mixed> */
|
||||
private $writerOptions = [];
|
||||
|
||||
/** @var bool */
|
||||
private $validateResult = false;
|
||||
|
||||
public function __construct(string $text = '')
|
||||
{
|
||||
$this->text = $text;
|
||||
|
||||
$this->errorCorrectionLevel = ErrorCorrectionLevel::LOW();
|
||||
$this->labelAlignment = LabelAlignment::CENTER();
|
||||
|
||||
$this->createWriterRegistry();
|
||||
}
|
||||
|
||||
public function setText(string $text): void
|
||||
{
|
||||
$this->text = $text;
|
||||
}
|
||||
|
||||
public function getText(): string
|
||||
{
|
||||
return $this->text;
|
||||
}
|
||||
|
||||
public function setSize(int $size): void
|
||||
{
|
||||
$this->size = $size;
|
||||
}
|
||||
|
||||
public function getSize(): int
|
||||
{
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
public function setMargin(int $margin): void
|
||||
{
|
||||
$this->margin = $margin;
|
||||
}
|
||||
|
||||
public function getMargin(): int
|
||||
{
|
||||
return $this->margin;
|
||||
}
|
||||
|
||||
/** @param array<int> $foregroundColor */
|
||||
public function setForegroundColor(array $foregroundColor): void
|
||||
{
|
||||
if (!isset($foregroundColor['a'])) {
|
||||
$foregroundColor['a'] = 0;
|
||||
}
|
||||
|
||||
foreach ($foregroundColor as &$color) {
|
||||
$color = intval($color);
|
||||
}
|
||||
|
||||
$this->foregroundColor = $foregroundColor;
|
||||
}
|
||||
|
||||
public function getForegroundColor(): array
|
||||
{
|
||||
return $this->foregroundColor;
|
||||
}
|
||||
|
||||
/** @param array<int> $backgroundColor */
|
||||
public function setBackgroundColor(array $backgroundColor): void
|
||||
{
|
||||
if (!isset($backgroundColor['a'])) {
|
||||
$backgroundColor['a'] = 0;
|
||||
}
|
||||
|
||||
foreach ($backgroundColor as &$color) {
|
||||
$color = intval($color);
|
||||
}
|
||||
|
||||
$this->backgroundColor = $backgroundColor;
|
||||
}
|
||||
|
||||
public function getBackgroundColor(): array
|
||||
{
|
||||
return $this->backgroundColor;
|
||||
}
|
||||
|
||||
public function setEncoding(string $encoding): void
|
||||
{
|
||||
$this->encoding = $encoding;
|
||||
}
|
||||
|
||||
public function getEncoding(): string
|
||||
{
|
||||
return $this->encoding;
|
||||
}
|
||||
|
||||
public function setRoundBlockSize(bool $roundBlockSize, string $roundBlockSizeMode = self::ROUND_BLOCK_SIZE_MODE_MARGIN): void
|
||||
{
|
||||
$this->roundBlockSize = $roundBlockSize;
|
||||
$this->setRoundBlockSizeMode($roundBlockSizeMode);
|
||||
}
|
||||
|
||||
public function getRoundBlockSize(): bool
|
||||
{
|
||||
return $this->roundBlockSize;
|
||||
}
|
||||
|
||||
public function setRoundBlockSizeMode(string $roundBlockSizeMode): void
|
||||
{
|
||||
if (!in_array($roundBlockSizeMode, [
|
||||
self::ROUND_BLOCK_SIZE_MODE_ENLARGE,
|
||||
self::ROUND_BLOCK_SIZE_MODE_MARGIN,
|
||||
self::ROUND_BLOCK_SIZE_MODE_SHRINK,
|
||||
])) {
|
||||
throw new ValidationException('Invalid round block size mode: '.$roundBlockSizeMode);
|
||||
}
|
||||
|
||||
$this->roundBlockSizeMode = $roundBlockSizeMode;
|
||||
}
|
||||
|
||||
public function setErrorCorrectionLevel(ErrorCorrectionLevel $errorCorrectionLevel): void
|
||||
{
|
||||
$this->errorCorrectionLevel = $errorCorrectionLevel;
|
||||
}
|
||||
|
||||
public function getErrorCorrectionLevel(): ErrorCorrectionLevel
|
||||
{
|
||||
return $this->errorCorrectionLevel;
|
||||
}
|
||||
|
||||
public function setLogoPath(string $logoPath): void
|
||||
{
|
||||
$this->logoPath = $logoPath;
|
||||
}
|
||||
|
||||
public function getLogoPath(): ?string
|
||||
{
|
||||
return $this->logoPath;
|
||||
}
|
||||
|
||||
public function setLogoSize(int $logoWidth, int $logoHeight = null): void
|
||||
{
|
||||
$this->logoWidth = $logoWidth;
|
||||
$this->logoHeight = $logoHeight;
|
||||
}
|
||||
|
||||
public function setLogoWidth(int $logoWidth): void
|
||||
{
|
||||
$this->logoWidth = $logoWidth;
|
||||
}
|
||||
|
||||
public function getLogoWidth(): ?int
|
||||
{
|
||||
return $this->logoWidth;
|
||||
}
|
||||
|
||||
public function setLogoHeight(int $logoHeight): void
|
||||
{
|
||||
$this->logoHeight = $logoHeight;
|
||||
}
|
||||
|
||||
public function getLogoHeight(): ?int
|
||||
{
|
||||
return $this->logoHeight;
|
||||
}
|
||||
|
||||
/** @param array<string, int> $labelMargin */
|
||||
public function setLabel(string $label, int $labelFontSize = null, string $labelFontPath = null, string $labelAlignment = null, array $labelMargin = null): void
|
||||
{
|
||||
$this->label = $label;
|
||||
|
||||
if (null !== $labelFontSize) {
|
||||
$this->setLabelFontSize($labelFontSize);
|
||||
}
|
||||
|
||||
if (null !== $labelFontPath) {
|
||||
$this->setLabelFontPath($labelFontPath);
|
||||
}
|
||||
|
||||
if (null !== $labelAlignment) {
|
||||
$this->setLabelAlignment($labelAlignment);
|
||||
}
|
||||
|
||||
if (null !== $labelMargin) {
|
||||
$this->setLabelMargin($labelMargin);
|
||||
}
|
||||
}
|
||||
|
||||
public function getLabel(): ?string
|
||||
{
|
||||
return $this->label;
|
||||
}
|
||||
|
||||
public function setLabelFontSize(int $labelFontSize): void
|
||||
{
|
||||
$this->labelFontSize = $labelFontSize;
|
||||
}
|
||||
|
||||
public function getLabelFontSize(): int
|
||||
{
|
||||
return $this->labelFontSize;
|
||||
}
|
||||
|
||||
public function setLabelFontPath(string $labelFontPath): void
|
||||
{
|
||||
$resolvedLabelFontPath = (string) realpath($labelFontPath);
|
||||
|
||||
if (!is_file($resolvedLabelFontPath)) {
|
||||
throw new InvalidFontException('Invalid label font path: '.$labelFontPath);
|
||||
}
|
||||
|
||||
$this->labelFontPath = $resolvedLabelFontPath;
|
||||
}
|
||||
|
||||
public function getLabelFontPath(): string
|
||||
{
|
||||
return $this->labelFontPath;
|
||||
}
|
||||
|
||||
public function setLabelAlignment(string $labelAlignment): void
|
||||
{
|
||||
$this->labelAlignment = new LabelAlignment($labelAlignment);
|
||||
}
|
||||
|
||||
public function getLabelAlignment(): string
|
||||
{
|
||||
return $this->labelAlignment->getValue();
|
||||
}
|
||||
|
||||
/** @param array<string, int> $labelMargin */
|
||||
public function setLabelMargin(array $labelMargin): void
|
||||
{
|
||||
$this->labelMargin = array_merge($this->labelMargin, $labelMargin);
|
||||
}
|
||||
|
||||
public function getLabelMargin(): array
|
||||
{
|
||||
return $this->labelMargin;
|
||||
}
|
||||
|
||||
public function setWriterRegistry(WriterRegistryInterface $writerRegistry): void
|
||||
{
|
||||
$this->writerRegistry = $writerRegistry;
|
||||
}
|
||||
|
||||
public function setWriter(WriterInterface $writer): void
|
||||
{
|
||||
$this->writer = $writer;
|
||||
}
|
||||
|
||||
public function getWriter(string $name = null): WriterInterface
|
||||
{
|
||||
if (!is_null($name)) {
|
||||
return $this->writerRegistry->getWriter($name);
|
||||
}
|
||||
|
||||
if ($this->writer instanceof WriterInterface) {
|
||||
return $this->writer;
|
||||
}
|
||||
|
||||
return $this->writerRegistry->getDefaultWriter();
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $writerOptions */
|
||||
public function setWriterOptions(array $writerOptions): void
|
||||
{
|
||||
$this->writerOptions = $writerOptions;
|
||||
}
|
||||
|
||||
public function getWriterOptions(): array
|
||||
{
|
||||
return $this->writerOptions;
|
||||
}
|
||||
|
||||
private function createWriterRegistry(): void
|
||||
{
|
||||
$this->writerRegistry = new WriterRegistry();
|
||||
$this->writerRegistry->loadDefaultWriters();
|
||||
}
|
||||
|
||||
public function setWriterByName(string $name): void
|
||||
{
|
||||
$this->writer = $this->getWriter($name);
|
||||
}
|
||||
|
||||
public function setWriterByPath(string $path): void
|
||||
{
|
||||
$extension = pathinfo($path, PATHINFO_EXTENSION);
|
||||
|
||||
$this->setWriterByExtension($extension);
|
||||
}
|
||||
|
||||
public function setWriterByExtension(string $extension): void
|
||||
{
|
||||
foreach ($this->writerRegistry->getWriters() as $writer) {
|
||||
if ($writer->supportsExtension($extension)) {
|
||||
$this->writer = $writer;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new UnsupportedExtensionException('Missing writer for extension "'.$extension.'"');
|
||||
}
|
||||
|
||||
public function writeString(): string
|
||||
{
|
||||
return $this->getWriter()->writeString($this);
|
||||
}
|
||||
|
||||
public function writeDataUri(): string
|
||||
{
|
||||
return $this->getWriter()->writeDataUri($this);
|
||||
}
|
||||
|
||||
public function writeFile(string $path): void
|
||||
{
|
||||
$this->getWriter()->writeFile($this, $path);
|
||||
}
|
||||
|
||||
public function getContentType(): string
|
||||
{
|
||||
return $this->getWriter()->getContentType();
|
||||
}
|
||||
|
||||
public function setValidateResult(bool $validateResult): void
|
||||
{
|
||||
$this->validateResult = $validateResult;
|
||||
}
|
||||
|
||||
public function getValidateResult(): bool
|
||||
{
|
||||
return $this->validateResult;
|
||||
}
|
||||
|
||||
public function getData(): array
|
||||
{
|
||||
$baconErrorCorrectionLevel = $this->errorCorrectionLevel->toBaconErrorCorrectionLevel();
|
||||
|
||||
$baconQrCode = Encoder::encode($this->text, $baconErrorCorrectionLevel, $this->encoding);
|
||||
|
||||
$baconMatrix = $baconQrCode->getMatrix();
|
||||
|
||||
$matrix = [];
|
||||
$columnCount = $baconMatrix->getWidth();
|
||||
$rowCount = $baconMatrix->getHeight();
|
||||
for ($rowIndex = 0; $rowIndex < $rowCount; ++$rowIndex) {
|
||||
$matrix[$rowIndex] = [];
|
||||
for ($columnIndex = 0; $columnIndex < $columnCount; ++$columnIndex) {
|
||||
$matrix[$rowIndex][$columnIndex] = $baconMatrix->get($columnIndex, $rowIndex);
|
||||
}
|
||||
}
|
||||
|
||||
$data = ['matrix' => $matrix];
|
||||
$data['block_count'] = count($matrix[0]);
|
||||
$data['block_size'] = $this->size / $data['block_count'];
|
||||
if ($this->roundBlockSize) {
|
||||
switch ($this->roundBlockSizeMode) {
|
||||
case self::ROUND_BLOCK_SIZE_MODE_ENLARGE:
|
||||
$data['block_size'] = intval(ceil($data['block_size']));
|
||||
$this->size = $data['block_size'] * $data['block_count'];
|
||||
break;
|
||||
case self::ROUND_BLOCK_SIZE_MODE_SHRINK:
|
||||
$data['block_size'] = intval(floor($data['block_size']));
|
||||
$this->size = $data['block_size'] * $data['block_count'];
|
||||
break;
|
||||
case self::ROUND_BLOCK_SIZE_MODE_MARGIN:
|
||||
default:
|
||||
$data['block_size'] = intval(floor($data['block_size']));
|
||||
}
|
||||
}
|
||||
$data['inner_width'] = $data['block_size'] * $data['block_count'];
|
||||
$data['inner_height'] = $data['block_size'] * $data['block_count'];
|
||||
$data['outer_width'] = $this->size + 2 * $this->margin;
|
||||
$data['outer_height'] = $this->size + 2 * $this->margin;
|
||||
$data['margin_left'] = ($data['outer_width'] - $data['inner_width']) / 2;
|
||||
if ($this->roundBlockSize) {
|
||||
$data['margin_left'] = intval(floor($data['margin_left']));
|
||||
}
|
||||
$data['margin_right'] = $data['outer_width'] - $data['inner_width'] - $data['margin_left'];
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
68
vendor/endroid/qr-code/src/QrCodeInterface.php
vendored
Normal file
68
vendor/endroid/qr-code/src/QrCodeInterface.php
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode;
|
||||
|
||||
interface QrCodeInterface
|
||||
{
|
||||
public function getText(): string;
|
||||
|
||||
public function getSize(): int;
|
||||
|
||||
public function getMargin(): int;
|
||||
|
||||
/** @return array<int> */
|
||||
public function getForegroundColor(): array;
|
||||
|
||||
/** @return array<int> */
|
||||
public function getBackgroundColor(): array;
|
||||
|
||||
public function getEncoding(): string;
|
||||
|
||||
public function getRoundBlockSize(): bool;
|
||||
|
||||
public function getErrorCorrectionLevel(): ErrorCorrectionLevel;
|
||||
|
||||
public function getLogoPath(): ?string;
|
||||
|
||||
public function getLogoWidth(): ?int;
|
||||
|
||||
public function getLogoHeight(): ?int;
|
||||
|
||||
public function getLabel(): ?string;
|
||||
|
||||
public function getLabelFontPath(): string;
|
||||
|
||||
public function getLabelFontSize(): int;
|
||||
|
||||
public function getLabelAlignment(): string;
|
||||
|
||||
/** @return array<int> */
|
||||
public function getLabelMargin(): array;
|
||||
|
||||
public function getValidateResult(): bool;
|
||||
|
||||
/** @return array<mixed> */
|
||||
public function getWriterOptions(): array;
|
||||
|
||||
public function getContentType(): string;
|
||||
|
||||
public function setWriterRegistry(WriterRegistryInterface $writerRegistry): void;
|
||||
|
||||
public function writeString(): string;
|
||||
|
||||
public function writeDataUri(): string;
|
||||
|
||||
public function writeFile(string $path): void;
|
||||
|
||||
/** @return array<mixed> */
|
||||
public function getData(): array;
|
||||
}
|
||||
92
vendor/endroid/qr-code/src/Writer/AbstractWriter.php
vendored
Normal file
92
vendor/endroid/qr-code/src/Writer/AbstractWriter.php
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\Exception\GenerateImageException;
|
||||
use Endroid\QrCode\Exception\InvalidLogoException;
|
||||
use Endroid\QrCode\Exception\MissingExtensionException;
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
|
||||
abstract class AbstractWriter implements WriterInterface
|
||||
{
|
||||
protected function getMimeType(string $path): string
|
||||
{
|
||||
if (false !== filter_var($path, FILTER_VALIDATE_URL)) {
|
||||
return $this->getMimeTypeFromUrl($path);
|
||||
}
|
||||
|
||||
return $this->getMimeTypeFromPath($path);
|
||||
}
|
||||
|
||||
private function getMimeTypeFromUrl(string $url): string
|
||||
{
|
||||
/** @var mixed $format */
|
||||
$format = PHP_VERSION > 80000 ? true : 1;
|
||||
|
||||
$headers = get_headers($url, $format);
|
||||
|
||||
if (!is_array($headers) || !isset($headers['Content-Type'])) {
|
||||
throw new InvalidLogoException(sprintf('Content type could not be determined for logo URL "%s"', $url));
|
||||
}
|
||||
|
||||
return $headers['Content-Type'];
|
||||
}
|
||||
|
||||
private function getMimeTypeFromPath(string $path): string
|
||||
{
|
||||
if (!function_exists('mime_content_type')) {
|
||||
throw new MissingExtensionException('You need the ext-fileinfo extension to determine logo mime type');
|
||||
}
|
||||
|
||||
$mimeType = mime_content_type($path);
|
||||
|
||||
if (!is_string($mimeType)) {
|
||||
throw new InvalidLogoException('Could not determine mime type');
|
||||
}
|
||||
|
||||
if (!preg_match('#^image/#', $mimeType)) {
|
||||
throw new GenerateImageException('Logo path is not an image');
|
||||
}
|
||||
|
||||
// Passing mime type image/svg results in invisible images
|
||||
if ('image/svg' === $mimeType) {
|
||||
return 'image/svg+xml';
|
||||
}
|
||||
|
||||
return $mimeType;
|
||||
}
|
||||
|
||||
public function writeDataUri(QrCodeInterface $qrCode): string
|
||||
{
|
||||
$dataUri = 'data:'.$this->getContentType().';base64,'.base64_encode($this->writeString($qrCode));
|
||||
|
||||
return $dataUri;
|
||||
}
|
||||
|
||||
public function writeFile(QrCodeInterface $qrCode, string $path): void
|
||||
{
|
||||
$string = $this->writeString($qrCode);
|
||||
file_put_contents($path, $string);
|
||||
}
|
||||
|
||||
public static function supportsExtension(string $extension): bool
|
||||
{
|
||||
return in_array($extension, static::getSupportedExtensions());
|
||||
}
|
||||
|
||||
public static function getSupportedExtensions(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
abstract public function getName(): string;
|
||||
}
|
||||
47
vendor/endroid/qr-code/src/Writer/BinaryWriter.php
vendored
Normal file
47
vendor/endroid/qr-code/src/Writer/BinaryWriter.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
|
||||
class BinaryWriter extends AbstractWriter
|
||||
{
|
||||
public function writeString(QrCodeInterface $qrCode): string
|
||||
{
|
||||
$rows = [];
|
||||
$data = $qrCode->getData();
|
||||
foreach ($data['matrix'] as $row) {
|
||||
$values = '';
|
||||
foreach ($row as $value) {
|
||||
$values .= $value;
|
||||
}
|
||||
$rows[] = $values;
|
||||
}
|
||||
|
||||
return implode("\n", $rows);
|
||||
}
|
||||
|
||||
public static function getContentType(): string
|
||||
{
|
||||
return 'text/plain';
|
||||
}
|
||||
|
||||
public static function getSupportedExtensions(): array
|
||||
{
|
||||
return ['bin', 'txt'];
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return 'binary';
|
||||
}
|
||||
}
|
||||
60
vendor/endroid/qr-code/src/Writer/DebugWriter.php
vendored
Normal file
60
vendor/endroid/qr-code/src/Writer/DebugWriter.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
use Exception;
|
||||
use ReflectionClass;
|
||||
|
||||
class DebugWriter extends AbstractWriter
|
||||
{
|
||||
public function writeString(QrCodeInterface $qrCode): string
|
||||
{
|
||||
$data = [];
|
||||
$skip = ['getData'];
|
||||
|
||||
$reflectionClass = new ReflectionClass($qrCode);
|
||||
foreach ($reflectionClass->getMethods() as $method) {
|
||||
$methodName = $method->getShortName();
|
||||
if (0 === strpos($methodName, 'get') && 0 == $method->getNumberOfParameters() && !in_array($methodName, $skip)) {
|
||||
$value = $qrCode->{$methodName}();
|
||||
if (is_array($value) && !is_object(current($value))) {
|
||||
$value = '['.implode(', ', $value).']';
|
||||
} elseif (is_bool($value)) {
|
||||
$value = $value ? 'true' : 'false';
|
||||
} elseif (is_string($value)) {
|
||||
$value = '"'.$value.'"';
|
||||
} elseif (is_null($value)) {
|
||||
$value = 'null';
|
||||
}
|
||||
try {
|
||||
$data[] = $methodName.': '.$value;
|
||||
} catch (Exception $exception) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$string = implode(" \n", $data);
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
public static function getContentType(): string
|
||||
{
|
||||
return 'text/plain';
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return 'debug';
|
||||
}
|
||||
}
|
||||
59
vendor/endroid/qr-code/src/Writer/EpsWriter.php
vendored
Normal file
59
vendor/endroid/qr-code/src/Writer/EpsWriter.php
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
|
||||
class EpsWriter extends AbstractWriter
|
||||
{
|
||||
public function writeString(QrCodeInterface $qrCode): string
|
||||
{
|
||||
$data = $qrCode->getData();
|
||||
|
||||
$epsData = [];
|
||||
$epsData[] = '%!PS-Adobe-3.0 EPSF-3.0';
|
||||
$epsData[] = '%%BoundingBox: 0 0 '.$data['outer_width'].' '.$data['outer_height'];
|
||||
$epsData[] = '/F { rectfill } def';
|
||||
$epsData[] = number_format($qrCode->getBackgroundColor()['r'] / 100, 2, '.', ',').' '.number_format($qrCode->getBackgroundColor()['g'] / 100, 2, '.', ',').' '.number_format($qrCode->getBackgroundColor()['b'] / 100, 2, '.', ',').' setrgbcolor';
|
||||
$epsData[] = '0 0 '.$data['outer_width'].' '.$data['outer_height'].' F';
|
||||
$epsData[] = number_format($qrCode->getForegroundColor()['r'] / 100, 2, '.', ',').' '.number_format($qrCode->getForegroundColor()['g'] / 100, 2, '.', ',').' '.number_format($qrCode->getForegroundColor()['b'] / 100, 2, '.', ',').' setrgbcolor';
|
||||
|
||||
// Please note an EPS has a reversed Y axis compared to PNG and SVG
|
||||
$data['matrix'] = array_reverse($data['matrix']);
|
||||
foreach ($data['matrix'] as $row => $values) {
|
||||
foreach ($values as $column => $value) {
|
||||
if (1 === $value) {
|
||||
$x = $data['margin_left'] + $data['block_size'] * $column;
|
||||
$y = $data['margin_left'] + $data['block_size'] * $row;
|
||||
$epsData[] = $x.' '.$y.' '.$data['block_size'].' '.$data['block_size'].' F';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return implode("\n", $epsData);
|
||||
}
|
||||
|
||||
public static function getContentType(): string
|
||||
{
|
||||
return 'image/eps';
|
||||
}
|
||||
|
||||
public static function getSupportedExtensions(): array
|
||||
{
|
||||
return ['eps'];
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return 'eps';
|
||||
}
|
||||
}
|
||||
131
vendor/endroid/qr-code/src/Writer/FpdfWriter.php
vendored
Normal file
131
vendor/endroid/qr-code/src/Writer/FpdfWriter.php
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\Exception\ValidationException;
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
|
||||
class FpdfWriter extends AbstractWriter
|
||||
{
|
||||
/**
|
||||
* Defines as which unit the size is handled. Default is: "mm".
|
||||
*
|
||||
* Allowed values: 'mm', 'pt', 'cm', 'in'
|
||||
*/
|
||||
public const WRITER_OPTION_MEASURE_UNIT = 'fpdf_measure_unit';
|
||||
|
||||
public function writeString(QrCodeInterface $qrCode): string
|
||||
{
|
||||
if (!\class_exists(\FPDF::class)) {
|
||||
throw new \BadMethodCallException('The Fpdf writer requires FPDF as dependency but the class "\\FPDF" couldn\'t be found.');
|
||||
}
|
||||
|
||||
if ($qrCode->getValidateResult()) {
|
||||
throw new ValidationException('Built-in validation reader can not check fpdf qr codes: please disable via setValidateResult(false)');
|
||||
}
|
||||
$foregroundColor = $qrCode->getForegroundColor();
|
||||
if (0 !== $foregroundColor['a']) {
|
||||
throw new \InvalidArgumentException('The foreground color has an alpha channel, but the fpdf qr writer doesn\'t support alpha channels.');
|
||||
}
|
||||
$backgroundColor = $qrCode->getBackgroundColor();
|
||||
if (0 !== $backgroundColor['a']) {
|
||||
throw new \InvalidArgumentException('The foreground color has an alpha channel, but the fpdf qr writer doesn\'t support alpha channels.');
|
||||
}
|
||||
|
||||
$label = $qrCode->getLabel();
|
||||
$labelHeight = null !== $label ? 30 : 0;
|
||||
|
||||
$data = $qrCode->getData();
|
||||
$options = $qrCode->getWriterOptions();
|
||||
|
||||
$fpdf = new \FPDF(
|
||||
'P',
|
||||
$options[self::WRITER_OPTION_MEASURE_UNIT] ?? 'mm',
|
||||
[$data['outer_width'], $data['outer_height'] + $labelHeight]
|
||||
);
|
||||
$fpdf->AddPage();
|
||||
|
||||
$fpdf->SetFillColor($backgroundColor['r'], $backgroundColor['g'], $backgroundColor['b']);
|
||||
$fpdf->Rect(0, 0, $data['outer_width'], $data['outer_height'], 'F');
|
||||
|
||||
$fpdf->SetFillColor($foregroundColor['r'], $foregroundColor['g'], $foregroundColor['b']);
|
||||
foreach ($data['matrix'] as $row => $values) {
|
||||
foreach ($values as $column => $value) {
|
||||
if (1 === $value) {
|
||||
$fpdf->Rect(
|
||||
$data['margin_left'] + ($column * $data['block_size']),
|
||||
$data['margin_left'] + ($row * $data['block_size']),
|
||||
$data['block_size'],
|
||||
$data['block_size'],
|
||||
'F'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$logoPath = $qrCode->getLogoPath();
|
||||
if (null !== $logoPath) {
|
||||
$this->addLogo(
|
||||
$fpdf,
|
||||
$logoPath,
|
||||
$qrCode->getLogoWidth(),
|
||||
$qrCode->getLogoHeight(),
|
||||
$data['outer_width'],
|
||||
$data['outer_height']
|
||||
);
|
||||
}
|
||||
|
||||
if (null !== $label) {
|
||||
$fpdf->setY($data['outer_height'] + 5);
|
||||
$fpdf->SetFont('Helvetica', null, $qrCode->getLabelFontSize());
|
||||
$fpdf->Cell(0, 0, $label, 0, 0, strtoupper($qrCode->getLabelAlignment()[0]));
|
||||
}
|
||||
|
||||
return $fpdf->Output('S');
|
||||
}
|
||||
|
||||
protected function addLogo(\FPDF $fpdf, string $logoPath, ?int $logoWidth, ?int $logoHeight, int $imageWidth, int $imageHeight): void
|
||||
{
|
||||
if (null === $logoHeight || null === $logoWidth) {
|
||||
[$logoSourceWidth, $logoSourceHeight] = \getimagesize($logoPath);
|
||||
|
||||
if (null === $logoWidth) {
|
||||
$logoWidth = (int) $logoSourceWidth;
|
||||
}
|
||||
|
||||
if (null === $logoHeight) {
|
||||
$aspectRatio = $logoWidth / $logoSourceWidth;
|
||||
$logoHeight = (int) ($logoSourceHeight * $aspectRatio);
|
||||
}
|
||||
}
|
||||
|
||||
$logoX = $imageWidth / 2 - (int) $logoWidth / 2;
|
||||
$logoY = $imageHeight / 2 - (int) $logoHeight / 2;
|
||||
|
||||
$fpdf->Image($logoPath, $logoX, $logoY, $logoWidth, $logoHeight);
|
||||
}
|
||||
|
||||
public static function getContentType(): string
|
||||
{
|
||||
return 'application/pdf';
|
||||
}
|
||||
|
||||
public static function getSupportedExtensions(): array
|
||||
{
|
||||
return ['pdf'];
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return 'fpdf';
|
||||
}
|
||||
}
|
||||
281
vendor/endroid/qr-code/src/Writer/PngWriter.php
vendored
Normal file
281
vendor/endroid/qr-code/src/Writer/PngWriter.php
vendored
Normal file
@@ -0,0 +1,281 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\Exception\GenerateImageException;
|
||||
use Endroid\QrCode\Exception\MissingFunctionException;
|
||||
use Endroid\QrCode\Exception\MissingLogoHeightException;
|
||||
use Endroid\QrCode\Exception\ValidationException;
|
||||
use Endroid\QrCode\LabelAlignment;
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
use Zxing\QrReader;
|
||||
|
||||
class PngWriter extends AbstractWriter
|
||||
{
|
||||
public function writeString(QrCodeInterface $qrCode): string
|
||||
{
|
||||
if (!extension_loaded('gd')) {
|
||||
throw new GenerateImageException('Unable to generate image: check your GD installation');
|
||||
}
|
||||
|
||||
$image = $this->createImage($qrCode->getData(), $qrCode);
|
||||
|
||||
$logoPath = $qrCode->getLogoPath();
|
||||
if (null !== $logoPath) {
|
||||
$image = $this->addLogo($image, $logoPath, $qrCode->getLogoWidth(), $qrCode->getLogoHeight());
|
||||
}
|
||||
|
||||
$label = $qrCode->getLabel();
|
||||
if (null !== $label) {
|
||||
$image = $this->addLabel($image, $label, $qrCode->getLabelFontPath(), $qrCode->getLabelFontSize(), $qrCode->getLabelAlignment(), $qrCode->getLabelMargin(), $qrCode->getForegroundColor(), $qrCode->getBackgroundColor());
|
||||
}
|
||||
|
||||
$string = $this->imageToString($image);
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
imagedestroy($image);
|
||||
}
|
||||
|
||||
if ($qrCode->getValidateResult()) {
|
||||
$reader = new QrReader($string, QrReader::SOURCE_TYPE_BLOB);
|
||||
if ($reader->text() !== $qrCode->getText()) {
|
||||
throw new ValidationException('Built-in validation reader read "'.$reader->text().'" instead of "'.$qrCode->getText().'".
|
||||
Adjust your parameters to increase readability or disable built-in validation.');
|
||||
}
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<mixed> $data
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function createImage(array $data, QrCodeInterface $qrCode)
|
||||
{
|
||||
$baseSize = $qrCode->getRoundBlockSize() ? $data['block_size'] : 25;
|
||||
|
||||
$baseImage = $this->createBaseImage($baseSize, $data, $qrCode);
|
||||
$interpolatedImage = $this->createInterpolatedImage($baseImage, $data, $qrCode);
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
imagedestroy($baseImage);
|
||||
}
|
||||
|
||||
return $interpolatedImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<mixed> $data
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function createBaseImage(int $baseSize, array $data, QrCodeInterface $qrCode)
|
||||
{
|
||||
$image = imagecreatetruecolor($data['block_count'] * $baseSize, $data['block_count'] * $baseSize);
|
||||
|
||||
if (!$image) {
|
||||
throw new GenerateImageException('Unable to generate image: check your GD installation');
|
||||
}
|
||||
|
||||
$foregroundColor = imagecolorallocatealpha($image, $qrCode->getForegroundColor()['r'], $qrCode->getForegroundColor()['g'], $qrCode->getForegroundColor()['b'], $qrCode->getForegroundColor()['a']);
|
||||
if (!is_int($foregroundColor)) {
|
||||
throw new GenerateImageException('Foreground color could not be allocated');
|
||||
}
|
||||
|
||||
$backgroundColor = imagecolorallocatealpha($image, $qrCode->getBackgroundColor()['r'], $qrCode->getBackgroundColor()['g'], $qrCode->getBackgroundColor()['b'], $qrCode->getBackgroundColor()['a']);
|
||||
if (!is_int($backgroundColor)) {
|
||||
throw new GenerateImageException('Background color could not be allocated');
|
||||
}
|
||||
|
||||
imagefill($image, 0, 0, $backgroundColor);
|
||||
|
||||
foreach ($data['matrix'] as $row => $values) {
|
||||
foreach ($values as $column => $value) {
|
||||
if (1 === $value) {
|
||||
imagefilledrectangle($image, $column * $baseSize, $row * $baseSize, intval(($column + 1) * $baseSize), intval(($row + 1) * $baseSize), $foregroundColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $baseImage
|
||||
* @param array<mixed> $data
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function createInterpolatedImage($baseImage, array $data, QrCodeInterface $qrCode)
|
||||
{
|
||||
$image = imagecreatetruecolor($data['outer_width'], $data['outer_height']);
|
||||
|
||||
if (!$image) {
|
||||
throw new GenerateImageException('Unable to generate image: check your GD installation');
|
||||
}
|
||||
|
||||
$backgroundColor = imagecolorallocatealpha($image, $qrCode->getBackgroundColor()['r'], $qrCode->getBackgroundColor()['g'], $qrCode->getBackgroundColor()['b'], $qrCode->getBackgroundColor()['a']);
|
||||
if (!is_int($backgroundColor)) {
|
||||
throw new GenerateImageException('Background color could not be allocated');
|
||||
}
|
||||
|
||||
imagefill($image, 0, 0, $backgroundColor);
|
||||
imagecopyresampled($image, $baseImage, (int) $data['margin_left'], (int) $data['margin_left'], 0, 0, (int) $data['inner_width'], (int) $data['inner_height'], imagesx($baseImage), imagesy($baseImage));
|
||||
|
||||
if ($qrCode->getBackgroundColor()['a'] > 0) {
|
||||
imagesavealpha($image, true);
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $sourceImage
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function addLogo($sourceImage, string $logoPath, int $logoWidth = null, int $logoHeight = null)
|
||||
{
|
||||
$mimeType = $this->getMimeType($logoPath);
|
||||
$logoImage = imagecreatefromstring(strval(file_get_contents($logoPath)));
|
||||
|
||||
if ('image/svg+xml' === $mimeType && (null === $logoHeight || null === $logoWidth)) {
|
||||
throw new MissingLogoHeightException('SVG Logos require an explicit height set via setLogoSize($width, $height)');
|
||||
}
|
||||
|
||||
if (!$logoImage) {
|
||||
throw new GenerateImageException('Unable to generate image: check your GD installation or logo path');
|
||||
}
|
||||
|
||||
$logoSourceWidth = imagesx($logoImage);
|
||||
$logoSourceHeight = imagesy($logoImage);
|
||||
|
||||
if (null === $logoWidth) {
|
||||
$logoWidth = $logoSourceWidth;
|
||||
}
|
||||
|
||||
if (null === $logoHeight) {
|
||||
$aspectRatio = $logoWidth / $logoSourceWidth;
|
||||
$logoHeight = intval($logoSourceHeight * $aspectRatio);
|
||||
}
|
||||
|
||||
$logoX = imagesx($sourceImage) / 2 - $logoWidth / 2;
|
||||
$logoY = imagesy($sourceImage) / 2 - $logoHeight / 2;
|
||||
|
||||
imagecopyresampled($sourceImage, $logoImage, intval($logoX), intval($logoY), 0, 0, $logoWidth, $logoHeight, $logoSourceWidth, $logoSourceHeight);
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
imagedestroy($logoImage);
|
||||
}
|
||||
|
||||
return $sourceImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $sourceImage
|
||||
* @param array<int> $labelMargin
|
||||
* @param array<int> $foregroundColor
|
||||
* @param array<int> $backgroundColor
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function addLabel($sourceImage, string $label, string $labelFontPath, int $labelFontSize, string $labelAlignment, array $labelMargin, array $foregroundColor, array $backgroundColor)
|
||||
{
|
||||
if (!function_exists('imagettfbbox')) {
|
||||
throw new MissingFunctionException('Missing function "imagettfbbox", please make sure you installed the FreeType library');
|
||||
}
|
||||
|
||||
$labelBox = imagettfbbox($labelFontSize, 0, $labelFontPath, $label);
|
||||
if (!$labelBox) {
|
||||
throw new GenerateImageException('Unable to add label: check your GD installation');
|
||||
}
|
||||
|
||||
$labelBoxWidth = intval($labelBox[2] - $labelBox[0]);
|
||||
$labelBoxHeight = intval($labelBox[0] - $labelBox[7]);
|
||||
|
||||
$sourceWidth = imagesx($sourceImage);
|
||||
$sourceHeight = imagesy($sourceImage);
|
||||
$targetWidth = $sourceWidth;
|
||||
$targetHeight = $sourceHeight + $labelBoxHeight + $labelMargin['t'] + $labelMargin['b'];
|
||||
|
||||
// Create empty target image
|
||||
$targetImage = imagecreatetruecolor($targetWidth, $targetHeight);
|
||||
|
||||
if (!$targetImage) {
|
||||
throw new GenerateImageException('Unable to generate image: check your GD installation');
|
||||
}
|
||||
|
||||
$foregroundColor = imagecolorallocate($targetImage, $foregroundColor['r'], $foregroundColor['g'], $foregroundColor['b']);
|
||||
if (!is_int($foregroundColor)) {
|
||||
throw new GenerateImageException('Foreground color could not be allocated');
|
||||
}
|
||||
|
||||
$backgroundColor = imagecolorallocate($targetImage, $backgroundColor['r'], $backgroundColor['g'], $backgroundColor['b']);
|
||||
if (!is_int($backgroundColor)) {
|
||||
throw new GenerateImageException('Background color could not be allocated');
|
||||
}
|
||||
|
||||
imagefill($targetImage, 0, 0, $backgroundColor);
|
||||
|
||||
// Copy source image to target image
|
||||
imagecopyresampled($targetImage, $sourceImage, 0, 0, 0, 0, $sourceWidth, $sourceHeight, $sourceWidth, $sourceHeight);
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
imagedestroy($sourceImage);
|
||||
}
|
||||
|
||||
switch ($labelAlignment) {
|
||||
case LabelAlignment::LEFT:
|
||||
$labelX = $labelMargin['l'];
|
||||
break;
|
||||
case LabelAlignment::RIGHT:
|
||||
$labelX = $targetWidth - $labelBoxWidth - $labelMargin['r'];
|
||||
break;
|
||||
default:
|
||||
$labelX = intval($targetWidth / 2 - $labelBoxWidth / 2);
|
||||
break;
|
||||
}
|
||||
|
||||
$labelY = $targetHeight - $labelMargin['b'];
|
||||
imagettftext($targetImage, $labelFontSize, 0, $labelX, $labelY, $foregroundColor, $labelFontPath, $label);
|
||||
|
||||
return $targetImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $image
|
||||
*/
|
||||
private function imageToString($image): string
|
||||
{
|
||||
ob_start();
|
||||
imagepng($image);
|
||||
|
||||
return (string) ob_get_clean();
|
||||
}
|
||||
|
||||
public static function getContentType(): string
|
||||
{
|
||||
return 'image/png';
|
||||
}
|
||||
|
||||
public static function getSupportedExtensions(): array
|
||||
{
|
||||
return ['png'];
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return 'png';
|
||||
}
|
||||
}
|
||||
169
vendor/endroid/qr-code/src/Writer/SvgWriter.php
vendored
Normal file
169
vendor/endroid/qr-code/src/Writer/SvgWriter.php
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\Exception\GenerateImageException;
|
||||
use Endroid\QrCode\Exception\MissingLogoHeightException;
|
||||
use Endroid\QrCode\Exception\ValidationException;
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
use SimpleXMLElement;
|
||||
|
||||
class SvgWriter extends AbstractWriter
|
||||
{
|
||||
public function writeString(QrCodeInterface $qrCode): string
|
||||
{
|
||||
$options = $qrCode->getWriterOptions();
|
||||
|
||||
if ($qrCode->getValidateResult()) {
|
||||
throw new ValidationException('Built-in validation reader can not check SVG images: please disable via setValidateResult(false)');
|
||||
}
|
||||
|
||||
$data = $qrCode->getData();
|
||||
|
||||
$svg = new SimpleXMLElement('<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"/>');
|
||||
$svg->addAttribute('version', '1.1');
|
||||
$svg->addAttribute('width', $data['outer_width'].'px');
|
||||
$svg->addAttribute('height', $data['outer_height'].'px');
|
||||
$svg->addAttribute('viewBox', '0 0 '.$data['outer_width'].' '.$data['outer_height']);
|
||||
$svg->addChild('defs');
|
||||
|
||||
// Block definition
|
||||
$block_id = isset($options['rect_id']) && $options['rect_id'] ? $options['rect_id'] : 'block';
|
||||
$blockDefinition = $svg->defs->addChild('rect');
|
||||
$blockDefinition->addAttribute('id', $block_id);
|
||||
$blockDefinition->addAttribute('width', strval($data['block_size']));
|
||||
$blockDefinition->addAttribute('height', strval($data['block_size']));
|
||||
$blockDefinition->addAttribute('fill', '#'.sprintf('%02x%02x%02x', $qrCode->getForegroundColor()['r'], $qrCode->getForegroundColor()['g'], $qrCode->getForegroundColor()['b']));
|
||||
$blockDefinition->addAttribute('fill-opacity', strval($this->getOpacity($qrCode->getForegroundColor()['a'])));
|
||||
|
||||
// Background
|
||||
$background = $svg->addChild('rect');
|
||||
$background->addAttribute('x', '0');
|
||||
$background->addAttribute('y', '0');
|
||||
$background->addAttribute('width', strval($data['outer_width']));
|
||||
$background->addAttribute('height', strval($data['outer_height']));
|
||||
$background->addAttribute('fill', '#'.sprintf('%02x%02x%02x', $qrCode->getBackgroundColor()['r'], $qrCode->getBackgroundColor()['g'], $qrCode->getBackgroundColor()['b']));
|
||||
$background->addAttribute('fill-opacity', strval($this->getOpacity($qrCode->getBackgroundColor()['a'])));
|
||||
|
||||
foreach ($data['matrix'] as $row => $values) {
|
||||
foreach ($values as $column => $value) {
|
||||
if (1 === $value) {
|
||||
$block = $svg->addChild('use');
|
||||
$block->addAttribute('x', strval($data['margin_left'] + $data['block_size'] * $column));
|
||||
$block->addAttribute('y', strval($data['margin_left'] + $data['block_size'] * $row));
|
||||
$block->addAttribute('xlink:href', '#'.$block_id, 'http://www.w3.org/1999/xlink');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$logoPath = $qrCode->getLogoPath();
|
||||
if (is_string($logoPath)) {
|
||||
$forceXlinkHref = false;
|
||||
if (isset($options['force_xlink_href']) && $options['force_xlink_href']) {
|
||||
$forceXlinkHref = true;
|
||||
}
|
||||
|
||||
$this->addLogo($svg, $data['outer_width'], $data['outer_height'], $logoPath, $qrCode->getLogoWidth(), $qrCode->getLogoHeight(), $forceXlinkHref);
|
||||
}
|
||||
|
||||
$xml = $svg->asXML();
|
||||
|
||||
if (!is_string($xml)) {
|
||||
throw new GenerateImageException('Unable to save SVG XML');
|
||||
}
|
||||
|
||||
if (isset($options['exclude_xml_declaration']) && $options['exclude_xml_declaration']) {
|
||||
$xml = str_replace("<?xml version=\"1.0\"?>\n", '', $xml);
|
||||
}
|
||||
|
||||
return $xml;
|
||||
}
|
||||
|
||||
private function addLogo(SimpleXMLElement $svg, int $imageWidth, int $imageHeight, string $logoPath, int $logoWidth = null, int $logoHeight = null, bool $forceXlinkHref = false): void
|
||||
{
|
||||
$mimeType = $this->getMimeType($logoPath);
|
||||
$imageData = file_get_contents($logoPath);
|
||||
|
||||
if (!is_string($imageData)) {
|
||||
throw new GenerateImageException('Unable to read image data: check your logo path');
|
||||
}
|
||||
|
||||
if ('image/svg+xml' === $mimeType && (null === $logoHeight || null === $logoWidth)) {
|
||||
throw new MissingLogoHeightException('SVG Logos require an explicit height set via setLogoSize($width, $height)');
|
||||
}
|
||||
|
||||
if (null === $logoHeight || null === $logoWidth) {
|
||||
$logoImage = imagecreatefromstring(strval($imageData));
|
||||
|
||||
if (!$logoImage) {
|
||||
throw new GenerateImageException('Unable to generate image: check your GD installation or logo path');
|
||||
}
|
||||
|
||||
/** @var mixed $logoImage */
|
||||
$logoSourceWidth = imagesx($logoImage);
|
||||
$logoSourceHeight = imagesy($logoImage);
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
imagedestroy($logoImage);
|
||||
}
|
||||
|
||||
if (null === $logoWidth) {
|
||||
$logoWidth = $logoSourceWidth;
|
||||
}
|
||||
|
||||
if (null === $logoHeight) {
|
||||
$aspectRatio = $logoWidth / $logoSourceWidth;
|
||||
$logoHeight = intval($logoSourceHeight * $aspectRatio);
|
||||
}
|
||||
}
|
||||
|
||||
$logoX = $imageWidth / 2 - $logoWidth / 2;
|
||||
$logoY = $imageHeight / 2 - $logoHeight / 2;
|
||||
|
||||
$imageDefinition = $svg->addChild('image');
|
||||
$imageDefinition->addAttribute('x', strval($logoX));
|
||||
$imageDefinition->addAttribute('y', strval($logoY));
|
||||
$imageDefinition->addAttribute('width', strval($logoWidth));
|
||||
$imageDefinition->addAttribute('height', strval($logoHeight));
|
||||
$imageDefinition->addAttribute('preserveAspectRatio', 'none');
|
||||
|
||||
// xlink:href is actually deprecated, but still required when placing the qr code in a pdf.
|
||||
// SimpleXML strips out the xlink part by using addAttribute(), so it must be set directly.
|
||||
if ($forceXlinkHref) {
|
||||
$imageDefinition['xlink:href'] = 'data:'.$mimeType.';base64,'.base64_encode($imageData);
|
||||
} else {
|
||||
$imageDefinition->addAttribute('href', 'data:'.$mimeType.';base64,'.base64_encode($imageData));
|
||||
}
|
||||
}
|
||||
|
||||
private function getOpacity(int $alpha): float
|
||||
{
|
||||
$opacity = 1 - $alpha / 127;
|
||||
|
||||
return $opacity;
|
||||
}
|
||||
|
||||
public static function getContentType(): string
|
||||
{
|
||||
return 'image/svg+xml';
|
||||
}
|
||||
|
||||
public static function getSupportedExtensions(): array
|
||||
{
|
||||
return ['svg'];
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return 'svg';
|
||||
}
|
||||
}
|
||||
32
vendor/endroid/qr-code/src/Writer/WriterInterface.php
vendored
Normal file
32
vendor/endroid/qr-code/src/Writer/WriterInterface.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
|
||||
interface WriterInterface
|
||||
{
|
||||
public function writeString(QrCodeInterface $qrCode): string;
|
||||
|
||||
public function writeDataUri(QrCodeInterface $qrCode): string;
|
||||
|
||||
public function writeFile(QrCodeInterface $qrCode, string $path): void;
|
||||
|
||||
public static function getContentType(): string;
|
||||
|
||||
public static function supportsExtension(string $extension): bool;
|
||||
|
||||
/** @return array<string> */
|
||||
public static function getSupportedExtensions(): array;
|
||||
|
||||
public function getName(): string;
|
||||
}
|
||||
93
vendor/endroid/qr-code/src/WriterRegistry.php
vendored
Normal file
93
vendor/endroid/qr-code/src/WriterRegistry.php
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode;
|
||||
|
||||
use Endroid\QrCode\Exception\InvalidWriterException;
|
||||
use Endroid\QrCode\Writer\BinaryWriter;
|
||||
use Endroid\QrCode\Writer\DebugWriter;
|
||||
use Endroid\QrCode\Writer\EpsWriter;
|
||||
use Endroid\QrCode\Writer\FpdfWriter;
|
||||
use Endroid\QrCode\Writer\PngWriter;
|
||||
use Endroid\QrCode\Writer\SvgWriter;
|
||||
use Endroid\QrCode\Writer\WriterInterface;
|
||||
|
||||
class WriterRegistry implements WriterRegistryInterface
|
||||
{
|
||||
/** @var WriterInterface[] */
|
||||
private $writers = [];
|
||||
|
||||
/** @var WriterInterface|null */
|
||||
private $defaultWriter;
|
||||
|
||||
public function loadDefaultWriters(): void
|
||||
{
|
||||
if (count($this->writers) > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->addWriters([
|
||||
new BinaryWriter(),
|
||||
new DebugWriter(),
|
||||
new EpsWriter(),
|
||||
new PngWriter(),
|
||||
new SvgWriter(),
|
||||
new FpdfWriter(),
|
||||
]);
|
||||
|
||||
$this->setDefaultWriter('png');
|
||||
}
|
||||
|
||||
public function addWriters(iterable $writers): void
|
||||
{
|
||||
foreach ($writers as $writer) {
|
||||
$this->addWriter($writer);
|
||||
}
|
||||
}
|
||||
|
||||
public function addWriter(WriterInterface $writer): void
|
||||
{
|
||||
$this->writers[$writer->getName()] = $writer;
|
||||
}
|
||||
|
||||
public function getWriter(string $name): WriterInterface
|
||||
{
|
||||
$this->assertValidWriter($name);
|
||||
|
||||
return $this->writers[$name];
|
||||
}
|
||||
|
||||
public function getDefaultWriter(): WriterInterface
|
||||
{
|
||||
if ($this->defaultWriter instanceof WriterInterface) {
|
||||
return $this->defaultWriter;
|
||||
}
|
||||
|
||||
throw new InvalidWriterException('Please set the default writer via the second argument of addWriter');
|
||||
}
|
||||
|
||||
public function setDefaultWriter(string $name): void
|
||||
{
|
||||
$this->defaultWriter = $this->writers[$name];
|
||||
}
|
||||
|
||||
public function getWriters(): array
|
||||
{
|
||||
return $this->writers;
|
||||
}
|
||||
|
||||
private function assertValidWriter(string $name): void
|
||||
{
|
||||
if (!isset($this->writers[$name])) {
|
||||
throw new InvalidWriterException('Invalid writer "'.$name.'"');
|
||||
}
|
||||
}
|
||||
}
|
||||
29
vendor/endroid/qr-code/src/WriterRegistryInterface.php
vendored
Normal file
29
vendor/endroid/qr-code/src/WriterRegistryInterface.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode;
|
||||
|
||||
use Endroid\QrCode\Writer\WriterInterface;
|
||||
|
||||
interface WriterRegistryInterface
|
||||
{
|
||||
/** @param WriterInterface[] $writers */
|
||||
public function addWriters(iterable $writers): void;
|
||||
|
||||
public function addWriter(WriterInterface $writer): void;
|
||||
|
||||
public function getWriter(string $name): WriterInterface;
|
||||
|
||||
public function getDefaultWriter(): WriterInterface;
|
||||
|
||||
/** @return WriterInterface[] */
|
||||
public function getWriters(): array;
|
||||
}
|
||||
296
vendor/endroid/qr-code/tests/QrCodeTest.php
vendored
Normal file
296
vendor/endroid/qr-code/tests/QrCodeTest.php
vendored
Normal file
@@ -0,0 +1,296 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* (c) Jeroen van den Enden <info@endroid.nl>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Endroid\QrCode\Tests;
|
||||
|
||||
use Endroid\QrCode\Exception\GenerateImageException;
|
||||
use Endroid\QrCode\Factory\QrCodeFactory;
|
||||
use Endroid\QrCode\QrCode;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Zxing\QrReader;
|
||||
|
||||
class QrCodeTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider stringProvider
|
||||
* @testdox QR code created with text $text is readable
|
||||
*/
|
||||
public function testReadable(string $text): void
|
||||
{
|
||||
$qrCode = new QrCode();
|
||||
$qrCode->setSize(300);
|
||||
$qrCode->setText($text);
|
||||
$pngData = $qrCode->writeString();
|
||||
$this->assertTrue(is_string($pngData));
|
||||
$reader = new QrReader($pngData, QrReader::SOURCE_TYPE_BLOB);
|
||||
$this->assertEquals($text, $reader->text());
|
||||
}
|
||||
|
||||
public function stringProvider(): array
|
||||
{
|
||||
return [
|
||||
['Tiny'],
|
||||
['This one has spaces'],
|
||||
['d2llMS9uU01BVmlvalM2YU9BUFBPTTdQMmJabHpqdndt'],
|
||||
['http://this.is.an/url?with=query&string=attached'],
|
||||
['11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111'],
|
||||
['{"i":"serialized.data","v":1,"t":1,"d":"4AEPc9XuIQ0OjsZoSRWp9DRWlN6UyDvuMlyOYy8XjOw="}'],
|
||||
['Spëci&al ch@ract3rs'],
|
||||
['有限公司'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider writerNameProvider
|
||||
* @testdox Writer set by name $writerName results in the correct data type
|
||||
*/
|
||||
public function testWriteQrCodeByWriterName(string $writerName, ?string $fileContent): void
|
||||
{
|
||||
$qrCode = new QrCode('QR Code');
|
||||
$qrCode->setLogoPath(__DIR__.'/../assets/images/symfony.png');
|
||||
$qrCode->setLogoWidth(100);
|
||||
|
||||
$qrCode->setWriterByName($writerName);
|
||||
$data = $qrCode->writeString();
|
||||
$this->assertTrue(is_string($data));
|
||||
|
||||
if (null !== $fileContent) {
|
||||
$uriData = $qrCode->writeDataUri();
|
||||
$this->assertTrue(0 === strpos($uriData, $fileContent));
|
||||
}
|
||||
}
|
||||
|
||||
public function writerNameProvider(): array
|
||||
{
|
||||
return [
|
||||
['binary', null],
|
||||
['debug', null],
|
||||
['eps', null],
|
||||
['png', 'data:image/png;base64'],
|
||||
['svg', 'data:image/svg+xml;base64'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider extensionsProvider
|
||||
* @testdox Writer set by extension $extension results in the correct data type
|
||||
*/
|
||||
public function testWriteQrCodeByWriterExtension(string $extension, ?string $fileContent): void
|
||||
{
|
||||
$qrCode = new QrCode('QR Code');
|
||||
$qrCode->setLogoPath(__DIR__.'/../assets/images/symfony.png');
|
||||
$qrCode->setLogoWidth(100);
|
||||
|
||||
$qrCode->setWriterByExtension($extension);
|
||||
$data = $qrCode->writeString();
|
||||
$this->assertTrue(is_string($data));
|
||||
|
||||
if (null !== $fileContent) {
|
||||
$uriData = $qrCode->writeDataUri();
|
||||
$this->assertTrue(0 === strpos($uriData, $fileContent));
|
||||
}
|
||||
}
|
||||
|
||||
public function extensionsProvider(): array
|
||||
{
|
||||
return [
|
||||
['bin', null],
|
||||
['txt', null],
|
||||
['eps', null],
|
||||
['png', 'data:image/png;base64'],
|
||||
['svg', 'data:image/svg+xml;base64'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox Factory creates a valid QR code
|
||||
*/
|
||||
public function testFactory(): void
|
||||
{
|
||||
$qrCodeFactory = new QrCodeFactory();
|
||||
$qrCode = $qrCodeFactory->create('QR Code', [
|
||||
'writer' => 'png',
|
||||
'size' => 300,
|
||||
'margin' => 10,
|
||||
'round_block_size_mode' => 'shrink',
|
||||
]);
|
||||
|
||||
$pngData = $qrCode->writeString();
|
||||
$this->assertTrue(is_string($pngData));
|
||||
$reader = new QrReader($pngData, QrReader::SOURCE_TYPE_BLOB);
|
||||
$this->assertEquals('QR Code', $reader->text());
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox Size and margin are handled correctly
|
||||
*/
|
||||
public function testSetSize(): void
|
||||
{
|
||||
$size = 400;
|
||||
$margin = 10;
|
||||
|
||||
$qrCode = new QrCode('QR Code');
|
||||
$qrCode->setSize($size);
|
||||
$qrCode->setMargin($margin);
|
||||
|
||||
$pngData = $qrCode->writeString();
|
||||
$image = imagecreatefromstring($pngData);
|
||||
|
||||
$this->assertTrue(imagesx($image) === $size + 2 * $margin);
|
||||
$this->assertTrue(imagesy($image) === $size + 2 * $margin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox Size and margin are handled correctly with rounded blocks
|
||||
* @dataProvider roundedSizeProvider
|
||||
*/
|
||||
public function testSetSizeRounded($size, $margin, $round, $mode, $expectedSize): void
|
||||
{
|
||||
$qrCode = new QrCode('QR Code contents with some length to have some data');
|
||||
$qrCode->setRoundBlockSize($round, $mode);
|
||||
$qrCode->setSize($size);
|
||||
$qrCode->setMargin($margin);
|
||||
|
||||
$pngData = $qrCode->writeString();
|
||||
$image = imagecreatefromstring($pngData);
|
||||
|
||||
$this->assertTrue(imagesx($image) === $expectedSize);
|
||||
$this->assertTrue(imagesy($image) === $expectedSize);
|
||||
}
|
||||
|
||||
public function roundedSizeProvider()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'size' => 400,
|
||||
'margin' => 0,
|
||||
'round' => true,
|
||||
'mode' => QrCode::ROUND_BLOCK_SIZE_MODE_ENLARGE,
|
||||
'expectedSize' => 406,
|
||||
],
|
||||
[
|
||||
'size' => 400,
|
||||
'margin' => 5,
|
||||
'round' => true,
|
||||
'mode' => QrCode::ROUND_BLOCK_SIZE_MODE_ENLARGE,
|
||||
'expectedSize' => 416,
|
||||
],
|
||||
[
|
||||
'size' => 400,
|
||||
'margin' => 0,
|
||||
'round' => true,
|
||||
'mode' => QrCode::ROUND_BLOCK_SIZE_MODE_MARGIN,
|
||||
'expectedSize' => 400,
|
||||
],
|
||||
[
|
||||
'size' => 400,
|
||||
'margin' => 5,
|
||||
'round' => true,
|
||||
'mode' => QrCode::ROUND_BLOCK_SIZE_MODE_MARGIN,
|
||||
'expectedSize' => 410,
|
||||
],
|
||||
[
|
||||
'size' => 400,
|
||||
'margin' => 0,
|
||||
'round' => true,
|
||||
'mode' => QrCode::ROUND_BLOCK_SIZE_MODE_SHRINK,
|
||||
'expectedSize' => 377,
|
||||
],
|
||||
[
|
||||
'size' => 400,
|
||||
'margin' => 5,
|
||||
'round' => true,
|
||||
'mode' => QrCode::ROUND_BLOCK_SIZE_MODE_SHRINK,
|
||||
'expectedSize' => 387,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox Label can be added and QR code is still readable
|
||||
*/
|
||||
public function testSetLabel(): void
|
||||
{
|
||||
$qrCode = new QrCode('QR Code');
|
||||
$qrCode->setSize(300);
|
||||
$qrCode->setLabel('Scan the code', 15);
|
||||
|
||||
$pngData = $qrCode->writeString();
|
||||
$this->assertTrue(is_string($pngData));
|
||||
$reader = new QrReader($pngData, QrReader::SOURCE_TYPE_BLOB);
|
||||
$this->assertEquals('QR Code', $reader->text());
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox Logo can be added and QR code is still readable
|
||||
*/
|
||||
public function testSetLogo(): void
|
||||
{
|
||||
$qrCode = new QrCode('QR Code');
|
||||
$qrCode->setSize(500);
|
||||
$qrCode->setLogoPath(__DIR__.'/../assets/images/symfony.png');
|
||||
$qrCode->setLogoWidth(100);
|
||||
$qrCode->setValidateResult(true);
|
||||
|
||||
$pngData = $qrCode->writeString();
|
||||
$this->assertTrue(is_string($pngData));
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox Resulting QR code can be written to file
|
||||
*/
|
||||
public function testWriteFile(): void
|
||||
{
|
||||
$filename = __DIR__.'/output/qr-code.png';
|
||||
|
||||
$qrCode = new QrCode('QR Code');
|
||||
$qrCode->writeFile($filename);
|
||||
|
||||
$image = imagecreatefromstring(file_get_contents($filename));
|
||||
|
||||
$this->assertTrue(false !== $image);
|
||||
|
||||
imagedestroy($image);
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox QR code data can be retrieved
|
||||
*/
|
||||
public function testData(): void
|
||||
{
|
||||
$qrCode = new QrCode('QR Code');
|
||||
|
||||
$data = $qrCode->getData();
|
||||
|
||||
$this->assertArrayHasKey('block_count', $data);
|
||||
$this->assertArrayHasKey('block_size', $data);
|
||||
$this->assertArrayHasKey('inner_width', $data);
|
||||
$this->assertArrayHasKey('inner_height', $data);
|
||||
$this->assertArrayHasKey('outer_width', $data);
|
||||
$this->assertArrayHasKey('outer_height', $data);
|
||||
$this->assertArrayHasKey('margin_left', $data);
|
||||
$this->assertArrayHasKey('margin_right', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox Invalid image data results in appropriate exception
|
||||
*/
|
||||
public function testNonImageData(): void
|
||||
{
|
||||
$qrCode = new QrCode('QR Code');
|
||||
$qrCode->setLogoPath(__DIR__.'/QrCodeTest.php');
|
||||
$qrCode->setLogoSize(200, 200);
|
||||
$qrCode->setWriterByExtension('svg');
|
||||
|
||||
$this->expectException(GenerateImageException::class);
|
||||
$qrCode->writeString();
|
||||
}
|
||||
}
|
||||
2
vendor/endroid/qr-code/tests/output/.gitignore
vendored
Normal file
2
vendor/endroid/qr-code/tests/output/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/*
|
||||
!/.gitignore
|
||||
Reference in New Issue
Block a user