1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Extend \DomNode |
4
|
|
|
* |
5
|
|
|
* PHP version 5.4 |
6
|
|
|
* |
7
|
|
|
* @category GLICER |
8
|
|
|
* @package GlHtml |
9
|
|
|
* @author Emmanuel ROECKER |
10
|
|
|
* @author Rym BOUCHAGOUR |
11
|
|
|
* @copyright 2015 GLICER |
12
|
|
|
* @license MIT |
13
|
|
|
* @link http://dev.glicer.com/ |
14
|
|
|
* |
15
|
|
|
* Created : 19/02/15 |
16
|
|
|
* File : GlHtmlNode.php |
17
|
|
|
* |
18
|
|
|
*/ |
19
|
|
|
|
20
|
|
|
|
21
|
|
|
namespace GlHtml; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* Class GlHtmlNode |
25
|
|
|
* @package GlHtml |
26
|
|
|
*/ |
27
|
|
|
class GlHtmlNode |
28
|
|
|
{ |
29
|
|
|
/** |
30
|
|
|
* @var \DOMNode |
31
|
|
|
*/ |
32
|
|
|
private $node; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* @param \DOMNode $node |
36
|
|
|
*/ |
37
|
|
|
public function __construct(\DOMNode $node) |
38
|
|
|
{ |
39
|
|
|
$this->node = $node; |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* @param array $attributes |
44
|
|
|
*/ |
45
|
|
|
public function setAttributes(array $attributes) |
46
|
|
|
{ |
47
|
|
|
foreach ($attributes as $name => $value) { |
48
|
|
|
$this->node->setAttribute($name, $value); |
49
|
|
|
} |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* @param string $value |
54
|
|
|
*/ |
55
|
|
|
public function setValue($value) |
56
|
|
|
{ |
57
|
|
|
$this->node->nodeValue = $value; |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* @param string $html |
62
|
|
|
*/ |
63
|
|
|
public |
64
|
|
|
function add( |
65
|
|
|
$html |
66
|
|
|
) { |
67
|
|
|
$frag = $this->node->ownerDocument->createDocumentFragment(); |
68
|
|
|
$frag->appendXML($html); |
69
|
|
|
$this->node->appendChild($frag); |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* @return GlHtmlNode |
74
|
|
|
*/ |
75
|
|
|
public function getParent() |
76
|
|
|
{ |
77
|
|
|
return new GlHtmlNode($this->node->parentNode); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* @param string $html |
82
|
|
|
*/ |
83
|
|
|
public |
84
|
|
|
function replaceMe( |
85
|
|
|
$html |
86
|
|
|
) { |
87
|
|
|
$frag = $this->node->ownerDocument->createDocumentFragment(); |
88
|
|
|
$frag->appendXML($html); |
89
|
|
|
$this->node->parentNode->replaceChild($frag, $this->node); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* @param string $html |
94
|
|
|
*/ |
95
|
|
|
public function replaceInner($html) |
96
|
|
|
{ |
97
|
|
|
$this->setValue(''); |
98
|
|
|
$this->add($html); |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* @return \DOMNode |
104
|
|
|
*/ |
105
|
|
|
public function getDOMNode() |
106
|
|
|
{ |
107
|
|
|
return $this->node; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* @return string |
112
|
|
|
*/ |
113
|
|
|
public function getName() |
114
|
|
|
{ |
115
|
|
|
return strtolower($this->node->nodeName); |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* @param array $hasAttributesList |
120
|
|
|
* |
121
|
|
|
* @return bool |
122
|
|
|
*/ |
123
|
|
|
public function hasAttributes(array $hasAttributesList) |
124
|
|
|
{ |
125
|
|
|
$attributes = $this->node->attributes; |
126
|
|
|
|
127
|
|
|
foreach ($attributes as $name => $attrNode) { |
128
|
|
|
if (in_array($name, $hasAttributesList)) { |
129
|
|
|
return true; |
130
|
|
|
} |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
return false; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
/** |
137
|
|
|
* @param string $name |
138
|
|
|
* |
139
|
|
|
* @return string |
140
|
|
|
*/ |
141
|
|
|
public |
142
|
|
|
function getAttribute( |
143
|
|
|
$name |
144
|
|
|
) { |
145
|
|
|
return $this->node->getAttribute($name); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
/** |
149
|
|
|
* @return string |
150
|
|
|
*/ |
151
|
|
|
public |
152
|
|
|
function getText() |
153
|
|
|
{ |
154
|
|
|
return $this->node->nodeValue; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* @return array |
160
|
|
|
*/ |
161
|
|
|
public function getSentences() |
162
|
|
|
{ |
163
|
|
|
$sentences = []; |
164
|
|
|
$sentence = ""; |
165
|
|
|
self::iterateSentencesOverNode($this->node, $sentence, $sentences); |
166
|
|
|
|
167
|
|
|
$sentence = trim($sentence); |
168
|
|
|
if (strlen($sentence) > 0) { |
169
|
|
|
$sentences[] = $sentence; |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
return $sentences; |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
public |
176
|
|
|
function delete() |
177
|
|
|
{ |
178
|
|
|
$this->node->parentNode->removeChild($this->node); |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* @return string |
183
|
|
|
*/ |
184
|
|
|
public |
185
|
|
|
function getHtml() |
186
|
|
|
{ |
187
|
|
|
$innerHTML = ''; |
188
|
|
|
$children = $this->node->childNodes; |
189
|
|
|
foreach ($children as $child) { |
190
|
|
|
$innerHTML .= $child->ownerDocument->saveXML($child, LIBXML_NOEMPTYTAG); |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
return $innerHTML; |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
/** |
197
|
|
|
* extract h tag from html |
198
|
|
|
* |
199
|
|
|
* @param \DOMNodeList $nodeList |
200
|
|
|
* @param callable $fct |
201
|
|
|
*/ |
202
|
|
|
private function recursiveCallChild(\DOMNodeList $nodeList, callable $fct) |
203
|
|
|
{ |
204
|
|
|
/** |
205
|
|
|
* @var \DOMNode $domNode |
206
|
|
|
*/ |
207
|
|
|
foreach ($nodeList as $domNode) { |
208
|
|
|
$fct(new GlHtmlNode($domNode)); |
209
|
|
|
if ($domNode->hasChildNodes()) { |
210
|
|
|
$this->recursiveCallChild($domNode->childNodes, $fct); |
211
|
|
|
} |
212
|
|
|
} |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
/** |
216
|
|
|
* @param callable $fct |
217
|
|
|
*/ |
218
|
|
|
public function callChild(callable $fct) |
219
|
|
|
{ |
220
|
|
|
$this->recursiveCallChild($this->node->childNodes, $fct); |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
/** |
224
|
|
|
* @param \DOMNode $node |
225
|
|
|
* @param string $sentence |
226
|
|
|
* @param array $sentences |
227
|
|
|
* |
228
|
|
|
* @return int |
229
|
|
|
*/ |
230
|
|
|
private static function iterateSentencesOverNode(\DOMNode $node, &$sentence, array &$sentences) |
231
|
|
|
{ |
232
|
|
|
if ($node instanceof \DOMText) { |
233
|
|
|
$sentence .= preg_replace("/[\\t\\n\\f\\r ]+/im", " ", $node->wholeText); |
234
|
|
|
|
235
|
|
|
return 0; |
236
|
|
|
} |
237
|
|
|
if ($node instanceof \DOMDocumentType) { |
238
|
|
|
return 0; |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
$name = strtolower($node->nodeName); |
242
|
|
|
if (preg_match('/^h(\d+)$/', $name)) { |
243
|
|
|
$name = "hx"; |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
switch ($name) { |
247
|
|
|
case "hr": |
248
|
|
|
case "style": |
249
|
|
|
case "head": |
250
|
|
|
case "title": |
251
|
|
|
case "meta": |
252
|
|
|
case "script": |
253
|
|
|
case "pre": |
254
|
|
|
return 0; |
255
|
|
|
|
256
|
|
|
case "p": |
257
|
|
|
case "hx": |
258
|
|
|
case "th": |
259
|
|
|
case "td": |
260
|
|
|
case "li": |
261
|
|
|
case "label": |
262
|
|
View Code Duplication |
case "button": |
|
|
|
|
263
|
|
|
$sentence = trim($sentence); |
264
|
|
|
if (strlen($sentence) > 0) { |
265
|
|
|
$sentences[] = $sentence; |
266
|
|
|
} |
267
|
|
|
$sentence = ""; |
268
|
|
|
break; |
269
|
|
|
|
270
|
|
|
case "br": |
271
|
|
|
$sentence .= " "; |
272
|
|
|
break; |
273
|
|
|
default: |
274
|
|
|
break; |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
$childs = $node->childNodes; |
278
|
|
|
foreach ($childs as $child) { |
279
|
|
|
self::iterateSentencesOverNode($child, $sentence, $sentences); |
280
|
|
|
} |
281
|
|
|
|
282
|
|
|
switch ($name) { |
283
|
|
|
case "style": |
284
|
|
|
case "head": |
285
|
|
|
case "title": |
286
|
|
|
case "meta": |
287
|
|
|
case "script": |
288
|
|
|
return ""; |
289
|
|
|
|
290
|
|
|
case "p": |
291
|
|
|
case "hx": |
292
|
|
|
case "th": |
293
|
|
|
case "td": |
294
|
|
|
case "li": |
295
|
|
|
case "label": |
296
|
|
View Code Duplication |
case "button": |
|
|
|
|
297
|
|
|
$sentence = trim($sentence); |
298
|
|
|
if (strlen($sentence) > 0) { |
299
|
|
|
$sentences[] = $sentence; |
300
|
|
|
} |
301
|
|
|
$sentence = ""; |
302
|
|
|
break; |
303
|
|
|
|
304
|
|
|
default: |
305
|
|
|
break; |
306
|
|
|
} |
307
|
|
|
|
308
|
|
|
return 0; |
309
|
|
|
} |
310
|
|
|
} |
311
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.