Passed
Push — master ( 9fc8db...3f1915 )
by Manuel
01:16 queued 12s
created

QrCode::writeDataUri()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php declare(strict_types=1);
2
3
namespace Sprain\SwissQrBill\QrCode;
4
5
use Endroid\QrCode\Encoding\Encoding;
6
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelMedium;
7
use Endroid\QrCode\Logo\Logo;
8
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeEnlarge;
9
use Endroid\QrCode\QrCode as BaseQrCode;
10
use Endroid\QrCode\Writer\PngWriter;
11
use Endroid\QrCode\Writer\Result\ResultInterface;
12
use Endroid\QrCode\Writer\SvgWriter;
13
use Endroid\QrCode\Writer\WriterInterface;
14
use Sprain\SwissQrBill\QrCode\Exception\UnsupportedFileExtensionException;
15
16
final class QrCode
17
{
18
    public const FILE_FORMAT_PNG = 'png';
19
    public const FILE_FORMAT_SVG = 'svg';
20
21
    private const SUPPORTED_FILE_FORMATS = [
22
        self::FILE_FORMAT_PNG,
23
        self::FILE_FORMAT_SVG
24
    ];
25
26
    private const SWISS_CROSS_LOGO_FILE = __DIR__ . '/../../assets/swiss-cross.optimized.png';
27
    private const PX_QR_CODE = 543;    // recommended 46x46 mm in px @ 300dpi – in pixel based outputs the final image size may be slightly different, depending on the qr code contents
28
    private const PX_SWISS_CROSS = 83; // recommended 7x7 mm in px @ 300dpi
29
30
    private BaseQrCode $qrCode;
31
    private Logo $qrCodeLogo;
32
    private WriterInterface $qrCodeWriter;
33
34
    public static function create(string $data, string $fileFormat = null): self
35
    {
36
        if (null === $fileFormat) {
37
            $fileFormat = self::FILE_FORMAT_SVG;
38
        }
39
40
        return new self($data, $fileFormat);
41
    }
42
43
    private function __construct(string $data, string $fileFormat)
44
    {
45
        $this->qrCode = BaseQrCode::create($data)
46
            ->setEncoding(new Encoding('UTF-8'))
47
            ->setErrorCorrectionLevel(new ErrorCorrectionLevelMedium())
48
            ->setSize(self::PX_QR_CODE)
49
            ->setMargin(0)
50
            ->setRoundBlockSizeMode(new RoundBlockSizeModeEnlarge());
51
52
        $this->qrCodeLogo = Logo::create(self::SWISS_CROSS_LOGO_FILE)
53
            ->setResizeToWidth(self::PX_SWISS_CROSS);
54
55
        $this->setWriterByExtension($fileFormat);
56
    }
57
58
    public function writeFile(string $path): void
59
    {
60
        $extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));
0 ignored issues
show
Bug introduced by
It seems like pathinfo($path, Sprain\S...ode\PATHINFO_EXTENSION) can also be of type array; however, parameter $string of strtolower() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

60
        $extension = strtolower(/** @scrutinizer ignore-type */ pathinfo($path, PATHINFO_EXTENSION));
Loading history...
61
        $this->setWriterByExtension($extension);
62
        $this->getQrCodeResult()->saveToFile($path);
63
    }
64
65
    public function writeDataUri(): string
66
    {
67
        return $this->getQrCodeResult()->getDataUri();
68
    }
69
70
    public function getText(): string
71
    {
72
        return $this->qrCode->getData();
73
    }
74
75
    private function setWriterByExtension(string $extension): void
76
    {
77
        if (!in_array($extension, self::SUPPORTED_FILE_FORMATS)) {
78
            throw new UnsupportedFileExtensionException(sprintf(
79
                'The qr code file cannot be created. Only these file formats are supported: %s. You provided: %s.',
80
                implode(', ', self::SUPPORTED_FILE_FORMATS),
81
                $extension
82
            ));
83
        }
84
85
        $this->qrCodeWriter = match ($extension) {
86
            self::FILE_FORMAT_SVG => new SvgWriter(),
87
            default => new PngWriter(),
88
        };
89
    }
90
91
    private function getQrCodeResult(): ResultInterface
92
    {
93
        return $this->qrCodeWriter->write(
94
            $this->qrCode,
95
            $this->qrCodeLogo,
96
            null,
97
            [SvgWriter::WRITER_OPTION_FORCE_XLINK_HREF => true]
98
        );
99
    }
100
}
101