diff class.template.php @ 0:c86959030ae8

Import initial
author Franck Deroche <webmaster@defr.net>
date Sat, 10 Mar 2007 21:48:42 +0100
parents
children 0f40a8a39c68
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/class.template.php	Sat Mar 10 21:48:42 2007 +0100
@@ -0,0 +1,154 @@
+<?php
+class Template {
+    var $xmlDocument;
+    var $xmlXPath;
+    
+    const NS = 'http://defr.net/2007/template';
+    
+    function __construct($fileName) {
+        $this->xmlDocument->validateOnParse = true;
+        $this->xmlDocument = DOMDocument::loadXML(file_get_contents($fileName));
+        $this->xmlXPath = new DOMXPath($this->xmlDocument);
+    }
+    
+    function apply($selector, $obj) {
+        $rootSelector = $this->parseSelector($selector);
+        // Cloning test
+        if(is_array($obj)) {
+            foreach($obj as $array) {
+                foreach($rootSelector->nodes as $node) {
+                    $nodeName = key($array);
+                    $tmp = $this->getClonedNode($node, $nodeName);
+                    $futureNode = $tmp->clone;
+                    $node->insertBefore($futureNode, $tmp->orig);
+                    foreach($array as $sel => $test) {
+                        $content = $this->parseReplacement($test);
+                        $localSelector = $this->parseSelector($sel);
+                        if(isset($localSelector->attribute))
+                            $futureNode->setAttribute($localSelector->attribute, $test);
+                        else {
+                            if($futureNode->namespaceURI == Template::NS)
+                                $this->replaceNode($futureNode, $content);
+                            else
+                                $this->setNodeContent($futureNode, $content);
+                        }
+                    }
+                }
+            }
+        } else
+        {
+            $content = $this->parseReplacement($obj);
+            foreach($rootSelector->nodes as $node) {
+                if(isset($rootSelector->attribute)) {
+                    $node->setAttribute($rootSelector->attribute, $obj);
+                } else {
+                    if($node->namespaceURI == Template::NS)
+                        $this->replaceNode($node, $content);
+                    else
+                        $this->setNodeContent($node, $content);
+                }
+            }
+        }
+    }
+    
+    function getClonedNode($node, $childNodeName) {
+        $canditates = $node->getElementsByTagName($childNodeName);
+        foreach($canditates as $canditate) {
+            if($canditate->nodeName == $childNodeName && $canditate->getAttributeNS(Template::NS, 'toClone') == 'true') {
+                $tmp = array();
+                $tmp['orig'] = $canditate;
+                $cnode = $canditate->cloneNode(true);
+                $cnode->removeAttribute('toClone');
+                $tmp['clone'] = $cnode;
+                return (object)$tmp;
+            }
+        }
+    }
+    
+    function parseSelector($selector, DOMElement $root=NULL) {
+        if(!($root instanceof DOMElement)) {
+            $root = $this->xmlDocument->documentElement;
+        }
+        $obj = array();
+        $pos = strpos($selector, '@');
+        if($pos !== false) {
+            $obj['attribute'] = substr($selector,$pos +1);
+            $selector = substr($selector, 0, $pos);
+        }
+        if($selector[0] == '#') {
+            $obj['xpath'] = "//*[@t:id='" . substr($selector, 1) . "']";
+            $obj['nodes'] = $this->xmlXPath->query($obj['xpath'], $root);
+        }
+        else {
+            $obj['nodeName'] = $selector;
+            $obj['nodes'] = $root->getElementsByTagName($selector);
+            $obj['nodes'] = $this->xmlDocument->getElementsByTagName($selector);
+        }
+        return (object)$obj;
+    }
+    
+    function getNodesMatching($selector, DOMElement $root) {
+        $pos = strpos($selector, '/');
+        if($pos !== false) {
+            $currentSelector = substr($selector, 0, $pos);
+            $remainingSelector = substr($selector, $pos+1);
+        }
+        else {
+            $currentSelector = $selector;
+            $remainingSelector = NULL;
+        }
+        if($selector[0] == '#') {
+            $nodes = $this->xmlXPath->query($currentSelector, $root);
+        }
+        else {
+            
+        }
+    }
+    
+    function parseReplacement($obj) {
+        $retVal = NULL;
+        if(is_string($obj))
+            $retVal = $this->xmlDocument->createTextNode($obj);
+        else if($obj instanceof DOMDocument)
+            $retVal = $obj->documentElement;
+        else if($obj instanceof DOMNode)
+            $retVal = $obj;
+        return $retVal;
+    }
+    
+    function setParams($array) {
+        foreach($array as $selector => $obj) {
+            $this->apply($selector, $obj);
+        }
+    }
+    
+    function replaceNode(DOMNode $node, DOMNode $content) {
+        $parent = $node->parentNode;
+        $parent->replaceChild($content, $node);
+    }
+    
+    function setNodeContent(DOMElement $node, DOMNode $content) {
+        // Suppress existing childs
+        foreach($node->childNodes as $child) {
+            $node->removeChild($child);
+        }
+        // Add the new child
+        $node->appendChild($content);
+    }
+    
+    function clean() {
+        // Suppression des noeuds à cloner
+        $nodes = $this->xmlXPath->query("//*[@t:toClone]|//t:*");
+        foreach($nodes as $node) {
+            if($node->parentNode) {
+                $node->parentNode->removeChild($node);
+            }
+        }
+    }
+    
+    function __toString() {
+        $this->clean();
+        $this->xmlDocument->saveXML();
+        return $this->xmlDocument->saveXML();
+    }
+}
\ No newline at end of file