1<?php
2/*
3    +-----------------------------------------------------------------------------+
4    | Copyright (c) by Alexandre Alapetite,                                       |
5    | http://alexandre.alapetite.net/cv/alexandre-alapetite.en.html               |
6    | http://alexandre.alapetite.net/doc-alex/domxml-php4-php5/                   |
7    | Modifications by Alex Killing, alex.killing@gmx.de  (search for ##)         |
8    |-----------------------------------------------------------------------------|
9    | Allows PHP4/DOMXML scripts to run on PHP5/DOM                               |
10    |                                                                             |
11    | Typical use:                                                                |
12    | {                                                                           |
13    | 	if (version_compare(PHP_VERSION,'5','>='))                                |
14    | 		require_once('domxml-php4-to-php5.php');                              |
15    | }                                                                           |
16    |-----------------------------------------------------------------------------|
17    | This code is published under Creative Commons                               |
18    | Attribution-ShareAlike 2.0 "BY-SA" licence.                                 |
19    | See http://creativecommons.org/licenses/by-sa/2.0/ for details.             |
20    +-----------------------------------------------------------------------------+
21*/
22
23
24function domxml_open_file($filename)
25{
26    return new php4DOMDocument($filename);
27}
28
29/*
30* ##added
31*/
32function domxml_open_mem($str)
33{
34    return new php4DOMDocument($str, false);
35}
36
37function xpath_eval($xpath_context, $eval_str)
38{
39    return $xpath_context->query($eval_str);
40}
41
42function xpath_new_context($dom_document)
43{
44    return new php4DOMXPath($dom_document);
45}
46
47class php4DOMAttr extends php4DOMNode
48{
49    public $myDOMAttr;
50
51    public function php4DOMAttr($aDOMAttr)
52    {
53        $this->myDOMAttr = $aDOMAttr;
54    }
55
56    public function Name()
57    {
58        return $this->myDOMAttr->name;
59    }
60
61    public function Specified()
62    {
63        return $this->myDOMAttr->specified;
64    }
65
66    public function Value()
67    {
68        return $this->myDOMAttr->value;
69    }
70}
71
72class php4DOMCDATASection extends php4DOMNode
73{
74    public $myDOMCDATASection;
75
76    public function php4DOMCDATASection($aDOMCDATASection)
77    {
78        parent::php4DOMNode($aDOMCDATASection);						// #added
79        $this->myDOMCDATASection = $aDOMCDATASection;
80    }
81}
82
83class php4DOMDocument
84{
85    public $myDOMDocument;
86
87    // ##altered
88    public function php4DOMDocument($source, $file = true)
89    {
90        $this->myDOMDocument = new DOMDocument();
91        if ($file) {
92            $this->myDOMDocument->load($source);
93        } else {
94            $this->myDOMDocument->loadXML($source);
95        }
96    }
97
98    // ##added
99    public function xpath_init()
100    {
101    }
102
103    public function free()
104    {
105        unset($this->myDOMDocument);
106    }
107
108    // ##added
109    public function xpath_new_context()
110    {
111        return xpath_new_context($this);
112    }
113
114    // ##added
115    public function dump_node($node)
116    {
117        $str = $this->myDOMDocument->saveXML($node->myDOMNode);
118        return $str;
119    }
120
121    // ##added
122    public function validate(&$error)
123    {
124        $ok = $this->myDOMDocument->validate();
125        if (!$ok) {
126            $error = array(array("0", "Unknown Error"));
127        }
128        return $error;
129    }
130
131    public function create_attribute($name, $value)
132    {
133        $myAttr = $this->myDOMDocument->createAttribute($name);
134        $myAttr->value = $value;
135
136        return new php4DOMAttr($myAttr);
137    }
138
139    public function create_cdata_section($content)
140    {
141        return new php4DOMCDATASection($this->myDOMDocument->createCDATASection($content));
142    }
143
144    public function create_comment($data)
145    {
146        return new php4DOMElement($this->myDOMDocument->createComment($data));
147    }
148
149    public function create_element($name)
150    {
151        return new php4DOMElement($this->myDOMDocument->createElement($name));
152    }
153
154    public function create_text_node($content)
155    {
156        return new php4DOMNode($this->myDOMDocument->createTextNode($content));
157    }
158
159    public function document_element()
160    {
161        return new php4DOMElement($this->myDOMDocument->documentElement);
162    }
163
164    public function dump_file($filename, $compressionmode = false, $format = false)
165    {
166        return $this->myDOMDocument->save($filename);
167    }
168
169    public function dump_mem($format = false, $encoding = false)
170    {
171        return $this->myDOMDocument->saveXML();
172    }
173
174    public function get_elements_by_tagname($name)
175    {
176        $myDOMNodeList = $this->myDOMDocument->getElementsByTagName($name);
177        $nodeSet = array();
178        $i = 0;
179        while ($node = $myDOMNodeList->item($i)) {
180            $nodeSet[] = new php4DOMElement($node);
181            $i++;
182        }
183
184        return $nodeSet;
185    }
186
187    public function html_dump_mem()
188    {
189        return $this->myDOMDocument->saveHTML();
190    }
191}
192
193/**
194* php4DomElement
195*/
196class php4DOMElement extends php4DOMNode
197{
198    public function get_attribute($name)
199    {
200        return $this->myDOMNode->getAttribute($name);
201    }
202
203    public function get_elements_by_tagname($name)
204    {
205        $myDOMNodeList = $this->myDOMNode->getElementsByTagName($name);
206        $nodeSet = array();
207        $i = 0;
208        while ($node = $myDOMNodeList->item($i)) {
209            $nodeSet[] = new php4DOMElement($node);
210            $i++;
211        }
212
213        return $nodeSet;
214    }
215
216    public function has_attribute($name)
217    {
218        return $this->myDOMNode->hasAttribute($name);
219    }
220
221    public function remove_attribute($name)
222    {
223        return $this->myDOMNode->removeAttribute($name);
224    }
225
226    public function set_attribute($name, $value)
227    {
228        return $this->myDOMNode->setAttribute($name, $value);
229    }
230
231    public function tagname()
232    {
233        return $this->myDOMNode->tagName;
234    }
235
236    // ##added
237    public function set_content($text)
238    {
239        // the following replace has been added to conform with PHP4.
240        // A set_content("&amp;") brought a get_content() = "&" there,
241        // whereas PHP5 gives a get_content() = "&amp;"
242        $text = str_replace("&lt;", "<", $text);
243        $text = str_replace("&gt;", ">", $text);
244        $text = str_replace("&amp;", "&", $text);
245
246        $text_node = new DOMText();
247        $text_node->appendData($text);
248        if (is_object($this->myDOMNode->firstChild)) {
249            $this->myDOMNode->replaceChild($text_node, $this->myDOMNode->firstChild);
250        } else {
251            $this->myDOMNode->appendChild($text_node);
252        }
253    }
254
255    // ##added
256    public function get_content()
257    {
258        $text_node = &$this->myDOMNode->firstChild;
259
260        if (is_object($text_node)) {
261            return $text_node->textContent;
262        } else {
263            return "";
264        }
265    }
266
267    // ## added
268    public function unlink($aDomNode)
269    {
270        parent::unlink_node($aDomNode);
271    }
272}
273
274/**
275* php4DOMNode
276*/
277class php4DOMNode
278{
279    public $myDOMNode;
280
281    public function php4DOMNode($aDomNode)
282    {
283        $this->myDOMNode = $aDomNode;
284    }
285
286    public function append_child($newnode)
287    {
288        //echo "BH";
289        //if (strtolower(get_class($newnode)) != "php4domcdatasection")
290        //{
291        $doc = &$this->myDOMNode->ownerDocument;
292        //echo "<br>BH1:".get_class($newnode).":";
293        $newnode->myDOMNode = &$doc->importNode($newnode->myDOMNode, true);
294        //echo "BH2";
295        return new php4DOMElement($this->myDOMNode->appendChild($newnode->myDOMNode));
296        //}
297        //else
298        //{
299        //}
300    }
301
302    public function replace_node($newnode)
303    {
304        return $this->set_content($newnode->myDOMNode->textContent);
305    }
306
307    public function append_sibling($newnode)
308    {
309        return new php4DOMElement($this->myDOMNode->parentNode->appendChild($newnode->myDOMNode));
310    }
311
312    public function attributes()
313    {
314        //echo "<br>node:".$this->myDOMNode->nodeName.":";
315        $myDOMNodeList = $this->myDOMNode->attributes;
316        $nodeSet = array();
317        $i = 0;
318        if (is_object($myDOMNodeList)) {
319            while ($node = $myDOMNodeList->item($i)) {
320                $nodeSet[] = new php4DOMAttr($node);
321                $i++;
322            }
323        }
324
325        return $nodeSet;
326    }
327
328    public function child_nodes()
329    {
330        $myDOMNodeList = $this->myDOMNode->childNodes;
331        $nodeSet = array();
332        $i = 0;
333        while ($node = $myDOMNodeList->item($i)) {
334            $nodeSet[] = new php4DOMElement($node);
335            $i++;
336        }
337        return $nodeSet;
338    }
339
340    // ## added
341    public function children()
342    {
343        //echo "<br>php4DomNode::children"; flush();
344        return $this->child_nodes();
345    }
346
347    // ## added
348    public function unlink_node($aDomNode = "")
349    {
350        // sometimes the node to unlink is passed
351        if (!is_object($aDomNode)) {
352            $aDomNode = &$this;
353        }
354
355        $parent = &$aDomNode->myDOMNode->parentNode;
356        if (is_object($parent)) {
357            $parent->removeChild($aDomNode->myDOMNode);
358        }
359    }
360
361    public function clone_node($deep = false)
362    {
363        return new php4DOMElement($this->myDOMNode->cloneNode($deep));
364    }
365
366    public function first_child()
367    {
368        return new php4DOMElement($this->myDOMNode->firstChild);
369    }
370
371    public function get_content()
372    {
373        return $this->myDOMNode->textContent;
374    }
375
376    public function has_attributes()
377    {
378        return $this->myDOMNode->hasAttributes();
379    }
380
381    public function has_child_nodes()
382    {
383        return $this->myDOMNode->hasChildNodes();
384    }
385
386    // ## changed
387    public function insert_before($newnode, $refnode)
388    {
389        //echo "BH";
390        $doc = &$this->myDOMNode->ownerDocument;
391        $newnode->myDOMNode = &$doc->importNode($newnode->myDOMNode, true);
392
393        $mydomnode = &$this->myDOMNode;
394        $mynewnode = &$newnode->myDOMNode;
395        $myrefnode = &$refnode->myDOMNode;
396        try {
397            $domel = &$mydomnode->insertBefore($mynewnode, $myrefnode);
398        } catch (DOMException $exception) {
399            // php 4 accepted $this == $refnode -> switch to parent of $this
400            $mydomnode = &$this->myDOMNode->parentNode;
401            $domel = &$mydomnode->insertBefore($mynewnode, $myrefnode);
402        }
403        $el = new php4DOMElement($domel);
404        return $el;
405    }
406
407    // ## changed
408    public function last_child()
409    {
410        $last = &$this->myDOMNode->lastChild;
411
412        if (is_object($last)) {
413            return new php4DOMElement($last);
414        } else {
415            return false;
416        }
417    }
418
419    // ## changed
420    public function next_sibling()
421    {
422        $next = &$this->myDOMNode->nextSibling;
423
424        if (is_object($next)) {
425            return new php4DOMElement($next);
426        } else {
427            return false;
428        }
429    }
430
431    public function node_name()
432    {
433        return $this->myDOMNode->nodeName;
434    }
435
436    public function node_type()
437    {
438        return $this->myDOMNode->nodeType;
439    }
440
441    public function node_value()
442    {
443        return $this->myDOMNode->nodeValue;
444    }
445
446    // ## changed
447    public function parent_node()
448    {
449        $parent = &$this->myDOMNode->parentNode;
450
451        if (is_object($parent)) {
452            return new php4DOMElement($parent);
453        } else {
454            return false;
455        }
456    }
457
458    // ## changed
459    public function previous_sibling()
460    {
461        $prev = &$this->myDOMNode->previousSibling;
462
463        if (is_object($prev)) {
464            return new php4DOMElement($prev);
465        } else {
466            return false;
467        }
468    }
469
470    public function remove_child($oldchild)
471    {
472        return new php4DOMElement($this->myDOMNode->removeChild($oldchild->myDOMNode));
473    }
474
475    public function replace_child($oldnode, $newnode)
476    {
477        return new php4DOMElement($this->myDOMNode->replaceChild($oldchild->myDOMNode, $newnode->myDOMNode));
478    }
479
480    public function set_content($text)
481    {
482        $this->myDOMNode->textContent = $text;
483        return $this->myDOMNode->textContent;
484    }
485}
486
487class php4DOMNodelist
488{
489    public $myDOMNodelist;
490    public $nodeset;
491
492    public function php4DOMNodelist($aDOMNodelist)
493    {
494        $this->myDOMNodelist = $aDOMNodelist;
495        $this->nodeset = array();
496        $i = 0;
497        while ($node = $this->myDOMNodelist->item($i)) {
498            $this->nodeset[] = new php4DOMElement($node);
499            $i++;
500        }
501    }
502}
503
504class php4DOMXPath
505{
506    public $myDOMXPath;
507
508    // ## added
509    public function xpath_eval($eval_str)
510    {
511        return xpath_eval($this, $eval_str);
512    }
513
514    public function php4DOMXPath($dom_document)
515    {
516        $this->myDOMXPath = new DOMXPath($dom_document->myDOMDocument);
517    }
518
519    public function query($eval_str)
520    {
521        return new php4DOMNodelist($this->myDOMXPath->query($eval_str));
522    }
523
524    public function xpath_register_ns($prefix, $namespaceURI)
525    {
526        return $this->myDOMXPath->registerNamespace($prefix, $namespaceURI);
527    }
528}
529