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