PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.10.20
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.10.20
1.10.20 1.10.19 1.10.18 1.10.17 1.10.16 1.10.15 1.10.13 1.10.14 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 untagged-3d9b7ccddc54df87c672 1.10.7 1.10.6 1.10.5 1.10.3 1.10.4 1.10.2 1.10.1 1.10.0 1.9.17 1.9.15 1.9.16 All 164 releases
woocommerce-pos / vendor_prefixed / chillerlan / php-qrcode / src / Output / QRMarkupSVG.php

QRMarkupSVG.php in WCPOS – Point of Sale (POS) plugin for WooCommerce 1.10.20, at vendor_prefixed/chillerlan/php-qrcode/src/Output/QRMarkupSVG.php

160 lines 5.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Class QRMarkupSVG
5 *
6 * @created 06.06.2022
7 * @author smiley <[email protected]>
8 * @copyright 2022 smiley
9 * @license MIT
10 */
11 namespace WCPOS\Vendor\chillerlan\QRCode\Output;
12
13 use function array_chunk, implode, is_string, preg_match, sprintf, trim;
14 /**
15 * SVG output
16 *
17 * @see https://github.com/codemasher/php-qrcode/pull/5
18 * @see https://developer.mozilla.org/en-US/docs/Web/SVG
19 * @see https://www.sarasoueidan.com/demos/interactive-svg-coordinate-system/
20 * @see https://lea.verou.me/blog/2019/05/utility-convert-svg-path-to-all-relative-or-all-absolute-commands/
21 * @see https://codepen.io/leaverou/full/RmwzKv
22 * @see https://jakearchibald.github.io/svgomg/
23 * @see https://web.archive.org/web/20200220211445/http://apex.infogridpacific.com/SVG/svg-tutorial-contents.html
24 */
25 class QRMarkupSVG extends QRMarkup
26 {
27 public const MIME_TYPE = 'image/svg+xml';
28 /**
29 * @todo: XSS proof
30 *
31 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill
32 * @inheritDoc
33 */
34 public static function moduleValueIsValid($value) : bool
35 {
36 if (!is_string($value)) {
37 return \false;
38 }
39 $value = trim($value);
40 // url(...)
41 if (preg_match('~^url\\([-/#a-z\\d]+\\)$~i', $value)) {
42 return \true;
43 }
44 // otherwise check for standard css notation
45 return parent::moduleValueIsValid($value);
46 }
47 /**
48 * @inheritDoc
49 */
50 protected function getOutputDimensions() : array
51 {
52 return [$this->moduleCount, $this->moduleCount];
53 }
54 /**
55 * @inheritDoc
56 */
57 protected function getCssClass(int $M_TYPE = 0) : string
58 {
59 return implode(' ', ['qr-' . ($this::LAYERNAMES[$M_TYPE] ?? $M_TYPE), $this->matrix->isDark($M_TYPE) ? 'dark' : 'light', $this->options->cssClass]);
60 }
61 /**
62 * @inheritDoc
63 */
64 protected function createMarkup(bool $saveToFile) : string
65 {
66 $svg = $this->header();
67 if ($this->options->svgDefs !== '') {
68 $svg .= sprintf('<defs>%1$s%2$s</defs>%2$s', $this->options->svgDefs, $this->eol);
69 }
70 $svg .= $this->paths();
71 // close svg
72 $svg .= sprintf('%1$s</svg>%1$s', $this->eol);
73 // transform to data URI only when not saving to file
74 if (!$saveToFile && $this->options->outputBase64) {
75 $svg = $this->toBase64DataURI($svg);
76 }
77 return $svg;
78 }
79 /**
80 * returns the value for the SVG viewBox attribute
81 *
82 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox
83 * @see https://css-tricks.com/scale-svg/#article-header-id-3
84 */
85 protected function getViewBox() : string
86 {
87 [$width, $height] = $this->getOutputDimensions();
88 return sprintf('0 0 %s %s', $width, $height);
89 }
90 /**
91 * returns the <svg> header with the given options parsed
92 *
93 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg
94 */
95 protected function header() : string
96 {
97 $header = sprintf('<svg xmlns="http://www.w3.org/2000/svg" class="qr-svg %1$s" viewBox="%2$s" preserveAspectRatio="%3$s">%4$s', $this->options->cssClass, $this->getViewBox(), $this->options->svgPreserveAspectRatio, $this->eol);
98 if ($this->options->svgAddXmlHeader) {
99 $header = sprintf('<?xml version="1.0" encoding="UTF-8"?>%s%s', $this->eol, $header);
100 }
101 return $header;
102 }
103 /**
104 * returns one or more SVG <path> elements
105 */
106 protected function paths() : string
107 {
108 /** @phan-suppress-next-line PhanDeprecatedFunction */
109 $paths = $this->collectModules(fn(int $x, int $y, int $M_TYPE): string => $this->module($x, $y, $M_TYPE));
110 $svg = [];
111 // create the path elements
112 foreach ($paths as $M_TYPE => $modules) {
113 // limit the total line length
114 $chunks = array_chunk($modules, 100);
115 $chonks = [];
116 foreach ($chunks as $chunk) {
117 $chonks[] = implode(' ', $chunk);
118 }
119 $path = implode($this->eol, $chonks);
120 if ($path === '') {
121 continue;
122 }
123 $svg[] = $this->path($path, $M_TYPE);
124 }
125 return implode($this->eol, $svg);
126 }
127 /**
128 * renders and returns a single <path> element
129 *
130 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path
131 */
132 protected function path(string $path, int $M_TYPE) : string
133 {
134 if ($this->options->svgUseFillAttributes) {
135 return sprintf('<path class="%s" fill="%s" d="%s"/>', $this->getCssClass($M_TYPE), $this->getModuleValue($M_TYPE), $path);
136 }
137 return sprintf('<path class="%s" d="%s"/>', $this->getCssClass($M_TYPE), $path);
138 }
139 /**
140 * returns a path segment for a single module
141 *
142 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d
143 */
144 protected function module(int $x, int $y, int $M_TYPE) : string
145 {
146 if (!$this->drawLightModules && !$this->matrix->isDark($M_TYPE)) {
147 return '';
148 }
149 if ($this->drawCircularModules && !$this->matrix->checkTypeIn($x, $y, $this->keepAsSquare)) {
150 // string interpolation: ugly and fast
151 $ix = $x + 0.5 - $this->circleRadius;
152 $iy = $y + 0.5;
153 // phpcs:ignore
154 return "M{$ix} {$iy} a{$this->circleRadius} {$this->circleRadius} 0 1 0 {$this->circleDiameter} 0 a{$this->circleRadius} {$this->circleRadius} 0 1 0 -{$this->circleDiameter} 0Z";
155 }
156 // phpcs:ignore
157 return "M{$x} {$y} h1 v1 h-1Z";
158 }
159 }
160