vendor/endroid/qr-code/src/Builder/Builder.php line 249

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Endroid\QrCode\Builder;
  4. use Endroid\QrCode\Color\ColorInterface;
  5. use Endroid\QrCode\Encoding\EncodingInterface;
  6. use Endroid\QrCode\ErrorCorrectionLevel;
  7. use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelInterface;
  8. use Endroid\QrCode\Exception\ValidationException;
  9. use Endroid\QrCode\Label\Alignment\LabelAlignmentInterface;
  10. use Endroid\QrCode\Label\Font\FontInterface;
  11. use Endroid\QrCode\Label\Label;
  12. use Endroid\QrCode\Label\LabelAlignment;
  13. use Endroid\QrCode\Label\LabelInterface;
  14. use Endroid\QrCode\Label\Margin\MarginInterface;
  15. use Endroid\QrCode\Logo\Logo;
  16. use Endroid\QrCode\Logo\LogoInterface;
  17. use Endroid\QrCode\QrCode;
  18. use Endroid\QrCode\RoundBlockSizeMode;
  19. use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeInterface;
  20. use Endroid\QrCode\Writer\PngWriter;
  21. use Endroid\QrCode\Writer\Result\ResultInterface;
  22. use Endroid\QrCode\Writer\ValidatingWriterInterface;
  23. use Endroid\QrCode\Writer\WriterInterface;
  24. class Builder implements BuilderInterface
  25. {
  26.     /**
  27.      * @var array<string, mixed>{
  28.      *     data: string,
  29.      *     writer: WriterInterface,
  30.      *     writerOptions: array,
  31.      *     qrCodeClass: class-string,
  32.      *     logoClass: class-string,
  33.      *     labelClass: class-string,
  34.      *     validateResult: bool,
  35.      *     size?: int,
  36.      *     encoding?: EncodingInterface,
  37.      *     errorCorrectionLevel?: ErrorCorrectionLevelInterface,
  38.      *     roundBlockSizeMode?: RoundBlockSizeModeInterface,
  39.      *     margin?: int,
  40.      *     backgroundColor?: ColorInterface,
  41.      *     foregroundColor?: ColorInterface,
  42.      *     labelText?: string,
  43.      *     labelFont?: FontInterface,
  44.      *     labelAlignment?: LabelAlignmentInterface,
  45.      *     labelMargin?: MarginInterface,
  46.      *     labelTextColor?: ColorInterface,
  47.      *     logoPath?: string,
  48.      *     logoResizeToWidth?: int,
  49.      *     logoResizeToHeight?: int,
  50.      *     logoPunchoutBackground?: bool
  51.      * }
  52.      */
  53.     private array $options;
  54.     public function __construct()
  55.     {
  56.         $this->options = [
  57.             'data' => '',
  58.             'writer' => new PngWriter(),
  59.             'writerOptions' => [],
  60.             'qrCodeClass' => QrCode::class,
  61.             'logoClass' => Logo::class,
  62.             'labelClass' => Label::class,
  63.             'validateResult' => false,
  64.         ];
  65.     }
  66.     public static function create(): BuilderInterface
  67.     {
  68.         return new self();
  69.     }
  70.     public function writer(WriterInterface $writer): BuilderInterface
  71.     {
  72.         $this->options['writer'] = $writer;
  73.         return $this;
  74.     }
  75.     /** @param array<string, mixed> $writerOptions */
  76.     public function writerOptions(array $writerOptions): BuilderInterface
  77.     {
  78.         $this->options['writerOptions'] = $writerOptions;
  79.         return $this;
  80.     }
  81.     public function data(string $data): BuilderInterface
  82.     {
  83.         $this->options['data'] = $data;
  84.         return $this;
  85.     }
  86.     public function encoding(EncodingInterface $encoding): BuilderInterface
  87.     {
  88.         $this->options['encoding'] = $encoding;
  89.         return $this;
  90.     }
  91.     public function errorCorrectionLevel(ErrorCorrectionLevel $errorCorrectionLevel): BuilderInterface
  92.     {
  93.         $this->options['errorCorrectionLevel'] = $errorCorrectionLevel;
  94.         return $this;
  95.     }
  96.     public function size(int $size): BuilderInterface
  97.     {
  98.         $this->options['size'] = $size;
  99.         return $this;
  100.     }
  101.     public function margin(int $margin): BuilderInterface
  102.     {
  103.         $this->options['margin'] = $margin;
  104.         return $this;
  105.     }
  106.     public function roundBlockSizeMode(RoundBlockSizeMode $roundBlockSizeMode): BuilderInterface
  107.     {
  108.         $this->options['roundBlockSizeMode'] = $roundBlockSizeMode;
  109.         return $this;
  110.     }
  111.     public function foregroundColor(ColorInterface $foregroundColor): BuilderInterface
  112.     {
  113.         $this->options['foregroundColor'] = $foregroundColor;
  114.         return $this;
  115.     }
  116.     public function backgroundColor(ColorInterface $backgroundColor): BuilderInterface
  117.     {
  118.         $this->options['backgroundColor'] = $backgroundColor;
  119.         return $this;
  120.     }
  121.     public function logoPath(string $logoPath): BuilderInterface
  122.     {
  123.         $this->options['logoPath'] = $logoPath;
  124.         return $this;
  125.     }
  126.     public function logoResizeToWidth(int $logoResizeToWidth): BuilderInterface
  127.     {
  128.         $this->options['logoResizeToWidth'] = $logoResizeToWidth;
  129.         return $this;
  130.     }
  131.     public function logoResizeToHeight(int $logoResizeToHeight): BuilderInterface
  132.     {
  133.         $this->options['logoResizeToHeight'] = $logoResizeToHeight;
  134.         return $this;
  135.     }
  136.     public function logoPunchoutBackground(bool $logoPunchoutBackground): BuilderInterface
  137.     {
  138.         $this->options['logoPunchoutBackground'] = $logoPunchoutBackground;
  139.         return $this;
  140.     }
  141.     public function labelText(string $labelText): BuilderInterface
  142.     {
  143.         $this->options['labelText'] = $labelText;
  144.         return $this;
  145.     }
  146.     public function labelFont(FontInterface $labelFont): BuilderInterface
  147.     {
  148.         $this->options['labelFont'] = $labelFont;
  149.         return $this;
  150.     }
  151.     public function labelAlignment(LabelAlignment $labelAlignment): BuilderInterface
  152.     {
  153.         $this->options['labelAlignment'] = $labelAlignment;
  154.         return $this;
  155.     }
  156.     public function labelMargin(MarginInterface $labelMargin): BuilderInterface
  157.     {
  158.         $this->options['labelMargin'] = $labelMargin;
  159.         return $this;
  160.     }
  161.     public function labelTextColor(ColorInterface $labelTextColor): BuilderInterface
  162.     {
  163.         $this->options['labelTextColor'] = $labelTextColor;
  164.         return $this;
  165.     }
  166.     public function validateResult(bool $validateResult): BuilderInterface
  167.     {
  168.         $this->options['validateResult'] = $validateResult;
  169.         return $this;
  170.     }
  171.     public function build(): ResultInterface
  172.     {
  173.         $writer $this->options['writer'];
  174.         if ($this->options['validateResult'] && !$writer instanceof ValidatingWriterInterface) {
  175.             throw ValidationException::createForUnsupportedWriter(strval(get_class($writer)));
  176.         }
  177.         /** @var QrCode $qrCode */
  178.         $qrCode $this->buildObject($this->options['qrCodeClass']);
  179.         /** @var LogoInterface|null $logo */
  180.         $logo $this->buildObject($this->options['logoClass'], 'logo');
  181.         /** @var LabelInterface|null $label */
  182.         $label $this->buildObject($this->options['labelClass'], 'label');
  183.         $result $writer->write($qrCode$logo$label$this->options['writerOptions']);
  184.         if ($this->options['validateResult'] && $writer instanceof ValidatingWriterInterface) {
  185.             $writer->validateResult($result$qrCode->getData());
  186.         }
  187.         return $result;
  188.     }
  189.     /**
  190.      * @param class-string $class
  191.      *
  192.      * @return mixed
  193.      */
  194.     private function buildObject(string $classstring $optionsPrefix null)
  195.     {
  196.         /** @var \ReflectionClass<object> $reflectionClass */
  197.         $reflectionClass = new \ReflectionClass($class);
  198.         $arguments = [];
  199.         $hasBuilderOptions false;
  200.         $missingRequiredArguments = [];
  201.         /** @var \ReflectionMethod $constructor */
  202.         $constructor $reflectionClass->getConstructor();
  203.         $constructorParameters $constructor->getParameters();
  204.         foreach ($constructorParameters as $parameter) {
  205.             $optionName null === $optionsPrefix $parameter->getName() : $optionsPrefix.ucfirst($parameter->getName());
  206.             if (isset($this->options[$optionName])) {
  207.                 $hasBuilderOptions true;
  208.                 $arguments[] = $this->options[$optionName];
  209.             } elseif ($parameter->isDefaultValueAvailable()) {
  210.                 $arguments[] = $parameter->getDefaultValue();
  211.             } else {
  212.                 $missingRequiredArguments[] = $optionName;
  213.             }
  214.         }
  215.         if (!$hasBuilderOptions) {
  216.             return null;
  217.         }
  218.         if (count($missingRequiredArguments) > 0) {
  219.             throw new \Exception(sprintf('Missing required arguments: %s'implode(', '$missingRequiredArguments)));
  220.         }
  221.         return $reflectionClass->newInstanceArgs($arguments);
  222.     }
  223. }