Completed
Push — master ( 102ef4...1ff5c6 )
by smiley
02:47
created

QRMarkup::dump()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 0
1
<?php
2
/**
3
 * Class QRMarkup
4
 *
5
 * @filesource   QRMarkup.php
6
 * @created      17.12.2016
7
 * @package      chillerlan\QRCode\Output
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2016 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\QRCode\Output;
14
15
use chillerlan\QRCode\QRCode;
16
17
/**
18
 *
19
 */
20
class QRMarkup extends QROutputAbstract{
21
22
	/**
23
	 * @var string
24
	 */
25
	protected $optionsInterface = QRMarkupOptions::class;
26
27
	/**
28
	 * @var array
29
	 */
30
	protected $types = [
31
		QRCode::OUTPUT_MARKUP_HTML,
32
		QRCode::OUTPUT_MARKUP_SVG,
33
	];
34
35
	/**
36
	 * @return string
37
	 */
38
	public function dump(){
39
		switch($this->options->type){
40
			case QRCode::OUTPUT_MARKUP_SVG : return $this->toSVG();
2 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
41
			case QRCode::OUTPUT_MARKUP_HTML:
42
			default:
43
				return $this->toHTML();
44
		}
45
	}
46
47
	/**
48
	 * @return string
49
	 */
50
	protected function toHTML(){
51
		$html = '';
52
53
		foreach($this->matrix as $row){
54
			// in order to not bloat the output too much, we use the shortest possible valid HTML tags
55
			$html .= '<'.$this->options->htmlRowTag.'>';
56
57
			foreach($row as $col){
58
				$tag = $col
59
					? 'b'  // dark
60
					: 'i'; // light
61
62
				$html .= '<'.$tag.'></'.$tag.'>';
63
			}
64
65
			if(!(bool)$this->options->htmlOmitEndTag){
66
				$html .= '</'.$this->options->htmlRowTag.'>';
67
			}
68
69
			$html .= $this->options->eol;
70
		}
71
72
		return $html;
73
	}
74
75
	/**
76
	 * @return string
77
	 * @throws \chillerlan\QRCode\Output\QRCodeOutputException
78
	 */
79
	protected function toSVG(){
80
		$length = $this->pixelCount * $this->options->pixelSize + $this->options->marginSize * 2;
81
		$class  = !empty($this->options->cssClass) ? $this->options->cssClass : hash('crc32', microtime(true));
82
83
		// svg header
84
		$svg = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="'.$length.'" height="'.$length.'" viewBox="0 0 '.$length.' '.$length.'" style="background-color:'.$this->options->bgColor.'">'.$this->options->eol.
85
		       '<defs><style>.'.$class.'{fill:'.$this->options->fgColor.'} rect{shape-rendering:crispEdges}</style></defs>'.$this->options->eol;
86
87
		// svg body
88
		foreach($this->matrix as $r => $row){
89
			//we'll combine active blocks within a single row as a lightweight compression technique
90
			$from  = -1;
91
			$count = 0;
92
93
			foreach($row as $c => $pixel){
94
				if($pixel){
95
					$count++;
96
97
					if($from < 0){
98
						$from = $c;
99
					}
100
				}
101
				elseif($from >= 0){
102
					$svg .= '<rect x="'.($from * $this->options->pixelSize + $this->options->marginSize).'" y="'.($r * $this->options->pixelSize + $this->options->marginSize)
103
					        .'" width="'.($this->options->pixelSize * $count).'" height="'.$this->options->pixelSize.'" class="'.$class.'" />'.$this->options->eol;
104
105
					// reset count
106
					$from  = -1;
107
					$count = 0;
108
				}
109
			}
110
111
			// close off the row, if applicable
112
			if($from >= 0){
113
				$svg .= '<rect x="'.($from * $this->options->pixelSize + $this->options->marginSize).'" y="'.($r * $this->options->pixelSize + $this->options->marginSize)
114
				        .'" width="'.($this->options->pixelSize * $count).'" height="'.$this->options->pixelSize.'" class="'.$class.'" />'.$this->options->eol;
115
			}
116
		}
117
118
		// close svg
119
		$svg .= '</svg>'.$this->options->eol;
120
121
		// if saving to file, append the correct headers
122
		if($this->options->cachefile){
123
			$svg = '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'.$this->options->eol.$svg;
124
125
			if(@file_put_contents($this->options->cachefile, $svg) === false){
126
				throw new QRCodeOutputException('Could not write to cache file.'); // @codeCoverageIgnore
127
			}
128
		}
129
130
		return $svg;
131
	}
132
133
}
134