webmaster@0: xmlDocument = new DOMDocument(); webmaster@6: $this->xmlDocument->validateOnParse = $shouldValidate; webmaster@2: $this->xmlDocument->loadXML(file_get_contents($fileName)); webmaster@0: $this->xmlXPath = new DOMXPath($this->xmlDocument); webmaster@8: $this->xmlXPath->registerNamespace('_t', Template::NS); webmaster@0: } webmaster@0: webmaster@3: function apply($selector, $obj, DOMElement $root = null) { webmaster@6: if(!($root instanceof DOMElement)) webmaster@3: $root = $this->xmlDocument->documentElement; webmaster@3: $rootSelector = $this->parseSelector($selector, $root); webmaster@6: if(is_array($obj)) webmaster@6: $this->applyClone($rootSelector, $obj, $root); webmaster@3: else { webmaster@0: foreach($rootSelector->nodes as $node) { webmaster@3: $content = $this->parseReplacement($obj); webmaster@0: if(isset($rootSelector->attribute)) { webmaster@0: $node->setAttribute($rootSelector->attribute, $obj); webmaster@0: } else { webmaster@0: if($node->namespaceURI == Template::NS) webmaster@0: $this->replaceNode($node, $content); webmaster@0: else webmaster@0: $this->setNodeContent($node, $content); webmaster@0: } webmaster@0: } webmaster@0: } webmaster@0: } webmaster@6: webmaster@6: function applyClone($rootSelector, $obj, $root) { webmaster@6: foreach($obj as $array) { webmaster@6: $nodeName = key($array); webmaster@6: foreach($rootSelector->nodes as $node) { webmaster@6: $tmp = $this->getClonedNode($node, $nodeName); webmaster@6: $futureNode = $tmp->clone; webmaster@6: $futureNode = $node->insertBefore($futureNode, $tmp->orig); webmaster@6: foreach($array as $sel => $test) { webmaster@6: $locSelector = $this->parseSelector($sel, $node); webmaster@7: if(isset($locSelector->attribute)) webmaster@6: $futureNode->setAttribute($locSelector->attribute, $test); webmaster@6: else { webmaster@6: $content = $this->parseReplacement($test); webmaster@6: $node->insertBefore($content, $tmp->orig); webmaster@6: if($futureNode->namespaceURI == Template::NS) webmaster@6: $this->replaceNode($futureNode, $content); webmaster@6: else webmaster@6: $this->setNodeContent($futureNode, $content); webmaster@6: } webmaster@6: } webmaster@6: } webmaster@6: } webmaster@6: } webmaster@0: webmaster@0: function getClonedNode($node, $childNodeName) { webmaster@3: $candidates = $this->parseSelector($childNodeName, $node)->nodes; webmaster@1: foreach($candidates as $candidate) { webmaster@3: if($candidate->getAttributeNS(Template::NS, 'toClone') == 'true') { webmaster@0: $tmp = array(); webmaster@1: $tmp['orig'] = $candidate; webmaster@1: $cnode = $candidate->cloneNode(true); webmaster@6: $cnode->removeAttributeNS(Template::NS, 'toClone'); webmaster@0: $tmp['clone'] = $cnode; webmaster@0: return (object)$tmp; webmaster@0: } webmaster@0: } webmaster@0: } webmaster@0: webmaster@3: function parseSelector($selector, DOMElement $root) { webmaster@0: $obj = array(); webmaster@0: $pos = strpos($selector, '@'); webmaster@0: if($pos !== false) { webmaster@0: $obj['attribute'] = substr($selector,$pos +1); webmaster@0: $selector = substr($selector, 0, $pos); webmaster@0: } webmaster@0: if($selector[0] == '#') { webmaster@8: $obj['xpath'] = "//*[@_t:id='" . substr($selector, 1) . "']"; webmaster@0: $obj['nodes'] = $this->xmlXPath->query($obj['xpath'], $root); webmaster@0: } webmaster@0: else { webmaster@0: $obj['nodeName'] = $selector; webmaster@0: $obj['nodes'] = $root->getElementsByTagName($selector); webmaster@0: } webmaster@0: return (object)$obj; webmaster@0: } webmaster@0: webmaster@0: function getNodesMatching($selector, DOMElement $root) { webmaster@0: $pos = strpos($selector, '/'); webmaster@0: if($pos !== false) { webmaster@0: $currentSelector = substr($selector, 0, $pos); webmaster@0: $remainingSelector = substr($selector, $pos+1); webmaster@0: } webmaster@0: else { webmaster@0: $currentSelector = $selector; webmaster@0: $remainingSelector = NULL; webmaster@0: } webmaster@0: if($selector[0] == '#') { webmaster@0: $nodes = $this->xmlXPath->query($currentSelector, $root); webmaster@0: } webmaster@0: else { webmaster@0: webmaster@0: } webmaster@0: } webmaster@0: webmaster@0: function parseReplacement($obj) { webmaster@0: $retVal = NULL; webmaster@0: if(is_string($obj)) webmaster@0: $retVal = $this->xmlDocument->createTextNode($obj); webmaster@0: else if($obj instanceof DOMDocument) webmaster@3: $retVal = $obj->documentElement->clone(true); webmaster@0: else if($obj instanceof DOMNode) webmaster@3: $retVal = $obj->clone(true); webmaster@0: return $retVal; webmaster@0: } webmaster@0: webmaster@0: function setParams($array) { webmaster@0: foreach($array as $selector => $obj) { webmaster@0: $this->apply($selector, $obj); webmaster@0: } webmaster@0: } webmaster@0: webmaster@0: function replaceNode(DOMNode $node, DOMNode $content) { webmaster@0: $parent = $node->parentNode; webmaster@0: $parent->replaceChild($content, $node); webmaster@0: } webmaster@0: webmaster@0: function setNodeContent(DOMElement $node, DOMNode $content) { webmaster@0: // Suppress existing childs webmaster@0: foreach($node->childNodes as $child) { webmaster@0: $node->removeChild($child); webmaster@0: } webmaster@0: // Add the new child webmaster@0: $node->appendChild($content); webmaster@0: } webmaster@0: webmaster@0: function clean() { webmaster@0: // Suppression des noeuds à cloner webmaster@8: $nodes = $this->xmlXPath->query("//*[@_t:toClone]|//_t:*"); webmaster@0: foreach($nodes as $node) { webmaster@0: if($node->parentNode) { webmaster@0: $node->parentNode->removeChild($node); webmaster@0: } webmaster@0: } webmaster@0: } webmaster@0: webmaster@0: function __toString() { webmaster@0: $this->clean(); webmaster@0: $this->xmlDocument->saveXML(); webmaster@0: return $this->xmlDocument->saveXML(); webmaster@0: } webmaster@6: }