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