xref: /PHP-5.3/ext/dom/document.c (revision a2045ff3)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 5                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2013 The PHP Group                                |
6    +----------------------------------------------------------------------+
7    | This source file is subject to version 3.01 of the PHP license,      |
8    | that is bundled with this package in the file LICENSE, and is        |
9    | available through the world-wide-web at the following url:           |
10    | http://www.php.net/license/3_01.txt                                  |
11    | If you did not receive a copy of the PHP license and are unable to   |
12    | obtain it through the world-wide-web, please send a note to          |
13    | license@php.net so we can mail you a copy immediately.               |
14    +----------------------------------------------------------------------+
15    | Authors: Christian Stocker <chregu@php.net>                          |
16    |          Rob Richards <rrichards@php.net>                            |
17    +----------------------------------------------------------------------+
18 */
19 
20 /* $Id$ */
21 
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #include "php.h"
27 #if HAVE_LIBXML && HAVE_DOM
28 #include "php_dom.h"
29 #include <libxml/SAX.h>
30 #ifdef LIBXML_SCHEMAS_ENABLED
31 #include <libxml/relaxng.h>
32 #include <libxml/xmlschemas.h>
33 #endif
34 
35 typedef struct _idsIterator idsIterator;
36 struct _idsIterator {
37 	xmlChar *elementId;
38 	xmlNode *element;
39 };
40 
41 #define DOM_LOAD_STRING 0
42 #define DOM_LOAD_FILE 1
43 
44 /* {{{ arginfo */
45 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_element, 0, 0, 1)
46 	ZEND_ARG_INFO(0, tagName)
47 	ZEND_ARG_INFO(0, value)
48 ZEND_END_ARG_INFO();
49 
50 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_document_fragment, 0, 0, 0)
51 ZEND_END_ARG_INFO();
52 
53 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_text_node, 0, 0, 1)
54 	ZEND_ARG_INFO(0, data)
55 ZEND_END_ARG_INFO();
56 
57 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_comment, 0, 0, 1)
58 	ZEND_ARG_INFO(0, data)
59 ZEND_END_ARG_INFO();
60 
61 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_cdatasection, 0, 0, 1)
62 	ZEND_ARG_INFO(0, data)
63 ZEND_END_ARG_INFO();
64 
65 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_processing_instruction, 0, 0, 2)
66 	ZEND_ARG_INFO(0, target)
67 	ZEND_ARG_INFO(0, data)
68 ZEND_END_ARG_INFO();
69 
70 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_attribute, 0, 0, 1)
71 	ZEND_ARG_INFO(0, name)
72 ZEND_END_ARG_INFO();
73 
74 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_entity_reference, 0, 0, 1)
75 	ZEND_ARG_INFO(0, name)
76 ZEND_END_ARG_INFO();
77 
78 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_get_elements_by_tag_name, 0, 0, 1)
79 	ZEND_ARG_INFO(0, tagName)
80 ZEND_END_ARG_INFO();
81 
82 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_import_node, 0, 0, 2)
83 	ZEND_ARG_OBJ_INFO(0, importedNode, DOMNode, 0)
84 	ZEND_ARG_INFO(0, deep)
85 ZEND_END_ARG_INFO();
86 
87 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_element_ns, 0, 0, 2)
88 	ZEND_ARG_INFO(0, namespaceURI)
89 	ZEND_ARG_INFO(0, qualifiedName)
90 	ZEND_ARG_INFO(0, value)
91 ZEND_END_ARG_INFO();
92 
93 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_attribute_ns, 0, 0, 2)
94 	ZEND_ARG_INFO(0, namespaceURI)
95 	ZEND_ARG_INFO(0, qualifiedName)
96 ZEND_END_ARG_INFO();
97 
98 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_get_elements_by_tag_name_ns, 0, 0, 2)
99 	ZEND_ARG_INFO(0, namespaceURI)
100 	ZEND_ARG_INFO(0, localName)
101 ZEND_END_ARG_INFO();
102 
103 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_get_element_by_id, 0, 0, 1)
104 	ZEND_ARG_INFO(0, elementId)
105 ZEND_END_ARG_INFO();
106 
107 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_adopt_node, 0, 0, 1)
108 	ZEND_ARG_OBJ_INFO(0, source, DOMNode, 0)
109 ZEND_END_ARG_INFO();
110 
111 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_normalize_document, 0, 0, 0)
112 ZEND_END_ARG_INFO();
113 
114 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_rename_node, 0, 0, 3)
115 	ZEND_ARG_OBJ_INFO(0, node, DOMNode, 0)
116 	ZEND_ARG_INFO(0, namespaceURI)
117 	ZEND_ARG_INFO(0, qualifiedName)
118 ZEND_END_ARG_INFO();
119 
120 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_load, 0, 0, 1)
121 	ZEND_ARG_INFO(0, source)
122 	ZEND_ARG_INFO(0, options)
123 ZEND_END_ARG_INFO();
124 
125 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_save, 0, 0, 1)
126 	ZEND_ARG_INFO(0, file)
127 ZEND_END_ARG_INFO();
128 
129 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_loadxml, 0, 0, 1)
130 	ZEND_ARG_INFO(0, source)
131 	ZEND_ARG_INFO(0, options)
132 ZEND_END_ARG_INFO();
133 
134 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_savexml, 0, 0, 0)
135 	ZEND_ARG_OBJ_INFO(0, node, DOMNode, 1)
136 ZEND_END_ARG_INFO();
137 
138 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_construct, 0, 0, 0)
139 	ZEND_ARG_INFO(0, version)
140 	ZEND_ARG_INFO(0, encoding)
141 ZEND_END_ARG_INFO();
142 
143 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_validate, 0, 0, 0)
144 ZEND_END_ARG_INFO();
145 
146 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_xinclude, 0, 0, 0)
147 	ZEND_ARG_INFO(0, options)
148 ZEND_END_ARG_INFO();
149 
150 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_loadhtml, 0, 0, 1)
151 	ZEND_ARG_INFO(0, source)
152 ZEND_END_ARG_INFO();
153 
154 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_loadhtmlfile, 0, 0, 1)
155 	ZEND_ARG_INFO(0, source)
156 ZEND_END_ARG_INFO();
157 
158 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_savehtml, 0, 0, 0)
159 ZEND_END_ARG_INFO();
160 
161 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_savehtmlfile, 0, 0, 1)
162 	ZEND_ARG_INFO(0, file)
163 ZEND_END_ARG_INFO();
164 
165 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_schema_validate_file, 0, 0, 1)
166 	ZEND_ARG_INFO(0, filename)
167 ZEND_END_ARG_INFO();
168 
169 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_schema_validate_xml, 0, 0, 1)
170 	ZEND_ARG_INFO(0, source)
171 ZEND_END_ARG_INFO();
172 
173 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_relaxNG_validate_file, 0, 0, 1)
174 	ZEND_ARG_INFO(0, filename)
175 ZEND_END_ARG_INFO();
176 
177 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_relaxNG_validate_xml, 0, 0, 1)
178 	ZEND_ARG_INFO(0, source)
179 ZEND_END_ARG_INFO();
180 
181 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_registernodeclass, 0, 0, 2)
182 	ZEND_ARG_INFO(0, baseClass)
183 	ZEND_ARG_INFO(0, extendedClass)
184 ZEND_END_ARG_INFO();
185 /* }}} */
186 
187 /*
188 * class DOMDocument extends DOMNode
189 *
190 * URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-i-Document
191 * Since:
192 */
193 
194 const zend_function_entry php_dom_document_class_functions[] = { /* {{{ */
195 	PHP_FALIAS(createElement, dom_document_create_element, arginfo_dom_document_create_element)
196 	PHP_FALIAS(createDocumentFragment, dom_document_create_document_fragment, arginfo_dom_document_create_document_fragment)
197 	PHP_FALIAS(createTextNode, dom_document_create_text_node, arginfo_dom_document_create_text_node)
198 	PHP_FALIAS(createComment, dom_document_create_comment, arginfo_dom_document_create_comment)
199 	PHP_FALIAS(createCDATASection, dom_document_create_cdatasection, arginfo_dom_document_create_cdatasection)
200 	PHP_FALIAS(createProcessingInstruction, dom_document_create_processing_instruction, arginfo_dom_document_create_processing_instruction)
201 	PHP_FALIAS(createAttribute, dom_document_create_attribute, arginfo_dom_document_create_attribute)
202 	PHP_FALIAS(createEntityReference, dom_document_create_entity_reference, arginfo_dom_document_create_entity_reference)
203 	PHP_FALIAS(getElementsByTagName, dom_document_get_elements_by_tag_name, arginfo_dom_document_get_elements_by_tag_name)
204 	PHP_FALIAS(importNode, dom_document_import_node, arginfo_dom_document_import_node)
205 	PHP_FALIAS(createElementNS, dom_document_create_element_ns, arginfo_dom_document_create_element_ns)
206 	PHP_FALIAS(createAttributeNS, dom_document_create_attribute_ns, arginfo_dom_document_create_attribute_ns)
207 	PHP_FALIAS(getElementsByTagNameNS, dom_document_get_elements_by_tag_name_ns, arginfo_dom_document_get_elements_by_tag_name_ns)
208 	PHP_FALIAS(getElementById, dom_document_get_element_by_id, arginfo_dom_document_get_element_by_id)
209 	PHP_FALIAS(adoptNode, dom_document_adopt_node, arginfo_dom_document_adopt_node)
210 	PHP_FALIAS(normalizeDocument, dom_document_normalize_document, arginfo_dom_document_normalize_document)
211 	PHP_FALIAS(renameNode, dom_document_rename_node, arginfo_dom_document_rename_node)
212 	PHP_ME(domdocument, load, arginfo_dom_document_load, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
213 	PHP_FALIAS(save, dom_document_save, arginfo_dom_document_save)
214 	PHP_ME(domdocument, loadXML, arginfo_dom_document_loadxml, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
215 	PHP_FALIAS(saveXML, dom_document_savexml, arginfo_dom_document_savexml)
216 	PHP_ME(domdocument, __construct, arginfo_dom_document_construct, ZEND_ACC_PUBLIC)
217 	PHP_FALIAS(validate, dom_document_validate, arginfo_dom_document_validate)
218 	PHP_FALIAS(xinclude, dom_document_xinclude, arginfo_dom_document_xinclude)
219 #if defined(LIBXML_HTML_ENABLED)
220 	PHP_ME(domdocument, loadHTML, arginfo_dom_document_loadhtml, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
221 	PHP_ME(domdocument, loadHTMLFile, arginfo_dom_document_loadhtmlfile, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
222 	PHP_FALIAS(saveHTML, dom_document_save_html, arginfo_dom_document_savehtml)
223 	PHP_FALIAS(saveHTMLFile, dom_document_save_html_file, arginfo_dom_document_savehtmlfile)
224 #endif  /* defined(LIBXML_HTML_ENABLED) */
225 #if defined(LIBXML_SCHEMAS_ENABLED)
226 	PHP_FALIAS(schemaValidate, dom_document_schema_validate_file, arginfo_dom_document_schema_validate_file)
227 	PHP_FALIAS(schemaValidateSource, dom_document_schema_validate_xml, arginfo_dom_document_schema_validate_xml)
228 	PHP_FALIAS(relaxNGValidate, dom_document_relaxNG_validate_file, arginfo_dom_document_relaxNG_validate_file)
229 	PHP_FALIAS(relaxNGValidateSource, dom_document_relaxNG_validate_xml, arginfo_dom_document_relaxNG_validate_xml)
230 #endif
231 	PHP_ME(domdocument, registerNodeClass, arginfo_dom_document_registernodeclass, ZEND_ACC_PUBLIC)
232 	PHP_FE_END
233 };
234 /* }}} */
235 
236 /* {{{ docType	DOMDocumentType
237 readonly=yes
238 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-B63ED1A31
239 Since:
240 */
dom_document_doctype_read(dom_object * obj,zval ** retval TSRMLS_DC)241 int dom_document_doctype_read(dom_object *obj, zval **retval TSRMLS_DC)
242 {
243 	xmlDoc *docp;
244 	xmlDtdPtr dtdptr;
245 	int ret;
246 
247 	docp = (xmlDocPtr) dom_object_get_node(obj);
248 
249 	if (docp == NULL) {
250 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
251 		return FAILURE;
252 	}
253 
254 	ALLOC_ZVAL(*retval);
255 
256 	dtdptr = xmlGetIntSubset(docp);
257 	if (!dtdptr) {
258 		ZVAL_NULL(*retval);
259 		return SUCCESS;
260 	}
261 
262 	if (NULL == (*retval = php_dom_create_object((xmlNodePtr) dtdptr, &ret, NULL, *retval, obj TSRMLS_CC))) {
263 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
264 		return FAILURE;
265 	}
266 	return SUCCESS;
267 
268 }
269 
270 /* }}} */
271 
272 /* {{{ implementation	DOMImplementation
273 readonly=yes
274 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1B793EBA
275 Since:
276 */
dom_document_implementation_read(dom_object * obj,zval ** retval TSRMLS_DC)277 int dom_document_implementation_read(dom_object *obj, zval **retval TSRMLS_DC)
278 {
279 	ALLOC_ZVAL(*retval);
280 	php_dom_create_implementation(retval TSRMLS_CC);
281 	return SUCCESS;
282 }
283 
284 /* }}} */
285 
286 /* {{{ documentElement	DOMElement
287 readonly=yes
288 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-87CD092
289 Since:
290 */
dom_document_document_element_read(dom_object * obj,zval ** retval TSRMLS_DC)291 int dom_document_document_element_read(dom_object *obj, zval **retval TSRMLS_DC)
292 {
293 	xmlDoc *docp;
294 	xmlNode *root;
295 	int ret;
296 
297 	docp = (xmlDocPtr) dom_object_get_node(obj);
298 
299 	if (docp == NULL) {
300 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
301 		return FAILURE;
302 	}
303 
304 	ALLOC_ZVAL(*retval);
305 
306 	root = xmlDocGetRootElement(docp);
307 	if (!root) {
308 		ZVAL_NULL(*retval);
309 		return SUCCESS;
310 	}
311 
312 	if (NULL == (*retval = php_dom_create_object(root, &ret, NULL, *retval, obj TSRMLS_CC))) {
313 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
314 		return FAILURE;
315 	}
316 	return SUCCESS;
317 }
318 
319 /* }}} */
320 
321 /* {{{ encoding	string
322 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-encoding
323 Since: DOM Level 3
324 */
dom_document_encoding_read(dom_object * obj,zval ** retval TSRMLS_DC)325 int dom_document_encoding_read(dom_object *obj, zval **retval TSRMLS_DC)
326 {
327 	xmlDoc *docp;
328 	char *encoding;
329 
330 	docp = (xmlDocPtr) dom_object_get_node(obj);
331 
332 	if (docp == NULL) {
333 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
334 		return FAILURE;
335 	}
336 
337 	encoding = (char *) docp->encoding;
338 	ALLOC_ZVAL(*retval);
339 
340 	if (encoding != NULL) {
341 		ZVAL_STRING(*retval, encoding, 1);
342 	} else {
343 		ZVAL_NULL(*retval);
344 	}
345 
346 	return SUCCESS;
347 }
348 
dom_document_encoding_write(dom_object * obj,zval * newval TSRMLS_DC)349 int dom_document_encoding_write(dom_object *obj, zval *newval TSRMLS_DC)
350 {
351 	zval value_copy;
352 	xmlDoc *docp;
353 	xmlCharEncodingHandlerPtr handler;
354 
355 	docp = (xmlDocPtr) dom_object_get_node(obj);
356 
357 	if (docp == NULL) {
358 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
359 		return FAILURE;
360 	}
361 
362 	if (newval->type != IS_STRING) {
363 		if(Z_REFCOUNT_P(newval) > 1) {
364 			value_copy = *newval;
365 			zval_copy_ctor(&value_copy);
366 			newval = &value_copy;
367 		}
368 		convert_to_string(newval);
369 	}
370 
371 	handler = xmlFindCharEncodingHandler(Z_STRVAL_P(newval));
372 
373     if (handler != NULL) {
374 		xmlCharEncCloseFunc(handler);
375 		if (docp->encoding != NULL) {
376 			xmlFree((xmlChar *)docp->encoding);
377 		}
378 		docp->encoding = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval));
379     } else {
380 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Document Encoding");
381     }
382 
383 	if (newval == &value_copy) {
384 		zval_dtor(newval);
385 	}
386 
387 	return SUCCESS;
388 }
389 
390 /* }}} */
391 
392 /* {{{ standalone	boolean
393 readonly=no
394 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-standalone
395 Since: DOM Level 3
396 */
dom_document_standalone_read(dom_object * obj,zval ** retval TSRMLS_DC)397 int dom_document_standalone_read(dom_object *obj, zval **retval TSRMLS_DC)
398 {
399 	xmlDoc *docp;
400 	int standalone;
401 
402 	docp = (xmlDocPtr) dom_object_get_node(obj);
403 
404 	if (docp == NULL) {
405 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
406 		return FAILURE;
407 	}
408 
409 	ALLOC_ZVAL(*retval);
410 	standalone = docp->standalone;
411 	ZVAL_BOOL(*retval, standalone);
412 
413 	return SUCCESS;
414 }
415 
dom_document_standalone_write(dom_object * obj,zval * newval TSRMLS_DC)416 int dom_document_standalone_write(dom_object *obj, zval *newval TSRMLS_DC)
417 {
418 	zval value_copy;
419 	xmlDoc *docp;
420 	int standalone;
421 
422 	docp = (xmlDocPtr) dom_object_get_node(obj);
423 
424 	if (docp == NULL) {
425 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
426 		return FAILURE;
427 	}
428 
429 	if(Z_REFCOUNT_P(newval) > 1) {
430 		value_copy = *newval;
431 		zval_copy_ctor(&value_copy);
432 		newval = &value_copy;
433 	}
434 	convert_to_long(newval);
435 
436 	standalone = Z_LVAL_P(newval);
437     if (standalone > 0) {
438         docp->standalone = 1;
439     }
440     else if (standalone < 0) {
441         docp->standalone = -1;
442     }
443     else {
444         docp->standalone = 0;
445     }
446 
447 	if (newval == &value_copy) {
448 		zval_dtor(newval);
449 	}
450 
451 	return SUCCESS;
452 }
453 
454 /* }}} */
455 
456 /* {{{ version	string
457 readonly=no
458 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-version
459 Since: DOM Level 3
460 */
dom_document_version_read(dom_object * obj,zval ** retval TSRMLS_DC)461 int dom_document_version_read(dom_object *obj, zval **retval TSRMLS_DC)
462 {
463 	xmlDoc *docp;
464 	char *version;
465 
466 	docp = (xmlDocPtr) dom_object_get_node(obj);
467 
468 	if (docp == NULL) {
469 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
470 		return FAILURE;
471 	}
472 
473 	version = (char *) docp->version;
474 	ALLOC_ZVAL(*retval);
475 
476 	if (version != NULL) {
477 		ZVAL_STRING(*retval, version, 1);
478 	} else {
479 		ZVAL_NULL(*retval);
480 	}
481 
482 	return SUCCESS;
483 }
484 
dom_document_version_write(dom_object * obj,zval * newval TSRMLS_DC)485 int dom_document_version_write(dom_object *obj, zval *newval TSRMLS_DC)
486 {
487 	zval value_copy;
488 	xmlDoc *docp;
489 
490 	docp = (xmlDocPtr) dom_object_get_node(obj);
491 
492 	if (docp == NULL) {
493 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
494 		return FAILURE;
495 	}
496 
497 	if (docp->version != NULL) {
498 		xmlFree((xmlChar *) docp->version );
499 	}
500 
501 	if (newval->type != IS_STRING) {
502 		if(Z_REFCOUNT_P(newval) > 1) {
503 			value_copy = *newval;
504 			zval_copy_ctor(&value_copy);
505 			newval = &value_copy;
506 		}
507 		convert_to_string(newval);
508 	}
509 
510 	docp->version = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval));
511 
512 	if (newval == &value_copy) {
513 		zval_dtor(newval);
514 	}
515 
516 	return SUCCESS;
517 }
518 
519 /* }}} */
520 
521 /* {{{ strictErrorChecking	boolean
522 readonly=no
523 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-strictErrorChecking
524 Since: DOM Level 3
525 */
dom_document_strict_error_checking_read(dom_object * obj,zval ** retval TSRMLS_DC)526 int dom_document_strict_error_checking_read(dom_object *obj, zval **retval TSRMLS_DC)
527 {
528 	dom_doc_propsptr doc_prop;
529 
530 	ALLOC_ZVAL(*retval);
531 	if (obj->document) {
532 		doc_prop = dom_get_doc_props(obj->document);
533 		ZVAL_BOOL(*retval, doc_prop->stricterror);
534 	} else {
535 		ZVAL_FALSE(*retval);
536 	}
537 	return SUCCESS;
538 }
539 
dom_document_strict_error_checking_write(dom_object * obj,zval * newval TSRMLS_DC)540 int dom_document_strict_error_checking_write(dom_object *obj, zval *newval TSRMLS_DC)
541 {
542 	zval value_copy;
543 	dom_doc_propsptr doc_prop;
544 
545 	if(Z_REFCOUNT_P(newval) > 1) {
546 		value_copy = *newval;
547 		zval_copy_ctor(&value_copy);
548 		newval = &value_copy;
549 	}
550 	convert_to_boolean(newval);
551 
552 	if (obj->document) {
553 		doc_prop = dom_get_doc_props(obj->document);
554 		doc_prop->stricterror = Z_LVAL_P(newval);
555 	}
556 
557 	if (newval == &value_copy) {
558 		zval_dtor(newval);
559 	}
560 
561 	return SUCCESS;
562 }
563 
564 /* }}} */
565 
566 /* {{{ formatOutput	boolean
567 readonly=no
568 */
dom_document_format_output_read(dom_object * obj,zval ** retval TSRMLS_DC)569 int dom_document_format_output_read(dom_object *obj, zval **retval TSRMLS_DC)
570 {
571 	dom_doc_propsptr doc_prop;
572 
573 	ALLOC_ZVAL(*retval);
574 	if (obj->document) {
575 		doc_prop = dom_get_doc_props(obj->document);
576 		ZVAL_BOOL(*retval, doc_prop->formatoutput);
577 	} else {
578 		ZVAL_FALSE(*retval);
579 	}
580 	return SUCCESS;
581 }
582 
dom_document_format_output_write(dom_object * obj,zval * newval TSRMLS_DC)583 int dom_document_format_output_write(dom_object *obj, zval *newval TSRMLS_DC)
584 {
585 	zval value_copy;
586 	dom_doc_propsptr doc_prop;
587 
588 	if(Z_REFCOUNT_P(newval) > 1) {
589 		value_copy = *newval;
590 		zval_copy_ctor(&value_copy);
591 		newval = &value_copy;
592 	}
593 	convert_to_boolean(newval);
594 
595 	if (obj->document) {
596 		doc_prop = dom_get_doc_props(obj->document);
597 		doc_prop->formatoutput = Z_LVAL_P(newval);
598 	}
599 
600 	if (newval == &value_copy) {
601 		zval_dtor(newval);
602 	}
603 
604 	return SUCCESS;
605 }
606 /* }}} */
607 
608 /* {{{ validateOnParse	boolean
609 readonly=no
610 */
dom_document_validate_on_parse_read(dom_object * obj,zval ** retval TSRMLS_DC)611 int	dom_document_validate_on_parse_read(dom_object *obj, zval **retval TSRMLS_DC)
612 {
613 	dom_doc_propsptr doc_prop;
614 
615 	ALLOC_ZVAL(*retval);
616 	if (obj->document) {
617 		doc_prop = dom_get_doc_props(obj->document);
618 		ZVAL_BOOL(*retval, doc_prop->validateonparse);
619 	} else {
620 		ZVAL_FALSE(*retval);
621 	}
622 	return SUCCESS;
623 }
624 
dom_document_validate_on_parse_write(dom_object * obj,zval * newval TSRMLS_DC)625 int dom_document_validate_on_parse_write(dom_object *obj, zval *newval TSRMLS_DC)
626 {
627 	zval value_copy;
628 	dom_doc_propsptr doc_prop;
629 
630 	if(Z_REFCOUNT_P(newval) > 1) {
631 		value_copy = *newval;
632 		zval_copy_ctor(&value_copy);
633 		newval = &value_copy;
634 	}
635 	convert_to_boolean(newval);
636 
637 	if (obj->document) {
638 		doc_prop = dom_get_doc_props(obj->document);
639 		doc_prop->validateonparse = Z_LVAL_P(newval);
640 	}
641 
642 	if (newval == &value_copy) {
643 		zval_dtor(newval);
644 	}
645 
646 	return SUCCESS;
647 }
648 /* }}} */
649 
650 /* {{{ resolveExternals	boolean
651 readonly=no
652 */
dom_document_resolve_externals_read(dom_object * obj,zval ** retval TSRMLS_DC)653 int dom_document_resolve_externals_read(dom_object *obj, zval **retval TSRMLS_DC)
654 {
655 	dom_doc_propsptr doc_prop;
656 
657 	ALLOC_ZVAL(*retval);
658 	if (obj->document) {
659 		doc_prop = dom_get_doc_props(obj->document);
660 		ZVAL_BOOL(*retval, doc_prop->resolveexternals);
661 	} else {
662 		ZVAL_FALSE(*retval);
663 	}
664 	return SUCCESS;
665 }
666 
dom_document_resolve_externals_write(dom_object * obj,zval * newval TSRMLS_DC)667 int dom_document_resolve_externals_write(dom_object *obj, zval *newval TSRMLS_DC)
668 {
669 	zval value_copy;
670 	dom_doc_propsptr doc_prop;
671 
672 	if(Z_REFCOUNT_P(newval) > 1) {
673 		value_copy = *newval;
674 		zval_copy_ctor(&value_copy);
675 		newval = &value_copy;
676 	}
677 	convert_to_boolean(newval);
678 
679 	if (obj->document) {
680 		doc_prop = dom_get_doc_props(obj->document);
681 		doc_prop->resolveexternals = Z_LVAL_P(newval);
682 	}
683 
684 	if (newval == &value_copy) {
685 		zval_dtor(newval);
686 	}
687 
688 	return SUCCESS;
689 }
690 /* }}} */
691 
692 /* {{{ preserveWhiteSpace	boolean
693 readonly=no
694 */
dom_document_preserve_whitespace_read(dom_object * obj,zval ** retval TSRMLS_DC)695 int dom_document_preserve_whitespace_read(dom_object *obj, zval **retval TSRMLS_DC)
696 {
697 	dom_doc_propsptr doc_prop;
698 
699 	ALLOC_ZVAL(*retval);
700 	if (obj->document) {
701 		doc_prop = dom_get_doc_props(obj->document);
702 		ZVAL_BOOL(*retval, doc_prop->preservewhitespace);
703 	} else {
704 		ZVAL_FALSE(*retval);
705 	}
706 	return SUCCESS;
707 }
708 
dom_document_preserve_whitespace_write(dom_object * obj,zval * newval TSRMLS_DC)709 int dom_document_preserve_whitespace_write(dom_object *obj, zval *newval TSRMLS_DC)
710 {
711 	zval value_copy;
712 	dom_doc_propsptr doc_prop;
713 
714 	if(Z_REFCOUNT_P(newval) > 1) {
715 		value_copy = *newval;
716 		zval_copy_ctor(&value_copy);
717 		newval = &value_copy;
718 	}
719 	convert_to_boolean(newval);
720 
721 	if (obj->document) {
722 		doc_prop = dom_get_doc_props(obj->document);
723 		doc_prop->preservewhitespace = Z_LVAL_P(newval);
724 	}
725 
726 	if (newval == &value_copy) {
727 		zval_dtor(newval);
728 	}
729 
730 	return SUCCESS;
731 }
732 /* }}} */
733 
734 /* {{{ recover	boolean
735 readonly=no
736 */
dom_document_recover_read(dom_object * obj,zval ** retval TSRMLS_DC)737 int dom_document_recover_read(dom_object *obj, zval **retval TSRMLS_DC)
738 {
739 	dom_doc_propsptr doc_prop;
740 
741 	ALLOC_ZVAL(*retval);
742 	if (obj->document) {
743 		doc_prop = dom_get_doc_props(obj->document);
744 		ZVAL_BOOL(*retval, doc_prop->recover);
745 	} else {
746 		ZVAL_FALSE(*retval);
747 	}
748 	return SUCCESS;
749 }
750 
dom_document_recover_write(dom_object * obj,zval * newval TSRMLS_DC)751 int dom_document_recover_write(dom_object *obj, zval *newval TSRMLS_DC)
752 {
753 	zval value_copy;
754 	dom_doc_propsptr doc_prop;
755 
756 	if(Z_REFCOUNT_P(newval) > 1) {
757 		value_copy = *newval;
758 		zval_copy_ctor(&value_copy);
759 		newval = &value_copy;
760 	}
761 	convert_to_boolean(newval);
762 
763 	if (obj->document) {
764 		doc_prop = dom_get_doc_props(obj->document);
765 		doc_prop->recover = Z_LVAL_P(newval);
766 	}
767 
768 	if (newval == &value_copy) {
769 		zval_dtor(newval);
770 	}
771 
772 	return SUCCESS;
773 }
774 /* }}} */
775 
776 /* {{{ substituteEntities	boolean
777 readonly=no
778 */
dom_document_substitue_entities_read(dom_object * obj,zval ** retval TSRMLS_DC)779 int dom_document_substitue_entities_read(dom_object *obj, zval **retval TSRMLS_DC)
780 {
781 	dom_doc_propsptr doc_prop;
782 
783 	ALLOC_ZVAL(*retval);
784 	if (obj->document) {
785 		doc_prop = dom_get_doc_props(obj->document);
786 		ZVAL_BOOL(*retval, doc_prop->substituteentities);
787 	} else {
788 		ZVAL_FALSE(*retval);
789 	}
790 	return SUCCESS;
791 }
792 
dom_document_substitue_entities_write(dom_object * obj,zval * newval TSRMLS_DC)793 int dom_document_substitue_entities_write(dom_object *obj, zval *newval TSRMLS_DC)
794 {
795 	zval value_copy;
796 	dom_doc_propsptr doc_prop;
797 
798 	if(Z_REFCOUNT_P(newval) > 1) {
799 		value_copy = *newval;
800 		zval_copy_ctor(&value_copy);
801 		newval = &value_copy;
802 	}
803 	convert_to_boolean(newval);
804 
805 	if (obj->document) {
806 		doc_prop = dom_get_doc_props(obj->document);
807 		doc_prop->substituteentities = Z_LVAL_P(newval);
808 	}
809 
810 	if (newval == &value_copy) {
811 		zval_dtor(newval);
812 	}
813 
814 	return SUCCESS;
815 }
816 /* }}} */
817 
818 /* {{{ documentURI	string
819 readonly=no
820 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-documentURI
821 Since: DOM Level 3
822 */
dom_document_document_uri_read(dom_object * obj,zval ** retval TSRMLS_DC)823 int dom_document_document_uri_read(dom_object *obj, zval **retval TSRMLS_DC)
824 {
825 	xmlDoc *docp;
826 	char *url;
827 
828 	docp = (xmlDocPtr) dom_object_get_node(obj);
829 
830 	if (docp == NULL) {
831 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
832 		return FAILURE;
833 	}
834 
835 	ALLOC_ZVAL(*retval);
836 	url = (char *) docp->URL;
837 	if (url != NULL) {
838 		ZVAL_STRING(*retval, url, 1);
839 	} else {
840 		ZVAL_NULL(*retval);
841 	}
842 
843 	return SUCCESS;
844 }
845 
dom_document_document_uri_write(dom_object * obj,zval * newval TSRMLS_DC)846 int dom_document_document_uri_write(dom_object *obj, zval *newval TSRMLS_DC)
847 {
848 	zval value_copy;
849 	xmlDoc *docp;
850 
851 	docp = (xmlDocPtr) dom_object_get_node(obj);
852 
853 	if (docp == NULL) {
854 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
855 		return FAILURE;
856 	}
857 
858 	if (docp->URL != NULL) {
859 		xmlFree((xmlChar *) docp->URL);
860 	}
861 
862 	if (newval->type != IS_STRING) {
863 		if(Z_REFCOUNT_P(newval) > 1) {
864 			value_copy = *newval;
865 			zval_copy_ctor(&value_copy);
866 			newval = &value_copy;
867 		}
868 		convert_to_string(newval);
869 	}
870 
871 	docp->URL = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval));
872 
873 	if (newval == &value_copy) {
874 		zval_dtor(newval);
875 	}
876 
877 	return SUCCESS;
878 }
879 
880 /* }}} */
881 
882 /* {{{ config	DOMConfiguration
883 readonly=yes
884 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-config
885 Since: DOM Level 3
886 */
dom_document_config_read(dom_object * obj,zval ** retval TSRMLS_DC)887 int dom_document_config_read(dom_object *obj, zval **retval TSRMLS_DC)
888 {
889 	ALLOC_ZVAL(*retval);
890 	ZVAL_NULL(*retval);
891 	return SUCCESS;
892 }
893 
894 /* }}} */
895 
896 /* {{{ proto DOMElement dom_document_create_element(string tagName [, string value]);
897 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-2141741547
898 Since:
899 */
PHP_FUNCTION(dom_document_create_element)900 PHP_FUNCTION(dom_document_create_element)
901 {
902 	zval *id, *rv = NULL;
903 	xmlNode *node;
904 	xmlDocPtr docp;
905 	dom_object *intern;
906 	int ret, name_len, value_len;
907 	char *name, *value = NULL;
908 
909 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_document_class_entry, &name, &name_len, &value, &value_len) == FAILURE) {
910 		return;
911 	}
912 
913 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
914 
915 	if (xmlValidateName((xmlChar *) name, 0) != 0) {
916 		php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
917 		RETURN_FALSE;
918 	}
919 
920 	node = xmlNewDocNode(docp, NULL, name, value);
921 	if (!node) {
922 		RETURN_FALSE;
923 	}
924 
925 	DOM_RET_OBJ(rv, node, &ret, intern);
926 }
927 /* }}} end dom_document_create_element */
928 
929 /* {{{ proto DOMDocumentFragment dom_document_create_document_fragment();
930 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-35CB04B5
931 Since:
932 */
PHP_FUNCTION(dom_document_create_document_fragment)933 PHP_FUNCTION(dom_document_create_document_fragment)
934 {
935 	zval *id, *rv = NULL;
936 	xmlNode *node;
937 	xmlDocPtr docp;
938 	dom_object *intern;
939 	int ret;
940 
941 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_document_class_entry) == FAILURE) {
942 		return;
943 	}
944 
945 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
946 
947 	node =  xmlNewDocFragment(docp);
948 	if (!node) {
949 		RETURN_FALSE;
950 	}
951 
952 	DOM_RET_OBJ(rv, node, &ret, intern);
953 }
954 /* }}} end dom_document_create_document_fragment */
955 
956 /* {{{ proto DOMText dom_document_create_text_node(string data);
957 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1975348127
958 Since:
959 */
PHP_FUNCTION(dom_document_create_text_node)960 PHP_FUNCTION(dom_document_create_text_node)
961 {
962 	zval *id, *rv = NULL;
963 	xmlNode *node;
964 	xmlDocPtr docp;
965 	int ret, value_len;
966 	dom_object *intern;
967 	char *value;
968 
969 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) {
970 		return;
971 	}
972 
973 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
974 
975 	node = xmlNewDocText(docp, (xmlChar *) value);
976 	if (!node) {
977 		RETURN_FALSE;
978 	}
979 
980 	DOM_RET_OBJ(rv, node, &ret, intern);
981 }
982 /* }}} end dom_document_create_text_node */
983 
984 /* {{{ proto DOMComment dom_document_create_comment(string data);
985 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1334481328
986 Since:
987 */
PHP_FUNCTION(dom_document_create_comment)988 PHP_FUNCTION(dom_document_create_comment)
989 {
990 	zval *id, *rv = NULL;
991 	xmlNode *node;
992 	xmlDocPtr docp;
993 	int ret, value_len;
994 	dom_object *intern;
995 	char *value;
996 
997 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) {
998 		return;
999 	}
1000 
1001 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1002 
1003 	node = xmlNewDocComment(docp, (xmlChar *) value);
1004 	if (!node) {
1005 		RETURN_FALSE;
1006 	}
1007 
1008 	DOM_RET_OBJ(rv, node, &ret, intern);
1009 }
1010 /* }}} end dom_document_create_comment */
1011 
1012 /* {{{ proto DOMCdataSection dom_document_create_cdatasection(string data);
1013 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D26C0AF8
1014 Since:
1015 */
PHP_FUNCTION(dom_document_create_cdatasection)1016 PHP_FUNCTION(dom_document_create_cdatasection)
1017 {
1018 	zval *id, *rv = NULL;
1019 	xmlNode *node;
1020 	xmlDocPtr docp;
1021 	int ret, value_len;
1022 	dom_object *intern;
1023 	char *value;
1024 
1025 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) {
1026 		return;
1027 	}
1028 
1029 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1030 
1031 	node = xmlNewCDataBlock(docp, (xmlChar *) value, value_len);
1032 	if (!node) {
1033 		RETURN_FALSE;
1034 	}
1035 
1036 	DOM_RET_OBJ(rv, node, &ret, intern);
1037 }
1038 /* }}} end dom_document_create_cdatasection */
1039 
1040 /* {{{ proto DOMProcessingInstruction dom_document_create_processing_instruction(string target, string data);
1041 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-135944439
1042 Since:
1043 */
PHP_FUNCTION(dom_document_create_processing_instruction)1044 PHP_FUNCTION(dom_document_create_processing_instruction)
1045 {
1046 	zval *id, *rv = NULL;
1047 	xmlNode *node;
1048 	xmlDocPtr docp;
1049 	int ret, value_len, name_len = 0;
1050 	dom_object *intern;
1051 	char *name, *value = NULL;
1052 
1053 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_document_class_entry, &name, &name_len, &value, &value_len) == FAILURE) {
1054 		return;
1055 	}
1056 
1057 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1058 
1059 	if (xmlValidateName((xmlChar *) name, 0) != 0) {
1060 		php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
1061 		RETURN_FALSE;
1062 	}
1063 
1064 	node = xmlNewPI((xmlChar *) name, (xmlChar *) value);
1065 	if (!node) {
1066 		RETURN_FALSE;
1067 	}
1068 
1069 	node->doc = docp;
1070 
1071 	DOM_RET_OBJ(rv, node, &ret, intern);
1072 }
1073 /* }}} end dom_document_create_processing_instruction */
1074 
1075 /* {{{ proto DOMAttr dom_document_create_attribute(string name);
1076 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1084891198
1077 Since:
1078 */
PHP_FUNCTION(dom_document_create_attribute)1079 PHP_FUNCTION(dom_document_create_attribute)
1080 {
1081 	zval *id, *rv = NULL;
1082 	xmlAttrPtr node;
1083 	xmlDocPtr docp;
1084 	int ret, name_len;
1085 	dom_object *intern;
1086 	char *name;
1087 
1088 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) {
1089 		return;
1090 	}
1091 
1092 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1093 
1094 	if (xmlValidateName((xmlChar *) name, 0) != 0) {
1095 		php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
1096 		RETURN_FALSE;
1097 	}
1098 
1099 	node = xmlNewDocProp(docp, (xmlChar *) name, NULL);
1100 	if (!node) {
1101 		RETURN_FALSE;
1102 	}
1103 
1104 	DOM_RET_OBJ(rv, (xmlNodePtr) node, &ret, intern);
1105 
1106 }
1107 /* }}} end dom_document_create_attribute */
1108 
1109 /* {{{ proto DOMEntityReference dom_document_create_entity_reference(string name);
1110 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-392B75AE
1111 Since:
1112 */
PHP_FUNCTION(dom_document_create_entity_reference)1113 PHP_FUNCTION(dom_document_create_entity_reference)
1114 {
1115 	zval *id, *rv = NULL;
1116 	xmlNode *node;
1117 	xmlDocPtr docp = NULL;
1118 	dom_object *intern;
1119 	int ret, name_len;
1120 	char *name;
1121 
1122 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) {
1123 		return;
1124 	}
1125 
1126 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1127 
1128 	if (xmlValidateName((xmlChar *) name, 0) != 0) {
1129 		php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
1130 		RETURN_FALSE;
1131 	}
1132 
1133 	node = xmlNewReference(docp, name);
1134 	if (!node) {
1135 		RETURN_FALSE;
1136 	}
1137 
1138 	DOM_RET_OBJ(rv, (xmlNodePtr) node, &ret, intern);
1139 }
1140 /* }}} end dom_document_create_entity_reference */
1141 
1142 /* {{{ proto DOMNodeList dom_document_get_elements_by_tag_name(string tagname);
1143 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C9094
1144 Since:
1145 */
PHP_FUNCTION(dom_document_get_elements_by_tag_name)1146 PHP_FUNCTION(dom_document_get_elements_by_tag_name)
1147 {
1148 	zval *id;
1149 	xmlDocPtr docp;
1150 	int name_len;
1151 	dom_object *intern, *namednode;
1152 	char *name;
1153 	xmlChar *local;
1154 
1155 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) {
1156 		return;
1157 	}
1158 
1159 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1160 
1161 	php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
1162 	namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
1163 	local = xmlCharStrndup(name, name_len);
1164 	dom_namednode_iter(intern, 0, namednode, NULL, local, NULL TSRMLS_CC);
1165 }
1166 /* }}} end dom_document_get_elements_by_tag_name */
1167 
1168 /* {{{ proto DOMNode dom_document_import_node(DOMNode importedNode, boolean deep);
1169 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Core-Document-importNode
1170 Since: DOM Level 2
1171 */
PHP_FUNCTION(dom_document_import_node)1172 PHP_FUNCTION(dom_document_import_node)
1173 {
1174 	zval *rv = NULL;
1175 	zval *id, *node;
1176 	xmlDocPtr docp;
1177 	xmlNodePtr nodep, retnodep;
1178 	dom_object *intern, *nodeobj;
1179 	int ret;
1180 	long recursive = 0;
1181 
1182 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO|l", &id, dom_document_class_entry, &node, dom_node_class_entry, &recursive) == FAILURE) {
1183 		return;
1184 	}
1185 
1186 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1187 
1188 	DOM_GET_OBJ(nodep, node, xmlNodePtr, nodeobj);
1189 
1190 	if (nodep->type == XML_HTML_DOCUMENT_NODE || nodep->type == XML_DOCUMENT_NODE
1191 		|| nodep->type == XML_DOCUMENT_TYPE_NODE) {
1192 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot import: Node Type Not Supported");
1193 		RETURN_FALSE;
1194 	}
1195 
1196 	if (nodep->doc == docp) {
1197 		retnodep = nodep;
1198 	} else {
1199 		if ((recursive == 0) && (nodep->type == XML_ELEMENT_NODE)) {
1200 			recursive = 2;
1201 		}
1202 		retnodep = xmlDocCopyNode(nodep, docp, recursive);
1203 		if (!retnodep) {
1204 			RETURN_FALSE;
1205 		}
1206 
1207 		if ((retnodep->type == XML_ATTRIBUTE_NODE) && (nodep->ns != NULL)) {
1208 			xmlNsPtr nsptr = NULL;
1209 			xmlNodePtr root = xmlDocGetRootElement(docp);
1210 
1211 			nsptr = xmlSearchNsByHref (nodep->doc, root, nodep->ns->href);
1212 			if (nsptr == NULL) {
1213 				int errorcode;
1214 				nsptr = dom_get_ns(root, nodep->ns->href, &errorcode, nodep->ns->prefix);
1215 			}
1216 			xmlSetNs(retnodep, nsptr);
1217 		}
1218 	}
1219 
1220 	DOM_RET_OBJ(rv, (xmlNodePtr) retnodep, &ret, intern);
1221 }
1222 /* }}} end dom_document_import_node */
1223 
1224 /* {{{ proto DOMElement dom_document_create_element_ns(string namespaceURI, string qualifiedName [,string value]);
1225 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrElNS
1226 Since: DOM Level 2
1227 */
PHP_FUNCTION(dom_document_create_element_ns)1228 PHP_FUNCTION(dom_document_create_element_ns)
1229 {
1230 	zval *id, *rv = NULL;
1231 	xmlDocPtr docp;
1232 	xmlNodePtr nodep = NULL;
1233 	xmlNsPtr nsptr = NULL;
1234 	int ret, uri_len = 0, name_len = 0, value_len = 0;
1235 	char *uri, *name, *value = NULL;
1236 	char *localname = NULL, *prefix = NULL;
1237 	int errorcode;
1238 	dom_object *intern;
1239 
1240 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s|s", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len, &value, &value_len) == FAILURE) {
1241 		return;
1242 	}
1243 
1244 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1245 
1246 	errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
1247 
1248 	if (errorcode == 0) {
1249 		if (xmlValidateName((xmlChar *) localname, 0) == 0) {
1250 			nodep = xmlNewDocNode (docp, NULL, localname, value);
1251 			if (nodep != NULL && uri != NULL) {
1252 				nsptr = xmlSearchNsByHref (nodep->doc, nodep, uri);
1253 				if (nsptr == NULL) {
1254 					nsptr = dom_get_ns(nodep, uri, &errorcode, prefix);
1255 				}
1256 				xmlSetNs(nodep, nsptr);
1257 			}
1258 		} else {
1259 			errorcode = INVALID_CHARACTER_ERR;
1260 		}
1261 	}
1262 
1263 	xmlFree(localname);
1264 	if (prefix != NULL) {
1265 		xmlFree(prefix);
1266 	}
1267 
1268 	if (errorcode != 0) {
1269 		if (nodep != NULL) {
1270 			xmlFreeNode(nodep);
1271 		}
1272 		php_dom_throw_error(errorcode, dom_get_strict_error(intern->document) TSRMLS_CC);
1273 		RETURN_FALSE;
1274 	}
1275 
1276 	if (nodep == NULL) {
1277 		RETURN_FALSE;
1278 	}
1279 
1280 
1281 	nodep->ns = nsptr;
1282 
1283 	DOM_RET_OBJ(rv, nodep, &ret, intern);
1284 }
1285 /* }}} end dom_document_create_element_ns */
1286 
1287 /* {{{ proto DOMAttr dom_document_create_attribute_ns(string namespaceURI, string qualifiedName);
1288 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrAttrNS
1289 Since: DOM Level 2
1290 */
PHP_FUNCTION(dom_document_create_attribute_ns)1291 PHP_FUNCTION(dom_document_create_attribute_ns)
1292 {
1293 	zval *id, *rv = NULL;
1294 	xmlDocPtr docp;
1295 	xmlNodePtr nodep = NULL, root;
1296 	xmlNsPtr nsptr;
1297 	int ret, uri_len = 0, name_len = 0;
1298 	char *uri, *name;
1299 	char *localname = NULL, *prefix = NULL;
1300 	dom_object *intern;
1301 	int errorcode;
1302 
1303 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
1304 		return;
1305 	}
1306 
1307 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1308 
1309 	root = xmlDocGetRootElement(docp);
1310 	if (root != NULL) {
1311 		errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
1312 		if (errorcode == 0) {
1313 			if (xmlValidateName((xmlChar *) localname, 0) == 0) {
1314 				nodep = (xmlNodePtr) xmlNewDocProp(docp, localname, NULL);
1315 				if (nodep != NULL && uri_len > 0) {
1316 					nsptr = xmlSearchNsByHref (nodep->doc, root, uri);
1317 					if (nsptr == NULL) {
1318 						nsptr = dom_get_ns(root, uri, &errorcode, prefix);
1319 					}
1320 					xmlSetNs(nodep, nsptr);
1321 				}
1322 			} else {
1323 				errorcode = INVALID_CHARACTER_ERR;
1324 			}
1325 		}
1326 	} else {
1327 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Missing Root Element");
1328 		RETURN_FALSE;
1329 	}
1330 
1331 	xmlFree(localname);
1332 	if (prefix != NULL) {
1333 		xmlFree(prefix);
1334 	}
1335 
1336 	if (errorcode != 0) {
1337 		if (nodep != NULL) {
1338 			xmlFreeProp((xmlAttrPtr) nodep);
1339 		}
1340 		php_dom_throw_error(errorcode, dom_get_strict_error(intern->document) TSRMLS_CC);
1341 		RETURN_FALSE;
1342 	}
1343 
1344 	if (nodep == NULL) {
1345 		RETURN_FALSE;
1346 	}
1347 
1348 	DOM_RET_OBJ(rv, nodep, &ret, intern);
1349 }
1350 /* }}} end dom_document_create_attribute_ns */
1351 
1352 /* {{{ proto DOMNodeList dom_document_get_elements_by_tag_name_ns(string namespaceURI, string localName);
1353 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBTNNS
1354 Since: DOM Level 2
1355 */
PHP_FUNCTION(dom_document_get_elements_by_tag_name_ns)1356 PHP_FUNCTION(dom_document_get_elements_by_tag_name_ns)
1357 {
1358 	zval *id;
1359 	xmlDocPtr docp;
1360 	int uri_len, name_len;
1361 	dom_object *intern, *namednode;
1362 	char *uri, *name;
1363 	xmlChar *local, *nsuri;
1364 
1365 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
1366 		return;
1367 	}
1368 
1369 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1370 
1371 	php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
1372 	namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
1373 	local = xmlCharStrndup(name, name_len);
1374 	nsuri = xmlCharStrndup(uri, uri_len);
1375 	dom_namednode_iter(intern, 0, namednode, NULL, local, nsuri TSRMLS_CC);
1376 }
1377 /* }}} end dom_document_get_elements_by_tag_name_ns */
1378 
1379 /* {{{ proto DOMElement dom_document_get_element_by_id(string elementId);
1380 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBId
1381 Since: DOM Level 2
1382 */
PHP_FUNCTION(dom_document_get_element_by_id)1383 PHP_FUNCTION(dom_document_get_element_by_id)
1384 {
1385 	zval *id, *rv = NULL;
1386 	xmlDocPtr docp;
1387 	xmlAttrPtr  attrp;
1388 	int ret, idname_len;
1389 	dom_object *intern;
1390 	char *idname;
1391 
1392 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &idname, &idname_len) == FAILURE) {
1393 		return;
1394 	}
1395 
1396 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1397 
1398 	attrp = xmlGetID(docp, (xmlChar *) idname);
1399 
1400 	if (attrp && attrp->parent) {
1401 		DOM_RET_OBJ(rv, (xmlNodePtr) attrp->parent, &ret, intern);
1402 	} else {
1403 		RETVAL_NULL();
1404 	}
1405 
1406 }
1407 /* }}} end dom_document_get_element_by_id */
1408 
1409 /* {{{ proto DOMNode dom_document_adopt_node(DOMNode source);
1410 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-adoptNode
1411 Since: DOM Level 3
1412 */
PHP_FUNCTION(dom_document_adopt_node)1413 PHP_FUNCTION(dom_document_adopt_node)
1414 {
1415  DOM_NOT_IMPLEMENTED();
1416 }
1417 /* }}} end dom_document_adopt_node */
1418 
1419 /* {{{ proto void dom_document_normalize_document();
1420 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-normalizeDocument
1421 Since: DOM Level 3
1422 */
PHP_FUNCTION(dom_document_normalize_document)1423 PHP_FUNCTION(dom_document_normalize_document)
1424 {
1425 	zval *id;
1426 	xmlDocPtr docp;
1427 	dom_object *intern;
1428 
1429 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_document_class_entry) == FAILURE) {
1430 		return;
1431 	}
1432 
1433 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1434 
1435 	dom_normalize((xmlNodePtr) docp TSRMLS_CC);
1436 }
1437 /* }}} end dom_document_normalize_document */
1438 
1439 /* {{{ proto DOMNode dom_document_rename_node(node n, string namespaceURI, string qualifiedName);
1440 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-renameNode
1441 Since: DOM Level 3
1442 */
PHP_FUNCTION(dom_document_rename_node)1443 PHP_FUNCTION(dom_document_rename_node)
1444 {
1445  DOM_NOT_IMPLEMENTED();
1446 }
1447 /* }}} end dom_document_rename_node */
1448 
1449 /* {{{ proto void DOMDocument::__construct([string version], [string encoding]); */
PHP_METHOD(domdocument,__construct)1450 PHP_METHOD(domdocument, __construct)
1451 {
1452 
1453 	zval *id;
1454 	xmlDoc *docp = NULL, *olddoc;
1455 	dom_object *intern;
1456 	char *encoding, *version = NULL;
1457 	int encoding_len = 0, version_len = 0, refcount;
1458 	zend_error_handling error_handling;
1459 
1460 	zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
1461 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|ss", &id, dom_document_class_entry, &version, &version_len, &encoding, &encoding_len) == FAILURE) {
1462 		zend_restore_error_handling(&error_handling TSRMLS_CC);
1463 		return;
1464 	}
1465 
1466 	zend_restore_error_handling(&error_handling TSRMLS_CC);
1467 	docp = xmlNewDoc(version);
1468 
1469 	if (!docp) {
1470 		php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
1471 		RETURN_FALSE;
1472 	}
1473 
1474 	if (encoding_len > 0) {
1475 		docp->encoding = (const xmlChar*)xmlStrdup(encoding);
1476 	}
1477 
1478 	intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
1479 	if (intern != NULL) {
1480 		olddoc = (xmlDocPtr) dom_object_get_node(intern);
1481 		if (olddoc != NULL) {
1482 			php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC);
1483 			refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
1484 			if (refcount != 0) {
1485 				olddoc->_private = NULL;
1486 			}
1487 		}
1488 		intern->document = NULL;
1489 		if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, docp TSRMLS_CC) == -1) {
1490 			RETURN_FALSE;
1491 		}
1492 		php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)docp, (void *)intern TSRMLS_CC);
1493 	}
1494 }
1495 /* }}} end DOMDocument::__construct */
1496 
_dom_get_valid_file_path(char * source,char * resolved_path,int resolved_path_len TSRMLS_DC)1497 char *_dom_get_valid_file_path(char *source, char *resolved_path, int resolved_path_len  TSRMLS_DC) /* {{{ */
1498 {
1499 	xmlURI *uri;
1500 	xmlChar *escsource;
1501 	char *file_dest;
1502 	int isFileUri = 0;
1503 
1504 	uri = xmlCreateURI();
1505 	escsource = xmlURIEscapeStr(source, ":");
1506 	xmlParseURIReference(uri, escsource);
1507 	xmlFree(escsource);
1508 
1509 	if (uri->scheme != NULL) {
1510 		/* absolute file uris - libxml only supports localhost or empty host */
1511 		if (strncasecmp(source, "file:///",8) == 0) {
1512 			isFileUri = 1;
1513 #ifdef PHP_WIN32
1514 			source += 8;
1515 #else
1516 			source += 7;
1517 #endif
1518 		} else if (strncasecmp(source, "file://localhost/",17) == 0) {
1519 			isFileUri = 1;
1520 #ifdef PHP_WIN32
1521 			source += 17;
1522 #else
1523 			source += 16;
1524 #endif
1525 		}
1526 	}
1527 
1528 	file_dest = source;
1529 
1530 	if ((uri->scheme == NULL || isFileUri)) {
1531 		/* XXX possible buffer overflow if VCWD_REALPATH does not know size of resolved_path */
1532 		if (!VCWD_REALPATH(source, resolved_path) && !expand_filepath(source, resolved_path TSRMLS_CC)) {
1533 			xmlFreeURI(uri);
1534 			return NULL;
1535 		}
1536 		file_dest = resolved_path;
1537 	}
1538 
1539 	xmlFreeURI(uri);
1540 
1541 	return file_dest;
1542 }
1543 /* }}} */
1544 
dom_document_parser(zval * id,int mode,char * source,int source_len,int options TSRMLS_DC)1545 static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, int source_len, int options TSRMLS_DC) /* {{{ */
1546 {
1547     xmlDocPtr ret;
1548     xmlParserCtxtPtr ctxt = NULL;
1549 	dom_doc_propsptr doc_props;
1550 	dom_object *intern;
1551 	php_libxml_ref_obj *document = NULL;
1552 	int validate, recover, resolve_externals, keep_blanks, substitute_ent;
1553 	int resolved_path_len;
1554 	int old_error_reporting = 0;
1555 	char *directory=NULL, resolved_path[MAXPATHLEN];
1556 
1557 	if (id != NULL) {
1558 		intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
1559 		document = intern->document;
1560 	}
1561 
1562 	doc_props = dom_get_doc_props(document);
1563 	validate = doc_props->validateonparse;
1564 	resolve_externals = doc_props->resolveexternals;
1565 	keep_blanks = doc_props->preservewhitespace;
1566 	substitute_ent = doc_props->substituteentities;
1567 	recover = doc_props->recover;
1568 
1569 	if (document == NULL) {
1570 		efree(doc_props);
1571 	}
1572 
1573 	xmlInitParser();
1574 
1575 	if (mode == DOM_LOAD_FILE) {
1576 		char *file_dest = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN  TSRMLS_CC);
1577 		if (file_dest) {
1578 			ctxt = xmlCreateFileParserCtxt(file_dest);
1579 		}
1580 
1581 	} else {
1582 		ctxt = xmlCreateMemoryParserCtxt(source, source_len);
1583 	}
1584 
1585 	if (ctxt == NULL) {
1586 		return(NULL);
1587 	}
1588 
1589 	/* If loading from memory, we need to set the base directory for the document */
1590 	if (mode != DOM_LOAD_FILE) {
1591 #if HAVE_GETCWD
1592 		directory = VCWD_GETCWD(resolved_path, MAXPATHLEN);
1593 #elif HAVE_GETWD
1594 		directory = VCWD_GETWD(resolved_path);
1595 #endif
1596 		if (directory) {
1597 			if(ctxt->directory != NULL) {
1598 				xmlFree((char *) ctxt->directory);
1599 			}
1600 			resolved_path_len = strlen(resolved_path);
1601 			if (resolved_path[resolved_path_len - 1] != DEFAULT_SLASH) {
1602 				resolved_path[resolved_path_len] = DEFAULT_SLASH;
1603 				resolved_path[++resolved_path_len] = '\0';
1604 			}
1605 			ctxt->directory = (char *) xmlCanonicPath((const xmlChar *) resolved_path);
1606 		}
1607 	}
1608 
1609 	ctxt->vctxt.error = php_libxml_ctx_error;
1610 	ctxt->vctxt.warning = php_libxml_ctx_warning;
1611 
1612 	if (ctxt->sax != NULL) {
1613 		ctxt->sax->error = php_libxml_ctx_error;
1614 		ctxt->sax->warning = php_libxml_ctx_warning;
1615 	}
1616 
1617 	if (validate && ! (options & XML_PARSE_DTDVALID)) {
1618 		options |= XML_PARSE_DTDVALID;
1619 	}
1620 	if (resolve_externals && ! (options & XML_PARSE_DTDATTR)) {
1621 		options |= XML_PARSE_DTDATTR;
1622 	}
1623 	if (substitute_ent && ! (options & XML_PARSE_NOENT)) {
1624 		options |= XML_PARSE_NOENT;
1625 	}
1626 	if (keep_blanks == 0 && ! (options & XML_PARSE_NOBLANKS)) {
1627 		options |= XML_PARSE_NOBLANKS;
1628 	}
1629 
1630 	xmlCtxtUseOptions(ctxt, options);
1631 
1632 	ctxt->recovery = recover;
1633 	if (recover) {
1634 		old_error_reporting = EG(error_reporting);
1635 		EG(error_reporting) = old_error_reporting | E_WARNING;
1636 	}
1637 
1638 	xmlParseDocument(ctxt);
1639 
1640 	if (ctxt->wellFormed || recover) {
1641 		ret = ctxt->myDoc;
1642 		if (ctxt->recovery) {
1643 			EG(error_reporting) = old_error_reporting;
1644 		}
1645 		/* If loading from memory, set the base reference uri for the document */
1646 		if (ret && ret->URL == NULL && ctxt->directory != NULL) {
1647 			ret->URL = xmlStrdup(ctxt->directory);
1648 		}
1649 	} else {
1650 		ret = NULL;
1651 		xmlFreeDoc(ctxt->myDoc);
1652 		ctxt->myDoc = NULL;
1653 	}
1654 
1655 	xmlFreeParserCtxt(ctxt);
1656 
1657 	return(ret);
1658 }
1659 /* }}} */
1660 
1661 /* {{{ static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) */
dom_parse_document(INTERNAL_FUNCTION_PARAMETERS,int mode)1662 static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) {
1663 	zval *id, *rv = NULL;
1664 	xmlDoc *docp = NULL, *newdoc;
1665 	dom_doc_propsptr doc_prop;
1666 	dom_object *intern;
1667 	char *source;
1668 	int source_len, refcount, ret;
1669 	long options = 0;
1670 
1671 	id = getThis();
1672 	if (id != NULL && ! instanceof_function(Z_OBJCE_P(id), dom_document_class_entry TSRMLS_CC)) {
1673 		id = NULL;
1674 	}
1675 
1676 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &source, &source_len, &options) == FAILURE) {
1677 		return;
1678 	}
1679 
1680 	if (!source_len) {
1681 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string supplied as input");
1682 		RETURN_FALSE;
1683 	}
1684 
1685 	newdoc = dom_document_parser(id, mode, source, source_len, options TSRMLS_CC);
1686 
1687 	if (!newdoc)
1688 		RETURN_FALSE;
1689 
1690 	if (id != NULL) {
1691 		intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
1692 		if (intern != NULL) {
1693 			docp = (xmlDocPtr) dom_object_get_node(intern);
1694 			doc_prop = NULL;
1695 			if (docp != NULL) {
1696 				php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC);
1697 				doc_prop = intern->document->doc_props;
1698 				intern->document->doc_props = NULL;
1699 				refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
1700 				if (refcount != 0) {
1701 					docp->_private = NULL;
1702 				}
1703 			}
1704 			intern->document = NULL;
1705 			if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, newdoc TSRMLS_CC) == -1) {
1706 				RETURN_FALSE;
1707 			}
1708 			intern->document->doc_props = doc_prop;
1709 		}
1710 
1711 		php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)newdoc, (void *)intern TSRMLS_CC);
1712 
1713 		RETURN_TRUE;
1714 	} else {
1715 		DOM_RET_OBJ(rv, (xmlNodePtr) newdoc, &ret, NULL);
1716 	}
1717 }
1718 /* }}} end dom_parser_document */
1719 
1720 /* {{{ proto DOMNode dom_document_load(string source [, int options]);
1721 URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-load
1722 Since: DOM Level 3
1723 */
PHP_METHOD(domdocument,load)1724 PHP_METHOD(domdocument, load)
1725 {
1726 	dom_parse_document(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
1727 }
1728 /* }}} end dom_document_load */
1729 
1730 /* {{{ proto DOMNode dom_document_loadxml(string source [, int options]);
1731 URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-loadXML
1732 Since: DOM Level 3
1733 */
PHP_METHOD(domdocument,loadXML)1734 PHP_METHOD(domdocument, loadXML)
1735 {
1736 	dom_parse_document(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
1737 }
1738 /* }}} end dom_document_loadxml */
1739 
1740 /* {{{ proto int dom_document_save(string file);
1741 Convenience method to save to file
1742 */
PHP_FUNCTION(dom_document_save)1743 PHP_FUNCTION(dom_document_save)
1744 {
1745 	zval *id;
1746 	xmlDoc *docp;
1747 	int file_len = 0, bytes, format, saveempty = 0;
1748 	dom_object *intern;
1749 	dom_doc_propsptr doc_props;
1750 	char *file;
1751 	long options = 0;
1752 
1753 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|l", &id, dom_document_class_entry, &file, &file_len, &options) == FAILURE) {
1754 		return;
1755 	}
1756 
1757 	if (file_len == 0) {
1758 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Filename");
1759 		RETURN_FALSE;
1760 	}
1761 
1762 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1763 
1764 	/* encoding handled by property on doc */
1765 
1766 	doc_props = dom_get_doc_props(intern->document);
1767 	format = doc_props->formatoutput;
1768 	if (options & LIBXML_SAVE_NOEMPTYTAG) {
1769 		saveempty = xmlSaveNoEmptyTags;
1770 		xmlSaveNoEmptyTags = 1;
1771 	}
1772 	bytes = xmlSaveFormatFileEnc(file, docp, NULL, format);
1773 	if (options & LIBXML_SAVE_NOEMPTYTAG) {
1774 		xmlSaveNoEmptyTags = saveempty;
1775 	}
1776 	if (bytes == -1) {
1777 		RETURN_FALSE;
1778 	}
1779 	RETURN_LONG(bytes);
1780 }
1781 /* }}} end dom_document_save */
1782 
1783 /* {{{ proto string dom_document_savexml([node n]);
1784 URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-saveXML
1785 Since: DOM Level 3
1786 */
PHP_FUNCTION(dom_document_savexml)1787 PHP_FUNCTION(dom_document_savexml)
1788 {
1789 	zval *id, *nodep = NULL;
1790 	xmlDoc *docp;
1791 	xmlNode *node;
1792 	xmlBufferPtr buf;
1793 	xmlChar *mem;
1794 	dom_object *intern, *nodeobj;
1795 	dom_doc_propsptr doc_props;
1796 	int size, format, saveempty = 0;
1797 	long options = 0;
1798 
1799 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|O!l", &id, dom_document_class_entry, &nodep, dom_node_class_entry, &options) == FAILURE) {
1800 		return;
1801 	}
1802 
1803 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1804 
1805 	doc_props = dom_get_doc_props(intern->document);
1806 	format = doc_props->formatoutput;
1807 
1808 	if (nodep != NULL) {
1809 		/* Dump contents of Node */
1810 		DOM_GET_OBJ(node, nodep, xmlNodePtr, nodeobj);
1811 		if (node->doc != docp) {
1812 			php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
1813 			RETURN_FALSE;
1814 		}
1815 		buf = xmlBufferCreate();
1816 		if (!buf) {
1817 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch buffer");
1818 			RETURN_FALSE;
1819 		}
1820 		if (options & LIBXML_SAVE_NOEMPTYTAG) {
1821 			saveempty = xmlSaveNoEmptyTags;
1822 			xmlSaveNoEmptyTags = 1;
1823 		}
1824 		xmlNodeDump(buf, docp, node, 0, format);
1825 		if (options & LIBXML_SAVE_NOEMPTYTAG) {
1826 			xmlSaveNoEmptyTags = saveempty;
1827 		}
1828 		mem = (xmlChar*) xmlBufferContent(buf);
1829 		if (!mem) {
1830 			xmlBufferFree(buf);
1831 			RETURN_FALSE;
1832 		}
1833 		RETVAL_STRING(mem, 1);
1834 		xmlBufferFree(buf);
1835 	} else {
1836 		if (options & LIBXML_SAVE_NOEMPTYTAG) {
1837 			saveempty = xmlSaveNoEmptyTags;
1838 			xmlSaveNoEmptyTags = 1;
1839 		}
1840 		/* Encoding is handled from the encoding property set on the document */
1841 		xmlDocDumpFormatMemory(docp, &mem, &size, format);
1842 		if (options & LIBXML_SAVE_NOEMPTYTAG) {
1843 			xmlSaveNoEmptyTags = saveempty;
1844 		}
1845 		if (!size) {
1846 			RETURN_FALSE;
1847 		}
1848 		RETVAL_STRINGL(mem, size, 1);
1849 		xmlFree(mem);
1850 	}
1851 }
1852 /* }}} end dom_document_savexml */
1853 
php_dom_free_xinclude_node(xmlNodePtr cur TSRMLS_DC)1854 static xmlNodePtr php_dom_free_xinclude_node(xmlNodePtr cur TSRMLS_DC) /* {{{ */
1855 {
1856 	xmlNodePtr xincnode;
1857 
1858 	xincnode = cur;
1859 	cur = cur->next;
1860 	xmlUnlinkNode(xincnode);
1861 	php_libxml_node_free_resource(xincnode TSRMLS_CC);
1862 
1863 	return cur;
1864 }
1865 /* }}} */
1866 
php_dom_remove_xinclude_nodes(xmlNodePtr cur TSRMLS_DC)1867 static void php_dom_remove_xinclude_nodes(xmlNodePtr cur TSRMLS_DC) /* {{{ */
1868 {
1869 	while(cur) {
1870 		if (cur->type == XML_XINCLUDE_START) {
1871 			cur = php_dom_free_xinclude_node(cur TSRMLS_CC);
1872 
1873 			/* XML_XINCLUDE_END node will be a sibling of XML_XINCLUDE_START */
1874 			while(cur && cur->type != XML_XINCLUDE_END) {
1875 				/* remove xinclude processing nodes from recursive xincludes */
1876 				if (cur->type == XML_ELEMENT_NODE) {
1877 					   php_dom_remove_xinclude_nodes(cur->children TSRMLS_CC);
1878 				}
1879 				cur = cur->next;
1880 			}
1881 
1882 			if (cur && cur->type == XML_XINCLUDE_END) {
1883 				cur = php_dom_free_xinclude_node(cur TSRMLS_CC);
1884 			}
1885 		} else {
1886 			if (cur->type == XML_ELEMENT_NODE) {
1887 				php_dom_remove_xinclude_nodes(cur->children TSRMLS_CC);
1888 			}
1889 			cur = cur->next;
1890 		}
1891 	}
1892 }
1893 /* }}} */
1894 
1895 /* {{{ proto int dom_document_xinclude([int options])
1896    Substitutues xincludes in a DomDocument */
PHP_FUNCTION(dom_document_xinclude)1897 PHP_FUNCTION(dom_document_xinclude)
1898 {
1899 	zval *id;
1900 	xmlDoc *docp;
1901 	xmlNodePtr root;
1902 	long flags = 0;
1903 	int err;
1904 	dom_object *intern;
1905 
1906 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &id, dom_document_class_entry, &flags) == FAILURE) {
1907 		return;
1908 	}
1909 
1910 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1911 
1912 	err = xmlXIncludeProcessFlags(docp, flags);
1913 
1914 	/* XML_XINCLUDE_START and XML_XINCLUDE_END nodes need to be removed as these
1915 	are added via xmlXIncludeProcess to mark beginning and ending of xincluded document
1916 	but are not wanted in resulting document - must be done even if err as it could fail after
1917 	having processed some xincludes */
1918 	root = (xmlNodePtr) docp->children;
1919 	while(root && root->type != XML_ELEMENT_NODE && root->type != XML_XINCLUDE_START) {
1920 		root = root->next;
1921 	}
1922 	if (root) {
1923 		php_dom_remove_xinclude_nodes(root TSRMLS_CC);
1924 	}
1925 
1926 	if (err) {
1927 		RETVAL_LONG(err);
1928 	} else {
1929 		RETVAL_FALSE;
1930 	}
1931 
1932 }
1933 /* }}} */
1934 
1935 /* {{{ proto boolean dom_document_validate();
1936 Since: DOM extended
1937 */
PHP_FUNCTION(dom_document_validate)1938 PHP_FUNCTION(dom_document_validate)
1939 {
1940 	zval *id;
1941 	xmlDoc *docp;
1942 	dom_object *intern;
1943 	xmlValidCtxt *cvp;
1944 
1945 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_document_class_entry) == FAILURE) {
1946 		return;
1947 	}
1948 
1949 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1950 
1951 	cvp = xmlNewValidCtxt();
1952 
1953 	cvp->userData = NULL;
1954 	cvp->error    = (xmlValidityErrorFunc) php_libxml_error_handler;
1955 	cvp->warning  = (xmlValidityErrorFunc) php_libxml_error_handler;
1956 
1957 	if (xmlValidateDocument(cvp, docp)) {
1958 		RETVAL_TRUE;
1959 	} else {
1960 		RETVAL_FALSE;
1961 	}
1962 
1963 	xmlFreeValidCtxt(cvp);
1964 
1965 }
1966 /* }}} */
1967 
1968 #if defined(LIBXML_SCHEMAS_ENABLED)
_dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS,int type)1969 static void _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
1970 {
1971 	zval *id;
1972 	xmlDoc *docp;
1973 	dom_object *intern;
1974 	char *source = NULL, *valid_file = NULL;
1975 	int source_len = 0;
1976 	xmlSchemaParserCtxtPtr  parser;
1977 	xmlSchemaPtr            sptr;
1978 	xmlSchemaValidCtxtPtr   vptr;
1979 	int                     is_valid;
1980 	char resolved_path[MAXPATHLEN + 1];
1981 
1982 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &source, &source_len) == FAILURE) {
1983 		return;
1984 	}
1985 
1986 	if (source_len == 0) {
1987 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema source");
1988 		RETURN_FALSE;
1989 	}
1990 
1991 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1992 
1993 	switch (type) {
1994 	case DOM_LOAD_FILE:
1995 		valid_file = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN  TSRMLS_CC);
1996 		if (!valid_file) {
1997 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema file source");
1998 			RETURN_FALSE;
1999 		}
2000 		parser = xmlSchemaNewParserCtxt(valid_file);
2001 		break;
2002 	case DOM_LOAD_STRING:
2003 		parser = xmlSchemaNewMemParserCtxt(source, source_len);
2004 		/* If loading from memory, we need to set the base directory for the document
2005 		   but it is not apparent how to do that for schema's */
2006 		break;
2007 	default:
2008 		return;
2009 	}
2010 
2011 	xmlSchemaSetParserErrors(parser,
2012 		(xmlSchemaValidityErrorFunc) php_libxml_error_handler,
2013 		(xmlSchemaValidityWarningFunc) php_libxml_error_handler,
2014 		parser);
2015 	sptr = xmlSchemaParse(parser);
2016 	xmlSchemaFreeParserCtxt(parser);
2017 	if (!sptr) {
2018 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema");
2019 		RETURN_FALSE;
2020 	}
2021 
2022 	docp = (xmlDocPtr) dom_object_get_node(intern);
2023 
2024 	vptr = xmlSchemaNewValidCtxt(sptr);
2025 	if (!vptr) {
2026 		xmlSchemaFree(sptr);
2027 		php_error(E_ERROR, "Invalid Schema Validation Context");
2028 		RETURN_FALSE;
2029 	}
2030 
2031 	xmlSchemaSetValidErrors(vptr, php_libxml_error_handler, php_libxml_error_handler, vptr);
2032 	is_valid = xmlSchemaValidateDoc(vptr, docp);
2033 	xmlSchemaFree(sptr);
2034 	xmlSchemaFreeValidCtxt(vptr);
2035 
2036 	if (is_valid == 0) {
2037 		RETURN_TRUE;
2038 	} else {
2039 		RETURN_FALSE;
2040 	}
2041 }
2042 /* }}} */
2043 
2044 /* {{{ proto boolean dom_document_schema_validate_file(string filename); */
PHP_FUNCTION(dom_document_schema_validate_file)2045 PHP_FUNCTION(dom_document_schema_validate_file)
2046 {
2047 	_dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
2048 }
2049 /* }}} end dom_document_schema_validate_file */
2050 
2051 /* {{{ proto boolean dom_document_schema_validate(string source); */
PHP_FUNCTION(dom_document_schema_validate_xml)2052 PHP_FUNCTION(dom_document_schema_validate_xml)
2053 {
2054 	_dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
2055 }
2056 /* }}} end dom_document_schema_validate */
2057 
_dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAMETERS,int type)2058 static void _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
2059 {
2060 	zval *id;
2061 	xmlDoc *docp;
2062 	dom_object *intern;
2063 	char *source = NULL, *valid_file = NULL;
2064 	int source_len = 0;
2065 	xmlRelaxNGParserCtxtPtr parser;
2066 	xmlRelaxNGPtr           sptr;
2067 	xmlRelaxNGValidCtxtPtr  vptr;
2068 	int                     is_valid;
2069 	char resolved_path[MAXPATHLEN + 1];
2070 
2071 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &source, &source_len) == FAILURE) {
2072 		return;
2073 	}
2074 
2075 	if (source_len == 0) {
2076 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema source");
2077 		RETURN_FALSE;
2078 	}
2079 
2080 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
2081 
2082 	switch (type) {
2083 	case DOM_LOAD_FILE:
2084 		valid_file = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN  TSRMLS_CC);
2085 		if (!valid_file) {
2086 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid RelaxNG file source");
2087 			RETURN_FALSE;
2088 		}
2089 		parser = xmlRelaxNGNewParserCtxt(valid_file);
2090 		break;
2091 	case DOM_LOAD_STRING:
2092 		parser = xmlRelaxNGNewMemParserCtxt(source, source_len);
2093 		/* If loading from memory, we need to set the base directory for the document
2094 		   but it is not apparent how to do that for schema's */
2095 		break;
2096 	default:
2097 		return;
2098 	}
2099 
2100 	xmlRelaxNGSetParserErrors(parser,
2101 		(xmlRelaxNGValidityErrorFunc) php_libxml_error_handler,
2102 		(xmlRelaxNGValidityWarningFunc) php_libxml_error_handler,
2103 		parser);
2104 	sptr = xmlRelaxNGParse(parser);
2105 	xmlRelaxNGFreeParserCtxt(parser);
2106 	if (!sptr) {
2107 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid RelaxNG");
2108 		RETURN_FALSE;
2109 	}
2110 
2111 	docp = (xmlDocPtr) dom_object_get_node(intern);
2112 
2113 	vptr = xmlRelaxNGNewValidCtxt(sptr);
2114 	if (!vptr) {
2115 		xmlRelaxNGFree(sptr);
2116 		php_error(E_ERROR, "Invalid RelaxNG Validation Context");
2117 		RETURN_FALSE;
2118 	}
2119 
2120 	xmlRelaxNGSetValidErrors(vptr, php_libxml_error_handler, php_libxml_error_handler, vptr);
2121 	is_valid = xmlRelaxNGValidateDoc(vptr, docp);
2122 	xmlRelaxNGFree(sptr);
2123 	xmlRelaxNGFreeValidCtxt(vptr);
2124 
2125 	if (is_valid == 0) {
2126 		RETURN_TRUE;
2127 	} else {
2128 		RETURN_FALSE;
2129 	}
2130 }
2131 /* }}} */
2132 
2133 /* {{{ proto boolean dom_document_relaxNG_validate_file(string filename); */
PHP_FUNCTION(dom_document_relaxNG_validate_file)2134 PHP_FUNCTION(dom_document_relaxNG_validate_file)
2135 {
2136 	_dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
2137 }
2138 /* }}} end dom_document_relaxNG_validate_file */
2139 
2140 /* {{{ proto boolean dom_document_relaxNG_validate_xml(string source); */
PHP_FUNCTION(dom_document_relaxNG_validate_xml)2141 PHP_FUNCTION(dom_document_relaxNG_validate_xml)
2142 {
2143 	_dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
2144 }
2145 /* }}} end dom_document_relaxNG_validate_xml */
2146 
2147 #endif
2148 
2149 #if defined(LIBXML_HTML_ENABLED)
2150 
dom_load_html(INTERNAL_FUNCTION_PARAMETERS,int mode)2151 static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */
2152 {
2153 	zval *id, *rv = NULL;
2154 	xmlDoc *docp = NULL, *newdoc;
2155 	dom_object *intern;
2156 	dom_doc_propsptr doc_prop;
2157 	char *source;
2158 	int source_len, refcount, ret;
2159 	htmlParserCtxtPtr ctxt;
2160 
2161 	id = getThis();
2162 
2163 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &source, &source_len) == FAILURE) {
2164 		return;
2165 	}
2166 
2167 	if (!source_len) {
2168 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string supplied as input");
2169 		RETURN_FALSE;
2170 	}
2171 
2172 	if (mode == DOM_LOAD_FILE) {
2173 		ctxt = htmlCreateFileParserCtxt(source, NULL);
2174 	} else {
2175 		source_len = xmlStrlen(source);
2176 		ctxt = htmlCreateMemoryParserCtxt(source, source_len);
2177 	}
2178 
2179 	if (!ctxt) {
2180 		RETURN_FALSE;
2181 	}
2182 
2183 	ctxt->vctxt.error = php_libxml_ctx_error;
2184 	ctxt->vctxt.warning = php_libxml_ctx_warning;
2185 	if (ctxt->sax != NULL) {
2186 		ctxt->sax->error = php_libxml_ctx_error;
2187 		ctxt->sax->warning = php_libxml_ctx_warning;
2188 	}
2189 	htmlParseDocument(ctxt);
2190 	newdoc = ctxt->myDoc;
2191 	htmlFreeParserCtxt(ctxt);
2192 
2193 	if (!newdoc)
2194 		RETURN_FALSE;
2195 
2196 	if (id != NULL && instanceof_function(Z_OBJCE_P(id), dom_document_class_entry TSRMLS_CC)) {
2197 		intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
2198 		if (intern != NULL) {
2199 			docp = (xmlDocPtr) dom_object_get_node(intern);
2200 			doc_prop = NULL;
2201 			if (docp != NULL) {
2202 				php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC);
2203 				doc_prop = intern->document->doc_props;
2204 				intern->document->doc_props = NULL;
2205 				refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
2206 				if (refcount != 0) {
2207 					docp->_private = NULL;
2208 				}
2209 			}
2210 			intern->document = NULL;
2211 			if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, newdoc TSRMLS_CC) == -1) {
2212 				RETURN_FALSE;
2213 			}
2214 			intern->document->doc_props = doc_prop;
2215 		}
2216 
2217 		php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)newdoc, (void *)intern TSRMLS_CC);
2218 
2219 		RETURN_TRUE;
2220 	} else {
2221 		DOM_RET_OBJ(rv, (xmlNodePtr) newdoc, &ret, NULL);
2222 	}
2223 }
2224 /* }}} */
2225 
2226 /* {{{ proto DOMNode dom_document_load_html_file(string source);
2227 Since: DOM extended
2228 */
PHP_METHOD(domdocument,loadHTMLFile)2229 PHP_METHOD(domdocument, loadHTMLFile)
2230 {
2231 	dom_load_html(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
2232 }
2233 /* }}} end dom_document_load_html_file */
2234 
2235 /* {{{ proto DOMNode dom_document_load_html(string source);
2236 Since: DOM extended
2237 */
PHP_METHOD(domdocument,loadHTML)2238 PHP_METHOD(domdocument, loadHTML)
2239 {
2240 	dom_load_html(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
2241 }
2242 /* }}} end dom_document_load_html */
2243 
2244 /* {{{ proto int dom_document_save_html_file(string file);
2245 Convenience method to save to file as html
2246 */
PHP_FUNCTION(dom_document_save_html_file)2247 PHP_FUNCTION(dom_document_save_html_file)
2248 {
2249 	zval *id;
2250 	xmlDoc *docp;
2251 	int file_len, bytes, format;
2252 	dom_object *intern;
2253 	dom_doc_propsptr doc_props;
2254 	char *file;
2255 	const char *encoding;
2256 
2257 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &file, &file_len) == FAILURE) {
2258 		return;
2259 	}
2260 
2261 	if (file_len == 0) {
2262 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Filename");
2263 		RETURN_FALSE;
2264 	}
2265 
2266 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
2267 
2268 
2269 	encoding = (const char *) htmlGetMetaEncoding(docp);
2270 
2271 	doc_props = dom_get_doc_props(intern->document);
2272 	format = doc_props->formatoutput;
2273 	bytes = htmlSaveFileFormat(file, docp, encoding, format);
2274 
2275 	if (bytes == -1) {
2276 		RETURN_FALSE;
2277 	}
2278 	RETURN_LONG(bytes);
2279 }
2280 /* }}} end dom_document_save_html_file */
2281 
2282 /* {{{ proto string dom_document_save_html();
2283 Convenience method to output as html
2284 */
PHP_FUNCTION(dom_document_save_html)2285 PHP_FUNCTION(dom_document_save_html)
2286 {
2287 	zval *id, *nodep = NULL;
2288 	xmlDoc *docp;
2289 	xmlNode *node;
2290 	xmlBufferPtr buf;
2291 	dom_object *intern, *nodeobj;
2292 	xmlChar *mem = NULL;
2293 	int size, format;
2294 	dom_doc_propsptr doc_props;
2295 
2296 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
2297 		"O|O!", &id, dom_document_class_entry, &nodep, dom_node_class_entry)
2298 		== FAILURE) {
2299 		return;
2300 	}
2301 
2302 	DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
2303 
2304 	doc_props = dom_get_doc_props(intern->document);
2305 	format = doc_props->formatoutput;
2306 
2307 	if (nodep != NULL) {
2308 		/* Dump contents of Node */
2309 		DOM_GET_OBJ(node, nodep, xmlNodePtr, nodeobj);
2310 		if (node->doc != docp) {
2311 			php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
2312 			RETURN_FALSE;
2313 		}
2314 
2315 		buf = xmlBufferCreate();
2316 		if (!buf) {
2317 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch buffer");
2318 			RETURN_FALSE;
2319 		}
2320 
2321 		size = htmlNodeDump(buf, docp, node);
2322 		if (size >= 0) {
2323 			mem = (xmlChar*) xmlBufferContent(buf);
2324 			if (!mem) {
2325 				RETVAL_FALSE;
2326 			} else {
2327 				RETVAL_STRINGL((const char*) mem, size, 1);
2328 			}
2329 		} else {
2330 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error dumping HTML node");
2331 			RETVAL_FALSE;
2332 		}
2333 		xmlBufferFree(buf);
2334 	} else {
2335 #if LIBXML_VERSION >= 20623
2336 		htmlDocDumpMemoryFormat(docp, &mem, &size, format);
2337 #else
2338 		htmlDocDumpMemory(docp, &mem, &size);
2339 #endif
2340 		if (!size) {
2341 			RETVAL_FALSE;
2342 		} else {
2343 			RETVAL_STRINGL((const char*) mem, size, 1);
2344 		}
2345 		if (mem)
2346 			xmlFree(mem);
2347 	}
2348 
2349 }
2350 /* }}} end dom_document_save_html */
2351 
2352 #endif  /* defined(LIBXML_HTML_ENABLED) */
2353 
2354 /* {{{ proto boolean DOMDocument::registerNodeClass(string baseclass, string extendedclass);
2355    Register extended class used to create base node type */
PHP_METHOD(domdocument,registerNodeClass)2356 PHP_METHOD(domdocument, registerNodeClass)
2357 {
2358 	zval *id;
2359 	xmlDoc *docp;
2360 	char *baseclass = NULL, *extendedclass = NULL;
2361 	int baseclass_len = 0, extendedclass_len = 0;
2362 	zend_class_entry *basece = NULL, *ce = NULL;
2363 	dom_object *intern;
2364 
2365 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss!", &id, dom_document_class_entry, &baseclass, &baseclass_len, &extendedclass, &extendedclass_len) == FAILURE) {
2366 		return;
2367 	}
2368 
2369 	if (baseclass_len) {
2370 		zend_class_entry **pce;
2371 		if (zend_lookup_class(baseclass, baseclass_len, &pce TSRMLS_CC) == FAILURE) {
2372 			php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s does not exist", baseclass);
2373 			return;
2374 		}
2375 		basece = *pce;
2376 	}
2377 
2378 	if (basece == NULL || ! instanceof_function(basece, dom_node_class_entry TSRMLS_CC)) {
2379 		php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s is not derived from DOMNode.", baseclass);
2380 		return;
2381 	}
2382 
2383 	if (extendedclass_len) {
2384 		zend_class_entry **pce;
2385 		if (zend_lookup_class(extendedclass, extendedclass_len, &pce TSRMLS_CC) == FAILURE) {
2386 			php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s does not exist", extendedclass);
2387 		}
2388 		ce = *pce;
2389 	}
2390 
2391 	if (ce == NULL || instanceof_function(ce, basece TSRMLS_CC)) {
2392 
2393 		DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
2394 
2395 		if (dom_set_doc_classmap(intern->document, basece, ce TSRMLS_CC) == FAILURE) {
2396 			php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s could not be registered.", extendedclass);
2397 		}
2398 		RETURN_TRUE;
2399 	} else {
2400 		php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s is not derived from %s.", extendedclass, baseclass);
2401 	}
2402 
2403 	RETURN_FALSE;
2404 }
2405 /* }}} */
2406 
2407 #endif  /* HAVE_LIBXML && HAVE_DOM */
2408 
2409 /*
2410  * Local variables:
2411  * tab-width: 4
2412  * c-basic-offset: 4
2413  * End:
2414  * vim600: noet sw=4 ts=4 fdm=marker
2415  * vim<600: noet sw=4 ts=4
2416  */
2417