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