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