webmaster@0
|
1 <?php |
webmaster@0
|
2 class Template { |
webmaster@2
|
3 private $xmlDocument; |
webmaster@2
|
4 private $xmlXPath; |
webmaster@0
|
5 |
webmaster@0
|
6 const NS = 'http://defr.net/2007/template'; |
webmaster@0
|
7 |
webmaster@0
|
8 function __construct($fileName) { |
webmaster@2
|
9 $this->xmlDocument = new DOMDocument(); |
webmaster@0
|
10 $this->xmlDocument->validateOnParse = true; |
webmaster@2
|
11 $this->xmlDocument->loadXML(file_get_contents($fileName)); |
webmaster@0
|
12 $this->xmlXPath = new DOMXPath($this->xmlDocument); |
webmaster@0
|
13 } |
webmaster@0
|
14 |
webmaster@0
|
15 function apply($selector, $obj) { |
webmaster@0
|
16 $rootSelector = $this->parseSelector($selector); |
webmaster@0
|
17 // Cloning test |
webmaster@0
|
18 if(is_array($obj)) { |
webmaster@0
|
19 foreach($obj as $array) { |
webmaster@0
|
20 foreach($rootSelector->nodes as $node) { |
webmaster@0
|
21 $nodeName = key($array); |
webmaster@0
|
22 $tmp = $this->getClonedNode($node, $nodeName); |
webmaster@0
|
23 $futureNode = $tmp->clone; |
webmaster@0
|
24 $node->insertBefore($futureNode, $tmp->orig); |
webmaster@0
|
25 foreach($array as $sel => $test) { |
webmaster@0
|
26 $content = $this->parseReplacement($test); |
webmaster@0
|
27 $localSelector = $this->parseSelector($sel); |
webmaster@0
|
28 if(isset($localSelector->attribute)) |
webmaster@0
|
29 $futureNode->setAttribute($localSelector->attribute, $test); |
webmaster@0
|
30 else { |
webmaster@0
|
31 if($futureNode->namespaceURI == Template::NS) |
webmaster@0
|
32 $this->replaceNode($futureNode, $content); |
webmaster@0
|
33 else |
webmaster@0
|
34 $this->setNodeContent($futureNode, $content); |
webmaster@0
|
35 } |
webmaster@0
|
36 } |
webmaster@0
|
37 } |
webmaster@0
|
38 } |
webmaster@0
|
39 } else |
webmaster@0
|
40 { |
webmaster@0
|
41 $content = $this->parseReplacement($obj); |
webmaster@0
|
42 foreach($rootSelector->nodes as $node) { |
webmaster@0
|
43 if(isset($rootSelector->attribute)) { |
webmaster@0
|
44 $node->setAttribute($rootSelector->attribute, $obj); |
webmaster@0
|
45 } else { |
webmaster@0
|
46 if($node->namespaceURI == Template::NS) |
webmaster@0
|
47 $this->replaceNode($node, $content); |
webmaster@0
|
48 else |
webmaster@0
|
49 $this->setNodeContent($node, $content); |
webmaster@0
|
50 } |
webmaster@0
|
51 } |
webmaster@0
|
52 } |
webmaster@0
|
53 } |
webmaster@0
|
54 |
webmaster@0
|
55 function getClonedNode($node, $childNodeName) { |
webmaster@1
|
56 $candidates = $node->getElementsByTagName($childNodeName); |
webmaster@1
|
57 foreach($candidates as $candidate) { |
webmaster@1
|
58 if($candidate->nodeName == $childNodeName && $candidate->getAttributeNS(Template::NS, 'toClone') == 'true') { |
webmaster@0
|
59 $tmp = array(); |
webmaster@1
|
60 $tmp['orig'] = $candidate; |
webmaster@1
|
61 $cnode = $candidate->cloneNode(true); |
webmaster@0
|
62 $cnode->removeAttribute('toClone'); |
webmaster@0
|
63 $tmp['clone'] = $cnode; |
webmaster@0
|
64 return (object)$tmp; |
webmaster@0
|
65 } |
webmaster@0
|
66 } |
webmaster@0
|
67 } |
webmaster@0
|
68 |
webmaster@0
|
69 function parseSelector($selector, DOMElement $root=NULL) { |
webmaster@0
|
70 if(!($root instanceof DOMElement)) { |
webmaster@0
|
71 $root = $this->xmlDocument->documentElement; |
webmaster@0
|
72 } |
webmaster@0
|
73 $obj = array(); |
webmaster@0
|
74 $pos = strpos($selector, '@'); |
webmaster@0
|
75 if($pos !== false) { |
webmaster@0
|
76 $obj['attribute'] = substr($selector,$pos +1); |
webmaster@0
|
77 $selector = substr($selector, 0, $pos); |
webmaster@0
|
78 } |
webmaster@0
|
79 if($selector[0] == '#') { |
webmaster@0
|
80 $obj['xpath'] = "//*[@t:id='" . substr($selector, 1) . "']"; |
webmaster@0
|
81 $obj['nodes'] = $this->xmlXPath->query($obj['xpath'], $root); |
webmaster@0
|
82 } |
webmaster@0
|
83 else { |
webmaster@0
|
84 $obj['nodeName'] = $selector; |
webmaster@0
|
85 $obj['nodes'] = $root->getElementsByTagName($selector); |
webmaster@0
|
86 $obj['nodes'] = $this->xmlDocument->getElementsByTagName($selector); |
webmaster@0
|
87 } |
webmaster@0
|
88 return (object)$obj; |
webmaster@0
|
89 } |
webmaster@0
|
90 |
webmaster@0
|
91 function getNodesMatching($selector, DOMElement $root) { |
webmaster@0
|
92 $pos = strpos($selector, '/'); |
webmaster@0
|
93 if($pos !== false) { |
webmaster@0
|
94 $currentSelector = substr($selector, 0, $pos); |
webmaster@0
|
95 $remainingSelector = substr($selector, $pos+1); |
webmaster@0
|
96 } |
webmaster@0
|
97 else { |
webmaster@0
|
98 $currentSelector = $selector; |
webmaster@0
|
99 $remainingSelector = NULL; |
webmaster@0
|
100 } |
webmaster@0
|
101 if($selector[0] == '#') { |
webmaster@0
|
102 $nodes = $this->xmlXPath->query($currentSelector, $root); |
webmaster@0
|
103 } |
webmaster@0
|
104 else { |
webmaster@0
|
105 |
webmaster@0
|
106 } |
webmaster@0
|
107 } |
webmaster@0
|
108 |
webmaster@0
|
109 function parseReplacement($obj) { |
webmaster@0
|
110 $retVal = NULL; |
webmaster@0
|
111 if(is_string($obj)) |
webmaster@0
|
112 $retVal = $this->xmlDocument->createTextNode($obj); |
webmaster@0
|
113 else if($obj instanceof DOMDocument) |
webmaster@0
|
114 $retVal = $obj->documentElement; |
webmaster@0
|
115 else if($obj instanceof DOMNode) |
webmaster@0
|
116 $retVal = $obj; |
webmaster@0
|
117 return $retVal; |
webmaster@0
|
118 } |
webmaster@0
|
119 |
webmaster@0
|
120 function setParams($array) { |
webmaster@0
|
121 foreach($array as $selector => $obj) { |
webmaster@0
|
122 $this->apply($selector, $obj); |
webmaster@0
|
123 } |
webmaster@0
|
124 } |
webmaster@0
|
125 |
webmaster@0
|
126 function replaceNode(DOMNode $node, DOMNode $content) { |
webmaster@0
|
127 $parent = $node->parentNode; |
webmaster@0
|
128 $parent->replaceChild($content, $node); |
webmaster@0
|
129 } |
webmaster@0
|
130 |
webmaster@0
|
131 function setNodeContent(DOMElement $node, DOMNode $content) { |
webmaster@0
|
132 // Suppress existing childs |
webmaster@0
|
133 foreach($node->childNodes as $child) { |
webmaster@0
|
134 $node->removeChild($child); |
webmaster@0
|
135 } |
webmaster@0
|
136 // Add the new child |
webmaster@0
|
137 $node->appendChild($content); |
webmaster@0
|
138 } |
webmaster@0
|
139 |
webmaster@0
|
140 function clean() { |
webmaster@0
|
141 // Suppression des noeuds à cloner |
webmaster@0
|
142 $nodes = $this->xmlXPath->query("//*[@t:toClone]|//t:*"); |
webmaster@0
|
143 foreach($nodes as $node) { |
webmaster@0
|
144 if($node->parentNode) { |
webmaster@0
|
145 $node->parentNode->removeChild($node); |
webmaster@0
|
146 } |
webmaster@0
|
147 } |
webmaster@0
|
148 } |
webmaster@0
|
149 |
webmaster@0
|
150 function __toString() { |
webmaster@0
|
151 $this->clean(); |
webmaster@0
|
152 $this->xmlDocument->saveXML(); |
webmaster@0
|
153 return $this->xmlDocument->saveXML(); |
webmaster@0
|
154 } |
webmaster@0
|
155 } |