Passed
Push — main ( 17d0bc...c79042 )
by smiley
01:56
created

QROptionsTrait::set_useImagickIfAvailable()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 1
nc 2
nop 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Trait QROptionsTrait
4
 *
5
 * @created      10.03.2018
6
 * @author       smiley <[email protected]>
7
 * @copyright    2018 smiley
8
 * @license      MIT
9
 *
10
 * @noinspection PhpUnused
11
 */
12
13
namespace chillerlan\QRCode;
14
15
use chillerlan\QRCode\Common\EccLevel;
16
17
use function array_values, count, extension_loaded, in_array, is_numeric, max, min, sprintf, strtolower;
18
19
/**
20
 * The QRCode plug-in settings & setter functionality
21
 */
22
trait QROptionsTrait{
23
24
	/**
25
	 * QR Code version number
26
	 *
27
	 * [1 ... 40] or QRCode::VERSION_AUTO
28
	 */
29
	protected int $version = QRCode::VERSION_AUTO;
30
31
	/**
32
	 * Minimum QR version
33
	 *
34
	 * if $version = QRCode::VERSION_AUTO
35
	 */
36
	protected int $versionMin = 1;
37
38
	/**
39
	 * Maximum QR version
40
	 */
41
	protected int $versionMax = 40;
42
43
	/**
44
	 * Error correct level
45
	 *
46
	 * QRCode::ECC_X where X is:
47
	 *
48
	 *   - L =>  7%
49
	 *   - M => 15%
50
	 *   - Q => 25%
51
	 *   - H => 30%
52
	 */
53
	protected int $eccLevel = EccLevel::L;
54
55
	/**
56
	 * Mask Pattern to use
57
	 *
58
	 * [0...7] or QRCode::MASK_PATTERN_AUTO
59
	 */
60
	protected int $maskPattern = QRCode::MASK_PATTERN_AUTO;
61
62
	/**
63
	 * Add a "quiet zone" (margin) according to the QR code spec
64
	 */
65
	protected bool $addQuietzone = true;
66
67
	/**
68
	 * Size of the quiet zone
69
	 *
70
	 * internally clamped to [0 ... $moduleCount / 2], defaults to 4 modules
71
	 */
72
	protected int $quietzoneSize = 4;
73
74
	/**
75
	 * The output type
76
	 *
77
	 *   - QRCode::OUTPUT_MARKUP_XXXX where XXXX = HTML, SVG
78
	 *   - QRCode::OUTPUT_IMAGE_XXX where XXX = PNG, GIF, JPG
79
	 *   - QRCode::OUTPUT_STRING_XXXX where XXXX = TEXT, JSON
80
	 *   - QRCode::OUTPUT_CUSTOM
81
	 */
82
	protected string $outputType = QRCode::OUTPUT_IMAGE_PNG;
83
84
	/**
85
	 * the FQCN of the custom QROutputInterface if $outputType is set to QRCode::OUTPUT_CUSTOM
86
	 */
87
	protected ?string $outputInterface = null;
88
89
	/**
90
	 * /path/to/cache.file
91
	 */
92
	protected ?string $cachefile = null;
93
94
	/**
95
	 * newline string [HTML, SVG, TEXT]
96
	 */
97
	protected string $eol = PHP_EOL;
98
99
	/**
100
	 * size of a QR code pixel [SVG, IMAGE_*], HTML via CSS
101
	 */
102
	protected int $scale = 5;
103
104
	/**
105
	 * a common css class
106
	 */
107
	protected string $cssClass = '';
108
109
	/**
110
	 * SVG opacity
111
	 */
112
	protected float $svgOpacity = 1.0;
113
114
	/**
115
	 * anything between <defs>
116
	 *
117
	 * @see https://developer.mozilla.org/docs/Web/SVG/Element/defs
118
	 */
119
	protected string $svgDefs = '<style>rect{shape-rendering:crispEdges}</style>';
120
121
	/**
122
	 * SVG viewBox size. a single integer number which defines width/height of the viewBox attribute.
123
	 *
124
	 * viewBox="0 0 x x"
125
	 *
126
	 * @see https://css-tricks.com/scale-svg/#article-header-id-3
127
	 */
128
	protected ?int $svgViewBoxSize = null;
129
130
	/**
131
	 * string substitute for dark
132
	 */
133
	protected string $textDark = '🔴';
134
135
	/**
136
	 * string substitute for light
137
	 */
138
	protected string $textLight = '⭕';
139
140
	/**
141
	 * markup substitute for dark (CSS value)
142
	 */
143
	protected string $markupDark = '#000';
144
145
	/**
146
	 * markup substitute for light (CSS value)
147
	 */
148
	protected string $markupLight = '#fff';
149
150
	/**
151
	 * Return the image resource instead of a render if applicable.
152
	 * This option overrides other output options, such as $cachefile and $imageBase64.
153
	 *
154
	 * Supported by the following modules:
155
	 *
156
	 * - QRImage:   resource (PHP < 8), GdImage
157
	 * - QRImagick: Imagick
158
	 * - QRFpdf:    FPDF
159
	 *
160
	 * @see \chillerlan\QRCode\Output\QROutputInterface::dump()
161
	 *
162
	 * @var bool
163
	 */
164
	protected bool $returnResource = false;
165
166
	/**
167
	 * toggle base64 or raw image data
168
	 */
169
	protected bool $imageBase64 = true;
170
171
	/**
172
	 * toggle transparency, not supported by jpg
173
	 */
174
	protected bool $imageTransparent = true;
175
176
	/**
177
	 * @see imagecolortransparent()
178
	 *
179
	 * [R, G, B]
180
	 */
181
	protected array $imageTransparencyBG = [255, 255, 255];
182
183
	/**
184
	 * @see imagepng()
185
	 */
186
	protected int $pngCompression = -1;
187
188
	/**
189
	 * @see imagejpeg()
190
	 */
191
	protected int $jpegQuality = 85;
192
193
	/**
194
	 * Imagick output format
195
	 *
196
	 * @see \Imagick::setType()
197
	 */
198
	protected string $imagickFormat = 'png';
199
200
	/**
201
	 * Imagick background color (defaults to "transparent")
202
	 *
203
	 * @see \ImagickPixel::__construct()
204
	 */
205
	protected ?string $imagickBG = null;
206
207
	/**
208
	 * Measurement unit for FPDF output: pt, mm, cm, in (defaults to "pt")
209
	 *
210
	 * @see \FPDF::__construct()
211
	 */
212
	protected string $fpdfMeasureUnit = 'pt';
213
214
	/**
215
	 * Module values map
216
	 *
217
	 *   - HTML, IMAGICK: #ABCDEF, cssname, rgb(), rgba()...
218
	 *   - IMAGE: [63, 127, 255] // R, G, B
219
	 */
220
	protected ?array $moduleValues = null;
221
222
	/**
223
	 * use Imaagick (if available) when reading QR Codes
224
	 */
225
	protected bool $useImagickIfAvailable = false;
226
227
	/**
228
	 * clamp min/max version number
229
	 */
230
	protected function setMinMaxVersion(int $versionMin, int $versionMax):void{
231
		$min = max(1, min(40, $versionMin));
232
		$max = max(1, min(40, $versionMax));
233
234
		$this->versionMin = min($min, $max);
235
		$this->versionMax = max($min, $max);
236
	}
237
238
	/**
239
	 * sets the minimum version number
240
	 */
241
	protected function set_versionMin(int $version):void{
242
		$this->setMinMaxVersion($version, $this->versionMax);
243
	}
244
245
	/**
246
	 * sets the maximum version number
247
	 */
248
	protected function set_versionMax(int $version):void{
249
		$this->setMinMaxVersion($this->versionMin, $version);
250
	}
251
252
	/**
253
	 * sets the error correction level
254
	 *
255
	 * @throws \chillerlan\QRCode\QRCodeException
256
	 */
257
	protected function set_eccLevel(int $eccLevel):void{
258
259
		if(!isset(EccLevel::MODES[$eccLevel])){
260
			throw new QRCodeException(sprintf('Invalid error correct level: %s', $eccLevel));
261
		}
262
263
		$this->eccLevel = $eccLevel;
264
	}
265
266
	/**
267
	 * sets/clamps the mask pattern
268
	 */
269
	protected function set_maskPattern(int $maskPattern):void{
270
271
		if($maskPattern !== QRCode::MASK_PATTERN_AUTO){
272
			$this->maskPattern = max(0, min(7, $maskPattern));
273
		}
274
275
	}
276
277
	/**
278
	 * sets the transparency background color
279
	 *
280
	 * @throws \chillerlan\QRCode\QRCodeException
281
	 */
282
	protected function set_imageTransparencyBG(array $imageTransparencyBG):void{
283
284
		// invalid value - set to white as default
285
		if(count($imageTransparencyBG) < 3){
286
			$this->imageTransparencyBG = [255, 255, 255];
287
288
			return;
289
		}
290
291
		foreach($imageTransparencyBG as $k => $v){
292
293
			// cut off exceeding items
294
			if($k > 2){
295
				break;
296
			}
297
298
			if(!is_numeric($v)){
299
				throw new QRCodeException('Invalid RGB value.');
300
			}
301
302
			// clamp the values
303
			$this->imageTransparencyBG[$k] = max(0, min(255, (int)$v));
304
		}
305
306
		// use the array values to not run into errors with the spread operator (...$arr)
307
		$this->imageTransparencyBG = array_values($this->imageTransparencyBG);
308
	}
309
310
	/**
311
	 * sets/clamps the version number
312
	 */
313
	protected function set_version(int $version):void{
314
315
		if($version !== QRCode::VERSION_AUTO){
316
			$this->version = max(1, min(40, $version));
317
		}
318
319
	}
320
321
	/**
322
	 * sets the FPDF measurement unit
323
	 *
324
	 * @codeCoverageIgnore
325
	 */
326
	protected function set_fpdfMeasureUnit(string $unit):void{
327
		$unit = strtolower($unit);
328
329
		if(in_array($unit, ['cm', 'in', 'mm', 'pt'], true)){
330
			$this->fpdfMeasureUnit = $unit;
331
		}
332
333
		// @todo throw or ignore silently?
334
	}
335
336
	/**
337
	 * enables Imagick for the QR Code reader if the extension is available
338
	 *
339
	 * @codeCoverageIgnore
340
	 */
341
	protected function set_useImagickIfAvailable(bool $useImagickIfAvailable):void{
342
		$this->useImagickIfAvailable = $useImagickIfAvailable && extension_loaded('imagick');
343
	}
344
345
}
346