10
10
11
11
namespace chillerlan \QRCode \Output ;
12
12
13
- use chillerlan \QRCode \Data \QRMatrix ;
14
- use chillerlan \QRCode \QRCode ;
15
-
16
- use function implode , is_string , sprintf , strip_tags , trim ;
13
+ use function is_string , strip_tags , trim ;
17
14
18
15
/**
19
- * Converts the matrix into markup types: HTML, SVG, ...
16
+ * Abstract for markup types: HTML, SVG, ... XML anyone?
20
17
*/
21
- class QRMarkup extends QROutputAbstract{
18
+ abstract class QRMarkup extends QROutputAbstract{
22
19
23
20
/**
24
21
* @inheritDoc
@@ -44,18 +41,11 @@ protected function getDefaultModuleValue(bool $isDark):string{
44
41
/**
45
42
* @inheritDoc
46
43
*/
47
- public function dump (string $ file = null ){
44
+ public function dump (string $ file = null ): string {
48
45
$ file ??= $ this ->options ->cachefile ;
49
46
$ saveToFile = $ file !== null ;
50
47
51
- switch ($ this ->options ->outputType ){
52
- case QRCode::OUTPUT_MARKUP_HTML :
53
- $ data = $ this ->html ($ saveToFile );
54
- break ;
55
- case QRCode::OUTPUT_MARKUP_SVG :
56
- default :
57
- $ data = $ this ->svg ($ saveToFile );
58
- }
48
+ $ data = $ this ->createMarkup ($ saveToFile );
59
49
60
50
if ($ saveToFile ){
61
51
$ this ->saveToFile ($ data , $ file );
@@ -65,143 +55,7 @@ public function dump(string $file = null){
65
55
}
66
56
67
57
/**
68
- * HTML output
69
- */
70
- protected function html (bool $ saveToFile ):string {
71
-
72
- $ html = empty ($ this ->options ->cssClass )
73
- ? '<div> '
74
- : sprintf ('<div class="%s"> ' , $ this ->options ->cssClass );
75
-
76
- $ html .= $ this ->options ->eol ;
77
-
78
- foreach ($ this ->matrix ->matrix () as $ row ){
79
- $ html .= '<div> ' ;
80
-
81
- foreach ($ row as $ M_TYPE ){
82
- $ html .= sprintf ('<span style="background: %s;"></span> ' , $ this ->moduleValues [$ M_TYPE ]);
83
- }
84
-
85
- $ html .= '</div> ' .$ this ->options ->eol ;
86
- }
87
-
88
- $ html .= '</div> ' .$ this ->options ->eol ;
89
-
90
- if ($ saveToFile ){
91
- return sprintf (
92
- '<!DOCTYPE html><head><meta charset="UTF-8"><title>QR Code</title></head><body>%s</body> ' ,
93
- $ this ->options ->eol .$ html
94
- );
95
- }
96
-
97
- return $ html ;
98
- }
99
-
100
- /**
101
- * SVG output
102
58
*
103
- * @see https://github.com/codemasher/php-qrcode/pull/5
104
- * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg
105
- * @see https://www.sarasoueidan.com/demos/interactive-svg-coordinate-system/
106
- */
107
- protected function svg (bool $ saveToFile ):string {
108
- $ svg = $ this ->svgHeader ();
109
-
110
- if (!empty ($ this ->options ->svgDefs )){
111
- $ svg .= sprintf ('<defs>%1$s%2$s</defs>%2$s ' , $ this ->options ->svgDefs , $ this ->options ->eol );
112
- }
113
-
114
- $ svg .= $ this ->svgPaths ();
115
-
116
- // close svg
117
- $ svg .= sprintf ('%1$s</svg>%1$s ' , $ this ->options ->eol );
118
-
119
- // transform to data URI only when not saving to file
120
- if (!$ saveToFile && $ this ->options ->imageBase64 ){
121
- $ svg = $ this ->base64encode ($ svg , 'image/svg+xml ' );
122
- }
123
-
124
- return $ svg ;
125
- }
126
-
127
- /**
128
- * returns the <svg> header with the given options parsed
129
59
*/
130
- protected function svgHeader ():string {
131
- $ width = $ this ->options ->svgWidth !== null ? sprintf (' width="%s" ' , $ this ->options ->svgWidth ) : '' ;
132
- $ height = $ this ->options ->svgHeight !== null ? sprintf (' height="%s" ' , $ this ->options ->svgHeight ) : '' ;
133
-
134
- /** @noinspection HtmlUnknownAttribute */
135
- return sprintf (
136
- '<?xml version="1.0" encoding="UTF-8"?>%6$s ' .
137
- '<svg xmlns="http://www.w3.org/2000/svg" class="qr-svg %1$s" viewBox="0 0 %2$s %2$s" preserveAspectRatio="%3$s"%4$s%5$s>%6$s ' ,
138
- $ this ->options ->cssClass ,
139
- $ this ->options ->svgViewBoxSize ?? $ this ->moduleCount ,
140
- $ this ->options ->svgPreserveAspectRatio ,
141
- $ width ,
142
- $ height ,
143
- $ this ->options ->eol
144
- );
145
- }
146
-
147
- /**
148
- * returns one or more SVG <path> elements
149
- *
150
- * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path
151
- */
152
- protected function svgPaths ():string {
153
- $ paths = $ this ->collectModules (fn (int $ x , int $ y ):string => $ this ->svgModule ($ x , $ y ));
154
- $ svg = [];
155
-
156
- // create the path elements
157
- foreach ($ paths as $ M_TYPE => $ path ){
158
- $ path = trim (implode (' ' , $ path ));
159
-
160
- if (empty ($ path )){
161
- continue ;
162
- }
163
-
164
- $ cssClass = implode (' ' , [
165
- 'qr- ' .$ M_TYPE ,
166
- ($ M_TYPE & QRMatrix::IS_DARK ) === QRMatrix::IS_DARK ? 'dark ' : 'light ' ,
167
- $ this ->options ->cssClass ,
168
- ]);
169
-
170
- $ format = empty ($ this ->moduleValues [$ M_TYPE ])
171
- ? '<path class="%1$s" d="%2$s"/> '
172
- : '<path class="%1$s" fill="%3$s" fill-opacity="%4$s" d="%2$s"/> ' ;
173
-
174
- $ svg [] = sprintf ($ format , $ cssClass , $ path , $ this ->moduleValues [$ M_TYPE ], $ this ->options ->svgOpacity );
175
- }
176
-
177
- return implode ($ this ->options ->eol , $ svg );
178
- }
179
-
180
- /**
181
- * returns a path segment for a single module
182
- *
183
- * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d
184
- */
185
- protected function svgModule (int $ x , int $ y ):string {
186
-
187
- if ($ this ->options ->imageTransparent && !$ this ->matrix ->check ($ x , $ y )){
188
- return '' ;
189
- }
190
-
191
- if ($ this ->options ->drawCircularModules && $ this ->matrix ->checkTypeNotIn ($ x , $ y , $ this ->options ->keepAsSquare )){
192
- $ r = $ this ->options ->circleRadius ;
193
-
194
- return sprintf (
195
- 'M%1$s %2$s a%3$s %3$s 0 1 0 %4$s 0 a%3$s %3$s 0 1 0 -%4$s 0Z ' ,
196
- ($ x + 0.5 - $ r ),
197
- ($ y + 0.5 ),
198
- $ r ,
199
- ($ r * 2 )
200
- );
201
-
202
- }
203
-
204
- return sprintf ('M%1$s %2$s h%3$s v1 h-%4$sZ ' , $ x , $ y , 1 , 1 );
205
- }
206
-
60
+ abstract protected function createMarkup (bool $ saveToFile ):string ;
207
61
}
0 commit comments