Passed
Push — main ( 8c75d8...000860 )
by smiley
10:08
created

QROutputAbstract::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 2
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Class QROutputAbstract
4
 *
5
 * @created      09.12.2015
6
 * @author       Smiley <[email protected]>
7
 * @copyright    2015 Smiley
8
 * @license      MIT
9
 */
10
11
namespace chillerlan\QRCode\Output;
12
13
use chillerlan\QRCode\Data\QRMatrix;
14
use chillerlan\Settings\SettingsContainerInterface;
15
use Closure;
16
use function base64_encode, dirname, file_put_contents, is_writable, ksort, sprintf;
17
18
/**
19
 * common output abstract
20
 */
21
abstract class QROutputAbstract implements QROutputInterface{
22
23
	/**
24
	 * the current size of the QR matrix
25
	 *
26
	 * @see \chillerlan\QRCode\Data\QRMatrix::size()
27
	 */
28
	protected int $moduleCount;
29
30
	/**
31
	 * the current scaling for a QR pixel
32
	 *
33
	 * @see \chillerlan\QRCode\QROptions::$scale
34
	 */
35
	protected int $scale;
36
37
	/**
38
	 * the side length of the QR image (modules * scale)
39
	 */
40
	protected int $length;
41
42
	/**
43
	 * an (optional) array of color values for the several QR matrix parts
44
	 */
45
	protected array $moduleValues;
46
47
	/**
48
	 * the (filled) data matrix object
49
	 */
50
	protected QRMatrix $matrix;
51
52
	/**
53
	 * @var \chillerlan\Settings\SettingsContainerInterface|\chillerlan\QRCode\QROptions
54
	 */
55
	protected SettingsContainerInterface $options;
56
57
	/**
58
	 * QROutputAbstract constructor.
59
	 */
60
	public function __construct(SettingsContainerInterface $options, QRMatrix $matrix){
61
		$this->options     = $options;
62
		$this->matrix      = $matrix;
63
		$this->moduleCount = $this->matrix->size();
64
		$this->scale       = $this->options->scale;
65
		$this->length      = $this->moduleCount * $this->scale;
66
67
		$this->setModuleValues();
68
	}
69
70
	/**
71
	 * Sets the initial module values
72
	 */
73
	protected function setModuleValues():void{
74
75
		foreach($this::DEFAULT_MODULE_VALUES as $M_TYPE => $defaultValue){
76
			$value = $this->options->moduleValues[$M_TYPE] ?? null;
77
78
			$this->moduleValues[$M_TYPE] = $this->moduleValueIsValid($value)
79
				? $this->getModuleValue($value)
80
				: $this->getDefaultModuleValue($defaultValue);
81
		}
82
83
	}
84
85
	/**
86
	 * Determines whether the given value is valid
87
	 *
88
	 * @param mixed|null $value
89
	 */
90
	abstract protected function moduleValueIsValid($value):bool;
91
92
	/**
93
	 * Returns the final value for the given input (return value depends on the output module)
94
	 *
95
	 * @param mixed $value
96
	 *
97
	 * @return mixed
98
	 */
99
	abstract protected function getModuleValue($value);
100
101
	/**
102
	 * Returns a defualt value for either dark or light modules (return value depends on the output module)
103
	 *
104
	 * @return mixed
105
	 */
106
	abstract protected function getDefaultModuleValue(bool $isDark);
107
108
	/**
109
	 * Returns a base64 data URI for the given string and mime type
110
	 */
111
	protected function base64encode(string $data, string $mime):string{
112
		return sprintf('data:%s;base64,%s', $mime, base64_encode($data));
113
	}
114
115
	/**
116
	 * saves the qr data to a file
117
	 *
118
	 * @see file_put_contents()
119
	 * @see \chillerlan\QRCode\QROptions::cachefile
120
	 *
121
	 * @throws \chillerlan\QRCode\Output\QRCodeOutputException
122
	 */
123
	protected function saveToFile(string $data, string $file):void{
124
125
		if(!is_writable(dirname($file))){
126
			throw new QRCodeOutputException(sprintf('Cannot write data to cache file: %s', $file));
127
		}
128
129
		if(file_put_contents($file, $data) === false){
130
			throw new QRCodeOutputException(sprintf('Cannot write data to cache file: %s (file_put_contents error)', $file));
131
		}
132
	}
133
134
	/**
135
	 * collects the modules per QRMatrix::M_* type and runs a $transform functio on each module and
136
	 * returns an array with the transformed modules
137
	 */
138
	protected function collectModules(Closure $transform):array{
139
		$paths = [];
140
141
		// collect the modules for each type
142
		foreach($this->matrix->matrix() as $y => $row){
143
			foreach($row as $x => $M_TYPE){
144
145
				if($this->options->connectPaths && !$this->matrix->checkTypes($x, $y, $this->options->excludeFromConnect)){
0 ignored issues
show
Bug introduced by
It seems like $this->options->excludeFromConnect can also be of type null; however, parameter $M_TYPES of chillerlan\QRCode\Data\QRMatrix::checkTypes() does only seem to accept array, 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

145
				if($this->options->connectPaths && !$this->matrix->checkTypes($x, $y, /** @scrutinizer ignore-type */ $this->options->excludeFromConnect)){
Loading history...
146
					// to connect paths we'll redeclare the $M_TYPE to data only
147
					$M_TYPE = QRMatrix::M_DATA;
148
149
					if($this->matrix->check($x, $y)){
150
						$M_TYPE |= QRMatrix::IS_DARK;
151
					}
152
				}
153
154
				// collect the modules per $M_TYPE
155
				$paths[$M_TYPE][] = $transform($x, $y);
156
			}
157
		}
158
159
		// beautify output
160
		ksort($paths);
161
162
		return $paths;
163
	}
164
165
}
166