DomHelperTrait::changeNodeName()   B
last analyzed

Complexity

Conditions 6
Paths 5

Size

Total Lines 24
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 12
nc 5
nop 2
dl 0
loc 24
rs 8.5125
c 0
b 0
f 0
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) {
0 ignored issues
show
Bug introduced by
The property length does not seem to exist in DOMNamedNodeMap.

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.

Loading history...
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