Skip to content

Commit cde2af5

Browse files
committed
🛀 extract QRMarkup into QRMarkupSVG and QRMarkupHTML
1 parent 4f454cb commit cde2af5

File tree

8 files changed

+211
-182
lines changed

8 files changed

+211
-182
lines changed

examples/QRSvgWithLogo.php

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,44 +10,26 @@
1010

1111
namespace chillerlan\QRCodeExamples;
1212

13-
use chillerlan\QRCode\Output\QRMarkup;
14-
use function file_get_contents, sprintf;
13+
use chillerlan\QRCode\Output\QRMarkupSVG;
14+
use function ceil, file_get_contents, sprintf;
1515

1616
/**
1717
* Create SVG QR Codes with embedded logos (that are also SVG)
1818
*/
19-
class QRSvgWithLogo extends QRMarkup{
19+
class QRSvgWithLogo extends QRMarkupSVG{
2020

2121
/**
22-
* SVG output
23-
*
24-
* @see https://github.com/codemasher/php-qrcode/pull/5
25-
* @see https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg
26-
* @see https://www.sarasoueidan.com/demos/interactive-svg-coordinate-system/
22+
* @inheritDoc
2723
*/
28-
protected function svg(bool $saveToFile):string{
24+
protected function paths():string{
2925
$size = (int)ceil($this->moduleCount * $this->options->svgLogoScale);
3026

3127
// we're calling QRMatrix::setLogoSpace() manually, so QROptions::$addLogoSpace has no effect here
3228
$this->matrix->setLogoSpace($size, $size);
3329

34-
$svg = $this->svgHeader();
35-
36-
if(!empty($this->options->svgDefs)){
37-
$svg .= sprintf('<defs>%1$s%2$s</defs>%2$s', $this->options->svgDefs, $this->options->eol);
38-
}
39-
40-
$svg .= $this->svgPaths();
30+
$svg = parent::paths();
4131
$svg .= $this->getLogo();
4232

43-
// close svg
44-
$svg .= sprintf('%1$s</svg>%1$s', $this->options->eol);
45-
46-
// transform to data URI only when not saving to file
47-
if(!$saveToFile && $this->options->imageBase64){
48-
$svg = $this->base64encode($svg, 'image/svg+xml');
49-
}
50-
5133
return $svg;
5234
}
5335

src/Output/QRMarkup.php

Lines changed: 6 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,12 @@
1010

1111
namespace chillerlan\QRCode\Output;
1212

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;
1714

1815
/**
19-
* Converts the matrix into markup types: HTML, SVG, ...
16+
* Abstract for markup types: HTML, SVG, ... XML anyone?
2017
*/
21-
class QRMarkup extends QROutputAbstract{
18+
abstract class QRMarkup extends QROutputAbstract{
2219

2320
/**
2421
* @inheritDoc
@@ -44,18 +41,11 @@ protected function getDefaultModuleValue(bool $isDark):string{
4441
/**
4542
* @inheritDoc
4643
*/
47-
public function dump(string $file = null){
44+
public function dump(string $file = null):string{
4845
$file ??= $this->options->cachefile;
4946
$saveToFile = $file !== null;
5047

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);
5949

6050
if($saveToFile){
6151
$this->saveToFile($data, $file);
@@ -65,143 +55,7 @@ public function dump(string $file = null){
6555
}
6656

6757
/**
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
10258
*
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
12959
*/
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;
20761
}

src/Output/QRMarkupHTML.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
/**
3+
* Class QRMarkupHTML
4+
*
5+
* @created 06.06.2022
6+
* @author smiley <[email protected]>
7+
* @copyright 2022 smiley
8+
* @license MIT
9+
*/
10+
11+
namespace chillerlan\QRCode\Output;
12+
13+
use function sprintf;
14+
15+
/**
16+
* HTML output
17+
*/
18+
class QRMarkupHTML extends QRMarkup{
19+
20+
/**
21+
* @inheritDoc
22+
*/
23+
protected function createMarkup(bool $saveToFile):string{
24+
$html = empty($this->options->cssClass)
25+
? '<div>'
26+
: sprintf('<div class="%s">', $this->options->cssClass);
27+
28+
$html .= $this->options->eol;
29+
30+
foreach($this->matrix->matrix() as $row){
31+
$html .= '<div>';
32+
33+
foreach($row as $M_TYPE){
34+
$html .= sprintf('<span style="background: %s;"></span>', $this->moduleValues[$M_TYPE]);
35+
}
36+
37+
$html .= '</div>'.$this->options->eol;
38+
}
39+
40+
$html .= '</div>'.$this->options->eol;
41+
42+
// wrap the snippet into a body when saving to file
43+
if($saveToFile){
44+
$html = sprintf(
45+
'<!DOCTYPE html><head><meta charset="UTF-8"><title>QR Code</title></head><body>%s</body>',
46+
$this->options->eol.$html
47+
);
48+
}
49+
50+
return $html;
51+
}
52+
53+
}

0 commit comments

Comments
 (0)