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