annotate class.template.php @ 2:ad12469f4db4

Initialisation de xmlDocument, puis chargement. Avant, on faisait un xmlDocument->validateOnParse sans avoir initialiser (donc, sur un NULL, c'est etrange que PHP n'est pas bronche), puis on utilisait une methode statique sur DOMDocument... Passage en privee des deux variables.
author Franck Deroche <webmaster@defr.net>
date Fri, 16 Mar 2007 16:01:10 +0100
parents 0f40a8a39c68
children a76a46cbb401
rev   line source
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 }