source: trunk/client/inc/hpdf5/spipu/html2pdf/src/Parsing/TagParser.php@ 347

Last change on this file since 347 was 347, checked in by roby, 3 years ago

Aggiornamento per compatibilità con php7.4

File size: 7.2 KB
Line 
1<?php
2/**
3 * Html2Pdf Library - parsing Html class
4 *
5 * HTML => PDF converter
6 * distributed under the OSL-3.0 License
7 *
8 * @package Html2pdf
9 * @author Laurent MINGUET <webmaster@html2pdf.fr>
10 * @copyright 2017 Laurent MINGUET
11 */
12namespace Spipu\Html2Pdf\Parsing;
13
14use Spipu\Html2Pdf\Exception\HtmlParsingException;
15
16/**
17 * Class TagParser
18 */
19class TagParser
20{
21 protected $level; // table level
22 protected $num = 0; // table number
23 protected $textParser;
24
25 public function __construct(TextParser $textParser)
26 {
27 $this->textParser = $textParser;
28 $this->level = array($this->num);
29 }
30
31 /**
32 * analyze a HTML tag
33 *
34 * @param string $code HTML code to analyze
35 *
36 * @return Node corresponding action
37 * @throws HtmlParsingException
38 */
39 public function analyzeTag($code)
40 {
41 // name of the tag, opening, closure, autoclosure
42 $tag = '<([\/]{0,1})([_a-z0-9]+)([\/>\s]+)';
43 if (!preg_match('/'.$tag.'/isU', $code, $match)) {
44 $e = new HtmlParsingException('The HTML tag ['.$code.'] provided is invalid');
45 $e->setInvalidTag($code);
46 throw $e;
47 }
48 $close = ($match[1] === '/' ? true : false);
49 $autoclose = preg_match('/\/>$/isU', $code);
50 $name = strtolower($match[2]);
51
52 // required parameters (depends on the tag name)
53 $defaultParams = array();
54 $defaultParams['style'] = '';
55 if ($name === 'img') {
56 $defaultParams['alt'] = '';
57 $defaultParams['src'] = '';
58 } elseif ($name === 'a') {
59 $defaultParams['href'] = '';
60 }
61
62 $param = array_merge($defaultParams, $this->extractTagAttributes($code));
63 $param['style'] = trim($param['style']);
64 if (strlen($param['style']) > 0 && substr($param['style'], -1) !== ';') {
65 $param['style'].= ';';
66 }
67
68 // compliance of each parameter
69 $color = "#000000";
70 $border = null;
71 foreach ($param as $key => $val) {
72 switch ($key) {
73 case 'width':
74 unset($param[$key]);
75 $param['style'] .= 'width: '.$val.'px; ';
76 break;
77
78 case 'align':
79 if ($name === 'img') {
80 unset($param[$key]);
81 $param['style'] .= 'float: '.$val.'; ';
82 } elseif ($name !== 'table') {
83 unset($param[$key]);
84 $param['style'] .= 'text-align: '.$val.'; ';
85 }
86 break;
87
88 case 'valign':
89 unset($param[$key]);
90 $param['style'] .= 'vertical-align: '.$val.'; ';
91 break;
92
93 case 'height':
94 unset($param[$key]);
95 $param['style'] .= 'height: '.$val.'px; ';
96 break;
97
98 case 'bgcolor':
99 unset($param[$key]);
100 $param['style'] .= 'background: '.$val.'; ';
101 break;
102
103 case 'bordercolor':
104 unset($param[$key]);
105 $color = $val;
106 break;
107
108 case 'border':
109 unset($param[$key]);
110 if (preg_match('/^[0-9]+$/isU', $val)) {
111 $val = $val.'px';
112 }
113 $border = $val;
114 break;
115
116 case 'cellpadding':
117 case 'cellspacing':
118 if (preg_match('/^([0-9]+)$/isU', $val)) {
119 $param[$key] = $val.'px';
120 }
121 break;
122
123 case 'colspan':
124 case 'rowspan':
125 $val = preg_replace('/[^0-9]/isU', '', $val);
126 if (!$val) {
127 $val = 1;
128 }
129 $param[$key] = (int) $val;
130 break;
131
132 case 'color':
133 if ($name === 'font') {
134 unset($param[$key]);
135 $param['style'] .= 'color: '.$val.'; ';
136 }
137 break;
138 }
139 }
140
141 // compliance of the border
142 if ($border !== null) {
143 if ($border && $border !== '0px') {
144 $border = 'solid '.$border.' '.$color;
145 } else {
146 $border = 'none';
147 }
148
149 $param['style'] .= 'border: '.$border.'; ';
150 $param['border'] = $border;
151 }
152
153 // reading styles: decomposition and standardization
154 $styles = explode(';', $param['style']);
155 $param['style'] = array();
156 foreach ($styles as $style) {
157 $tmp = explode(':', $style);
158 if (count($tmp) > 1) {
159 $cod = $tmp[0];
160 unset($tmp[0]);
161 $tmp = implode(':', $tmp);
162 $param['style'][trim(strtolower($cod))] = preg_replace('/[\s]+/isU', ' ', trim($tmp));
163 }
164 }
165
166 // determining the level of table opening, with an added level
167 if (in_array($name, array('ul', 'ol', 'table')) && !$close) {
168 $this->num++;
169 array_push($this->level, $this->num);
170 }
171
172 // get the level of the table containing the element
173 if (!isset($param['num'])) {
174 $param['num'] = end($this->level);
175 }
176
177 // for closures table: remove a level
178 if (in_array($name, array('ul', 'ol', 'table')) && $close) {
179 array_pop($this->level);
180 }
181
182 // prepare the parameters
183 if (isset($param['value'])) {
184 $keepSpaces = in_array($name, array('qrcode', 'barcode'));
185 $param['value'] = $this->textParser->prepareTxt($param['value'], !$keepSpaces);
186 }
187 if (isset($param['alt'])) {
188 $param['alt'] = $this->textParser->prepareTxt($param['alt']);
189 }
190 if (isset($param['title'])) {
191 $param['title'] = $this->textParser->prepareTxt($param['title']);
192 }
193 if (isset($param['class'])) {
194 $param['class'] = $this->textParser->prepareTxt($param['class']);
195 }
196
197 // return the new action to do
198 return new Node($name, $param, $close, $autoclose);
199 }
200
201 /**
202 * Extract the list of attribute => value inside an HTML tag
203 *
204 * @param string $code The full HTML tag to parse
205 *
206 * @return array
207 */
208 public function extractTagAttributes($code)
209 {
210 $param = array();
211 $regexes = array(
212 '([a-zA-Z0-9_]+)=([^"\'\s>]+)', // read the parameters : name=value
213 '([a-zA-Z0-9_]+)=["]([^"]*)["]', // read the parameters : name="value"
214 "([a-zA-Z0-9_]+)=[']([^']*)[']" // read the parameters : name='value'
215 );
216
217 foreach ($regexes as $regex) {
218 preg_match_all('/'.$regex.'/is', $code, $match);
219 $amountMatch = count($match[0]);
220 for ($k = 0; $k < $amountMatch; $k++) {
221 $param[trim(strtolower($match[1][$k]))] = trim($match[2][$k]);
222 }
223 }
224
225 return $param;
226 }
227}
Note: See TracBrowser for help on using the repository browser.