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