annotate class.template.php @ 7:61dee7e34a9d

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