Passed
Push — main ( 709a03...3e1426 )
by smiley
02:31
created

QROutputAbstract::saveToFile()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 2
dl 0
loc 7
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, QRCode};
14
use chillerlan\Settings\SettingsContainerInterface;
15
use function base64_encode, dirname, file_put_contents, get_called_class, in_array, is_writable, sprintf;
16
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::size()
26
	 */
27
	protected int $moduleCount;
28
29
	/**
30
	 * the current output mode
31
	 *
32
	 * @see \chillerlan\QRCode\QROptions::$outputType
33
	 */
34
	protected string $outputMode;
35
36
	/**
37
	 * the default output mode of the current output module
38
	 */
39
	protected string $defaultMode;
40
41
	/**
42
	 * the current scaling for a QR pixel
43
	 *
44
	 * @see \chillerlan\QRCode\QROptions::$scale
45
	 */
46
	protected int $scale;
47
48
	/**
49
	 * the side length of the QR image (modules * scale)
50
	 */
51
	protected int $length;
52
53
	/**
54
	 * an (optional) array of color values for the several QR matrix parts
55
	 */
56
	protected array $moduleValues;
57
58
	/**
59
	 * the (filled) data matrix object
60
	 */
61
	protected QRMatrix $matrix;
62
63
	/**
64
	 * @var \chillerlan\Settings\SettingsContainerInterface|\chillerlan\QRCode\QROptions
65
	 */
66
	protected SettingsContainerInterface $options;
67
68
	/**
69
	 * QROutputAbstract constructor.
70
	 */
71
	public function __construct(SettingsContainerInterface $options, QRMatrix $matrix){
72
		$this->options     = $options;
73
		$this->matrix      = $matrix;
74
		$this->moduleCount = $this->matrix->size();
75
		$this->scale       = $this->options->scale;
76
		$this->length      = $this->moduleCount * $this->scale;
77
		$class             = get_called_class();
78
79
		if(isset(QRCode::OUTPUT_MODES[$class]) && in_array($this->options->outputType, QRCode::OUTPUT_MODES[$class])){
80
			$this->outputMode = $this->options->outputType;
81
		}
82
83
		$this->setModuleValues();
84
	}
85
86
	/**
87
	 * Sets the initial module values
88
	 */
89
	protected function setModuleValues():void{
90
91
		foreach($this::DEFAULT_MODULE_VALUES as $M_TYPE => $defaultValue){
92
			$value = $this->options->moduleValues[$M_TYPE] ?? null;
93
94
			$this->moduleValues[$M_TYPE] = $this->moduleValueIsValid($value)
95
				? $this->getModuleValue($value)
96
				: $this->getDefaultModuleValue($defaultValue);
97
		}
98
99
	}
100
101
	/**
102
	 * Determines whether the given value is valid
103
	 *
104
	 * @param mixed|null $value
105
	 */
106
	abstract protected function moduleValueIsValid($value):bool;
107
108
	/**
109
	 * Returns the final value for the given input (return value depends on the output module)
110
	 *
111
	 * @param mixed $value
112
	 *
113
	 * @return mixed
114
	 */
115
	abstract protected function getModuleValue($value);
116
117
	/**
118
	 * Returns a defualt value for either dark or light modules (return value depends on the output module)
119
	 *
120
	 * @return mixed
121
	 */
122
	abstract protected function getDefaultModuleValue(bool $isDark);
123
124
	/**
125
	 * Returns a base64 data URI for the given string and mime type
126
	 */
127
	protected function base64encode(string $data, string $mime):string{
128
		return sprintf('data:%s;base64,%s', $mime, base64_encode($data));
129
	}
130
131
	/**
132
	 * saves the qr data to a file
133
	 *
134
	 * @see file_put_contents()
135
	 * @see \chillerlan\QRCode\QROptions::cachefile
136
	 *
137
	 * @throws \chillerlan\QRCode\Output\QRCodeOutputException
138
	 */
139
	protected function saveToFile(string $data, string $file):bool{
140
141
		if(!is_writable(dirname($file))){
142
			throw new QRCodeOutputException(sprintf('Cannot write data to cache file: %s', $file));
143
		}
144
145
		return (bool)file_put_contents($file, $data);
146
	}
147
148
	/**
149
	 * @inheritDoc
150
	 */
151
	public function dump(string $file = null){
152
		$file ??= $this->options->cachefile;
153
154
		// call the built-in output method with the optional file path as parameter
155
		// to make the called method aware if a cache file was given
156
		$data = $this->{$this->outputMode ?? $this->defaultMode}($file);
157
158
		if($file !== null){
159
			$this->saveToFile($data, $file);
160
		}
161
162
		return $data;
163
	}
164
165
}
166