1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Drupal\embed; |
4
|
|
|
|
5
|
|
|
use Drupal\Component\Utility\Html; |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Wrapper methods for manipulating DOM entries. |
9
|
|
|
* |
10
|
|
|
* This utility trait should only be used in application-level code, such as |
11
|
|
|
* classes that would implement ContainerInjectionInterface. Services registered |
12
|
|
|
* in the Container should not use this trait but inject the appropriate service |
13
|
|
|
* directly for easier testing. |
14
|
|
|
*/ |
15
|
|
|
trait DomHelperTrait { |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Rename a DOMNode tag. |
19
|
|
|
* |
20
|
|
|
* @param \DOMNode $node |
21
|
|
|
* A DOMElement object. |
22
|
|
|
* @param string $name |
23
|
|
|
* The new tag name. |
24
|
|
|
*/ |
25
|
|
|
protected function changeNodeName(\DOMNode &$node, $name = 'div') { |
26
|
|
|
if ($node->nodeName != $name) { |
27
|
|
|
/** @var \DOMElement $replacement_node */ |
28
|
|
|
$replacement_node = $node->ownerDocument->createElement($name); |
29
|
|
|
|
30
|
|
|
// Copy all children of the original node to the new node. |
31
|
|
|
if ($node->childNodes->length) { |
32
|
|
|
foreach ($node->childNodes as $child) { |
33
|
|
|
$child = $replacement_node->ownerDocument->importNode($child, TRUE); |
34
|
|
|
$replacement_node->appendChild($child); |
35
|
|
|
} |
36
|
|
|
} |
37
|
|
|
|
38
|
|
|
// Copy all attributes of the original node to the new node. |
39
|
|
|
if ($node->attributes->length) { |
|
|
|
|
40
|
|
|
foreach ($node->attributes as $attribute) { |
41
|
|
|
$replacement_node->setAttribute($attribute->nodeName, $attribute->nodeValue); |
42
|
|
|
} |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
$node->parentNode->replaceChild($replacement_node, $node); |
46
|
|
|
$node = $replacement_node; |
47
|
|
|
} |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* Set the contents of a DOMNode. |
52
|
|
|
* |
53
|
|
|
* @param \DOMNode $node |
54
|
|
|
* A DOMNode object. |
55
|
|
|
* @param string $content |
56
|
|
|
* The text or HTML that will replace the contents of $node. |
57
|
|
|
*/ |
58
|
|
|
protected function setNodeContent(\DOMNode $node, $content) { |
59
|
|
|
// Remove all children of the DOMNode. |
60
|
|
|
while ($node->hasChildNodes()) { |
61
|
|
|
$node->removeChild($node->firstChild); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
if (strlen($content)) { |
65
|
|
|
// Load the contents into a new DOMDocument and retrieve the elements. |
66
|
|
|
$replacement_nodes = Html::load($content)->getElementsByTagName('body')->item(0); |
67
|
|
|
|
68
|
|
|
// Finally, import and append the contents to the original node. |
69
|
|
|
foreach ($replacement_nodes->childNodes as $replacement_node) { |
70
|
|
|
$replacement_node = $node->ownerDocument->importNode($replacement_node, TRUE); |
71
|
|
|
$node->appendChild($replacement_node); |
72
|
|
|
} |
73
|
|
|
} |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* Replace the contents of a DOMNode. |
78
|
|
|
* |
79
|
|
|
* @param \DOMNode $node |
80
|
|
|
* A DOMNode object. |
81
|
|
|
* @param string $content |
82
|
|
|
* The text or HTML that will replace the contents of $node. |
83
|
|
|
*/ |
84
|
|
|
protected function replaceNodeContent(\DOMNode &$node, $content) { |
85
|
|
|
if (strlen($content)) { |
86
|
|
|
// Load the content into a new DOMDocument and retrieve the DOM nodes. |
87
|
|
|
$replacement_nodes = Html::load($content)->getElementsByTagName('body') |
88
|
|
|
->item(0) |
89
|
|
|
->childNodes; |
90
|
|
|
} |
91
|
|
|
else { |
92
|
|
|
$replacement_nodes = [$node->ownerDocument->createTextNode('')]; |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
foreach ($replacement_nodes as $replacement_node) { |
96
|
|
|
// Import the replacement node from the new DOMDocument into the original |
97
|
|
|
// one, importing also the child nodes of the replacement node. |
98
|
|
|
$replacement_node = $node->ownerDocument->importNode($replacement_node, TRUE); |
99
|
|
|
$node->parentNode->insertBefore($replacement_node, $node); |
100
|
|
|
} |
101
|
|
|
$node->parentNode->removeChild($node); |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* Convert the attributes on a DOMNode object to an array. |
106
|
|
|
* |
107
|
|
|
* This will also un-serialize any attribute values stored as JSON. |
108
|
|
|
* |
109
|
|
|
* @param \DOMNode $node |
110
|
|
|
* A DOMNode object. |
111
|
|
|
* |
112
|
|
|
* @return array |
113
|
|
|
* The attributes as an associative array, keyed by the attribute names. |
114
|
|
|
*/ |
115
|
|
|
public function getNodeAttributesAsArray(\DOMNode $node) { |
116
|
|
|
$return = []; |
117
|
|
|
|
118
|
|
|
// Convert the data attributes to the context array. |
119
|
|
|
foreach ($node->attributes as $attribute) { |
120
|
|
|
$key = $attribute->nodeName; |
121
|
|
|
$return[$key] = $attribute->nodeValue; |
122
|
|
|
|
123
|
|
|
// Check for JSON-encoded attributes. |
124
|
|
|
$data = json_decode($return[$key], TRUE, 10); |
125
|
|
|
if ($data !== NULL && json_last_error() === JSON_ERROR_NONE) { |
126
|
|
|
$return[$key] = $data; |
127
|
|
|
} |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
return $return; |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
} |
134
|
|
|
|
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.
If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.