PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.9.15
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.9.15
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 1.9.14 All 163 releases
woocommerce-pos / vendor_prefixed / chillerlan / php-qrcode / src / Output / QROutputAbstract.php

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

247 lines 8.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Class QROutputAbstract
5 *
6 * @created 09.12.2015
7 * @author Smiley <smiley@chillerlan.net>
8 * @copyright 2015 Smiley
9 * @license MIT
10 */
11 namespace WCPOS\Vendor\chillerlan\QRCode\Output;
12
13 use WCPOS\Vendor\chillerlan\QRCode\Data\QRMatrix;
14 use WCPOS\Vendor\chillerlan\Settings\SettingsContainerInterface;
15 use Closure;
16 use function base64_encode, dirname, file_put_contents, is_writable, ksort, sprintf;
17 /**
18 * common output abstract
19 */
20 abstract class QROutputAbstract implements QROutputInterface
21 {
22 /**
23 * the current size of the QR matrix
24 *
25 * @see \chillerlan\QRCode\Data\QRMatrix::getSize()
26 */
27 protected int $moduleCount;
28 /**
29 * the side length of the QR image (modules * scale)
30 */
31 protected int $length;
32 /**
33 * an (optional) array of color values for the several QR matrix parts
34 */
35 protected array $moduleValues;
36 /**
37 * the (filled) data matrix object
38 */
39 protected QRMatrix $matrix;
40 /**
41 * @var \chillerlan\Settings\SettingsContainerInterface|\chillerlan\QRCode\QROptions
42 */
43 protected SettingsContainerInterface $options;
44 /** @see \chillerlan\QRCode\QROptions::$scale */
45 protected int $scale;
46 /** @see \chillerlan\QRCode\QROptions::$connectPaths */
47 protected bool $connectPaths;
48 /** @see \chillerlan\QRCode\QROptions::$excludeFromConnect */
49 protected array $excludeFromConnect;
50 /** @see \chillerlan\QRCode\QROptions::$eol */
51 protected string $eol;
52 /** @see \chillerlan\QRCode\QROptions::$drawLightModules */
53 protected bool $drawLightModules;
54 /** @see \chillerlan\QRCode\QROptions::$drawCircularModules */
55 protected bool $drawCircularModules;
56 /** @see \chillerlan\QRCode\QROptions::$keepAsSquare */
57 protected array $keepAsSquare;
58 /** @see \chillerlan\QRCode\QROptions::$circleRadius */
59 protected float $circleRadius;
60 protected float $circleDiameter;
61 /**
62 * QROutputAbstract constructor.
63 */
64 public function __construct(SettingsContainerInterface $options, QRMatrix $matrix)
65 {
66 $this->options = $options;
67 $this->matrix = $matrix;
68 if ($this->options->invertMatrix) {
69 $this->matrix->invert();
70 }
71 $this->copyVars();
72 $this->setMatrixDimensions();
73 $this->setModuleValues();
74 }
75 /**
76 * Creates copies of several QROptions values to avoid calling the magic getters
77 * in long loops for a significant performance increase.
78 *
79 * These variables are usually used in the "module" methods and are called up to 31329 times (at version 40).
80 */
81 protected function copyVars() : void
82 {
83 $vars = ['connectPaths', 'excludeFromConnect', 'eol', 'drawLightModules', 'drawCircularModules', 'keepAsSquare', 'circleRadius'];
84 foreach ($vars as $property) {
85 $this->{$property} = $this->options->{$property};
86 }
87 $this->circleDiameter = $this->circleRadius * 2;
88 }
89 /**
90 * Sets/updates the matrix dimensions
91 *
92 * Call this method if you modify the matrix from within your custom module in case the dimensions have been changed
93 */
94 protected function setMatrixDimensions() : void
95 {
96 $this->moduleCount = $this->matrix->getSize();
97 $this->scale = $this->options->scale;
98 $this->length = $this->moduleCount * $this->scale;
99 }
100 /**
101 * Returns a 2 element array with the current output width and height
102 *
103 * The type and units of the values depend on the output class. The default value is the current module count * scale.
104 */
105 protected function getOutputDimensions() : array
106 {
107 return [$this->length, $this->length];
108 }
109 /**
110 * Sets the initial module values
111 */
112 protected function setModuleValues() : void
113 {
114 // first fill the map with the default values
115 foreach ($this::DEFAULT_MODULE_VALUES as $M_TYPE => $defaultValue) {
116 $this->moduleValues[$M_TYPE] = $this->getDefaultModuleValue($defaultValue);
117 }
118 // now loop over the options values to replace defaults and add extra values
119 foreach ($this->options->moduleValues as $M_TYPE => $value) {
120 if ($this::moduleValueIsValid($value)) {
121 $this->moduleValues[$M_TYPE] = $this->prepareModuleValue($value);
122 }
123 }
124 }
125 /**
126 * Prepares the value for the given input (return value depends on the output class)
127 *
128 * @param mixed $value
129 *
130 * @return mixed|null
131 */
132 protected abstract function prepareModuleValue($value);
133 /**
134 * Returns a default value for either dark or light modules (return value depends on the output class)
135 *
136 * @return mixed|null
137 */
138 protected abstract function getDefaultModuleValue(bool $isDark);
139 /**
140 * Returns the prepared value for the given $M_TYPE
141 *
142 * @return mixed return value depends on the output class
143 * @throws \chillerlan\QRCode\Output\QRCodeOutputException if $moduleValues[$M_TYPE] doesn't exist
144 */
145 protected function getModuleValue(int $M_TYPE)
146 {
147 if (!isset($this->moduleValues[$M_TYPE])) {
148 throw new QRCodeOutputException(sprintf('$M_TYPE %012b not found in module values map', $M_TYPE));
149 }
150 return $this->moduleValues[$M_TYPE];
151 }
152 /**
153 * Returns the prepared module value at the given coordinate [$x, $y] (convenience)
154 *
155 * @return mixed|null
156 */
157 protected function getModuleValueAt(int $x, int $y)
158 {
159 return $this->getModuleValue($this->matrix->get($x, $y));
160 }
161 /**
162 * Returns a base64 data URI for the given string and mime type
163 */
164 protected function toBase64DataURI(string $data, ?string $mime = null) : string
165 {
166 return sprintf('data:%s;base64,%s', $mime ?? $this::MIME_TYPE, base64_encode($data));
167 }
168 /**
169 * Saves the qr $data to a $file. If $file is null, nothing happens.
170 *
171 * @see file_put_contents()
172 * @see \chillerlan\QRCode\QROptions::$cachefile
173 *
174 * @throws \chillerlan\QRCode\Output\QRCodeOutputException
175 */
176 protected function saveToFile(string $data, ?string $file = null) : void
177 {
178 if ($file === null) {
179 return;
180 }
181 if (!is_writable(dirname($file))) {
182 throw new QRCodeOutputException(sprintf('Cannot write data to cache file: %s', $file));
183 }
184 if (file_put_contents($file, $data) === \false) {
185 throw new QRCodeOutputException(sprintf('Cannot write data to cache file: %s (file_put_contents error)', $file));
186 }
187 }
188 /**
189 * collects the modules per QRMatrix::M_* type and runs a $transform function on each module and
190 * returns an array with the transformed modules
191 *
192 * The transform callback is called with the following parameters:
193 *
194 * $x - current column
195 * $y - current row
196 * $M_TYPE - field value
197 * $M_TYPE_LAYER - (possibly modified) field value that acts as layer id
198 *
199 * @deprecated 5.0.5 The parameter $transform will be removed in the next major version
200 * in favor of a concrete method QROutputAbstract::moduleTransform()
201 * @see \chillerlan\QRCode\Output\QROutputAbstract::moduleTransform()
202 */
203 protected function collectModules(Closure $transform) : array
204 {
205 $paths = [];
206 // collect the modules for each type
207 foreach ($this->matrix->getMatrix() as $y => $row) {
208 foreach ($row as $x => $M_TYPE) {
209 $M_TYPE_LAYER = $M_TYPE;
210 if ($this->connectPaths && !$this->matrix->checkTypeIn($x, $y, $this->excludeFromConnect)) {
211 // to connect paths we'll redeclare the $M_TYPE_LAYER to data only
212 $M_TYPE_LAYER = QRMatrix::M_DATA;
213 if ($this->matrix->isDark($M_TYPE)) {
214 $M_TYPE_LAYER = QRMatrix::M_DATA_DARK;
215 }
216 }
217 // collect the modules per $M_TYPE
218 $module = $transform($x, $y, $M_TYPE, $M_TYPE_LAYER);
219 if (!empty($module)) {
220 $paths[$M_TYPE_LAYER][] = $module;
221 }
222 }
223 }
224 // beautify output
225 ksort($paths);
226 return $paths;
227 }
228 /**
229 * The transform callback for the module collector
230 *
231 * $x - current column
232 * $y - current row
233 * $M_TYPE - field value
234 * $M_TYPE_LAYER - (possibly modified) field value that acts as layer id ($paths array key)
235 *
236 * This method should return a value suitable for the current output class.
237 * It must return `null` for an empty value.
238 *
239 * @see \chillerlan\QRCode\Output\QROutputAbstract::collectModules()
240 * @return mixed|null
241 */
242 protected function moduleTransform(int $x, int $y, int $M_TYPE, int $M_TYPE_LAYER)
243 {
244 return null;
245 }
246 }
247