first commit
This commit is contained in:
30
vendor/endroid/qr-code/src/Bacon/ErrorCorrectionLevelConverter.php
vendored
Normal file
30
vendor/endroid/qr-code/src/Bacon/ErrorCorrectionLevelConverter.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Bacon;
|
||||
|
||||
use BaconQrCode\Common\ErrorCorrectionLevel;
|
||||
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelHigh;
|
||||
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelInterface;
|
||||
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelLow;
|
||||
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelMedium;
|
||||
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelQuartile;
|
||||
|
||||
final class ErrorCorrectionLevelConverter
|
||||
{
|
||||
public static function convertToBaconErrorCorrectionLevel(ErrorCorrectionLevelInterface $errorCorrectionLevel): ErrorCorrectionLevel
|
||||
{
|
||||
if ($errorCorrectionLevel instanceof ErrorCorrectionLevelLow) {
|
||||
return ErrorCorrectionLevel::valueOf('L');
|
||||
} elseif ($errorCorrectionLevel instanceof ErrorCorrectionLevelMedium) {
|
||||
return ErrorCorrectionLevel::valueOf('M');
|
||||
} elseif ($errorCorrectionLevel instanceof ErrorCorrectionLevelQuartile) {
|
||||
return ErrorCorrectionLevel::valueOf('Q');
|
||||
} elseif ($errorCorrectionLevel instanceof ErrorCorrectionLevelHigh) {
|
||||
return ErrorCorrectionLevel::valueOf('H');
|
||||
}
|
||||
|
||||
throw new \Exception('Error correction level could not be converted');
|
||||
}
|
||||
}
|
||||
32
vendor/endroid/qr-code/src/Bacon/MatrixFactory.php
vendored
Normal file
32
vendor/endroid/qr-code/src/Bacon/MatrixFactory.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Bacon;
|
||||
|
||||
use BaconQrCode\Encoder\Encoder;
|
||||
use Endroid\QrCode\Matrix\Matrix;
|
||||
use Endroid\QrCode\Matrix\MatrixFactoryInterface;
|
||||
use Endroid\QrCode\Matrix\MatrixInterface;
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
|
||||
final class MatrixFactory implements MatrixFactoryInterface
|
||||
{
|
||||
public function create(QrCodeInterface $qrCode): MatrixInterface
|
||||
{
|
||||
$baconErrorCorrectionLevel = ErrorCorrectionLevelConverter::convertToBaconErrorCorrectionLevel($qrCode->getErrorCorrectionLevel());
|
||||
$baconMatrix = Encoder::encode($qrCode->getData(), $baconErrorCorrectionLevel, strval($qrCode->getEncoding()))->getMatrix();
|
||||
|
||||
$blockValues = [];
|
||||
$columnCount = $baconMatrix->getWidth();
|
||||
$rowCount = $baconMatrix->getHeight();
|
||||
for ($rowIndex = 0; $rowIndex < $rowCount; ++$rowIndex) {
|
||||
$blockValues[$rowIndex] = [];
|
||||
for ($columnIndex = 0; $columnIndex < $columnCount; ++$columnIndex) {
|
||||
$blockValues[$rowIndex][$columnIndex] = $baconMatrix->get($columnIndex, $rowIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return new Matrix($blockValues, $qrCode->getSize(), $qrCode->getMargin(), $qrCode->getRoundBlockSizeMode());
|
||||
}
|
||||
}
|
||||
279
vendor/endroid/qr-code/src/Builder/Builder.php
vendored
Normal file
279
vendor/endroid/qr-code/src/Builder/Builder.php
vendored
Normal file
@@ -0,0 +1,279 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Builder;
|
||||
|
||||
use Endroid\QrCode\Color\ColorInterface;
|
||||
use Endroid\QrCode\Encoding\EncodingInterface;
|
||||
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelInterface;
|
||||
use Endroid\QrCode\Exception\ValidationException;
|
||||
use Endroid\QrCode\Label\Alignment\LabelAlignmentInterface;
|
||||
use Endroid\QrCode\Label\Font\FontInterface;
|
||||
use Endroid\QrCode\Label\Label;
|
||||
use Endroid\QrCode\Label\LabelInterface;
|
||||
use Endroid\QrCode\Label\Margin\MarginInterface;
|
||||
use Endroid\QrCode\Logo\Logo;
|
||||
use Endroid\QrCode\Logo\LogoInterface;
|
||||
use Endroid\QrCode\QrCode;
|
||||
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeInterface;
|
||||
use Endroid\QrCode\Writer\PngWriter;
|
||||
use Endroid\QrCode\Writer\Result\ResultInterface;
|
||||
use Endroid\QrCode\Writer\ValidatingWriterInterface;
|
||||
use Endroid\QrCode\Writer\WriterInterface;
|
||||
|
||||
class Builder implements BuilderInterface
|
||||
{
|
||||
/**
|
||||
* @var array<string, mixed>{
|
||||
* data: string,
|
||||
* writer: WriterInterface,
|
||||
* writerOptions: array,
|
||||
* qrCodeClass: class-string,
|
||||
* logoClass: class-string,
|
||||
* labelClass: class-string,
|
||||
* validateResult: bool,
|
||||
* size?: int,
|
||||
* encoding?: EncodingInterface,
|
||||
* errorCorrectionLevel?: ErrorCorrectionLevelInterface,
|
||||
* roundBlockSizeMode?: RoundBlockSizeModeInterface,
|
||||
* margin?: int,
|
||||
* backgroundColor?: ColorInterface,
|
||||
* foregroundColor?: ColorInterface,
|
||||
* labelText?: string,
|
||||
* labelFont?: FontInterface,
|
||||
* labelAlignment?: LabelAlignmentInterface,
|
||||
* labelMargin?: MarginInterface,
|
||||
* labelTextColor?: ColorInterface,
|
||||
* logoPath?: string,
|
||||
* logoResizeToWidth?: int,
|
||||
* logoResizeToHeight?: int,
|
||||
* logoPunchoutBackground?: bool
|
||||
* }
|
||||
*/
|
||||
private array $options;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->options = [
|
||||
'data' => '',
|
||||
'writer' => new PngWriter(),
|
||||
'writerOptions' => [],
|
||||
'qrCodeClass' => QrCode::class,
|
||||
'logoClass' => Logo::class,
|
||||
'labelClass' => Label::class,
|
||||
'validateResult' => false,
|
||||
];
|
||||
}
|
||||
|
||||
public static function create(): BuilderInterface
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
public function writer(WriterInterface $writer): BuilderInterface
|
||||
{
|
||||
$this->options['writer'] = $writer;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $writerOptions */
|
||||
public function writerOptions(array $writerOptions): BuilderInterface
|
||||
{
|
||||
$this->options['writerOptions'] = $writerOptions;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function data(string $data): BuilderInterface
|
||||
{
|
||||
$this->options['data'] = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function encoding(EncodingInterface $encoding): BuilderInterface
|
||||
{
|
||||
$this->options['encoding'] = $encoding;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function errorCorrectionLevel(ErrorCorrectionLevelInterface $errorCorrectionLevel): BuilderInterface
|
||||
{
|
||||
$this->options['errorCorrectionLevel'] = $errorCorrectionLevel;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function size(int $size): BuilderInterface
|
||||
{
|
||||
$this->options['size'] = $size;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function margin(int $margin): BuilderInterface
|
||||
{
|
||||
$this->options['margin'] = $margin;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function roundBlockSizeMode(RoundBlockSizeModeInterface $roundBlockSizeMode): BuilderInterface
|
||||
{
|
||||
$this->options['roundBlockSizeMode'] = $roundBlockSizeMode;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function foregroundColor(ColorInterface $foregroundColor): BuilderInterface
|
||||
{
|
||||
$this->options['foregroundColor'] = $foregroundColor;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function backgroundColor(ColorInterface $backgroundColor): BuilderInterface
|
||||
{
|
||||
$this->options['backgroundColor'] = $backgroundColor;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function logoPath(string $logoPath): BuilderInterface
|
||||
{
|
||||
$this->options['logoPath'] = $logoPath;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function logoResizeToWidth(int $logoResizeToWidth): BuilderInterface
|
||||
{
|
||||
$this->options['logoResizeToWidth'] = $logoResizeToWidth;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function logoResizeToHeight(int $logoResizeToHeight): BuilderInterface
|
||||
{
|
||||
$this->options['logoResizeToHeight'] = $logoResizeToHeight;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function logoPunchoutBackground(bool $logoPunchoutBackground): BuilderInterface
|
||||
{
|
||||
$this->options['logoPunchoutBackground'] = $logoPunchoutBackground;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function labelText(string $labelText): BuilderInterface
|
||||
{
|
||||
$this->options['labelText'] = $labelText;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function labelFont(FontInterface $labelFont): BuilderInterface
|
||||
{
|
||||
$this->options['labelFont'] = $labelFont;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function labelAlignment(LabelAlignmentInterface $labelAlignment): BuilderInterface
|
||||
{
|
||||
$this->options['labelAlignment'] = $labelAlignment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function labelMargin(MarginInterface $labelMargin): BuilderInterface
|
||||
{
|
||||
$this->options['labelMargin'] = $labelMargin;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function labelTextColor(ColorInterface $labelTextColor): BuilderInterface
|
||||
{
|
||||
$this->options['labelTextColor'] = $labelTextColor;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function validateResult(bool $validateResult): BuilderInterface
|
||||
{
|
||||
$this->options['validateResult'] = $validateResult;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function build(): ResultInterface
|
||||
{
|
||||
$writer = $this->options['writer'];
|
||||
|
||||
if ($this->options['validateResult'] && !$writer instanceof ValidatingWriterInterface) {
|
||||
throw ValidationException::createForUnsupportedWriter(strval(get_class($writer)));
|
||||
}
|
||||
|
||||
/** @var QrCode $qrCode */
|
||||
$qrCode = $this->buildObject($this->options['qrCodeClass']);
|
||||
|
||||
/** @var LogoInterface|null $logo */
|
||||
$logo = $this->buildObject($this->options['logoClass'], 'logo');
|
||||
|
||||
/** @var LabelInterface|null $label */
|
||||
$label = $this->buildObject($this->options['labelClass'], 'label');
|
||||
|
||||
$result = $writer->write($qrCode, $logo, $label, $this->options['writerOptions']);
|
||||
|
||||
if ($this->options['validateResult'] && $writer instanceof ValidatingWriterInterface) {
|
||||
$writer->validateResult($result, $qrCode->getData());
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param class-string $class
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function buildObject(string $class, string|null $optionsPrefix = null)
|
||||
{
|
||||
/** @var \ReflectionClass<object> $reflectionClass */
|
||||
$reflectionClass = new \ReflectionClass($class);
|
||||
|
||||
$arguments = [];
|
||||
$hasBuilderOptions = false;
|
||||
$missingRequiredArguments = [];
|
||||
/** @var \ReflectionMethod $constructor */
|
||||
$constructor = $reflectionClass->getConstructor();
|
||||
$constructorParameters = $constructor->getParameters();
|
||||
foreach ($constructorParameters as $parameter) {
|
||||
$optionName = null === $optionsPrefix ? $parameter->getName() : $optionsPrefix.ucfirst($parameter->getName());
|
||||
if (isset($this->options[$optionName])) {
|
||||
$hasBuilderOptions = true;
|
||||
$arguments[] = $this->options[$optionName];
|
||||
} elseif ($parameter->isDefaultValueAvailable()) {
|
||||
$arguments[] = $parameter->getDefaultValue();
|
||||
} else {
|
||||
$missingRequiredArguments[] = $optionName;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$hasBuilderOptions) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (count($missingRequiredArguments) > 0) {
|
||||
throw new \Exception(sprintf('Missing required arguments: %s', implode(', ', $missingRequiredArguments)));
|
||||
}
|
||||
|
||||
return $reflectionClass->newInstanceArgs($arguments);
|
||||
}
|
||||
}
|
||||
63
vendor/endroid/qr-code/src/Builder/BuilderInterface.php
vendored
Normal file
63
vendor/endroid/qr-code/src/Builder/BuilderInterface.php
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Builder;
|
||||
|
||||
use Endroid\QrCode\Color\ColorInterface;
|
||||
use Endroid\QrCode\Encoding\EncodingInterface;
|
||||
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelInterface;
|
||||
use Endroid\QrCode\Label\Alignment\LabelAlignmentInterface;
|
||||
use Endroid\QrCode\Label\Font\FontInterface;
|
||||
use Endroid\QrCode\Label\Margin\MarginInterface;
|
||||
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeInterface;
|
||||
use Endroid\QrCode\Writer\Result\ResultInterface;
|
||||
use Endroid\QrCode\Writer\WriterInterface;
|
||||
|
||||
interface BuilderInterface
|
||||
{
|
||||
public static function create(): BuilderInterface;
|
||||
|
||||
public function writer(WriterInterface $writer): BuilderInterface;
|
||||
|
||||
/** @param array<string, mixed> $writerOptions */
|
||||
public function writerOptions(array $writerOptions): BuilderInterface;
|
||||
|
||||
public function data(string $data): BuilderInterface;
|
||||
|
||||
public function encoding(EncodingInterface $encoding): BuilderInterface;
|
||||
|
||||
public function errorCorrectionLevel(ErrorCorrectionLevelInterface $errorCorrectionLevel): BuilderInterface;
|
||||
|
||||
public function size(int $size): BuilderInterface;
|
||||
|
||||
public function margin(int $margin): BuilderInterface;
|
||||
|
||||
public function roundBlockSizeMode(RoundBlockSizeModeInterface $roundBlockSizeMode): BuilderInterface;
|
||||
|
||||
public function foregroundColor(ColorInterface $foregroundColor): BuilderInterface;
|
||||
|
||||
public function backgroundColor(ColorInterface $backgroundColor): BuilderInterface;
|
||||
|
||||
public function logoPath(string $logoPath): BuilderInterface;
|
||||
|
||||
public function logoResizeToWidth(int $logoResizeToWidth): BuilderInterface;
|
||||
|
||||
public function logoResizeToHeight(int $logoResizeToHeight): BuilderInterface;
|
||||
|
||||
public function logoPunchoutBackground(bool $logoPunchoutBackground): BuilderInterface;
|
||||
|
||||
public function labelText(string $labelText): BuilderInterface;
|
||||
|
||||
public function labelFont(FontInterface $labelFont): BuilderInterface;
|
||||
|
||||
public function labelAlignment(LabelAlignmentInterface $labelAlignment): BuilderInterface;
|
||||
|
||||
public function labelMargin(MarginInterface $labelMargin): BuilderInterface;
|
||||
|
||||
public function labelTextColor(ColorInterface $labelTextColor): BuilderInterface;
|
||||
|
||||
public function validateResult(bool $validateResult): BuilderInterface;
|
||||
|
||||
public function build(): ResultInterface;
|
||||
}
|
||||
25
vendor/endroid/qr-code/src/Builder/BuilderRegistry.php
vendored
Normal file
25
vendor/endroid/qr-code/src/Builder/BuilderRegistry.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Builder;
|
||||
|
||||
final class BuilderRegistry implements BuilderRegistryInterface
|
||||
{
|
||||
/** @var array<BuilderInterface> */
|
||||
private array $builders = [];
|
||||
|
||||
public function getBuilder(string $name): BuilderInterface
|
||||
{
|
||||
if (!isset($this->builders[$name])) {
|
||||
throw new \Exception(sprintf('Builder with name "%s" not available from registry', $name));
|
||||
}
|
||||
|
||||
return $this->builders[$name];
|
||||
}
|
||||
|
||||
public function addBuilder(string $name, BuilderInterface $builder): void
|
||||
{
|
||||
$this->builders[$name] = $builder;
|
||||
}
|
||||
}
|
||||
12
vendor/endroid/qr-code/src/Builder/BuilderRegistryInterface.php
vendored
Normal file
12
vendor/endroid/qr-code/src/Builder/BuilderRegistryInterface.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Builder;
|
||||
|
||||
interface BuilderRegistryInterface
|
||||
{
|
||||
public function getBuilder(string $name): BuilderInterface;
|
||||
|
||||
public function addBuilder(string $name, BuilderInterface $builder): void;
|
||||
}
|
||||
56
vendor/endroid/qr-code/src/Color/Color.php
vendored
Normal file
56
vendor/endroid/qr-code/src/Color/Color.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Color;
|
||||
|
||||
final class Color implements ColorInterface
|
||||
{
|
||||
public function __construct(
|
||||
private int $red,
|
||||
private int $green,
|
||||
private int $blue,
|
||||
private int $alpha = 0
|
||||
) {
|
||||
}
|
||||
|
||||
public function getRed(): int
|
||||
{
|
||||
return $this->red;
|
||||
}
|
||||
|
||||
public function getGreen(): int
|
||||
{
|
||||
return $this->green;
|
||||
}
|
||||
|
||||
public function getBlue(): int
|
||||
{
|
||||
return $this->blue;
|
||||
}
|
||||
|
||||
public function getAlpha(): int
|
||||
{
|
||||
return $this->alpha;
|
||||
}
|
||||
|
||||
public function getOpacity(): float
|
||||
{
|
||||
return 1 - $this->alpha / 127;
|
||||
}
|
||||
|
||||
public function getHex(): string
|
||||
{
|
||||
return sprintf('#%02x%02x%02x', $this->red, $this->green, $this->blue);
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'red' => $this->red,
|
||||
'green' => $this->green,
|
||||
'blue' => $this->blue,
|
||||
'alpha' => $this->alpha,
|
||||
];
|
||||
}
|
||||
}
|
||||
23
vendor/endroid/qr-code/src/Color/ColorInterface.php
vendored
Normal file
23
vendor/endroid/qr-code/src/Color/ColorInterface.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Color;
|
||||
|
||||
interface ColorInterface
|
||||
{
|
||||
public function getRed(): int;
|
||||
|
||||
public function getGreen(): int;
|
||||
|
||||
public function getBlue(): int;
|
||||
|
||||
public function getAlpha(): int;
|
||||
|
||||
public function getOpacity(): float;
|
||||
|
||||
public function getHex(): string;
|
||||
|
||||
/** @return array<string, int> */
|
||||
public function toArray(): array;
|
||||
}
|
||||
21
vendor/endroid/qr-code/src/Encoding/Encoding.php
vendored
Normal file
21
vendor/endroid/qr-code/src/Encoding/Encoding.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Encoding;
|
||||
|
||||
final class Encoding implements EncodingInterface
|
||||
{
|
||||
public function __construct(
|
||||
private string $value
|
||||
) {
|
||||
if (!in_array($value, mb_list_encodings())) {
|
||||
throw new \Exception(sprintf('Invalid encoding "%s"', $value));
|
||||
}
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
||||
10
vendor/endroid/qr-code/src/Encoding/EncodingInterface.php
vendored
Normal file
10
vendor/endroid/qr-code/src/Encoding/EncodingInterface.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Encoding;
|
||||
|
||||
interface EncodingInterface
|
||||
{
|
||||
public function __toString(): string;
|
||||
}
|
||||
9
vendor/endroid/qr-code/src/ErrorCorrectionLevel/ErrorCorrectionLevelHigh.php
vendored
Normal file
9
vendor/endroid/qr-code/src/ErrorCorrectionLevel/ErrorCorrectionLevelHigh.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\ErrorCorrectionLevel;
|
||||
|
||||
final class ErrorCorrectionLevelHigh implements ErrorCorrectionLevelInterface
|
||||
{
|
||||
}
|
||||
9
vendor/endroid/qr-code/src/ErrorCorrectionLevel/ErrorCorrectionLevelInterface.php
vendored
Normal file
9
vendor/endroid/qr-code/src/ErrorCorrectionLevel/ErrorCorrectionLevelInterface.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\ErrorCorrectionLevel;
|
||||
|
||||
interface ErrorCorrectionLevelInterface
|
||||
{
|
||||
}
|
||||
9
vendor/endroid/qr-code/src/ErrorCorrectionLevel/ErrorCorrectionLevelLow.php
vendored
Normal file
9
vendor/endroid/qr-code/src/ErrorCorrectionLevel/ErrorCorrectionLevelLow.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\ErrorCorrectionLevel;
|
||||
|
||||
final class ErrorCorrectionLevelLow implements ErrorCorrectionLevelInterface
|
||||
{
|
||||
}
|
||||
9
vendor/endroid/qr-code/src/ErrorCorrectionLevel/ErrorCorrectionLevelMedium.php
vendored
Normal file
9
vendor/endroid/qr-code/src/ErrorCorrectionLevel/ErrorCorrectionLevelMedium.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\ErrorCorrectionLevel;
|
||||
|
||||
final class ErrorCorrectionLevelMedium implements ErrorCorrectionLevelInterface
|
||||
{
|
||||
}
|
||||
9
vendor/endroid/qr-code/src/ErrorCorrectionLevel/ErrorCorrectionLevelQuartile.php
vendored
Normal file
9
vendor/endroid/qr-code/src/ErrorCorrectionLevel/ErrorCorrectionLevelQuartile.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\ErrorCorrectionLevel;
|
||||
|
||||
final class ErrorCorrectionLevelQuartile implements ErrorCorrectionLevelInterface
|
||||
{
|
||||
}
|
||||
23
vendor/endroid/qr-code/src/Exception/ValidationException.php
vendored
Normal file
23
vendor/endroid/qr-code/src/Exception/ValidationException.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Exception;
|
||||
|
||||
final class ValidationException extends \Exception
|
||||
{
|
||||
public static function createForUnsupportedWriter(string $writerClass): self
|
||||
{
|
||||
return new self(sprintf('Unable to validate the result: "%s" does not support validation', $writerClass));
|
||||
}
|
||||
|
||||
public static function createForMissingPackage(string $packageName): self
|
||||
{
|
||||
return new self(sprintf('Please install "%s" or disable image validation', $packageName));
|
||||
}
|
||||
|
||||
public static function createForInvalidData(string $expectedData, string $actualData): self
|
||||
{
|
||||
return new self('The validation reader read "'.$actualData.'" instead of "'.$expectedData.'". Adjust your parameters to increase readability or disable validation.');
|
||||
}
|
||||
}
|
||||
48
vendor/endroid/qr-code/src/ImageData/LabelImageData.php
vendored
Normal file
48
vendor/endroid/qr-code/src/ImageData/LabelImageData.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\ImageData;
|
||||
|
||||
use Endroid\QrCode\Label\LabelInterface;
|
||||
|
||||
class LabelImageData
|
||||
{
|
||||
private function __construct(
|
||||
private int $width,
|
||||
private int $height
|
||||
) {
|
||||
}
|
||||
|
||||
public static function createForLabel(LabelInterface $label): self
|
||||
{
|
||||
if (false !== strpos($label->getText(), "\n")) {
|
||||
throw new \Exception('Label does not support line breaks');
|
||||
}
|
||||
|
||||
if (!function_exists('imagettfbbox')) {
|
||||
throw new \Exception('Function "imagettfbbox" does not exist: check your FreeType installation');
|
||||
}
|
||||
|
||||
$labelBox = imagettfbbox($label->getFont()->getSize(), 0, $label->getFont()->getPath(), $label->getText());
|
||||
|
||||
if (!is_array($labelBox)) {
|
||||
throw new \Exception('Unable to generate label image box: check your FreeType installation');
|
||||
}
|
||||
|
||||
return new self(
|
||||
intval($labelBox[2] - $labelBox[0]),
|
||||
intval($labelBox[0] - $labelBox[7])
|
||||
);
|
||||
}
|
||||
|
||||
public function getWidth(): int
|
||||
{
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
public function getHeight(): int
|
||||
{
|
||||
return $this->height;
|
||||
}
|
||||
}
|
||||
143
vendor/endroid/qr-code/src/ImageData/LogoImageData.php
vendored
Normal file
143
vendor/endroid/qr-code/src/ImageData/LogoImageData.php
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\ImageData;
|
||||
|
||||
use Endroid\QrCode\Logo\LogoInterface;
|
||||
|
||||
class LogoImageData
|
||||
{
|
||||
private function __construct(
|
||||
private string $data,
|
||||
private \GdImage|null $image,
|
||||
private string $mimeType,
|
||||
private int $width,
|
||||
private int $height,
|
||||
private bool $punchoutBackground
|
||||
) {
|
||||
}
|
||||
|
||||
public static function createForLogo(LogoInterface $logo): self
|
||||
{
|
||||
$data = @file_get_contents($logo->getPath());
|
||||
|
||||
if (!is_string($data)) {
|
||||
throw new \Exception(sprintf('Invalid data at path "%s"', $logo->getPath()));
|
||||
}
|
||||
|
||||
if (false !== filter_var($logo->getPath(), FILTER_VALIDATE_URL)) {
|
||||
$mimeType = self::detectMimeTypeFromUrl($logo->getPath());
|
||||
} else {
|
||||
$mimeType = self::detectMimeTypeFromPath($logo->getPath());
|
||||
}
|
||||
|
||||
$width = $logo->getResizeToWidth();
|
||||
$height = $logo->getResizeToHeight();
|
||||
|
||||
if ('image/svg+xml' === $mimeType) {
|
||||
if (null === $width || null === $height) {
|
||||
throw new \Exception('SVG Logos require an explicitly set resize width and height');
|
||||
}
|
||||
|
||||
return new self($data, null, $mimeType, $width, $height, $logo->getPunchoutBackground());
|
||||
}
|
||||
|
||||
$image = @imagecreatefromstring($data);
|
||||
|
||||
if (!$image) {
|
||||
throw new \Exception(sprintf('Unable to parse image data at path "%s"', $logo->getPath()));
|
||||
}
|
||||
|
||||
// No target width and height specified: use from original image
|
||||
if (null !== $width && null !== $height) {
|
||||
return new self($data, $image, $mimeType, $width, $height, $logo->getPunchoutBackground());
|
||||
}
|
||||
|
||||
// Only target width specified: calculate height
|
||||
if (null !== $width && null === $height) {
|
||||
return new self($data, $image, $mimeType, $width, intval(imagesy($image) * $width / imagesx($image)), $logo->getPunchoutBackground());
|
||||
}
|
||||
|
||||
// Only target height specified: calculate width
|
||||
if (null === $width && null !== $height) {
|
||||
return new self($data, $image, $mimeType, intval(imagesx($image) * $height / imagesy($image)), $height, $logo->getPunchoutBackground());
|
||||
}
|
||||
|
||||
return new self($data, $image, $mimeType, imagesx($image), imagesy($image), $logo->getPunchoutBackground());
|
||||
}
|
||||
|
||||
public function getData(): string
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
public function getImage(): \GdImage
|
||||
{
|
||||
if (!$this->image instanceof \GdImage) {
|
||||
throw new \Exception('SVG Images have no image resource');
|
||||
}
|
||||
|
||||
return $this->image;
|
||||
}
|
||||
|
||||
public function getMimeType(): string
|
||||
{
|
||||
return $this->mimeType;
|
||||
}
|
||||
|
||||
public function getWidth(): int
|
||||
{
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
public function getHeight(): int
|
||||
{
|
||||
return $this->height;
|
||||
}
|
||||
|
||||
public function getPunchoutBackground(): bool
|
||||
{
|
||||
return $this->punchoutBackground;
|
||||
}
|
||||
|
||||
public function createDataUri(): string
|
||||
{
|
||||
return 'data:'.$this->mimeType.';base64,'.base64_encode($this->data);
|
||||
}
|
||||
|
||||
private static function detectMimeTypeFromUrl(string $url): string
|
||||
{
|
||||
$headers = get_headers($url, true);
|
||||
|
||||
if (!is_array($headers) || !isset($headers['Content-Type'])) {
|
||||
throw new \Exception(sprintf('Content type could not be determined for logo URL "%s"', $url));
|
||||
}
|
||||
|
||||
return is_array($headers['Content-Type']) ? $headers['Content-Type'][1] : $headers['Content-Type'];
|
||||
}
|
||||
|
||||
private static function detectMimeTypeFromPath(string $path): string
|
||||
{
|
||||
if (!function_exists('mime_content_type')) {
|
||||
throw new \Exception('You need the ext-fileinfo extension to determine logo mime type');
|
||||
}
|
||||
|
||||
$mimeType = @mime_content_type($path);
|
||||
|
||||
if (!is_string($mimeType)) {
|
||||
throw new \Exception('Could not determine mime type');
|
||||
}
|
||||
|
||||
if (!preg_match('#^image/#', $mimeType)) {
|
||||
throw new \Exception('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;
|
||||
}
|
||||
}
|
||||
9
vendor/endroid/qr-code/src/Label/Alignment/LabelAlignmentCenter.php
vendored
Normal file
9
vendor/endroid/qr-code/src/Label/Alignment/LabelAlignmentCenter.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Label\Alignment;
|
||||
|
||||
final class LabelAlignmentCenter implements LabelAlignmentInterface
|
||||
{
|
||||
}
|
||||
9
vendor/endroid/qr-code/src/Label/Alignment/LabelAlignmentInterface.php
vendored
Normal file
9
vendor/endroid/qr-code/src/Label/Alignment/LabelAlignmentInterface.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Label\Alignment;
|
||||
|
||||
interface LabelAlignmentInterface
|
||||
{
|
||||
}
|
||||
9
vendor/endroid/qr-code/src/Label/Alignment/LabelAlignmentLeft.php
vendored
Normal file
9
vendor/endroid/qr-code/src/Label/Alignment/LabelAlignmentLeft.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Label\Alignment;
|
||||
|
||||
final class LabelAlignmentLeft implements LabelAlignmentInterface
|
||||
{
|
||||
}
|
||||
9
vendor/endroid/qr-code/src/Label/Alignment/LabelAlignmentRight.php
vendored
Normal file
9
vendor/endroid/qr-code/src/Label/Alignment/LabelAlignmentRight.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Label\Alignment;
|
||||
|
||||
final class LabelAlignmentRight implements LabelAlignmentInterface
|
||||
{
|
||||
}
|
||||
32
vendor/endroid/qr-code/src/Label/Font/Font.php
vendored
Normal file
32
vendor/endroid/qr-code/src/Label/Font/Font.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Label\Font;
|
||||
|
||||
final class Font implements FontInterface
|
||||
{
|
||||
public function __construct(
|
||||
private string $path,
|
||||
private int $size = 16
|
||||
) {
|
||||
$this->assertValidPath($path);
|
||||
}
|
||||
|
||||
private function assertValidPath(string $path): void
|
||||
{
|
||||
if (!file_exists($path)) {
|
||||
throw new \Exception(sprintf('Invalid font path "%s"', $path));
|
||||
}
|
||||
}
|
||||
|
||||
public function getPath(): string
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function getSize(): int
|
||||
{
|
||||
return $this->size;
|
||||
}
|
||||
}
|
||||
12
vendor/endroid/qr-code/src/Label/Font/FontInterface.php
vendored
Normal file
12
vendor/endroid/qr-code/src/Label/Font/FontInterface.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Label\Font;
|
||||
|
||||
interface FontInterface
|
||||
{
|
||||
public function getPath(): string;
|
||||
|
||||
public function getSize(): int;
|
||||
}
|
||||
23
vendor/endroid/qr-code/src/Label/Font/NotoSans.php
vendored
Normal file
23
vendor/endroid/qr-code/src/Label/Font/NotoSans.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Label\Font;
|
||||
|
||||
final class NotoSans implements FontInterface
|
||||
{
|
||||
public function __construct(
|
||||
private int $size = 16
|
||||
) {
|
||||
}
|
||||
|
||||
public function getPath(): string
|
||||
{
|
||||
return __DIR__.'/../../../assets/noto_sans.otf';
|
||||
}
|
||||
|
||||
public function getSize(): int
|
||||
{
|
||||
return $this->size;
|
||||
}
|
||||
}
|
||||
23
vendor/endroid/qr-code/src/Label/Font/OpenSans.php
vendored
Normal file
23
vendor/endroid/qr-code/src/Label/Font/OpenSans.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Label\Font;
|
||||
|
||||
final class OpenSans implements FontInterface
|
||||
{
|
||||
public function __construct(
|
||||
private int $size = 16
|
||||
) {
|
||||
}
|
||||
|
||||
public function getPath(): string
|
||||
{
|
||||
return __DIR__.'/../../../assets/open_sans.ttf';
|
||||
}
|
||||
|
||||
public function getSize(): int
|
||||
{
|
||||
return $this->size;
|
||||
}
|
||||
}
|
||||
100
vendor/endroid/qr-code/src/Label/Label.php
vendored
Normal file
100
vendor/endroid/qr-code/src/Label/Label.php
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Label;
|
||||
|
||||
use Endroid\QrCode\Color\Color;
|
||||
use Endroid\QrCode\Color\ColorInterface;
|
||||
use Endroid\QrCode\Label\Alignment\LabelAlignmentCenter;
|
||||
use Endroid\QrCode\Label\Alignment\LabelAlignmentInterface;
|
||||
use Endroid\QrCode\Label\Font\Font;
|
||||
use Endroid\QrCode\Label\Font\FontInterface;
|
||||
use Endroid\QrCode\Label\Margin\Margin;
|
||||
use Endroid\QrCode\Label\Margin\MarginInterface;
|
||||
|
||||
final class Label implements LabelInterface
|
||||
{
|
||||
private FontInterface $font;
|
||||
private LabelAlignmentInterface $alignment;
|
||||
private MarginInterface $margin;
|
||||
private ColorInterface $textColor;
|
||||
|
||||
public function __construct(
|
||||
private string $text,
|
||||
FontInterface|null $font = null,
|
||||
LabelAlignmentInterface|null $alignment = null,
|
||||
MarginInterface|null $margin = null,
|
||||
ColorInterface|null $textColor = null
|
||||
) {
|
||||
$this->font = $font ?? new Font(__DIR__.'/../../assets/noto_sans.otf', 16);
|
||||
$this->alignment = $alignment ?? new LabelAlignmentCenter();
|
||||
$this->margin = $margin ?? new Margin(0, 10, 10, 10);
|
||||
$this->textColor = $textColor ?? new Color(0, 0, 0);
|
||||
}
|
||||
|
||||
public static function create(string $text): self
|
||||
{
|
||||
return new self($text);
|
||||
}
|
||||
|
||||
public function getText(): string
|
||||
{
|
||||
return $this->text;
|
||||
}
|
||||
|
||||
public function setText(string $text): self
|
||||
{
|
||||
$this->text = $text;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFont(): FontInterface
|
||||
{
|
||||
return $this->font;
|
||||
}
|
||||
|
||||
public function setFont(FontInterface $font): self
|
||||
{
|
||||
$this->font = $font;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAlignment(): LabelAlignmentInterface
|
||||
{
|
||||
return $this->alignment;
|
||||
}
|
||||
|
||||
public function setAlignment(LabelAlignmentInterface $alignment): self
|
||||
{
|
||||
$this->alignment = $alignment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMargin(): MarginInterface
|
||||
{
|
||||
return $this->margin;
|
||||
}
|
||||
|
||||
public function setMargin(MarginInterface $margin): self
|
||||
{
|
||||
$this->margin = $margin;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTextColor(): ColorInterface
|
||||
{
|
||||
return $this->textColor;
|
||||
}
|
||||
|
||||
public function setTextColor(ColorInterface $textColor): self
|
||||
{
|
||||
$this->textColor = $textColor;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
23
vendor/endroid/qr-code/src/Label/LabelInterface.php
vendored
Normal file
23
vendor/endroid/qr-code/src/Label/LabelInterface.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Label;
|
||||
|
||||
use Endroid\QrCode\Color\ColorInterface;
|
||||
use Endroid\QrCode\Label\Alignment\LabelAlignmentInterface;
|
||||
use Endroid\QrCode\Label\Font\FontInterface;
|
||||
use Endroid\QrCode\Label\Margin\MarginInterface;
|
||||
|
||||
interface LabelInterface
|
||||
{
|
||||
public function getText(): string;
|
||||
|
||||
public function getFont(): FontInterface;
|
||||
|
||||
public function getAlignment(): LabelAlignmentInterface;
|
||||
|
||||
public function getMargin(): MarginInterface;
|
||||
|
||||
public function getTextColor(): ColorInterface;
|
||||
}
|
||||
47
vendor/endroid/qr-code/src/Label/Margin/Margin.php
vendored
Normal file
47
vendor/endroid/qr-code/src/Label/Margin/Margin.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Label\Margin;
|
||||
|
||||
final class Margin implements MarginInterface
|
||||
{
|
||||
public function __construct(
|
||||
private int $top,
|
||||
private int $right,
|
||||
private int $bottom,
|
||||
private int $left
|
||||
) {
|
||||
}
|
||||
|
||||
public function getTop(): int
|
||||
{
|
||||
return $this->top;
|
||||
}
|
||||
|
||||
public function getRight(): int
|
||||
{
|
||||
return $this->right;
|
||||
}
|
||||
|
||||
public function getBottom(): int
|
||||
{
|
||||
return $this->bottom;
|
||||
}
|
||||
|
||||
public function getLeft(): int
|
||||
{
|
||||
return $this->left;
|
||||
}
|
||||
|
||||
/** @return array<string, int> */
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'top' => $this->top,
|
||||
'right' => $this->right,
|
||||
'bottom' => $this->bottom,
|
||||
'left' => $this->left,
|
||||
];
|
||||
}
|
||||
}
|
||||
19
vendor/endroid/qr-code/src/Label/Margin/MarginInterface.php
vendored
Normal file
19
vendor/endroid/qr-code/src/Label/Margin/MarginInterface.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Label\Margin;
|
||||
|
||||
interface MarginInterface
|
||||
{
|
||||
public function getTop(): int;
|
||||
|
||||
public function getRight(): int;
|
||||
|
||||
public function getBottom(): int;
|
||||
|
||||
public function getLeft(): int;
|
||||
|
||||
/** @return array<string, int> */
|
||||
public function toArray(): array;
|
||||
}
|
||||
69
vendor/endroid/qr-code/src/Logo/Logo.php
vendored
Normal file
69
vendor/endroid/qr-code/src/Logo/Logo.php
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Logo;
|
||||
|
||||
final class Logo implements LogoInterface
|
||||
{
|
||||
public function __construct(
|
||||
private string $path,
|
||||
private int|null $resizeToWidth = null,
|
||||
private int|null $resizeToHeight = null,
|
||||
private bool $punchoutBackground = false
|
||||
) {
|
||||
}
|
||||
|
||||
public static function create(string $path): self
|
||||
{
|
||||
return new self($path);
|
||||
}
|
||||
|
||||
public function getPath(): string
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function setPath(string $path): self
|
||||
{
|
||||
$this->path = $path;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getResizeToWidth(): int|null
|
||||
{
|
||||
return $this->resizeToWidth;
|
||||
}
|
||||
|
||||
public function setResizeToWidth(int|null $resizeToWidth): self
|
||||
{
|
||||
$this->resizeToWidth = $resizeToWidth;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getResizeToHeight(): int|null
|
||||
{
|
||||
return $this->resizeToHeight;
|
||||
}
|
||||
|
||||
public function setResizeToHeight(int|null $resizeToHeight): self
|
||||
{
|
||||
$this->resizeToHeight = $resizeToHeight;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPunchoutBackground(): bool
|
||||
{
|
||||
return $this->punchoutBackground;
|
||||
}
|
||||
|
||||
public function setPunchoutBackground(bool $punchoutBackground): self
|
||||
{
|
||||
$this->punchoutBackground = $punchoutBackground;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
16
vendor/endroid/qr-code/src/Logo/LogoInterface.php
vendored
Normal file
16
vendor/endroid/qr-code/src/Logo/LogoInterface.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Logo;
|
||||
|
||||
interface LogoInterface
|
||||
{
|
||||
public function getPath(): string;
|
||||
|
||||
public function getResizeToWidth(): int|null;
|
||||
|
||||
public function getResizeToHeight(): int|null;
|
||||
|
||||
public function getPunchoutBackground(): bool;
|
||||
}
|
||||
86
vendor/endroid/qr-code/src/Matrix/Matrix.php
vendored
Normal file
86
vendor/endroid/qr-code/src/Matrix/Matrix.php
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Matrix;
|
||||
|
||||
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeEnlarge;
|
||||
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeInterface;
|
||||
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeMargin;
|
||||
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeShrink;
|
||||
|
||||
final class Matrix implements MatrixInterface
|
||||
{
|
||||
private float $blockSize;
|
||||
private int $innerSize;
|
||||
private int $outerSize;
|
||||
private int $marginLeft;
|
||||
private int $marginRight;
|
||||
|
||||
/** @param array<array<int>> $blockValues */
|
||||
public function __construct(
|
||||
private array $blockValues,
|
||||
int $size,
|
||||
int $margin,
|
||||
RoundBlockSizeModeInterface $roundBlockSizeMode
|
||||
) {
|
||||
$this->blockSize = $size / $this->getBlockCount();
|
||||
$this->innerSize = $size;
|
||||
$this->outerSize = $size + 2 * $margin;
|
||||
|
||||
if ($roundBlockSizeMode instanceof RoundBlockSizeModeEnlarge) {
|
||||
$this->blockSize = intval(ceil($this->blockSize));
|
||||
$this->innerSize = intval($this->blockSize * $this->getBlockCount());
|
||||
$this->outerSize = $this->innerSize + 2 * $margin;
|
||||
} elseif ($roundBlockSizeMode instanceof RoundBlockSizeModeShrink) {
|
||||
$this->blockSize = intval(floor($this->blockSize));
|
||||
$this->innerSize = intval($this->blockSize * $this->getBlockCount());
|
||||
$this->outerSize = $this->innerSize + 2 * $margin;
|
||||
} elseif ($roundBlockSizeMode instanceof RoundBlockSizeModeMargin) {
|
||||
$this->blockSize = intval(floor($this->blockSize));
|
||||
$this->innerSize = intval($this->blockSize * $this->getBlockCount());
|
||||
}
|
||||
|
||||
if ($this->blockSize < 1) {
|
||||
throw new \Exception('Too much data: increase image dimensions or lower error correction level');
|
||||
}
|
||||
|
||||
$this->marginLeft = intval(($this->outerSize - $this->innerSize) / 2);
|
||||
$this->marginRight = $this->outerSize - $this->innerSize - $this->marginLeft;
|
||||
}
|
||||
|
||||
public function getBlockValue(int $rowIndex, int $columnIndex): int
|
||||
{
|
||||
return $this->blockValues[$rowIndex][$columnIndex];
|
||||
}
|
||||
|
||||
public function getBlockCount(): int
|
||||
{
|
||||
return count($this->blockValues[0]);
|
||||
}
|
||||
|
||||
public function getBlockSize(): float
|
||||
{
|
||||
return $this->blockSize;
|
||||
}
|
||||
|
||||
public function getInnerSize(): int
|
||||
{
|
||||
return $this->innerSize;
|
||||
}
|
||||
|
||||
public function getOuterSize(): int
|
||||
{
|
||||
return $this->outerSize;
|
||||
}
|
||||
|
||||
public function getMarginLeft(): int
|
||||
{
|
||||
return $this->marginLeft;
|
||||
}
|
||||
|
||||
public function getMarginRight(): int
|
||||
{
|
||||
return $this->marginRight;
|
||||
}
|
||||
}
|
||||
12
vendor/endroid/qr-code/src/Matrix/MatrixFactoryInterface.php
vendored
Normal file
12
vendor/endroid/qr-code/src/Matrix/MatrixFactoryInterface.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Matrix;
|
||||
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
|
||||
interface MatrixFactoryInterface
|
||||
{
|
||||
public function create(QrCodeInterface $qrCode): MatrixInterface;
|
||||
}
|
||||
22
vendor/endroid/qr-code/src/Matrix/MatrixInterface.php
vendored
Normal file
22
vendor/endroid/qr-code/src/Matrix/MatrixInterface.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Matrix;
|
||||
|
||||
interface MatrixInterface
|
||||
{
|
||||
public function getBlockValue(int $rowIndex, int $columnIndex): int;
|
||||
|
||||
public function getBlockCount(): int;
|
||||
|
||||
public function getBlockSize(): float;
|
||||
|
||||
public function getInnerSize(): int;
|
||||
|
||||
public function getOuterSize(): int;
|
||||
|
||||
public function getMarginLeft(): int;
|
||||
|
||||
public function getMarginRight(): int;
|
||||
}
|
||||
141
vendor/endroid/qr-code/src/QrCode.php
vendored
Normal file
141
vendor/endroid/qr-code/src/QrCode.php
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode;
|
||||
|
||||
use Endroid\QrCode\Color\Color;
|
||||
use Endroid\QrCode\Color\ColorInterface;
|
||||
use Endroid\QrCode\Encoding\Encoding;
|
||||
use Endroid\QrCode\Encoding\EncodingInterface;
|
||||
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelInterface;
|
||||
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelLow;
|
||||
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeInterface;
|
||||
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeMargin;
|
||||
|
||||
final class QrCode implements QrCodeInterface
|
||||
{
|
||||
private EncodingInterface $encoding;
|
||||
private ErrorCorrectionLevelInterface $errorCorrectionLevel;
|
||||
private RoundBlockSizeModeInterface $roundBlockSizeMode;
|
||||
private ColorInterface $foregroundColor;
|
||||
private ColorInterface $backgroundColor;
|
||||
|
||||
public function __construct(
|
||||
private string $data,
|
||||
EncodingInterface|null $encoding = null,
|
||||
ErrorCorrectionLevelInterface|null $errorCorrectionLevel = null,
|
||||
private int $size = 300,
|
||||
private int $margin = 10,
|
||||
RoundBlockSizeModeInterface|null $roundBlockSizeMode = null,
|
||||
ColorInterface|null $foregroundColor = null,
|
||||
ColorInterface|null $backgroundColor = null
|
||||
) {
|
||||
$this->encoding = $encoding ?? new Encoding('UTF-8');
|
||||
$this->errorCorrectionLevel = $errorCorrectionLevel ?? new ErrorCorrectionLevelLow();
|
||||
$this->roundBlockSizeMode = $roundBlockSizeMode ?? new RoundBlockSizeModeMargin();
|
||||
$this->foregroundColor = $foregroundColor ?? new Color(0, 0, 0);
|
||||
$this->backgroundColor = $backgroundColor ?? new Color(255, 255, 255);
|
||||
}
|
||||
|
||||
public static function create(string $data): self
|
||||
{
|
||||
return new self($data);
|
||||
}
|
||||
|
||||
public function getData(): string
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
public function setData(string $data): self
|
||||
{
|
||||
$this->data = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getEncoding(): EncodingInterface
|
||||
{
|
||||
return $this->encoding;
|
||||
}
|
||||
|
||||
public function setEncoding(Encoding $encoding): self
|
||||
{
|
||||
$this->encoding = $encoding;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getErrorCorrectionLevel(): ErrorCorrectionLevelInterface
|
||||
{
|
||||
return $this->errorCorrectionLevel;
|
||||
}
|
||||
|
||||
public function setErrorCorrectionLevel(ErrorCorrectionLevelInterface $errorCorrectionLevel): self
|
||||
{
|
||||
$this->errorCorrectionLevel = $errorCorrectionLevel;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSize(): int
|
||||
{
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
public function setSize(int $size): self
|
||||
{
|
||||
$this->size = $size;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMargin(): int
|
||||
{
|
||||
return $this->margin;
|
||||
}
|
||||
|
||||
public function setMargin(int $margin): self
|
||||
{
|
||||
$this->margin = $margin;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRoundBlockSizeMode(): RoundBlockSizeModeInterface
|
||||
{
|
||||
return $this->roundBlockSizeMode;
|
||||
}
|
||||
|
||||
public function setRoundBlockSizeMode(RoundBlockSizeModeInterface $roundBlockSizeMode): self
|
||||
{
|
||||
$this->roundBlockSizeMode = $roundBlockSizeMode;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getForegroundColor(): ColorInterface
|
||||
{
|
||||
return $this->foregroundColor;
|
||||
}
|
||||
|
||||
public function setForegroundColor(ColorInterface $foregroundColor): self
|
||||
{
|
||||
$this->foregroundColor = $foregroundColor;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBackgroundColor(): ColorInterface
|
||||
{
|
||||
return $this->backgroundColor;
|
||||
}
|
||||
|
||||
public function setBackgroundColor(ColorInterface $backgroundColor): self
|
||||
{
|
||||
$this->backgroundColor = $backgroundColor;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
29
vendor/endroid/qr-code/src/QrCodeInterface.php
vendored
Normal file
29
vendor/endroid/qr-code/src/QrCodeInterface.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode;
|
||||
|
||||
use Endroid\QrCode\Color\ColorInterface;
|
||||
use Endroid\QrCode\Encoding\EncodingInterface;
|
||||
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelInterface;
|
||||
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeInterface;
|
||||
|
||||
interface QrCodeInterface
|
||||
{
|
||||
public function getData(): string;
|
||||
|
||||
public function getEncoding(): EncodingInterface;
|
||||
|
||||
public function getErrorCorrectionLevel(): ErrorCorrectionLevelInterface;
|
||||
|
||||
public function getSize(): int;
|
||||
|
||||
public function getMargin(): int;
|
||||
|
||||
public function getRoundBlockSizeMode(): RoundBlockSizeModeInterface;
|
||||
|
||||
public function getForegroundColor(): ColorInterface;
|
||||
|
||||
public function getBackgroundColor(): ColorInterface;
|
||||
}
|
||||
9
vendor/endroid/qr-code/src/RoundBlockSizeMode/RoundBlockSizeModeEnlarge.php
vendored
Normal file
9
vendor/endroid/qr-code/src/RoundBlockSizeMode/RoundBlockSizeModeEnlarge.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\RoundBlockSizeMode;
|
||||
|
||||
final class RoundBlockSizeModeEnlarge implements RoundBlockSizeModeInterface
|
||||
{
|
||||
}
|
||||
9
vendor/endroid/qr-code/src/RoundBlockSizeMode/RoundBlockSizeModeInterface.php
vendored
Normal file
9
vendor/endroid/qr-code/src/RoundBlockSizeMode/RoundBlockSizeModeInterface.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\RoundBlockSizeMode;
|
||||
|
||||
interface RoundBlockSizeModeInterface
|
||||
{
|
||||
}
|
||||
9
vendor/endroid/qr-code/src/RoundBlockSizeMode/RoundBlockSizeModeMargin.php
vendored
Normal file
9
vendor/endroid/qr-code/src/RoundBlockSizeMode/RoundBlockSizeModeMargin.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\RoundBlockSizeMode;
|
||||
|
||||
final class RoundBlockSizeModeMargin implements RoundBlockSizeModeInterface
|
||||
{
|
||||
}
|
||||
9
vendor/endroid/qr-code/src/RoundBlockSizeMode/RoundBlockSizeModeNone.php
vendored
Normal file
9
vendor/endroid/qr-code/src/RoundBlockSizeMode/RoundBlockSizeModeNone.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\RoundBlockSizeMode;
|
||||
|
||||
final class RoundBlockSizeModeNone implements RoundBlockSizeModeInterface
|
||||
{
|
||||
}
|
||||
9
vendor/endroid/qr-code/src/RoundBlockSizeMode/RoundBlockSizeModeShrink.php
vendored
Normal file
9
vendor/endroid/qr-code/src/RoundBlockSizeMode/RoundBlockSizeModeShrink.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\RoundBlockSizeMode;
|
||||
|
||||
final class RoundBlockSizeModeShrink implements RoundBlockSizeModeInterface
|
||||
{
|
||||
}
|
||||
205
vendor/endroid/qr-code/src/Writer/AbstractGdWriter.php
vendored
Normal file
205
vendor/endroid/qr-code/src/Writer/AbstractGdWriter.php
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\Bacon\MatrixFactory;
|
||||
use Endroid\QrCode\Exception\ValidationException;
|
||||
use Endroid\QrCode\ImageData\LabelImageData;
|
||||
use Endroid\QrCode\ImageData\LogoImageData;
|
||||
use Endroid\QrCode\Label\Alignment\LabelAlignmentLeft;
|
||||
use Endroid\QrCode\Label\Alignment\LabelAlignmentRight;
|
||||
use Endroid\QrCode\Label\LabelInterface;
|
||||
use Endroid\QrCode\Logo\LogoInterface;
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeNone;
|
||||
use Endroid\QrCode\Writer\Result\GdResult;
|
||||
use Endroid\QrCode\Writer\Result\ResultInterface;
|
||||
use Zxing\QrReader;
|
||||
|
||||
abstract class AbstractGdWriter implements WriterInterface, ValidatingWriterInterface
|
||||
{
|
||||
public function write(QrCodeInterface $qrCode, LogoInterface|null $logo = null, LabelInterface|null $label = null, array $options = []): ResultInterface
|
||||
{
|
||||
if (!extension_loaded('gd')) {
|
||||
throw new \Exception('Unable to generate image: please check if the GD extension is enabled and configured correctly');
|
||||
}
|
||||
|
||||
$matrixFactory = new MatrixFactory();
|
||||
$matrix = $matrixFactory->create($qrCode);
|
||||
|
||||
$baseBlockSize = $qrCode->getRoundBlockSizeMode() instanceof RoundBlockSizeModeNone ? 10 : intval($matrix->getBlockSize());
|
||||
$baseImage = imagecreatetruecolor($matrix->getBlockCount() * $baseBlockSize, $matrix->getBlockCount() * $baseBlockSize);
|
||||
|
||||
if (!$baseImage) {
|
||||
throw new \Exception('Unable to generate image: please check if the GD extension is enabled and configured correctly');
|
||||
}
|
||||
|
||||
/** @var int $foregroundColor */
|
||||
$foregroundColor = imagecolorallocatealpha(
|
||||
$baseImage,
|
||||
$qrCode->getForegroundColor()->getRed(),
|
||||
$qrCode->getForegroundColor()->getGreen(),
|
||||
$qrCode->getForegroundColor()->getBlue(),
|
||||
$qrCode->getForegroundColor()->getAlpha()
|
||||
);
|
||||
|
||||
/** @var int $transparentColor */
|
||||
$transparentColor = imagecolorallocatealpha($baseImage, 255, 255, 255, 127);
|
||||
|
||||
imagefill($baseImage, 0, 0, $transparentColor);
|
||||
|
||||
for ($rowIndex = 0; $rowIndex < $matrix->getBlockCount(); ++$rowIndex) {
|
||||
for ($columnIndex = 0; $columnIndex < $matrix->getBlockCount(); ++$columnIndex) {
|
||||
if (1 === $matrix->getBlockValue($rowIndex, $columnIndex)) {
|
||||
imagefilledrectangle(
|
||||
$baseImage,
|
||||
$columnIndex * $baseBlockSize,
|
||||
$rowIndex * $baseBlockSize,
|
||||
($columnIndex + 1) * $baseBlockSize - 1,
|
||||
($rowIndex + 1) * $baseBlockSize - 1,
|
||||
$foregroundColor
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$targetWidth = $matrix->getOuterSize();
|
||||
$targetHeight = $matrix->getOuterSize();
|
||||
|
||||
if ($label instanceof LabelInterface) {
|
||||
$labelImageData = LabelImageData::createForLabel($label);
|
||||
$targetHeight += $labelImageData->getHeight() + $label->getMargin()->getTop() + $label->getMargin()->getBottom();
|
||||
}
|
||||
|
||||
$targetImage = imagecreatetruecolor($targetWidth, $targetHeight);
|
||||
|
||||
if (!$targetImage) {
|
||||
throw new \Exception('Unable to generate image: please check if the GD extension is enabled and configured correctly');
|
||||
}
|
||||
|
||||
/** @var int $backgroundColor */
|
||||
$backgroundColor = imagecolorallocatealpha(
|
||||
$targetImage,
|
||||
$qrCode->getBackgroundColor()->getRed(),
|
||||
$qrCode->getBackgroundColor()->getGreen(),
|
||||
$qrCode->getBackgroundColor()->getBlue(),
|
||||
$qrCode->getBackgroundColor()->getAlpha()
|
||||
);
|
||||
|
||||
imagefill($targetImage, 0, 0, $backgroundColor);
|
||||
|
||||
imagecopyresampled(
|
||||
$targetImage,
|
||||
$baseImage,
|
||||
$matrix->getMarginLeft(),
|
||||
$matrix->getMarginLeft(),
|
||||
0,
|
||||
0,
|
||||
$matrix->getInnerSize(),
|
||||
$matrix->getInnerSize(),
|
||||
imagesx($baseImage),
|
||||
imagesy($baseImage)
|
||||
);
|
||||
|
||||
if ($qrCode->getBackgroundColor()->getAlpha() > 0) {
|
||||
imagesavealpha($targetImage, true);
|
||||
}
|
||||
|
||||
$result = new GdResult($matrix, $targetImage);
|
||||
|
||||
if ($logo instanceof LogoInterface) {
|
||||
$result = $this->addLogo($logo, $result);
|
||||
}
|
||||
|
||||
if ($label instanceof LabelInterface) {
|
||||
$result = $this->addLabel($label, $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function addLogo(LogoInterface $logo, GdResult $result): GdResult
|
||||
{
|
||||
$logoImageData = LogoImageData::createForLogo($logo);
|
||||
|
||||
if ('image/svg+xml' === $logoImageData->getMimeType()) {
|
||||
throw new \Exception('PNG Writer does not support SVG logo');
|
||||
}
|
||||
|
||||
$targetImage = $result->getImage();
|
||||
$matrix = $result->getMatrix();
|
||||
|
||||
if ($logoImageData->getPunchoutBackground()) {
|
||||
/** @var int $transparent */
|
||||
$transparent = imagecolorallocatealpha($targetImage, 255, 255, 255, 127);
|
||||
imagealphablending($targetImage, false);
|
||||
$xOffsetStart = intval($matrix->getOuterSize() / 2 - $logoImageData->getWidth() / 2);
|
||||
$yOffsetStart = intval($matrix->getOuterSize() / 2 - $logoImageData->getHeight() / 2);
|
||||
for ($xOffset = $xOffsetStart; $xOffset < $xOffsetStart + $logoImageData->getWidth(); ++$xOffset) {
|
||||
for ($yOffset = $yOffsetStart; $yOffset < $yOffsetStart + $logoImageData->getHeight(); ++$yOffset) {
|
||||
imagesetpixel($targetImage, $xOffset, $yOffset, $transparent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
imagecopyresampled(
|
||||
$targetImage,
|
||||
$logoImageData->getImage(),
|
||||
intval($matrix->getOuterSize() / 2 - $logoImageData->getWidth() / 2),
|
||||
intval($matrix->getOuterSize() / 2 - $logoImageData->getHeight() / 2),
|
||||
0,
|
||||
0,
|
||||
$logoImageData->getWidth(),
|
||||
$logoImageData->getHeight(),
|
||||
imagesx($logoImageData->getImage()),
|
||||
imagesy($logoImageData->getImage())
|
||||
);
|
||||
|
||||
return new GdResult($matrix, $targetImage);
|
||||
}
|
||||
|
||||
private function addLabel(LabelInterface $label, GdResult $result): GdResult
|
||||
{
|
||||
$targetImage = $result->getImage();
|
||||
|
||||
$labelImageData = LabelImageData::createForLabel($label);
|
||||
|
||||
/** @var int $textColor */
|
||||
$textColor = imagecolorallocatealpha(
|
||||
$targetImage,
|
||||
$label->getTextColor()->getRed(),
|
||||
$label->getTextColor()->getGreen(),
|
||||
$label->getTextColor()->getBlue(),
|
||||
$label->getTextColor()->getAlpha()
|
||||
);
|
||||
|
||||
$x = intval(imagesx($targetImage) / 2 - $labelImageData->getWidth() / 2);
|
||||
$y = imagesy($targetImage) - $label->getMargin()->getBottom();
|
||||
|
||||
if ($label->getAlignment() instanceof LabelAlignmentLeft) {
|
||||
$x = $label->getMargin()->getLeft();
|
||||
} elseif ($label->getAlignment() instanceof LabelAlignmentRight) {
|
||||
$x = imagesx($targetImage) - $labelImageData->getWidth() - $label->getMargin()->getRight();
|
||||
}
|
||||
|
||||
imagettftext($targetImage, $label->getFont()->getSize(), 0, $x, $y, $textColor, $label->getFont()->getPath(), $label->getText());
|
||||
|
||||
return new GdResult($result->getMatrix(), $targetImage);
|
||||
}
|
||||
|
||||
public function validateResult(ResultInterface $result, string $expectedData): void
|
||||
{
|
||||
$string = $result->getString();
|
||||
|
||||
if (!class_exists(QrReader::class)) {
|
||||
throw ValidationException::createForMissingPackage('khanamiryan/qrcode-detector-decoder');
|
||||
}
|
||||
|
||||
$reader = new QrReader($string, QrReader::SOURCE_TYPE_BLOB);
|
||||
if ($reader->text() !== $expectedData) {
|
||||
throw ValidationException::createForInvalidData($expectedData, strval($reader->text()));
|
||||
}
|
||||
}
|
||||
}
|
||||
23
vendor/endroid/qr-code/src/Writer/BinaryWriter.php
vendored
Normal file
23
vendor/endroid/qr-code/src/Writer/BinaryWriter.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\Bacon\MatrixFactory;
|
||||
use Endroid\QrCode\Label\LabelInterface;
|
||||
use Endroid\QrCode\Logo\LogoInterface;
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
use Endroid\QrCode\Writer\Result\BinaryResult;
|
||||
use Endroid\QrCode\Writer\Result\ResultInterface;
|
||||
|
||||
final class BinaryWriter implements WriterInterface
|
||||
{
|
||||
public function write(QrCodeInterface $qrCode, LogoInterface|null $logo = null, LabelInterface|null $label = null, array $options = []): ResultInterface
|
||||
{
|
||||
$matrixFactory = new MatrixFactory();
|
||||
$matrix = $matrixFactory->create($qrCode);
|
||||
|
||||
return new BinaryResult($matrix);
|
||||
}
|
||||
}
|
||||
23
vendor/endroid/qr-code/src/Writer/ConsoleWriter.php
vendored
Normal file
23
vendor/endroid/qr-code/src/Writer/ConsoleWriter.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\Bacon\MatrixFactory;
|
||||
use Endroid\QrCode\Label\LabelInterface;
|
||||
use Endroid\QrCode\Logo\LogoInterface;
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
use Endroid\QrCode\Writer\Result\ConsoleResult;
|
||||
use Endroid\QrCode\Writer\Result\ResultInterface;
|
||||
|
||||
final class ConsoleWriter implements WriterInterface
|
||||
{
|
||||
public function write(QrCodeInterface $qrCode, LogoInterface|null $logo = null, LabelInterface|null $label = null, $options = []): ResultInterface
|
||||
{
|
||||
$matrixFactory = new MatrixFactory();
|
||||
$matrix = $matrixFactory->create($qrCode);
|
||||
|
||||
return new ConsoleResult($matrix, $qrCode->getForegroundColor(), $qrCode->getBackgroundColor());
|
||||
}
|
||||
}
|
||||
32
vendor/endroid/qr-code/src/Writer/DebugWriter.php
vendored
Normal file
32
vendor/endroid/qr-code/src/Writer/DebugWriter.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\Bacon\MatrixFactory;
|
||||
use Endroid\QrCode\Label\LabelInterface;
|
||||
use Endroid\QrCode\Logo\LogoInterface;
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
use Endroid\QrCode\Writer\Result\DebugResult;
|
||||
use Endroid\QrCode\Writer\Result\ResultInterface;
|
||||
|
||||
final class DebugWriter implements WriterInterface, ValidatingWriterInterface
|
||||
{
|
||||
public function write(QrCodeInterface $qrCode, LogoInterface|null $logo = null, LabelInterface|null $label = null, array $options = []): ResultInterface
|
||||
{
|
||||
$matrixFactory = new MatrixFactory();
|
||||
$matrix = $matrixFactory->create($qrCode);
|
||||
|
||||
return new DebugResult($matrix, $qrCode, $logo, $label, $options);
|
||||
}
|
||||
|
||||
public function validateResult(ResultInterface $result, string $expectedData): void
|
||||
{
|
||||
if (!$result instanceof DebugResult) {
|
||||
throw new \Exception('Unable to write logo: instance of DebugResult expected');
|
||||
}
|
||||
|
||||
$result->setValidateResult(true);
|
||||
}
|
||||
}
|
||||
44
vendor/endroid/qr-code/src/Writer/EpsWriter.php
vendored
Normal file
44
vendor/endroid/qr-code/src/Writer/EpsWriter.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\Bacon\MatrixFactory;
|
||||
use Endroid\QrCode\Label\LabelInterface;
|
||||
use Endroid\QrCode\Logo\LogoInterface;
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
use Endroid\QrCode\Writer\Result\EpsResult;
|
||||
use Endroid\QrCode\Writer\Result\ResultInterface;
|
||||
|
||||
final class EpsWriter implements WriterInterface
|
||||
{
|
||||
public const DECIMAL_PRECISION = 10;
|
||||
|
||||
public function write(QrCodeInterface $qrCode, LogoInterface|null $logo = null, LabelInterface|null $label = null, array $options = []): ResultInterface
|
||||
{
|
||||
$matrixFactory = new MatrixFactory();
|
||||
$matrix = $matrixFactory->create($qrCode);
|
||||
|
||||
$lines = [
|
||||
'%!PS-Adobe-3.0 EPSF-3.0',
|
||||
'%%BoundingBox: 0 0 '.$matrix->getOuterSize().' '.$matrix->getOuterSize(),
|
||||
'/F { rectfill } def',
|
||||
number_format($qrCode->getBackgroundColor()->getRed() / 100, 2, '.', ',').' '.number_format($qrCode->getBackgroundColor()->getGreen() / 100, 2, '.', ',').' '.number_format($qrCode->getBackgroundColor()->getBlue() / 100, 2, '.', ',').' setrgbcolor',
|
||||
'0 0 '.$matrix->getOuterSize().' '.$matrix->getOuterSize().' F',
|
||||
number_format($qrCode->getForegroundColor()->getRed() / 100, 2, '.', ',').' '.number_format($qrCode->getForegroundColor()->getGreen() / 100, 2, '.', ',').' '.number_format($qrCode->getForegroundColor()->getBlue() / 100, 2, '.', ',').' setrgbcolor',
|
||||
];
|
||||
|
||||
for ($rowIndex = 0; $rowIndex < $matrix->getBlockCount(); ++$rowIndex) {
|
||||
for ($columnIndex = 0; $columnIndex < $matrix->getBlockCount(); ++$columnIndex) {
|
||||
if (1 === $matrix->getBlockValue($matrix->getBlockCount() - 1 - $rowIndex, $columnIndex)) {
|
||||
$x = $matrix->getMarginLeft() + $matrix->getBlockSize() * $columnIndex;
|
||||
$y = $matrix->getMarginLeft() + $matrix->getBlockSize() * $rowIndex;
|
||||
$lines[] = number_format($x, self::DECIMAL_PRECISION, '.', '').' '.number_format($y, self::DECIMAL_PRECISION, '.', '').' '.number_format($matrix->getBlockSize(), self::DECIMAL_PRECISION, '.', '').' '.number_format($matrix->getBlockSize(), self::DECIMAL_PRECISION, '.', '').' F';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new EpsResult($matrix, $lines);
|
||||
}
|
||||
}
|
||||
23
vendor/endroid/qr-code/src/Writer/GifWriter.php
vendored
Normal file
23
vendor/endroid/qr-code/src/Writer/GifWriter.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\Label\LabelInterface;
|
||||
use Endroid\QrCode\Logo\LogoInterface;
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
use Endroid\QrCode\Writer\Result\GdResult;
|
||||
use Endroid\QrCode\Writer\Result\GifResult;
|
||||
use Endroid\QrCode\Writer\Result\ResultInterface;
|
||||
|
||||
final class GifWriter extends AbstractGdWriter
|
||||
{
|
||||
public function write(QrCodeInterface $qrCode, LogoInterface|null $logo = null, LabelInterface|null $label = null, array $options = []): ResultInterface
|
||||
{
|
||||
/** @var GdResult $gdResult */
|
||||
$gdResult = parent::write($qrCode, $logo, $label, $options);
|
||||
|
||||
return new GifResult($gdResult->getMatrix(), $gdResult->getImage());
|
||||
}
|
||||
}
|
||||
139
vendor/endroid/qr-code/src/Writer/PdfWriter.php
vendored
Normal file
139
vendor/endroid/qr-code/src/Writer/PdfWriter.php
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\Bacon\MatrixFactory;
|
||||
use Endroid\QrCode\Label\LabelInterface;
|
||||
use Endroid\QrCode\Logo\LogoInterface;
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
use Endroid\QrCode\Writer\Result\PdfResult;
|
||||
use Endroid\QrCode\Writer\Result\ResultInterface;
|
||||
|
||||
final class PdfWriter implements WriterInterface
|
||||
{
|
||||
public const WRITER_OPTION_UNIT = 'unit';
|
||||
public const WRITER_OPTION_PDF = 'fpdf';
|
||||
public const WRITER_OPTION_X = 'x';
|
||||
public const WRITER_OPTION_Y = 'y';
|
||||
public const WRITER_OPTION_LINK = 'link';
|
||||
|
||||
public function write(QrCodeInterface $qrCode, LogoInterface|null $logo = null, LabelInterface|null $label = null, array $options = []): ResultInterface
|
||||
{
|
||||
$matrixFactory = new MatrixFactory();
|
||||
$matrix = $matrixFactory->create($qrCode);
|
||||
|
||||
$unit = 'mm';
|
||||
if (isset($options[self::WRITER_OPTION_UNIT])) {
|
||||
$unit = $options[self::WRITER_OPTION_UNIT];
|
||||
}
|
||||
|
||||
$allowedUnits = ['mm', 'pt', 'cm', 'in'];
|
||||
if (!in_array($unit, $allowedUnits)) {
|
||||
throw new \Exception(sprintf('PDF Measure unit should be one of [%s]', implode(', ', $allowedUnits)));
|
||||
}
|
||||
|
||||
$labelSpace = 0;
|
||||
if ($label instanceof LabelInterface) {
|
||||
$labelSpace = 30;
|
||||
}
|
||||
|
||||
if (!class_exists(\FPDF::class)) {
|
||||
throw new \Exception('Unable to find FPDF: check your installation');
|
||||
}
|
||||
|
||||
$foregroundColor = $qrCode->getForegroundColor();
|
||||
if ($foregroundColor->getAlpha() > 0) {
|
||||
throw new \Exception('PDF Writer does not support alpha channels');
|
||||
}
|
||||
$backgroundColor = $qrCode->getBackgroundColor();
|
||||
if ($backgroundColor->getAlpha() > 0) {
|
||||
throw new \Exception('PDF Writer does not support alpha channels');
|
||||
}
|
||||
|
||||
if (isset($options[self::WRITER_OPTION_PDF])) {
|
||||
$fpdf = $options[self::WRITER_OPTION_PDF];
|
||||
if (!$fpdf instanceof \FPDF) {
|
||||
throw new \Exception('pdf option must be an instance of FPDF');
|
||||
}
|
||||
} else {
|
||||
// @todo Check how to add label height later
|
||||
$fpdf = new \FPDF('P', $unit, [$matrix->getOuterSize(), $matrix->getOuterSize() + $labelSpace]);
|
||||
$fpdf->AddPage();
|
||||
}
|
||||
|
||||
$x = 0;
|
||||
if (isset($options[self::WRITER_OPTION_X])) {
|
||||
$x = $options[self::WRITER_OPTION_X];
|
||||
}
|
||||
$y = 0;
|
||||
if (isset($options[self::WRITER_OPTION_Y])) {
|
||||
$y = $options[self::WRITER_OPTION_Y];
|
||||
}
|
||||
|
||||
$fpdf->SetFillColor($backgroundColor->getRed(), $backgroundColor->getGreen(), $backgroundColor->getBlue());
|
||||
$fpdf->Rect($x, $y, $matrix->getOuterSize(), $matrix->getOuterSize(), 'F');
|
||||
$fpdf->SetFillColor($foregroundColor->getRed(), $foregroundColor->getGreen(), $foregroundColor->getBlue());
|
||||
|
||||
for ($rowIndex = 0; $rowIndex < $matrix->getBlockCount(); ++$rowIndex) {
|
||||
for ($columnIndex = 0; $columnIndex < $matrix->getBlockCount(); ++$columnIndex) {
|
||||
if (1 === $matrix->getBlockValue($rowIndex, $columnIndex)) {
|
||||
$fpdf->Rect(
|
||||
$x + $matrix->getMarginLeft() + ($columnIndex * $matrix->getBlockSize()),
|
||||
$y + $matrix->getMarginLeft() + ($rowIndex * $matrix->getBlockSize()),
|
||||
$matrix->getBlockSize(),
|
||||
$matrix->getBlockSize(),
|
||||
'F'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($logo instanceof LogoInterface) {
|
||||
$this->addLogo($logo, $fpdf, $x, $y, $matrix->getOuterSize());
|
||||
}
|
||||
|
||||
if ($label instanceof LabelInterface) {
|
||||
$fpdf->SetXY($x, $y + $matrix->getOuterSize() + $labelSpace - 25);
|
||||
$fpdf->SetFont('Helvetica', '', $label->getFont()->getSize());
|
||||
$fpdf->Cell($matrix->getOuterSize(), 0, $label->getText(), 0, 0, 'C');
|
||||
}
|
||||
|
||||
if (isset($options[self::WRITER_OPTION_LINK])) {
|
||||
$link = $options[self::WRITER_OPTION_LINK];
|
||||
$fpdf->Link($x, $y, $x + $matrix->getOuterSize(), $y + $matrix->getOuterSize(), $link);
|
||||
}
|
||||
|
||||
return new PdfResult($matrix, $fpdf);
|
||||
}
|
||||
|
||||
private function addLogo(LogoInterface $logo, \FPDF $fpdf, float $x, float $y, float $size): void
|
||||
{
|
||||
$logoPath = $logo->getPath();
|
||||
$logoHeight = $logo->getResizeToHeight();
|
||||
$logoWidth = $logo->getResizeToWidth();
|
||||
|
||||
if (null === $logoHeight || null === $logoWidth) {
|
||||
$imageSize = \getimagesize($logoPath);
|
||||
if (!$imageSize) {
|
||||
throw new \Exception(sprintf('Unable to read image size for logo "%s"', $logoPath));
|
||||
}
|
||||
[$logoSourceWidth, $logoSourceHeight] = $imageSize;
|
||||
|
||||
if (null === $logoWidth) {
|
||||
$logoWidth = (int) $logoSourceWidth;
|
||||
}
|
||||
|
||||
if (null === $logoHeight) {
|
||||
$aspectRatio = $logoWidth / $logoSourceWidth;
|
||||
$logoHeight = (int) ($logoSourceHeight * $aspectRatio);
|
||||
}
|
||||
}
|
||||
|
||||
$logoX = $x + $size / 2 - $logoWidth / 2;
|
||||
$logoY = $y + $size / 2 - $logoHeight / 2;
|
||||
|
||||
$fpdf->Image($logoPath, $logoX, $logoY, $logoWidth, $logoHeight);
|
||||
}
|
||||
}
|
||||
29
vendor/endroid/qr-code/src/Writer/PngWriter.php
vendored
Normal file
29
vendor/endroid/qr-code/src/Writer/PngWriter.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\Label\LabelInterface;
|
||||
use Endroid\QrCode\Logo\LogoInterface;
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
use Endroid\QrCode\Writer\Result\GdResult;
|
||||
use Endroid\QrCode\Writer\Result\PngResult;
|
||||
use Endroid\QrCode\Writer\Result\ResultInterface;
|
||||
|
||||
final class PngWriter extends AbstractGdWriter
|
||||
{
|
||||
public const WRITER_OPTION_COMPRESSION_LEVEL = 'compression_level';
|
||||
|
||||
public function write(QrCodeInterface $qrCode, LogoInterface|null $logo = null, LabelInterface|null $label = null, array $options = []): ResultInterface
|
||||
{
|
||||
if (!isset($options[self::WRITER_OPTION_COMPRESSION_LEVEL])) {
|
||||
$options[self::WRITER_OPTION_COMPRESSION_LEVEL] = -1;
|
||||
}
|
||||
|
||||
/** @var GdResult $gdResult */
|
||||
$gdResult = parent::write($qrCode, $logo, $label, $options);
|
||||
|
||||
return new PngResult($gdResult->getMatrix(), $gdResult->getImage(), $options[self::WRITER_OPTION_COMPRESSION_LEVEL]);
|
||||
}
|
||||
}
|
||||
31
vendor/endroid/qr-code/src/Writer/Result/AbstractResult.php
vendored
Normal file
31
vendor/endroid/qr-code/src/Writer/Result/AbstractResult.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer\Result;
|
||||
|
||||
use Endroid\QrCode\Matrix\MatrixInterface;
|
||||
|
||||
abstract class AbstractResult implements ResultInterface
|
||||
{
|
||||
public function __construct(
|
||||
private MatrixInterface $matrix
|
||||
) {
|
||||
}
|
||||
|
||||
public function getMatrix(): MatrixInterface
|
||||
{
|
||||
return $this->matrix;
|
||||
}
|
||||
|
||||
public function getDataUri(): string
|
||||
{
|
||||
return 'data:'.$this->getMimeType().';base64,'.base64_encode($this->getString());
|
||||
}
|
||||
|
||||
public function saveToFile(string $path): void
|
||||
{
|
||||
$string = $this->getString();
|
||||
file_put_contents($path, $string);
|
||||
}
|
||||
}
|
||||
35
vendor/endroid/qr-code/src/Writer/Result/BinaryResult.php
vendored
Normal file
35
vendor/endroid/qr-code/src/Writer/Result/BinaryResult.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer\Result;
|
||||
|
||||
use Endroid\QrCode\Matrix\MatrixInterface;
|
||||
|
||||
final class BinaryResult extends AbstractResult
|
||||
{
|
||||
public function __construct(MatrixInterface $matrix)
|
||||
{
|
||||
parent::__construct($matrix);
|
||||
}
|
||||
|
||||
public function getString(): string
|
||||
{
|
||||
$matrix = $this->getMatrix();
|
||||
|
||||
$binaryString = '';
|
||||
for ($rowIndex = 0; $rowIndex < $matrix->getBlockCount(); ++$rowIndex) {
|
||||
for ($columnIndex = 0; $columnIndex < $matrix->getBlockCount(); ++$columnIndex) {
|
||||
$binaryString .= $matrix->getBlockValue($rowIndex, $columnIndex);
|
||||
}
|
||||
$binaryString .= "\n";
|
||||
}
|
||||
|
||||
return $binaryString;
|
||||
}
|
||||
|
||||
public function getMimeType(): string
|
||||
{
|
||||
return 'text/plain';
|
||||
}
|
||||
}
|
||||
69
vendor/endroid/qr-code/src/Writer/Result/ConsoleResult.php
vendored
Normal file
69
vendor/endroid/qr-code/src/Writer/Result/ConsoleResult.php
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer\Result;
|
||||
|
||||
use Endroid\QrCode\Color\ColorInterface;
|
||||
use Endroid\QrCode\Matrix\MatrixInterface;
|
||||
|
||||
class ConsoleResult extends AbstractResult
|
||||
{
|
||||
private const TWO_BLOCKS = [
|
||||
0 => ' ',
|
||||
1 => "\xe2\x96\x80",
|
||||
2 => "\xe2\x96\x84",
|
||||
3 => "\xe2\x96\x88",
|
||||
];
|
||||
|
||||
private string $colorEscapeCode;
|
||||
|
||||
public function __construct(
|
||||
MatrixInterface $matrix,
|
||||
ColorInterface $foreground,
|
||||
ColorInterface $background
|
||||
) {
|
||||
parent::__construct($matrix);
|
||||
|
||||
$this->colorEscapeCode = sprintf(
|
||||
"\e[38;2;%d;%d;%dm\e[48;2;%d;%d;%dm",
|
||||
$foreground->getRed(),
|
||||
$foreground->getGreen(),
|
||||
$foreground->getBlue(),
|
||||
$background->getRed(),
|
||||
$background->getGreen(),
|
||||
$background->getBlue()
|
||||
);
|
||||
}
|
||||
|
||||
public function getMimeType(): string
|
||||
{
|
||||
return 'text/plain';
|
||||
}
|
||||
|
||||
public function getString(): string
|
||||
{
|
||||
$matrix = $this->getMatrix();
|
||||
|
||||
$side = $matrix->getBlockCount();
|
||||
$marginLeft = $this->colorEscapeCode.self::TWO_BLOCKS[0].self::TWO_BLOCKS[0];
|
||||
$marginRight = self::TWO_BLOCKS[0].self::TWO_BLOCKS[0]."\e[0m".PHP_EOL;
|
||||
$marginVertical = $marginLeft.str_repeat(self::TWO_BLOCKS[0], $side).$marginRight;
|
||||
|
||||
$qrCodeString = $marginVertical;
|
||||
for ($rowIndex = 0; $rowIndex < $side; $rowIndex += 2) {
|
||||
$qrCodeString .= $marginLeft;
|
||||
for ($columnIndex = 0; $columnIndex < $side; ++$columnIndex) {
|
||||
$combined = $matrix->getBlockValue($rowIndex, $columnIndex);
|
||||
if ($rowIndex + 1 < $side) {
|
||||
$combined |= $matrix->getBlockValue($rowIndex + 1, $columnIndex) << 1;
|
||||
}
|
||||
$qrCodeString .= self::TWO_BLOCKS[$combined];
|
||||
}
|
||||
$qrCodeString .= $marginRight;
|
||||
}
|
||||
$qrCodeString .= $marginVertical;
|
||||
|
||||
return $qrCodeString;
|
||||
}
|
||||
}
|
||||
73
vendor/endroid/qr-code/src/Writer/Result/DebugResult.php
vendored
Normal file
73
vendor/endroid/qr-code/src/Writer/Result/DebugResult.php
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer\Result;
|
||||
|
||||
use Endroid\QrCode\Label\LabelInterface;
|
||||
use Endroid\QrCode\Logo\LogoInterface;
|
||||
use Endroid\QrCode\Matrix\MatrixInterface;
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
|
||||
final class DebugResult extends AbstractResult
|
||||
{
|
||||
private bool $validateResult = false;
|
||||
|
||||
public function __construct(
|
||||
MatrixInterface $matrix,
|
||||
private QrCodeInterface $qrCode,
|
||||
private LogoInterface|null $logo = null,
|
||||
private LabelInterface|null $label = null,
|
||||
/** @var array<string, mixed> $options */
|
||||
private array $options = []
|
||||
) {
|
||||
parent::__construct($matrix);
|
||||
}
|
||||
|
||||
public function setValidateResult(bool $validateResult): void
|
||||
{
|
||||
$this->validateResult = $validateResult;
|
||||
}
|
||||
|
||||
public function getString(): string
|
||||
{
|
||||
$debugLines = [];
|
||||
|
||||
$debugLines[] = 'Data: '.$this->qrCode->getData();
|
||||
$debugLines[] = 'Encoding: '.$this->qrCode->getEncoding();
|
||||
$debugLines[] = 'Error Correction Level: '.get_class($this->qrCode->getErrorCorrectionLevel());
|
||||
$debugLines[] = 'Size: '.$this->qrCode->getSize();
|
||||
$debugLines[] = 'Margin: '.$this->qrCode->getMargin();
|
||||
$debugLines[] = 'Round block size mode: '.get_class($this->qrCode->getRoundBlockSizeMode());
|
||||
$debugLines[] = 'Foreground color: ['.implode(', ', $this->qrCode->getForegroundColor()->toArray()).']';
|
||||
$debugLines[] = 'Background color: ['.implode(', ', $this->qrCode->getBackgroundColor()->toArray()).']';
|
||||
|
||||
foreach ($this->options as $key => $value) {
|
||||
$debugLines[] = 'Writer option: '.$key.': '.$value;
|
||||
}
|
||||
|
||||
if (isset($this->logo)) {
|
||||
$debugLines[] = 'Logo path: '.$this->logo->getPath();
|
||||
$debugLines[] = 'Logo resize to width: '.$this->logo->getResizeToWidth();
|
||||
$debugLines[] = 'Logo resize to height: '.$this->logo->getResizeToHeight();
|
||||
}
|
||||
|
||||
if (isset($this->label)) {
|
||||
$debugLines[] = 'Label text: '.$this->label->getText();
|
||||
$debugLines[] = 'Label font path: '.$this->label->getFont()->getPath();
|
||||
$debugLines[] = 'Label font size: '.$this->label->getFont()->getSize();
|
||||
$debugLines[] = 'Label alignment: '.get_class($this->label->getAlignment());
|
||||
$debugLines[] = 'Label margin: ['.implode(', ', $this->label->getMargin()->toArray()).']';
|
||||
$debugLines[] = 'Label text color: ['.implode(', ', $this->label->getTextColor()->toArray()).']';
|
||||
}
|
||||
|
||||
$debugLines[] = 'Validate result: '.($this->validateResult ? 'true' : 'false');
|
||||
|
||||
return implode("\n", $debugLines);
|
||||
}
|
||||
|
||||
public function getMimeType(): string
|
||||
{
|
||||
return 'text/plain';
|
||||
}
|
||||
}
|
||||
28
vendor/endroid/qr-code/src/Writer/Result/EpsResult.php
vendored
Normal file
28
vendor/endroid/qr-code/src/Writer/Result/EpsResult.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer\Result;
|
||||
|
||||
use Endroid\QrCode\Matrix\MatrixInterface;
|
||||
|
||||
final class EpsResult extends AbstractResult
|
||||
{
|
||||
public function __construct(
|
||||
MatrixInterface $matrix,
|
||||
/** @var array<string> $lines */
|
||||
private array $lines
|
||||
) {
|
||||
parent::__construct($matrix);
|
||||
}
|
||||
|
||||
public function getString(): string
|
||||
{
|
||||
return implode("\n", $this->lines);
|
||||
}
|
||||
|
||||
public function getMimeType(): string
|
||||
{
|
||||
return 'image/eps';
|
||||
}
|
||||
}
|
||||
32
vendor/endroid/qr-code/src/Writer/Result/GdResult.php
vendored
Normal file
32
vendor/endroid/qr-code/src/Writer/Result/GdResult.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer\Result;
|
||||
|
||||
use Endroid\QrCode\Matrix\MatrixInterface;
|
||||
|
||||
class GdResult extends AbstractResult
|
||||
{
|
||||
public function __construct(
|
||||
MatrixInterface $matrix,
|
||||
protected \GdImage $image
|
||||
) {
|
||||
parent::__construct($matrix);
|
||||
}
|
||||
|
||||
public function getImage(): \GdImage
|
||||
{
|
||||
return $this->image;
|
||||
}
|
||||
|
||||
public function getString(): string
|
||||
{
|
||||
throw new \Exception('You can only use this method in a concrete implementation');
|
||||
}
|
||||
|
||||
public function getMimeType(): string
|
||||
{
|
||||
throw new \Exception('You can only use this method in a concrete implementation');
|
||||
}
|
||||
}
|
||||
21
vendor/endroid/qr-code/src/Writer/Result/GifResult.php
vendored
Normal file
21
vendor/endroid/qr-code/src/Writer/Result/GifResult.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer\Result;
|
||||
|
||||
final class GifResult extends GdResult
|
||||
{
|
||||
public function getString(): string
|
||||
{
|
||||
ob_start();
|
||||
imagegif($this->image);
|
||||
|
||||
return strval(ob_get_clean());
|
||||
}
|
||||
|
||||
public function getMimeType(): string
|
||||
{
|
||||
return 'image/gif';
|
||||
}
|
||||
}
|
||||
32
vendor/endroid/qr-code/src/Writer/Result/PdfResult.php
vendored
Normal file
32
vendor/endroid/qr-code/src/Writer/Result/PdfResult.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer\Result;
|
||||
|
||||
use Endroid\QrCode\Matrix\MatrixInterface;
|
||||
|
||||
final class PdfResult extends AbstractResult
|
||||
{
|
||||
public function __construct(
|
||||
MatrixInterface $matrix,
|
||||
private \FPDF $fpdf
|
||||
) {
|
||||
parent::__construct($matrix);
|
||||
}
|
||||
|
||||
public function getPdf(): \FPDF
|
||||
{
|
||||
return $this->fpdf;
|
||||
}
|
||||
|
||||
public function getString(): string
|
||||
{
|
||||
return $this->fpdf->Output('S');
|
||||
}
|
||||
|
||||
public function getMimeType(): string
|
||||
{
|
||||
return 'application/pdf';
|
||||
}
|
||||
}
|
||||
31
vendor/endroid/qr-code/src/Writer/Result/PngResult.php
vendored
Normal file
31
vendor/endroid/qr-code/src/Writer/Result/PngResult.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer\Result;
|
||||
|
||||
use Endroid\QrCode\Matrix\MatrixInterface;
|
||||
|
||||
final class PngResult extends GdResult
|
||||
{
|
||||
private int $quality;
|
||||
|
||||
public function __construct(MatrixInterface $matrix, \GdImage $image, int $quality = -1)
|
||||
{
|
||||
parent::__construct($matrix, $image);
|
||||
$this->quality = $quality;
|
||||
}
|
||||
|
||||
public function getString(): string
|
||||
{
|
||||
ob_start();
|
||||
imagepng($this->image, quality: $this->quality);
|
||||
|
||||
return strval(ob_get_clean());
|
||||
}
|
||||
|
||||
public function getMimeType(): string
|
||||
{
|
||||
return 'image/png';
|
||||
}
|
||||
}
|
||||
20
vendor/endroid/qr-code/src/Writer/Result/ResultInterface.php
vendored
Normal file
20
vendor/endroid/qr-code/src/Writer/Result/ResultInterface.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer\Result;
|
||||
|
||||
use Endroid\QrCode\Matrix\MatrixInterface;
|
||||
|
||||
interface ResultInterface
|
||||
{
|
||||
public function getMatrix(): MatrixInterface;
|
||||
|
||||
public function getString(): string;
|
||||
|
||||
public function getDataUri(): string;
|
||||
|
||||
public function saveToFile(string $path): void;
|
||||
|
||||
public function getMimeType(): string;
|
||||
}
|
||||
43
vendor/endroid/qr-code/src/Writer/Result/SvgResult.php
vendored
Normal file
43
vendor/endroid/qr-code/src/Writer/Result/SvgResult.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer\Result;
|
||||
|
||||
use Endroid\QrCode\Matrix\MatrixInterface;
|
||||
|
||||
final class SvgResult extends AbstractResult
|
||||
{
|
||||
public function __construct(
|
||||
MatrixInterface $matrix,
|
||||
private \SimpleXMLElement $xml,
|
||||
private bool $excludeXmlDeclaration = false
|
||||
) {
|
||||
parent::__construct($matrix);
|
||||
}
|
||||
|
||||
public function getXml(): \SimpleXMLElement
|
||||
{
|
||||
return $this->xml;
|
||||
}
|
||||
|
||||
public function getString(): string
|
||||
{
|
||||
$string = $this->xml->asXML();
|
||||
|
||||
if (!is_string($string)) {
|
||||
throw new \Exception('Could not save SVG XML to string');
|
||||
}
|
||||
|
||||
if ($this->excludeXmlDeclaration) {
|
||||
$string = str_replace("<?xml version=\"1.0\"?>\n", '', $string);
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
public function getMimeType(): string
|
||||
{
|
||||
return 'image/svg+xml';
|
||||
}
|
||||
}
|
||||
35
vendor/endroid/qr-code/src/Writer/Result/WebPResult.php
vendored
Normal file
35
vendor/endroid/qr-code/src/Writer/Result/WebPResult.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer\Result;
|
||||
|
||||
use Endroid\QrCode\Matrix\MatrixInterface;
|
||||
|
||||
final class WebPResult extends GdResult
|
||||
{
|
||||
private int $quality;
|
||||
|
||||
public function __construct(MatrixInterface $matrix, \GdImage $image, int $quality = -1)
|
||||
{
|
||||
parent::__construct($matrix, $image);
|
||||
$this->quality = $quality;
|
||||
}
|
||||
|
||||
public function getString(): string
|
||||
{
|
||||
if (!function_exists('imagewebp')) {
|
||||
throw new \Exception('WebP support is not available in your GD installation');
|
||||
}
|
||||
|
||||
ob_start();
|
||||
imagewebp($this->image, quality: $this->quality);
|
||||
|
||||
return strval(ob_get_clean());
|
||||
}
|
||||
|
||||
public function getMimeType(): string
|
||||
{
|
||||
return 'image/webp';
|
||||
}
|
||||
}
|
||||
114
vendor/endroid/qr-code/src/Writer/SvgWriter.php
vendored
Normal file
114
vendor/endroid/qr-code/src/Writer/SvgWriter.php
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\Bacon\MatrixFactory;
|
||||
use Endroid\QrCode\ImageData\LogoImageData;
|
||||
use Endroid\QrCode\Label\LabelInterface;
|
||||
use Endroid\QrCode\Logo\LogoInterface;
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
use Endroid\QrCode\Writer\Result\ResultInterface;
|
||||
use Endroid\QrCode\Writer\Result\SvgResult;
|
||||
|
||||
final class SvgWriter implements WriterInterface
|
||||
{
|
||||
public const DECIMAL_PRECISION = 10;
|
||||
public const WRITER_OPTION_BLOCK_ID = 'block_id';
|
||||
public const WRITER_OPTION_EXCLUDE_XML_DECLARATION = 'exclude_xml_declaration';
|
||||
public const WRITER_OPTION_EXCLUDE_SVG_WIDTH_AND_HEIGHT = 'exclude_svg_width_and_height';
|
||||
public const WRITER_OPTION_FORCE_XLINK_HREF = 'force_xlink_href';
|
||||
|
||||
public function write(QrCodeInterface $qrCode, LogoInterface|null $logo = null, LabelInterface|null $label = null, array $options = []): ResultInterface
|
||||
{
|
||||
if (!isset($options[self::WRITER_OPTION_BLOCK_ID])) {
|
||||
$options[self::WRITER_OPTION_BLOCK_ID] = 'block';
|
||||
}
|
||||
|
||||
if (!isset($options[self::WRITER_OPTION_EXCLUDE_XML_DECLARATION])) {
|
||||
$options[self::WRITER_OPTION_EXCLUDE_XML_DECLARATION] = false;
|
||||
}
|
||||
|
||||
if (!isset($options[self::WRITER_OPTION_EXCLUDE_SVG_WIDTH_AND_HEIGHT])) {
|
||||
$options[self::WRITER_OPTION_EXCLUDE_SVG_WIDTH_AND_HEIGHT] = false;
|
||||
}
|
||||
|
||||
$matrixFactory = new MatrixFactory();
|
||||
$matrix = $matrixFactory->create($qrCode);
|
||||
|
||||
$xml = new \SimpleXMLElement('<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"/>');
|
||||
$xml->addAttribute('version', '1.1');
|
||||
if (!$options[self::WRITER_OPTION_EXCLUDE_SVG_WIDTH_AND_HEIGHT]) {
|
||||
$xml->addAttribute('width', $matrix->getOuterSize().'px');
|
||||
$xml->addAttribute('height', $matrix->getOuterSize().'px');
|
||||
}
|
||||
$xml->addAttribute('viewBox', '0 0 '.$matrix->getOuterSize().' '.$matrix->getOuterSize());
|
||||
$xml->addChild('defs');
|
||||
|
||||
$blockDefinition = $xml->defs->addChild('rect');
|
||||
$blockDefinition->addAttribute('id', strval($options[self::WRITER_OPTION_BLOCK_ID]));
|
||||
$blockDefinition->addAttribute('width', number_format($matrix->getBlockSize(), self::DECIMAL_PRECISION, '.', ''));
|
||||
$blockDefinition->addAttribute('height', number_format($matrix->getBlockSize(), self::DECIMAL_PRECISION, '.', ''));
|
||||
$blockDefinition->addAttribute('fill', '#'.sprintf('%02x%02x%02x', $qrCode->getForegroundColor()->getRed(), $qrCode->getForegroundColor()->getGreen(), $qrCode->getForegroundColor()->getBlue()));
|
||||
$blockDefinition->addAttribute('fill-opacity', strval($qrCode->getForegroundColor()->getOpacity()));
|
||||
|
||||
$background = $xml->addChild('rect');
|
||||
$background->addAttribute('x', '0');
|
||||
$background->addAttribute('y', '0');
|
||||
$background->addAttribute('width', strval($matrix->getOuterSize()));
|
||||
$background->addAttribute('height', strval($matrix->getOuterSize()));
|
||||
$background->addAttribute('fill', '#'.sprintf('%02x%02x%02x', $qrCode->getBackgroundColor()->getRed(), $qrCode->getBackgroundColor()->getGreen(), $qrCode->getBackgroundColor()->getBlue()));
|
||||
$background->addAttribute('fill-opacity', strval($qrCode->getBackgroundColor()->getOpacity()));
|
||||
|
||||
for ($rowIndex = 0; $rowIndex < $matrix->getBlockCount(); ++$rowIndex) {
|
||||
for ($columnIndex = 0; $columnIndex < $matrix->getBlockCount(); ++$columnIndex) {
|
||||
if (1 === $matrix->getBlockValue($rowIndex, $columnIndex)) {
|
||||
$block = $xml->addChild('use');
|
||||
$block->addAttribute('x', number_format($matrix->getMarginLeft() + $matrix->getBlockSize() * $columnIndex, self::DECIMAL_PRECISION, '.', ''));
|
||||
$block->addAttribute('y', number_format($matrix->getMarginLeft() + $matrix->getBlockSize() * $rowIndex, self::DECIMAL_PRECISION, '.', ''));
|
||||
$block->addAttribute('xlink:href', '#'.$options[self::WRITER_OPTION_BLOCK_ID], 'http://www.w3.org/1999/xlink');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result = new SvgResult($matrix, $xml, boolval($options[self::WRITER_OPTION_EXCLUDE_XML_DECLARATION]));
|
||||
|
||||
if ($logo instanceof LogoInterface) {
|
||||
$this->addLogo($logo, $result, $options);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $options */
|
||||
private function addLogo(LogoInterface $logo, SvgResult $result, array $options): void
|
||||
{
|
||||
$logoImageData = LogoImageData::createForLogo($logo);
|
||||
|
||||
if (!isset($options[self::WRITER_OPTION_FORCE_XLINK_HREF])) {
|
||||
$options[self::WRITER_OPTION_FORCE_XLINK_HREF] = false;
|
||||
}
|
||||
|
||||
$xml = $result->getXml();
|
||||
|
||||
/** @var \SimpleXMLElement $xmlAttributes */
|
||||
$xmlAttributes = $xml->attributes();
|
||||
|
||||
$x = intval($xmlAttributes->width) / 2 - $logoImageData->getWidth() / 2;
|
||||
$y = intval($xmlAttributes->height) / 2 - $logoImageData->getHeight() / 2;
|
||||
|
||||
$imageDefinition = $xml->addChild('image');
|
||||
$imageDefinition->addAttribute('x', strval($x));
|
||||
$imageDefinition->addAttribute('y', strval($y));
|
||||
$imageDefinition->addAttribute('width', strval($logoImageData->getWidth()));
|
||||
$imageDefinition->addAttribute('height', strval($logoImageData->getHeight()));
|
||||
$imageDefinition->addAttribute('preserveAspectRatio', 'none');
|
||||
|
||||
if ($options[self::WRITER_OPTION_FORCE_XLINK_HREF]) {
|
||||
$imageDefinition->addAttribute('xlink:href', $logoImageData->createDataUri(), 'http://www.w3.org/1999/xlink');
|
||||
} else {
|
||||
$imageDefinition->addAttribute('href', $logoImageData->createDataUri());
|
||||
}
|
||||
}
|
||||
}
|
||||
12
vendor/endroid/qr-code/src/Writer/ValidatingWriterInterface.php
vendored
Normal file
12
vendor/endroid/qr-code/src/Writer/ValidatingWriterInterface.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\Writer\Result\ResultInterface;
|
||||
|
||||
interface ValidatingWriterInterface
|
||||
{
|
||||
public function validateResult(ResultInterface $result, string $expectedData): void;
|
||||
}
|
||||
29
vendor/endroid/qr-code/src/Writer/WebPWriter.php
vendored
Normal file
29
vendor/endroid/qr-code/src/Writer/WebPWriter.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\Label\LabelInterface;
|
||||
use Endroid\QrCode\Logo\LogoInterface;
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
use Endroid\QrCode\Writer\Result\GdResult;
|
||||
use Endroid\QrCode\Writer\Result\ResultInterface;
|
||||
use Endroid\QrCode\Writer\Result\WebPResult;
|
||||
|
||||
final class WebPWriter extends AbstractGdWriter
|
||||
{
|
||||
public const WRITER_OPTION_QUALITY = 'quality';
|
||||
|
||||
public function write(QrCodeInterface $qrCode, LogoInterface|null $logo = null, LabelInterface|null $label = null, array $options = []): ResultInterface
|
||||
{
|
||||
if (!isset($options[self::WRITER_OPTION_QUALITY])) {
|
||||
$options[self::WRITER_OPTION_QUALITY] = -1;
|
||||
}
|
||||
|
||||
/** @var GdResult $gdResult */
|
||||
$gdResult = parent::write($qrCode, $logo, $label, $options);
|
||||
|
||||
return new WebPResult($gdResult->getMatrix(), $gdResult->getImage(), $options[self::WRITER_OPTION_QUALITY]);
|
||||
}
|
||||
}
|
||||
16
vendor/endroid/qr-code/src/Writer/WriterInterface.php
vendored
Normal file
16
vendor/endroid/qr-code/src/Writer/WriterInterface.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Endroid\QrCode\Writer;
|
||||
|
||||
use Endroid\QrCode\Label\LabelInterface;
|
||||
use Endroid\QrCode\Logo\LogoInterface;
|
||||
use Endroid\QrCode\QrCodeInterface;
|
||||
use Endroid\QrCode\Writer\Result\ResultInterface;
|
||||
|
||||
interface WriterInterface
|
||||
{
|
||||
/** @param array<string, mixed> $options */
|
||||
public function write(QrCodeInterface $qrCode, LogoInterface|null $logo = null, LabelInterface|null $label = null, array $options = []): ResultInterface;
|
||||
}
|
||||
Reference in New Issue
Block a user