1 <?php
2 3 4 5 6 7
8
9 namespace Cross\Lib\Document;
10
11 use Closure;
12 use DOMDocument;
13 use DOMElement;
14 use DOMNode;
15
16 17 18 19 20 21 22
23 class CallTreeToHTML
24 {
25 26 27
28 private $dom;
29
30 31 32
33 private $element;
34
35 private function __construct()
36 {
37 $this->dom = new DOMDocument();
38 }
39
40 static function getInstance()
41 {
42 return new CallTreeToHTML();
43 }
44
45 46 47 48 49 50
51 function getDom($node)
52 {
53 $this->makeNode($node);
54 $this->dom->appendChild($this->element);
55 return $this->dom;
56 }
57
58 59 60 61 62 63 64
65 function getHTML($node, $html_decode = true)
66 {
67 $dom = $this->getDom($node);
68 $dom->encoding = 'utf-8';
69 $html = $dom->saveHTML($dom->firstChild);
70 if ($html_decode) {
71 $html = html_entity_decode($html);
72 }
73
74 return $html;
75 }
76
77 78 79 80 81 82
83 function makeNode($node, DOMNode $parentElement = null)
84 {
85 $content = null;
86 $attr_set = array();
87
88
89 if (null === $parentElement) {
90 $root_element_name = current(array_keys($node));
91
92 $node = current($node);
93 if (isset($node[0]) && !$node[0] instanceof CallTree) {
94 if (is_array($node[0])) {
95 if (isset($node[0]['@content'])) {
96 $content = $node[0]['@content'];
97 unset($node[0]['@content']);
98 }
99 $attr_set = $node[0];
100 } else {
101 $content = $node[0];
102 unset($node[0]);
103 }
104 }
105
106 $this->element = $this->dom->createElement($root_element_name, htmlentities($content));
107 if (!empty($attr_set)) {
108 foreach ($attr_set as $attr_set_name => $attr_set_value) {
109 $this->element->setAttribute($attr_set_name, $attr_set_value);
110 }
111 }
112 }
113
114
115 if ($parentElement && isset($node[0]) && !$node[0] instanceof CallTree) {
116 if (!empty($node[0])) {
117 foreach ($node[0] as $attr_set_name => $attr_set_value) {
118 if ($attr_set_value instanceof Closure) {
119 $attr_set_value = call_user_func($attr_set_value);
120 }
121 $parentElement->setAttribute($attr_set_name, $attr_set_value);
122 }
123 }
124 }
125
126 foreach ($node as $n) {
127 if (!empty($n) && $n instanceof CallTree) {
128 $node_detail = $n->getNode();
129 foreach ($node_detail as $element_name => $child_node) {
130
131
132 if (isset($child_node[0]) && !$child_node[0] instanceof CallTree) {
133 if (is_array($child_node[0])) {
134 if (isset($child_node[0]['@content'])) {
135 $content = $child_node[0]['@content'];
136 unset($child_node[0]['@content']);
137 }
138 } else {
139 $content = $child_node[0];
140 unset($child_node[0]);
141 }
142 }
143
144 $element = $this->dom->createElement($element_name, htmlentities($content));
145 if ($parentElement instanceof DOMElement) {
146 $current_element = $parentElement->appendChild($element);
147 } else {
148 $current_element = $this->element->appendChild($element);
149 }
150
151 if (!empty($child_node)) {
152 $this->makeNode($child_node, $current_element);
153 }
154 }
155 }
156 }
157 }
158 }
159