]> git.sesse.net Git - xml-template/blob - php/xml-template.php
NULL fixes for the PHP code.
[xml-template] / php / xml-template.php
1 <?php
2
3 function XML_Template_process_file($filename, $obj, $clean = 1)
4 {
5         $doc = domxml_open_file($filename);
6         XML_Template_process($doc, $obj, $clean);
7         return $doc;
8 }
9
10 function XML_Template_process($node, $obj, $clean = 1)
11 {
12         if (is_a($obj, 'domnode')) {                          # overwrite
13                 foreach ($node->child_nodes() as $child) {
14                         $node->remove_child($child);
15                 }
16
17                 if (is_a($obj, 'domdocument')) {
18                         $obj = $obj->document_element();
19                 }
20
21                 $newobj = $obj->clone_node(true);
22                 $node->append_child($newobj);
23         } else if (!is_array($obj)) {                         # overwrite
24                 foreach ($node->child_nodes() as $child) {
25                         $node->remove_child($child);
26                 }
27                 $doc = $node->owner_document();
28                 $node->add_child($doc->create_text_node($obj));
29         } else if (is_associative_array($obj)) {              # substitute
30                 foreach ($node->child_nodes() as $child) {
31                         $processed = false;
32
33                         if ($child->node_type() == XML_ELEMENT_NODE) {
34                                 $tag = $child->node_name();
35                                 $attrs = $child->attributes();
36                                 if (isset($attrs)) {
37                                         foreach ($child->attributes() as $attr) {
38                                                 if ($attr->namespace_uri() == 'http://template.sesse.net/' && $attr->name() == 'id') {
39                                                         $id = $attr->value();
40                                                         if ($clean) {
41                                                                 $child->remove_attribute($attr->name());
42                                                         }
43                                                 }
44                                         }
45                                 }
46                         
47                                 # check all substitutions to see if we found anything
48                                 # appropriate
49                                 foreach (array_keys($obj) as $key) {
50                                         # FIXME: we would want something like \Q and \E here...
51                                         if (preg_match('/^' . $tag . '\/(.*)$/', $key, $matches) ||
52                                             (isset($id) && preg_match('/^#' . $id . '\/(.*)$/', $key, $matches))) {
53                                                 $child->set_attribute($matches[1], $obj[$key]);
54                                         }
55
56                                         if ($processed) {
57                                                 continue;
58                                         }
59                                         if ($key == $tag || (isset($id) && $key == ('#'.$id))) {
60                                                 XML_Template_process($child, $obj[$key], $clean);
61                                                 $processed = true;
62                                         }
63                                 }
64                         }
65
66                         if (!$processed) {
67                                 XML_Template_process($child, $obj, $clean);
68                         }
69                 }
70         } else {                                                # repeat
71                 $doc = $node->owner_document();
72                 $frag = $doc->create_element("temporary-fragment");    # ugh
73
74                 foreach ($node->child_nodes() as $child) {
75                         $frag->append_child($child);
76                         $node->remove_child($child);
77                 }
78
79                 foreach ($obj as $instance) {
80                         $newnode = $frag->clone_node(true);
81                         $node->append_child($newnode);
82                         XML_Template_process($newnode, $instance, $clean);
83                         if ($clean) {
84                                 XML_Template_clean($newnode);
85                         }
86                 }
87
88                 # remove all the <fragment> tags
89
90                 foreach ($node->child_nodes() as $child) {
91                         if ($child->name() != 'temporary-fragment') {
92                                 continue;
93                         }
94                         foreach ($child->child_nodes() as $child2) {
95                                 $node->append_child($child2);
96                         }
97                         $node->remove_child($child);
98                 }       
99
100                 return;
101         }
102
103         if ($clean) {
104                 XML_Template_clean($node);
105         }
106 }
107
108 function XML_Template_clean($node)
109 {
110         if ($node->node_type() == XML_ELEMENT_NODE) {
111                 if ($node->namespace_uri() != 'http://template.sesse.net/') {
112                         return;
113                 }
114
115                 # as this is a dummy node, we want to remove it and move everything further up
116                 # after we've done any required replacements
117                 $doc = $node->owner_document();
118                 $parent = $node->parent_node();
119                 foreach ($node->child_nodes() as $child) {
120                         $node->remove_child($child);
121                         $node->insert_before($child, $node);
122                 }
123                 $parent->remove_child($node);
124         }
125 }
126
127 # FIXME: use varargs here
128 function XML_Template_alternate($tag, $array, $elems)
129 {
130         $i = 0;
131         $num = count($elems);
132
133         for ($i = 0; $i < count($array); $i++) {
134                 $array[$i][$tag] = $elems[$i % $num];
135         }
136
137         return $array;
138 }
139
140 function is_associative_array($arr)
141 {
142         if (!is_array($arr)) {
143                 return false;
144         }
145         $diff = array_diff(range(0, count($arr) - 1), array_keys($arr));
146         return (count($diff) > 0);
147 }
148 ?>