root/ext/dom/document.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dom_document_doctype_read
  2. dom_document_implementation_read
  3. dom_document_document_element_read
  4. dom_document_encoding_read
  5. dom_document_encoding_write
  6. dom_document_standalone_read
  7. dom_document_standalone_write
  8. dom_document_version_read
  9. dom_document_version_write
  10. dom_document_strict_error_checking_read
  11. dom_document_strict_error_checking_write
  12. dom_document_format_output_read
  13. dom_document_format_output_write
  14. dom_document_validate_on_parse_read
  15. dom_document_validate_on_parse_write
  16. dom_document_resolve_externals_read
  17. dom_document_resolve_externals_write
  18. dom_document_preserve_whitespace_read
  19. dom_document_preserve_whitespace_write
  20. dom_document_recover_read
  21. dom_document_recover_write
  22. dom_document_substitue_entities_read
  23. dom_document_substitue_entities_write
  24. dom_document_document_uri_read
  25. dom_document_document_uri_write
  26. dom_document_config_read
  27. PHP_FUNCTION
  28. PHP_FUNCTION
  29. PHP_FUNCTION
  30. PHP_FUNCTION
  31. PHP_FUNCTION
  32. PHP_FUNCTION
  33. PHP_FUNCTION
  34. PHP_FUNCTION
  35. PHP_FUNCTION
  36. PHP_FUNCTION
  37. PHP_FUNCTION
  38. PHP_FUNCTION
  39. PHP_FUNCTION
  40. PHP_FUNCTION
  41. PHP_FUNCTION
  42. PHP_FUNCTION
  43. PHP_FUNCTION
  44. PHP_METHOD
  45. _dom_get_valid_file_path
  46. dom_document_parser
  47. dom_parse_document
  48. PHP_METHOD
  49. PHP_METHOD
  50. PHP_FUNCTION
  51. PHP_FUNCTION
  52. php_dom_free_xinclude_node
  53. php_dom_remove_xinclude_nodes
  54. PHP_FUNCTION
  55. PHP_FUNCTION
  56. _dom_document_schema_validate
  57. PHP_FUNCTION
  58. PHP_FUNCTION
  59. _dom_document_relaxNG_validate
  60. PHP_FUNCTION
  61. PHP_FUNCTION
  62. dom_load_html
  63. PHP_METHOD
  64. PHP_METHOD
  65. PHP_FUNCTION
  66. PHP_FUNCTION
  67. PHP_METHOD

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

/* [<][>][^][v][top][bottom][index][help] */