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 | Marcus Borger <helly@php.net> | 18 +----------------------------------------------------------------------+ 19*/ 20 21/* $Id$ */ 22 23#ifdef HAVE_CONFIG_H 24#include "config.h" 25#endif 26 27#include "php.h" 28#if HAVE_LIBXML && HAVE_DOM 29#include "ext/standard/php_rand.h" 30#include "php_dom.h" 31#include "dom_properties.h" 32#include "zend_interfaces.h" 33 34#include "ext/standard/info.h" 35#define PHP_XPATH 1 36#define PHP_XPTR 2 37 38/* {{{ class entries */ 39zend_class_entry *dom_node_class_entry; 40zend_class_entry *dom_domexception_class_entry; 41zend_class_entry *dom_domstringlist_class_entry; 42zend_class_entry *dom_namelist_class_entry; 43zend_class_entry *dom_domimplementationlist_class_entry; 44zend_class_entry *dom_domimplementationsource_class_entry; 45zend_class_entry *dom_domimplementation_class_entry; 46zend_class_entry *dom_documentfragment_class_entry; 47zend_class_entry *dom_document_class_entry; 48zend_class_entry *dom_nodelist_class_entry; 49zend_class_entry *dom_namednodemap_class_entry; 50zend_class_entry *dom_characterdata_class_entry; 51zend_class_entry *dom_attr_class_entry; 52zend_class_entry *dom_element_class_entry; 53zend_class_entry *dom_text_class_entry; 54zend_class_entry *dom_comment_class_entry; 55zend_class_entry *dom_typeinfo_class_entry; 56zend_class_entry *dom_userdatahandler_class_entry; 57zend_class_entry *dom_domerror_class_entry; 58zend_class_entry *dom_domerrorhandler_class_entry; 59zend_class_entry *dom_domlocator_class_entry; 60zend_class_entry *dom_domconfiguration_class_entry; 61zend_class_entry *dom_cdatasection_class_entry; 62zend_class_entry *dom_documenttype_class_entry; 63zend_class_entry *dom_notation_class_entry; 64zend_class_entry *dom_entity_class_entry; 65zend_class_entry *dom_entityreference_class_entry; 66zend_class_entry *dom_processinginstruction_class_entry; 67zend_class_entry *dom_string_extend_class_entry; 68#if defined(LIBXML_XPATH_ENABLED) 69zend_class_entry *dom_xpath_class_entry; 70#endif 71zend_class_entry *dom_namespace_node_class_entry; 72/* }}} */ 73 74zend_object_handlers dom_object_handlers; 75 76static HashTable classes; 77/* {{{ prop handler tables */ 78static HashTable dom_domstringlist_prop_handlers; 79static HashTable dom_namelist_prop_handlers; 80static HashTable dom_domimplementationlist_prop_handlers; 81static HashTable dom_document_prop_handlers; 82static HashTable dom_node_prop_handlers; 83static HashTable dom_nodelist_prop_handlers; 84static HashTable dom_namednodemap_prop_handlers; 85static HashTable dom_characterdata_prop_handlers; 86static HashTable dom_attr_prop_handlers; 87static HashTable dom_element_prop_handlers; 88static HashTable dom_text_prop_handlers; 89static HashTable dom_typeinfo_prop_handlers; 90static HashTable dom_domerror_prop_handlers; 91static HashTable dom_domlocator_prop_handlers; 92static HashTable dom_documenttype_prop_handlers; 93static HashTable dom_notation_prop_handlers; 94static HashTable dom_entity_prop_handlers; 95static HashTable dom_processinginstruction_prop_handlers; 96static HashTable dom_namespace_node_prop_handlers; 97#if defined(LIBXML_XPATH_ENABLED) 98static HashTable dom_xpath_prop_handlers; 99#endif 100/* }}} */ 101 102typedef int (*dom_read_t)(dom_object *obj, zval **retval TSRMLS_DC); 103typedef int (*dom_write_t)(dom_object *obj, zval *newval TSRMLS_DC); 104 105typedef struct _dom_prop_handler { 106 dom_read_t read_func; 107 dom_write_t write_func; 108} dom_prop_handler; 109 110/* {{{ int dom_node_is_read_only(xmlNodePtr node) */ 111int dom_node_is_read_only(xmlNodePtr node) { 112 switch (node->type) { 113 case XML_ENTITY_REF_NODE: 114 case XML_ENTITY_NODE: 115 case XML_DOCUMENT_TYPE_NODE: 116 case XML_NOTATION_NODE: 117 case XML_DTD_NODE: 118 case XML_ELEMENT_DECL: 119 case XML_ATTRIBUTE_DECL: 120 case XML_ENTITY_DECL: 121 case XML_NAMESPACE_DECL: 122 return SUCCESS; 123 break; 124 default: 125 if (node->doc == NULL) { 126 return SUCCESS; 127 } else { 128 return FAILURE; 129 } 130 } 131} 132/* }}} end dom_node_is_read_only */ 133 134/* {{{ int dom_node_children_valid(xmlNodePtr node) */ 135int dom_node_children_valid(xmlNodePtr node) { 136 switch (node->type) { 137 case XML_DOCUMENT_TYPE_NODE: 138 case XML_DTD_NODE: 139 case XML_PI_NODE: 140 case XML_COMMENT_NODE: 141 case XML_TEXT_NODE: 142 case XML_CDATA_SECTION_NODE: 143 case XML_NOTATION_NODE: 144 return FAILURE; 145 break; 146 default: 147 return SUCCESS; 148 } 149} 150/* }}} end dom_node_children_valid */ 151 152/* {{{ dom_get_doc_props() */ 153dom_doc_propsptr dom_get_doc_props(php_libxml_ref_obj *document) 154{ 155 dom_doc_propsptr doc_props; 156 157 if (document && document->doc_props) { 158 return document->doc_props; 159 } else { 160 doc_props = emalloc(sizeof(libxml_doc_props)); 161 doc_props->formatoutput = 0; 162 doc_props->validateonparse = 0; 163 doc_props->resolveexternals = 0; 164 doc_props->preservewhitespace = 1; 165 doc_props->substituteentities = 0; 166 doc_props->stricterror = 1; 167 doc_props->recover = 0; 168 doc_props->classmap = NULL; 169 if (document) { 170 document->doc_props = doc_props; 171 } 172 return doc_props; 173 } 174} 175 176static void dom_copy_doc_props(php_libxml_ref_obj *source_doc, php_libxml_ref_obj *dest_doc) 177{ 178 dom_doc_propsptr source, dest; 179 180 if (source_doc && dest_doc) { 181 182 source = dom_get_doc_props(source_doc); 183 dest = dom_get_doc_props(dest_doc); 184 185 dest->formatoutput = source->formatoutput; 186 dest->validateonparse = source->validateonparse; 187 dest->resolveexternals = source->resolveexternals; 188 dest->preservewhitespace = source->preservewhitespace; 189 dest->substituteentities = source->substituteentities; 190 dest->stricterror = source->stricterror; 191 dest->recover = source->recover; 192 if (source->classmap) { 193 ALLOC_HASHTABLE(dest->classmap); 194 zend_hash_init(dest->classmap, 0, NULL, NULL, 0); 195 zend_hash_copy(dest->classmap, source->classmap, NULL, NULL, sizeof(zend_class_entry *)); 196 } 197 198 } 199} 200 201int dom_set_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece, zend_class_entry *ce TSRMLS_DC) 202{ 203 dom_doc_propsptr doc_props; 204 205 if (document) { 206 doc_props = dom_get_doc_props(document); 207 if (doc_props->classmap == NULL) { 208 if (ce == NULL) { 209 return SUCCESS; 210 } 211 ALLOC_HASHTABLE(doc_props->classmap); 212 zend_hash_init(doc_props->classmap, 0, NULL, NULL, 0); 213 } 214 if (ce) { 215 return zend_hash_update(doc_props->classmap, basece->name, basece->name_length + 1, &ce, sizeof(zend_class_entry *), NULL); 216 } else { 217 zend_hash_del(doc_props->classmap, basece->name, basece->name_length + 1); 218 } 219 } 220 return SUCCESS; 221} 222 223zend_class_entry *dom_get_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece TSRMLS_DC) 224{ 225 dom_doc_propsptr doc_props; 226 zend_class_entry **ce = NULL; 227 228 if (document) { 229 doc_props = dom_get_doc_props(document); 230 if (doc_props->classmap) { 231 if (zend_hash_find(doc_props->classmap, basece->name, basece->name_length + 1, (void**) &ce) == SUCCESS) { 232 return *ce; 233 } 234 } 235 } 236 237 return basece; 238} 239/* }}} */ 240 241/* {{{ dom_get_strict_error() */ 242int dom_get_strict_error(php_libxml_ref_obj *document) { 243 int stricterror; 244 dom_doc_propsptr doc_props; 245 246 doc_props = dom_get_doc_props(document); 247 stricterror = doc_props->stricterror; 248 if (document == NULL) { 249 efree(doc_props); 250 } 251 252 return stricterror; 253} 254/* }}} */ 255 256/* {{{ xmlNodePtr dom_object_get_node(dom_object *obj) */ 257PHP_DOM_EXPORT xmlNodePtr dom_object_get_node(dom_object *obj) 258{ 259 if (obj && obj->ptr != NULL) { 260 return ((php_libxml_node_ptr *)obj->ptr)->node; 261 } else { 262 return NULL; 263 } 264} 265/* }}} end dom_object_get_node */ 266 267/* {{{ dom_object *php_dom_object_get_data(xmlNodePtr obj) */ 268PHP_DOM_EXPORT dom_object *php_dom_object_get_data(xmlNodePtr obj) 269{ 270 if (obj && obj->_private != NULL) { 271 return (dom_object *) ((php_libxml_node_ptr *) obj->_private)->_private; 272 } else { 273 return NULL; 274 } 275} 276/* }}} end php_dom_object_get_data */ 277 278/* {{{ dom_read_na */ 279static int dom_read_na(dom_object *obj, zval **retval TSRMLS_DC) 280{ 281 *retval = NULL; 282 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot read property"); 283 return FAILURE; 284} 285/* }}} */ 286 287/* {{{ dom_write_na */ 288static int dom_write_na(dom_object *obj, zval *newval TSRMLS_DC) 289{ 290 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot write property"); 291 return FAILURE; 292} 293/* }}} */ 294 295/* {{{ dom_register_prop_handler */ 296static void dom_register_prop_handler(HashTable *prop_handler, char *name, dom_read_t read_func, dom_write_t write_func TSRMLS_DC) 297{ 298 dom_prop_handler hnd; 299 300 hnd.read_func = read_func ? read_func : dom_read_na; 301 hnd.write_func = write_func ? write_func : dom_write_na; 302 zend_hash_add(prop_handler, name, strlen(name)+1, &hnd, sizeof(dom_prop_handler), NULL); 303} 304/* }}} */ 305 306static zval **dom_get_property_ptr_ptr(zval *object, zval *member TSRMLS_DC) /* {{{ */ 307{ 308 dom_object *obj; 309 zval tmp_member; 310 zval **retval = NULL; 311 dom_prop_handler *hnd; 312 zend_object_handlers *std_hnd; 313 int ret = FAILURE; 314 315 if (member->type != IS_STRING) { 316 tmp_member = *member; 317 zval_copy_ctor(&tmp_member); 318 convert_to_string(&tmp_member); 319 member = &tmp_member; 320 } 321 322 obj = (dom_object *)zend_objects_get_address(object TSRMLS_CC); 323 324 if (obj->prop_handler != NULL) { 325 ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); 326 } 327 if (ret == FAILURE) { 328 std_hnd = zend_get_std_object_handlers(); 329 retval = std_hnd->get_property_ptr_ptr(object, member TSRMLS_CC); 330 } 331 332 if (member == &tmp_member) { 333 zval_dtor(member); 334 } 335 return retval; 336} 337/* }}} */ 338 339/* {{{ dom_read_property */ 340zval *dom_read_property(zval *object, zval *member, int type TSRMLS_DC) 341{ 342 dom_object *obj; 343 zval tmp_member; 344 zval *retval; 345 dom_prop_handler *hnd; 346 zend_object_handlers *std_hnd; 347 int ret; 348 349 if (member->type != IS_STRING) { 350 tmp_member = *member; 351 zval_copy_ctor(&tmp_member); 352 convert_to_string(&tmp_member); 353 member = &tmp_member; 354 } 355 356 ret = FAILURE; 357 obj = (dom_object *)zend_objects_get_address(object TSRMLS_CC); 358 359 if (obj->prop_handler != NULL) { 360 ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); 361 } else if (instanceof_function(obj->std.ce, dom_node_class_entry TSRMLS_CC)) { 362 php_error(E_WARNING, "Couldn't fetch %s. Node no longer exists", obj->std.ce->name); 363 } 364 if (ret == SUCCESS) { 365 ret = hnd->read_func(obj, &retval TSRMLS_CC); 366 if (ret == SUCCESS) { 367 /* ensure we're creating a temporary variable */ 368 Z_SET_REFCOUNT_P(retval, 0); 369 Z_UNSET_ISREF_P(retval); 370 } else { 371 retval = EG(uninitialized_zval_ptr); 372 } 373 } else { 374 std_hnd = zend_get_std_object_handlers(); 375 retval = std_hnd->read_property(object, member, type TSRMLS_CC); 376 } 377 378 if (member == &tmp_member) { 379 zval_dtor(member); 380 } 381 return retval; 382} 383/* }}} */ 384 385/* {{{ dom_write_property */ 386void dom_write_property(zval *object, zval *member, zval *value TSRMLS_DC) 387{ 388 dom_object *obj; 389 zval tmp_member; 390 dom_prop_handler *hnd; 391 zend_object_handlers *std_hnd; 392 int ret; 393 394 if (member->type != IS_STRING) { 395 tmp_member = *member; 396 zval_copy_ctor(&tmp_member); 397 convert_to_string(&tmp_member); 398 member = &tmp_member; 399 } 400 401 ret = FAILURE; 402 obj = (dom_object *)zend_objects_get_address(object TSRMLS_CC); 403 404 if (obj->prop_handler != NULL) { 405 ret = zend_hash_find((HashTable *)obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); 406 } 407 if (ret == SUCCESS) { 408 hnd->write_func(obj, value TSRMLS_CC); 409 } else { 410 std_hnd = zend_get_std_object_handlers(); 411 std_hnd->write_property(object, member, value TSRMLS_CC); 412 } 413 414 if (member == &tmp_member) { 415 zval_dtor(member); 416 } 417} 418/* }}} */ 419 420/* {{{ dom_property_exists */ 421static int dom_property_exists(zval *object, zval *member, int check_empty TSRMLS_DC) 422{ 423 dom_object *obj; 424 zval tmp_member; 425 dom_prop_handler *hnd; 426 zend_object_handlers *std_hnd; 427 int ret, retval=0; 428 429 if (member->type != IS_STRING) { 430 tmp_member = *member; 431 zval_copy_ctor(&tmp_member); 432 convert_to_string(&tmp_member); 433 member = &tmp_member; 434 } 435 436 ret = FAILURE; 437 obj = (dom_object *)zend_objects_get_address(object TSRMLS_CC); 438 439 if (obj->prop_handler != NULL) { 440 ret = zend_hash_find((HashTable *)obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); 441 } 442 if (ret == SUCCESS) { 443 zval *tmp; 444 445 if (check_empty == 2) { 446 retval = 1; 447 } else if (hnd->read_func(obj, &tmp TSRMLS_CC) == SUCCESS) { 448 Z_SET_REFCOUNT_P(tmp, 1); 449 Z_UNSET_ISREF_P(tmp); 450 if (check_empty == 1) { 451 retval = zend_is_true(tmp); 452 } else if (check_empty == 0) { 453 retval = (Z_TYPE_P(tmp) != IS_NULL); 454 } 455 zval_ptr_dtor(&tmp); 456 } 457 } else { 458 std_hnd = zend_get_std_object_handlers(); 459 retval = std_hnd->has_property(object, member, check_empty TSRMLS_CC); 460 } 461 462 if (member == &tmp_member) { 463 zval_dtor(member); 464 } 465 return retval; 466} 467/* }}} */ 468 469static HashTable* dom_get_debug_info_helper(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ 470{ 471 dom_object *obj = zend_object_store_get_object(object TSRMLS_CC); 472 HashTable *debug_info, 473 *prop_handlers = obj->prop_handler, 474 *std_props; 475 HashPosition pos; 476 dom_prop_handler *entry; 477 zval *object_value, 478 *null_value; 479 480 *is_temp = 1; 481 482 ALLOC_HASHTABLE(debug_info); 483 ZEND_INIT_SYMTABLE_EX(debug_info, 32, 0); 484 485 std_props = zend_std_get_properties(object TSRMLS_CC); 486 zend_hash_copy(debug_info, std_props, (copy_ctor_func_t)zval_add_ref, 487 NULL, sizeof(zval*)); 488 489 if (!prop_handlers) { 490 return debug_info; 491 } 492 493 ALLOC_INIT_ZVAL(object_value); 494 ZVAL_STRING(object_value, "(object value omitted)", 1); 495 496 ALLOC_INIT_ZVAL(null_value); 497 ZVAL_NULL(null_value); 498 499 for (zend_hash_internal_pointer_reset_ex(prop_handlers, &pos); 500 zend_hash_get_current_data_ex(prop_handlers, (void **)&entry, &pos) 501 == SUCCESS; 502 zend_hash_move_forward_ex(prop_handlers, &pos)) { 503 zval *value; 504 char *string_key = NULL; 505 uint string_length = 0; 506 ulong num_key; 507 508 if (entry->read_func(obj, &value TSRMLS_CC) == FAILURE) { 509 continue; 510 } 511 512 if (zend_hash_get_current_key_ex(prop_handlers, &string_key, 513 &string_length, &num_key, 0, &pos) != HASH_KEY_IS_STRING) { 514 continue; 515 } 516 517 if (value == EG(uninitialized_zval_ptr)) { 518 value = null_value; 519 } else if (Z_TYPE_P(value) == IS_OBJECT) { 520 /* these are zvalues create on demand, with refcount and is_ref 521 * status left in an uninitalized stated */ 522 zval_dtor(value); 523 efree(value); 524 525 value = object_value; 526 } else { 527 /* see comment above */ 528 Z_SET_REFCOUNT_P(value, 0); 529 Z_UNSET_ISREF_P(value); 530 } 531 532 zval_add_ref(&value); 533 zend_hash_add(debug_info, string_key, string_length, 534 &value, sizeof(zval *), NULL); 535 } 536 537 zval_ptr_dtor(&null_value); 538 zval_ptr_dtor(&object_value); 539 540 return debug_info; 541} 542/* }}} */ 543 544static HashTable* dom_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ 545{ 546 return dom_get_debug_info_helper(object, is_temp TSRMLS_CC); 547} 548/* }}} */ 549 550void *php_dom_export_node(zval *object TSRMLS_DC) /* {{{ */ 551{ 552 php_libxml_node_object *intern; 553 xmlNodePtr nodep = NULL; 554 555 intern = (php_libxml_node_object *)zend_object_store_get_object(object TSRMLS_CC); 556 if (intern && intern->node) { 557 nodep = intern->node->node; 558 } 559 560 return nodep; 561} 562/* }}} */ 563 564/* {{{ proto somNode dom_import_simplexml(sxeobject node) 565 Get a simplexml_element object from dom to allow for processing */ 566PHP_FUNCTION(dom_import_simplexml) 567{ 568 zval *rv = NULL; 569 zval *node; 570 xmlNodePtr nodep = NULL; 571 php_libxml_node_object *nodeobj; 572 int ret; 573 574 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &node) == FAILURE) { 575 return; 576 } 577 578 nodeobj = (php_libxml_node_object *)zend_object_store_get_object(node TSRMLS_CC); 579 nodep = php_libxml_import_node(node TSRMLS_CC); 580 581 if (nodep && nodeobj && (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE)) { 582 DOM_RET_OBJ(rv, (xmlNodePtr) nodep, &ret, (dom_object *)nodeobj); 583 } else { 584 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Nodetype to import"); 585 RETURN_NULL(); 586 } 587} 588/* }}} */ 589 590zend_object_value dom_objects_store_clone_obj(zval *zobject TSRMLS_DC) /* {{{ */ 591{ 592 zend_object_value retval; 593 void *new_object; 594 dom_object *intern; 595 dom_object *old_object; 596 struct _store_object *obj; 597 zend_object_handle handle = Z_OBJ_HANDLE_P(zobject); 598 599 obj = &EG(objects_store).object_buckets[handle].bucket.obj; 600 601 if (obj->clone == NULL) { 602 php_error(E_ERROR, "Trying to clone an uncloneable object of class %s", Z_OBJCE_P(zobject)->name); 603 } 604 605 obj->clone(obj->object, &new_object TSRMLS_CC); 606 607 retval.handle = zend_objects_store_put(new_object, obj->dtor, obj->free_storage, obj->clone TSRMLS_CC); 608 intern = (dom_object *) new_object; 609 intern->handle = retval.handle; 610 retval.handlers = Z_OBJ_HT_P(zobject); 611 612 old_object = (dom_object *) obj->object; 613 zend_objects_clone_members(&intern->std, retval, &old_object->std, intern->handle TSRMLS_CC); 614 615 return retval; 616} 617/* }}} */ 618 619/* {{{ arginfo */ 620ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_import_simplexml, 0, 0, 1) 621 ZEND_ARG_INFO(0, node) 622ZEND_END_ARG_INFO() 623/* }}} */ 624 625static const zend_function_entry dom_functions[] = { 626 PHP_FE(dom_import_simplexml, arginfo_dom_import_simplexml) 627 PHP_FE_END 628}; 629 630static zend_object_handlers* dom_get_obj_handlers(TSRMLS_D) { 631 return &dom_object_handlers; 632} 633 634static const zend_module_dep dom_deps[] = { 635 ZEND_MOD_REQUIRED("libxml") 636 ZEND_MOD_CONFLICTS("domxml") 637 ZEND_MOD_END 638}; 639 640zend_module_entry dom_module_entry = { /* {{{ */ 641 STANDARD_MODULE_HEADER_EX, NULL, 642 dom_deps, 643 "dom", 644 dom_functions, 645 PHP_MINIT(dom), 646 PHP_MSHUTDOWN(dom), 647 NULL, 648 NULL, 649 PHP_MINFO(dom), 650 DOM_API_VERSION, /* Extension versionnumber */ 651 STANDARD_MODULE_PROPERTIES 652}; 653/* }}} */ 654 655#ifdef COMPILE_DL_DOM 656ZEND_GET_MODULE(dom) 657#endif 658 659/* {{{ PHP_MINIT_FUNCTION(dom) */ 660PHP_MINIT_FUNCTION(dom) 661{ 662 zend_class_entry ce; 663 664 memcpy(&dom_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); 665 dom_object_handlers.read_property = dom_read_property; 666 dom_object_handlers.write_property = dom_write_property; 667 dom_object_handlers.get_property_ptr_ptr = dom_get_property_ptr_ptr; 668 dom_object_handlers.clone_obj = dom_objects_store_clone_obj; 669 dom_object_handlers.has_property = dom_property_exists; 670 dom_object_handlers.get_debug_info = dom_get_debug_info; 671 672 zend_hash_init(&classes, 0, NULL, NULL, 1); 673 674 INIT_CLASS_ENTRY(ce, "DOMException", php_dom_domexception_class_functions); 675 dom_domexception_class_entry = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC); 676 dom_domexception_class_entry->ce_flags |= ZEND_ACC_FINAL; 677 zend_declare_property_long(dom_domexception_class_entry, "code", sizeof("code")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); 678 679 REGISTER_DOM_CLASS(ce, "DOMStringList", NULL, php_dom_domstringlist_class_functions, dom_domstringlist_class_entry); 680 681 zend_hash_init(&dom_domstringlist_prop_handlers, 0, NULL, NULL, 1); 682 dom_register_prop_handler(&dom_domstringlist_prop_handlers, "length", dom_domstringlist_length_read, NULL TSRMLS_CC); 683 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_domstringlist_prop_handlers, sizeof(dom_domstringlist_prop_handlers), NULL); 684 685 REGISTER_DOM_CLASS(ce, "DOMNameList", NULL, php_dom_namelist_class_functions, dom_namelist_class_entry); 686 687 zend_hash_init(&dom_namelist_prop_handlers, 0, NULL, NULL, 1); 688 dom_register_prop_handler(&dom_namelist_prop_handlers, "length", dom_namelist_length_read, NULL TSRMLS_CC); 689 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_namelist_prop_handlers, sizeof(dom_namelist_prop_handlers), NULL); 690 691 REGISTER_DOM_CLASS(ce, "DOMImplementationList", NULL, php_dom_domimplementationlist_class_functions, dom_domimplementationlist_class_entry); 692 693 zend_hash_init(&dom_domimplementationlist_prop_handlers, 0, NULL, NULL, 1); 694 dom_register_prop_handler(&dom_domimplementationlist_prop_handlers, "length", dom_domimplementationlist_length_read, NULL TSRMLS_CC); 695 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_domimplementationlist_prop_handlers, sizeof(dom_domimplementationlist_prop_handlers), NULL); 696 697 REGISTER_DOM_CLASS(ce, "DOMImplementationSource", NULL, php_dom_domimplementationsource_class_functions, dom_domimplementationsource_class_entry); 698 REGISTER_DOM_CLASS(ce, "DOMImplementation", NULL, php_dom_domimplementation_class_functions, dom_domimplementation_class_entry); 699 700 REGISTER_DOM_CLASS(ce, "DOMNode", NULL, php_dom_node_class_functions, dom_node_class_entry); 701 702 zend_hash_init(&dom_node_prop_handlers, 0, NULL, NULL, 1); 703 dom_register_prop_handler(&dom_node_prop_handlers, "nodeName", dom_node_node_name_read, NULL TSRMLS_CC); 704 dom_register_prop_handler(&dom_node_prop_handlers, "nodeValue", dom_node_node_value_read, dom_node_node_value_write TSRMLS_CC); 705 dom_register_prop_handler(&dom_node_prop_handlers, "nodeType", dom_node_node_type_read, NULL TSRMLS_CC); 706 dom_register_prop_handler(&dom_node_prop_handlers, "parentNode", dom_node_parent_node_read, NULL TSRMLS_CC); 707 dom_register_prop_handler(&dom_node_prop_handlers, "childNodes", dom_node_child_nodes_read, NULL TSRMLS_CC); 708 dom_register_prop_handler(&dom_node_prop_handlers, "firstChild", dom_node_first_child_read, NULL TSRMLS_CC); 709 dom_register_prop_handler(&dom_node_prop_handlers, "lastChild", dom_node_last_child_read, NULL TSRMLS_CC); 710 dom_register_prop_handler(&dom_node_prop_handlers, "previousSibling", dom_node_previous_sibling_read, NULL TSRMLS_CC); 711 dom_register_prop_handler(&dom_node_prop_handlers, "nextSibling", dom_node_next_sibling_read, NULL TSRMLS_CC); 712 dom_register_prop_handler(&dom_node_prop_handlers, "attributes", dom_node_attributes_read, NULL TSRMLS_CC); 713 dom_register_prop_handler(&dom_node_prop_handlers, "ownerDocument", dom_node_owner_document_read, NULL TSRMLS_CC); 714 dom_register_prop_handler(&dom_node_prop_handlers, "namespaceURI", dom_node_namespace_uri_read, NULL TSRMLS_CC); 715 dom_register_prop_handler(&dom_node_prop_handlers, "prefix", dom_node_prefix_read, dom_node_prefix_write TSRMLS_CC); 716 dom_register_prop_handler(&dom_node_prop_handlers, "localName", dom_node_local_name_read, NULL TSRMLS_CC); 717 dom_register_prop_handler(&dom_node_prop_handlers, "baseURI", dom_node_base_uri_read, NULL TSRMLS_CC); 718 dom_register_prop_handler(&dom_node_prop_handlers, "textContent", dom_node_text_content_read, dom_node_text_content_write TSRMLS_CC); 719 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_node_prop_handlers, sizeof(dom_node_prop_handlers), NULL); 720 721 REGISTER_DOM_CLASS(ce, "DOMNameSpaceNode", NULL, NULL, dom_namespace_node_class_entry); 722 723 zend_hash_init(&dom_namespace_node_prop_handlers, 0, NULL, NULL, 1); 724 dom_register_prop_handler(&dom_namespace_node_prop_handlers, "nodeName", dom_node_node_name_read, NULL TSRMLS_CC); 725 dom_register_prop_handler(&dom_namespace_node_prop_handlers, "nodeValue", dom_node_node_value_read, NULL TSRMLS_CC); 726 dom_register_prop_handler(&dom_namespace_node_prop_handlers, "nodeType", dom_node_node_type_read, NULL TSRMLS_CC); 727 dom_register_prop_handler(&dom_namespace_node_prop_handlers, "prefix", dom_node_prefix_read, NULL TSRMLS_CC); 728 dom_register_prop_handler(&dom_namespace_node_prop_handlers, "localName", dom_node_local_name_read, NULL TSRMLS_CC); 729 dom_register_prop_handler(&dom_namespace_node_prop_handlers, "namespaceURI", dom_node_namespace_uri_read, NULL TSRMLS_CC); 730 dom_register_prop_handler(&dom_namespace_node_prop_handlers, "ownerDocument", dom_node_owner_document_read, NULL TSRMLS_CC); 731 dom_register_prop_handler(&dom_namespace_node_prop_handlers, "parentNode", dom_node_parent_node_read, NULL TSRMLS_CC); 732 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_namespace_node_prop_handlers, sizeof(dom_namespace_node_prop_handlers), NULL); 733 734 REGISTER_DOM_CLASS(ce, "DOMDocumentFragment", dom_node_class_entry, php_dom_documentfragment_class_functions, dom_documentfragment_class_entry); 735 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_node_prop_handlers, sizeof(dom_node_prop_handlers), NULL); 736 737 REGISTER_DOM_CLASS(ce, "DOMDocument", dom_node_class_entry, php_dom_document_class_functions, dom_document_class_entry); 738 zend_hash_init(&dom_document_prop_handlers, 0, NULL, NULL, 1); 739 dom_register_prop_handler(&dom_document_prop_handlers, "doctype", dom_document_doctype_read, NULL TSRMLS_CC); 740 dom_register_prop_handler(&dom_document_prop_handlers, "implementation", dom_document_implementation_read, NULL TSRMLS_CC); 741 dom_register_prop_handler(&dom_document_prop_handlers, "documentElement", dom_document_document_element_read, NULL TSRMLS_CC); 742 dom_register_prop_handler(&dom_document_prop_handlers, "actualEncoding", dom_document_encoding_read, NULL TSRMLS_CC); 743 dom_register_prop_handler(&dom_document_prop_handlers, "encoding", dom_document_encoding_read, dom_document_encoding_write TSRMLS_CC); 744 dom_register_prop_handler(&dom_document_prop_handlers, "xmlEncoding", dom_document_encoding_read, NULL TSRMLS_CC); 745 dom_register_prop_handler(&dom_document_prop_handlers, "standalone", dom_document_standalone_read, dom_document_standalone_write TSRMLS_CC); 746 dom_register_prop_handler(&dom_document_prop_handlers, "xmlStandalone", dom_document_standalone_read, dom_document_standalone_write TSRMLS_CC); 747 dom_register_prop_handler(&dom_document_prop_handlers, "version", dom_document_version_read, dom_document_version_write TSRMLS_CC); 748 dom_register_prop_handler(&dom_document_prop_handlers, "xmlVersion", dom_document_version_read, dom_document_version_write TSRMLS_CC); 749 dom_register_prop_handler(&dom_document_prop_handlers, "strictErrorChecking", dom_document_strict_error_checking_read, dom_document_strict_error_checking_write TSRMLS_CC); 750 dom_register_prop_handler(&dom_document_prop_handlers, "documentURI", dom_document_document_uri_read, dom_document_document_uri_write TSRMLS_CC); 751 dom_register_prop_handler(&dom_document_prop_handlers, "config", dom_document_config_read, NULL TSRMLS_CC); 752 dom_register_prop_handler(&dom_document_prop_handlers, "formatOutput", dom_document_format_output_read, dom_document_format_output_write TSRMLS_CC); 753 dom_register_prop_handler(&dom_document_prop_handlers, "validateOnParse", dom_document_validate_on_parse_read, dom_document_validate_on_parse_write TSRMLS_CC); 754 dom_register_prop_handler(&dom_document_prop_handlers, "resolveExternals", dom_document_resolve_externals_read, dom_document_resolve_externals_write TSRMLS_CC); 755 dom_register_prop_handler(&dom_document_prop_handlers, "preserveWhiteSpace", dom_document_preserve_whitespace_read, dom_document_preserve_whitespace_write TSRMLS_CC); 756 dom_register_prop_handler(&dom_document_prop_handlers, "recover", dom_document_recover_read, dom_document_recover_write TSRMLS_CC); 757 dom_register_prop_handler(&dom_document_prop_handlers, "substituteEntities", dom_document_substitue_entities_read, dom_document_substitue_entities_write TSRMLS_CC); 758 759 zend_hash_merge(&dom_document_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); 760 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_document_prop_handlers, sizeof(dom_document_prop_handlers), NULL); 761 762 INIT_CLASS_ENTRY(ce, "DOMNodeList", php_dom_nodelist_class_functions); 763 ce.create_object = dom_nnodemap_objects_new; 764 dom_nodelist_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); 765 dom_nodelist_class_entry->get_iterator = php_dom_get_iterator; 766 zend_class_implements(dom_nodelist_class_entry TSRMLS_CC, 1, zend_ce_traversable); 767 768 zend_hash_init(&dom_nodelist_prop_handlers, 0, NULL, NULL, 1); 769 dom_register_prop_handler(&dom_nodelist_prop_handlers, "length", dom_nodelist_length_read, NULL TSRMLS_CC); 770 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_nodelist_prop_handlers, sizeof(dom_nodelist_prop_handlers), NULL); 771 772 INIT_CLASS_ENTRY(ce, "DOMNamedNodeMap", php_dom_namednodemap_class_functions); 773 ce.create_object = dom_nnodemap_objects_new; 774 dom_namednodemap_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); 775 dom_namednodemap_class_entry->get_iterator = php_dom_get_iterator; 776 zend_class_implements(dom_namednodemap_class_entry TSRMLS_CC, 1, zend_ce_traversable); 777 778 zend_hash_init(&dom_namednodemap_prop_handlers, 0, NULL, NULL, 1); 779 dom_register_prop_handler(&dom_namednodemap_prop_handlers, "length", dom_namednodemap_length_read, NULL TSRMLS_CC); 780 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_namednodemap_prop_handlers, sizeof(dom_namednodemap_prop_handlers), NULL); 781 782 REGISTER_DOM_CLASS(ce, "DOMCharacterData", dom_node_class_entry, php_dom_characterdata_class_functions, dom_characterdata_class_entry); 783 784 zend_hash_init(&dom_characterdata_prop_handlers, 0, NULL, NULL, 1); 785 dom_register_prop_handler(&dom_characterdata_prop_handlers, "data", dom_characterdata_data_read, dom_characterdata_data_write TSRMLS_CC); 786 dom_register_prop_handler(&dom_characterdata_prop_handlers, "length", dom_characterdata_length_read, NULL TSRMLS_CC); 787 zend_hash_merge(&dom_characterdata_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); 788 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_characterdata_prop_handlers, sizeof(dom_characterdata_prop_handlers), NULL); 789 790 REGISTER_DOM_CLASS(ce, "DOMAttr", dom_node_class_entry, php_dom_attr_class_functions, dom_attr_class_entry); 791 792 zend_hash_init(&dom_attr_prop_handlers, 0, NULL, NULL, 1); 793 dom_register_prop_handler(&dom_attr_prop_handlers, "name", dom_attr_name_read, NULL TSRMLS_CC); 794 dom_register_prop_handler(&dom_attr_prop_handlers, "specified", dom_attr_specified_read, NULL TSRMLS_CC); 795 dom_register_prop_handler(&dom_attr_prop_handlers, "value", dom_attr_value_read, dom_attr_value_write TSRMLS_CC); 796 dom_register_prop_handler(&dom_attr_prop_handlers, "ownerElement", dom_attr_owner_element_read, NULL TSRMLS_CC); 797 dom_register_prop_handler(&dom_attr_prop_handlers, "schemaTypeInfo", dom_attr_schema_type_info_read, NULL TSRMLS_CC); 798 zend_hash_merge(&dom_attr_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); 799 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_attr_prop_handlers, sizeof(dom_attr_prop_handlers), NULL); 800 801 REGISTER_DOM_CLASS(ce, "DOMElement", dom_node_class_entry, php_dom_element_class_functions, dom_element_class_entry); 802 803 zend_hash_init(&dom_element_prop_handlers, 0, NULL, NULL, 1); 804 dom_register_prop_handler(&dom_element_prop_handlers, "tagName", dom_element_tag_name_read, NULL TSRMLS_CC); 805 dom_register_prop_handler(&dom_element_prop_handlers, "schemaTypeInfo", dom_element_schema_type_info_read, NULL TSRMLS_CC); 806 zend_hash_merge(&dom_element_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); 807 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_element_prop_handlers, sizeof(dom_element_prop_handlers), NULL); 808 809 REGISTER_DOM_CLASS(ce, "DOMText", dom_characterdata_class_entry, php_dom_text_class_functions, dom_text_class_entry); 810 811 zend_hash_init(&dom_text_prop_handlers, 0, NULL, NULL, 1); 812 dom_register_prop_handler(&dom_text_prop_handlers, "wholeText", dom_text_whole_text_read, NULL TSRMLS_CC); 813 zend_hash_merge(&dom_text_prop_handlers, &dom_characterdata_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); 814 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_text_prop_handlers, sizeof(dom_text_prop_handlers), NULL); 815 816 REGISTER_DOM_CLASS(ce, "DOMComment", dom_characterdata_class_entry, php_dom_comment_class_functions, dom_comment_class_entry); 817 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_characterdata_prop_handlers, sizeof(dom_typeinfo_prop_handlers), NULL); 818 819 REGISTER_DOM_CLASS(ce, "DOMTypeinfo", NULL, php_dom_typeinfo_class_functions, dom_typeinfo_class_entry); 820 821 zend_hash_init(&dom_typeinfo_prop_handlers, 0, NULL, NULL, 1); 822 dom_register_prop_handler(&dom_typeinfo_prop_handlers, "typeName", dom_typeinfo_type_name_read, NULL TSRMLS_CC); 823 dom_register_prop_handler(&dom_typeinfo_prop_handlers, "typeNamespace", dom_typeinfo_type_namespace_read, NULL TSRMLS_CC); 824 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_typeinfo_prop_handlers, sizeof(dom_typeinfo_prop_handlers), NULL); 825 826 REGISTER_DOM_CLASS(ce, "DOMUserDataHandler", NULL, php_dom_userdatahandler_class_functions, dom_userdatahandler_class_entry); 827 REGISTER_DOM_CLASS(ce, "DOMDomError", NULL, php_dom_domerror_class_functions, dom_domerror_class_entry); 828 829 zend_hash_init(&dom_domerror_prop_handlers, 0, NULL, NULL, 1); 830 dom_register_prop_handler(&dom_domerror_prop_handlers, "severity", dom_domerror_severity_read, NULL TSRMLS_CC); 831 dom_register_prop_handler(&dom_domerror_prop_handlers, "message", dom_domerror_message_read, NULL TSRMLS_CC); 832 dom_register_prop_handler(&dom_domerror_prop_handlers, "type", dom_domerror_type_read, NULL TSRMLS_CC); 833 dom_register_prop_handler(&dom_domerror_prop_handlers, "relatedException", dom_domerror_related_exception_read, NULL TSRMLS_CC); 834 dom_register_prop_handler(&dom_domerror_prop_handlers, "related_data", dom_domerror_related_data_read, NULL TSRMLS_CC); 835 dom_register_prop_handler(&dom_domerror_prop_handlers, "location", dom_domerror_location_read, NULL TSRMLS_CC); 836 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_domerror_prop_handlers, sizeof(dom_domerror_prop_handlers), NULL); 837 838 REGISTER_DOM_CLASS(ce, "DOMErrorHandler", NULL, php_dom_domerrorhandler_class_functions, dom_domerrorhandler_class_entry); 839 REGISTER_DOM_CLASS(ce, "DOMLocator", NULL, php_dom_domlocator_class_functions, dom_domlocator_class_entry); 840 841 zend_hash_init(&dom_domlocator_prop_handlers, 0, NULL, NULL, 1); 842 dom_register_prop_handler(&dom_domlocator_prop_handlers, "lineNumber", dom_domlocator_line_number_read, NULL TSRMLS_CC); 843 dom_register_prop_handler(&dom_domlocator_prop_handlers, "columnNumber", dom_domlocator_column_number_read, NULL TSRMLS_CC); 844 dom_register_prop_handler(&dom_domlocator_prop_handlers, "offset", dom_domlocator_offset_read, NULL TSRMLS_CC); 845 dom_register_prop_handler(&dom_domlocator_prop_handlers, "relatedNode", dom_domlocator_related_node_read, NULL TSRMLS_CC); 846 dom_register_prop_handler(&dom_domlocator_prop_handlers, "uri", dom_domlocator_uri_read, NULL TSRMLS_CC); 847 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_domlocator_prop_handlers, sizeof(dom_domlocator_prop_handlers), NULL); 848 849 REGISTER_DOM_CLASS(ce, "DOMConfiguration", NULL, php_dom_domconfiguration_class_functions, dom_domconfiguration_class_entry); 850 REGISTER_DOM_CLASS(ce, "DOMCdataSection", dom_text_class_entry, php_dom_cdatasection_class_functions, dom_cdatasection_class_entry); 851 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_text_prop_handlers, sizeof(dom_documenttype_prop_handlers), NULL); 852 853 REGISTER_DOM_CLASS(ce, "DOMDocumentType", dom_node_class_entry, php_dom_documenttype_class_functions, dom_documenttype_class_entry); 854 855 zend_hash_init(&dom_documenttype_prop_handlers, 0, NULL, NULL, 1); 856 dom_register_prop_handler(&dom_documenttype_prop_handlers, "name", dom_documenttype_name_read, NULL TSRMLS_CC); 857 dom_register_prop_handler(&dom_documenttype_prop_handlers, "entities", dom_documenttype_entities_read, NULL TSRMLS_CC); 858 dom_register_prop_handler(&dom_documenttype_prop_handlers, "notations", dom_documenttype_notations_read, NULL TSRMLS_CC); 859 dom_register_prop_handler(&dom_documenttype_prop_handlers, "publicId", dom_documenttype_public_id_read, NULL TSRMLS_CC); 860 dom_register_prop_handler(&dom_documenttype_prop_handlers, "systemId", dom_documenttype_system_id_read, NULL TSRMLS_CC); 861 dom_register_prop_handler(&dom_documenttype_prop_handlers, "internalSubset", dom_documenttype_internal_subset_read, NULL TSRMLS_CC); 862 zend_hash_merge(&dom_documenttype_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); 863 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_documenttype_prop_handlers, sizeof(dom_documenttype_prop_handlers), NULL); 864 865 REGISTER_DOM_CLASS(ce, "DOMNotation", dom_node_class_entry, php_dom_notation_class_functions, dom_notation_class_entry); 866 867 zend_hash_init(&dom_notation_prop_handlers, 0, NULL, NULL, 1); 868 dom_register_prop_handler(&dom_notation_prop_handlers, "publicId", dom_notation_public_id_read, NULL TSRMLS_CC); 869 dom_register_prop_handler(&dom_notation_prop_handlers, "systemId", dom_notation_system_id_read, NULL TSRMLS_CC); 870 zend_hash_merge(&dom_notation_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); 871 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_notation_prop_handlers, sizeof(dom_notation_prop_handlers), NULL); 872 873 REGISTER_DOM_CLASS(ce, "DOMEntity", dom_node_class_entry, php_dom_entity_class_functions, dom_entity_class_entry); 874 875 zend_hash_init(&dom_entity_prop_handlers, 0, NULL, NULL, 1); 876 dom_register_prop_handler(&dom_entity_prop_handlers, "publicId", dom_entity_public_id_read, NULL TSRMLS_CC); 877 dom_register_prop_handler(&dom_entity_prop_handlers, "systemId", dom_entity_system_id_read, NULL TSRMLS_CC); 878 dom_register_prop_handler(&dom_entity_prop_handlers, "notationName", dom_entity_notation_name_read, NULL TSRMLS_CC); 879 dom_register_prop_handler(&dom_entity_prop_handlers, "actualEncoding", dom_entity_actual_encoding_read, dom_entity_actual_encoding_write TSRMLS_CC); 880 dom_register_prop_handler(&dom_entity_prop_handlers, "encoding", dom_entity_encoding_read, dom_entity_encoding_write TSRMLS_CC); 881 dom_register_prop_handler(&dom_entity_prop_handlers, "version", dom_entity_version_read, dom_entity_version_write TSRMLS_CC); 882 zend_hash_merge(&dom_entity_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); 883 884 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_entity_prop_handlers, sizeof(dom_entity_prop_handlers), NULL); 885 886 REGISTER_DOM_CLASS(ce, "DOMEntityReference", dom_node_class_entry, php_dom_entityreference_class_functions, dom_entityreference_class_entry); 887 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_node_prop_handlers, sizeof(dom_entity_prop_handlers), NULL); 888 889 REGISTER_DOM_CLASS(ce, "DOMProcessingInstruction", dom_node_class_entry, php_dom_processinginstruction_class_functions, dom_processinginstruction_class_entry); 890 891 zend_hash_init(&dom_processinginstruction_prop_handlers, 0, NULL, NULL, 1); 892 dom_register_prop_handler(&dom_processinginstruction_prop_handlers, "target", dom_processinginstruction_target_read, NULL TSRMLS_CC); 893 dom_register_prop_handler(&dom_processinginstruction_prop_handlers, "data", dom_processinginstruction_data_read, dom_processinginstruction_data_write TSRMLS_CC); 894 zend_hash_merge(&dom_processinginstruction_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); 895 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_processinginstruction_prop_handlers, sizeof(dom_processinginstruction_prop_handlers), NULL); 896 897 REGISTER_DOM_CLASS(ce, "DOMStringExtend", NULL, php_dom_string_extend_class_functions, dom_string_extend_class_entry); 898 899#if defined(LIBXML_XPATH_ENABLED) 900 INIT_CLASS_ENTRY(ce, "DOMXPath", php_dom_xpath_class_functions); 901 ce.create_object = dom_xpath_objects_new; 902 dom_xpath_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); 903 904 zend_hash_init(&dom_xpath_prop_handlers, 0, NULL, NULL, 1); 905 dom_register_prop_handler(&dom_xpath_prop_handlers, "document", dom_xpath_document_read, NULL TSRMLS_CC); 906 zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_xpath_prop_handlers, sizeof(dom_xpath_prop_handlers), NULL); 907#endif 908 909 REGISTER_LONG_CONSTANT("XML_ELEMENT_NODE", XML_ELEMENT_NODE, CONST_CS | CONST_PERSISTENT); 910 REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_NODE", XML_ATTRIBUTE_NODE, CONST_CS | CONST_PERSISTENT); 911 REGISTER_LONG_CONSTANT("XML_TEXT_NODE", XML_TEXT_NODE, CONST_CS | CONST_PERSISTENT); 912 REGISTER_LONG_CONSTANT("XML_CDATA_SECTION_NODE", XML_CDATA_SECTION_NODE, CONST_CS | CONST_PERSISTENT); 913 REGISTER_LONG_CONSTANT("XML_ENTITY_REF_NODE", XML_ENTITY_REF_NODE, CONST_CS | CONST_PERSISTENT); 914 REGISTER_LONG_CONSTANT("XML_ENTITY_NODE", XML_ENTITY_NODE, CONST_CS | CONST_PERSISTENT); 915 REGISTER_LONG_CONSTANT("XML_PI_NODE", XML_PI_NODE, CONST_CS | CONST_PERSISTENT); 916 REGISTER_LONG_CONSTANT("XML_COMMENT_NODE", XML_COMMENT_NODE, CONST_CS | CONST_PERSISTENT); 917 REGISTER_LONG_CONSTANT("XML_DOCUMENT_NODE", XML_DOCUMENT_NODE, CONST_CS | CONST_PERSISTENT); 918 REGISTER_LONG_CONSTANT("XML_DOCUMENT_TYPE_NODE", XML_DOCUMENT_TYPE_NODE, CONST_CS | CONST_PERSISTENT); 919 REGISTER_LONG_CONSTANT("XML_DOCUMENT_FRAG_NODE", XML_DOCUMENT_FRAG_NODE, CONST_CS | CONST_PERSISTENT); 920 REGISTER_LONG_CONSTANT("XML_NOTATION_NODE", XML_NOTATION_NODE, CONST_CS | CONST_PERSISTENT); 921 REGISTER_LONG_CONSTANT("XML_HTML_DOCUMENT_NODE", XML_HTML_DOCUMENT_NODE, CONST_CS | CONST_PERSISTENT); 922 REGISTER_LONG_CONSTANT("XML_DTD_NODE", XML_DTD_NODE, CONST_CS | CONST_PERSISTENT); 923 REGISTER_LONG_CONSTANT("XML_ELEMENT_DECL_NODE", XML_ELEMENT_DECL, CONST_CS | CONST_PERSISTENT); 924 REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_DECL_NODE", XML_ATTRIBUTE_DECL, CONST_CS | CONST_PERSISTENT); 925 REGISTER_LONG_CONSTANT("XML_ENTITY_DECL_NODE", XML_ENTITY_DECL, CONST_CS | CONST_PERSISTENT); 926 REGISTER_LONG_CONSTANT("XML_NAMESPACE_DECL_NODE", XML_NAMESPACE_DECL, CONST_CS | CONST_PERSISTENT); 927#ifdef XML_GLOBAL_NAMESPACE 928 REGISTER_LONG_CONSTANT("XML_GLOBAL_NAMESPACE", XML_GLOBAL_NAMESPACE, CONST_CS | CONST_PERSISTENT); 929#endif 930 REGISTER_LONG_CONSTANT("XML_LOCAL_NAMESPACE", XML_LOCAL_NAMESPACE, CONST_CS | CONST_PERSISTENT); 931 REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_CDATA", XML_ATTRIBUTE_CDATA, CONST_CS | CONST_PERSISTENT); 932 REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_ID", XML_ATTRIBUTE_ID, CONST_CS | CONST_PERSISTENT); 933 REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_IDREF", XML_ATTRIBUTE_IDREF, CONST_CS | CONST_PERSISTENT); 934 REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_IDREFS", XML_ATTRIBUTE_IDREFS, CONST_CS | CONST_PERSISTENT); 935 REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_ENTITY", XML_ATTRIBUTE_ENTITIES, CONST_CS | CONST_PERSISTENT); 936 REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_NMTOKEN", XML_ATTRIBUTE_NMTOKEN, CONST_CS | CONST_PERSISTENT); 937 REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_NMTOKENS", XML_ATTRIBUTE_NMTOKENS, CONST_CS | CONST_PERSISTENT); 938 REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_ENUMERATION", XML_ATTRIBUTE_ENUMERATION, CONST_CS | CONST_PERSISTENT); 939 REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_NOTATION", XML_ATTRIBUTE_NOTATION, CONST_CS | CONST_PERSISTENT); 940 941 /* DOMException Codes */ 942 REGISTER_LONG_CONSTANT("DOM_PHP_ERR", PHP_ERR, CONST_CS | CONST_PERSISTENT); 943 REGISTER_LONG_CONSTANT("DOM_INDEX_SIZE_ERR", INDEX_SIZE_ERR, CONST_CS | CONST_PERSISTENT); 944 REGISTER_LONG_CONSTANT("DOMSTRING_SIZE_ERR", DOMSTRING_SIZE_ERR, CONST_CS | CONST_PERSISTENT); 945 REGISTER_LONG_CONSTANT("DOM_HIERARCHY_REQUEST_ERR", HIERARCHY_REQUEST_ERR, CONST_CS | CONST_PERSISTENT); 946 REGISTER_LONG_CONSTANT("DOM_WRONG_DOCUMENT_ERR", WRONG_DOCUMENT_ERR, CONST_CS | CONST_PERSISTENT); 947 REGISTER_LONG_CONSTANT("DOM_INVALID_CHARACTER_ERR", INVALID_CHARACTER_ERR, CONST_CS | CONST_PERSISTENT); 948 REGISTER_LONG_CONSTANT("DOM_NO_DATA_ALLOWED_ERR", NO_DATA_ALLOWED_ERR, CONST_CS | CONST_PERSISTENT); 949 REGISTER_LONG_CONSTANT("DOM_NO_MODIFICATION_ALLOWED_ERR", NO_MODIFICATION_ALLOWED_ERR, CONST_CS | CONST_PERSISTENT); 950 REGISTER_LONG_CONSTANT("DOM_NOT_FOUND_ERR", NOT_FOUND_ERR, CONST_CS | CONST_PERSISTENT); 951 REGISTER_LONG_CONSTANT("DOM_NOT_SUPPORTED_ERR", NOT_SUPPORTED_ERR, CONST_CS | CONST_PERSISTENT); 952 REGISTER_LONG_CONSTANT("DOM_INUSE_ATTRIBUTE_ERR", INUSE_ATTRIBUTE_ERR, CONST_CS | CONST_PERSISTENT); 953 REGISTER_LONG_CONSTANT("DOM_INVALID_STATE_ERR", INVALID_STATE_ERR, CONST_CS | CONST_PERSISTENT); 954 REGISTER_LONG_CONSTANT("DOM_SYNTAX_ERR", SYNTAX_ERR, CONST_CS | CONST_PERSISTENT); 955 REGISTER_LONG_CONSTANT("DOM_INVALID_MODIFICATION_ERR", INVALID_MODIFICATION_ERR, CONST_CS | CONST_PERSISTENT); 956 REGISTER_LONG_CONSTANT("DOM_NAMESPACE_ERR", NAMESPACE_ERR, CONST_CS | CONST_PERSISTENT); 957 REGISTER_LONG_CONSTANT("DOM_INVALID_ACCESS_ERR", INVALID_ACCESS_ERR, CONST_CS | CONST_PERSISTENT); 958 REGISTER_LONG_CONSTANT("DOM_VALIDATION_ERR", VALIDATION_ERR, CONST_CS | CONST_PERSISTENT); 959 960 php_libxml_register_export(dom_node_class_entry, php_dom_export_node); 961 962 return SUCCESS; 963} 964/* }}} */ 965 966/* {{{ */ 967PHP_MINFO_FUNCTION(dom) 968{ 969 php_info_print_table_start(); 970 php_info_print_table_row(2, "DOM/XML", "enabled"); 971 php_info_print_table_row(2, "DOM/XML API Version", DOM_API_VERSION); 972 php_info_print_table_row(2, "libxml Version", LIBXML_DOTTED_VERSION); 973#if defined(LIBXML_HTML_ENABLED) 974 php_info_print_table_row(2, "HTML Support", "enabled"); 975#endif 976#if defined(LIBXML_XPATH_ENABLED) 977 php_info_print_table_row(2, "XPath Support", "enabled"); 978#endif 979#if defined(LIBXML_XPTR_ENABLED) 980 php_info_print_table_row(2, "XPointer Support", "enabled"); 981#endif 982#ifdef LIBXML_SCHEMAS_ENABLED 983 php_info_print_table_row(2, "Schema Support", "enabled"); 984 php_info_print_table_row(2, "RelaxNG Support", "enabled"); 985#endif 986 php_info_print_table_end(); 987} 988/* }}} */ 989 990PHP_MSHUTDOWN_FUNCTION(dom) /* {{{ */ 991{ 992 zend_hash_destroy(&dom_domstringlist_prop_handlers); 993 zend_hash_destroy(&dom_namelist_prop_handlers); 994 zend_hash_destroy(&dom_domimplementationlist_prop_handlers); 995 zend_hash_destroy(&dom_document_prop_handlers); 996 zend_hash_destroy(&dom_node_prop_handlers); 997 zend_hash_destroy(&dom_namespace_node_prop_handlers); 998 zend_hash_destroy(&dom_nodelist_prop_handlers); 999 zend_hash_destroy(&dom_namednodemap_prop_handlers); 1000 zend_hash_destroy(&dom_characterdata_prop_handlers); 1001 zend_hash_destroy(&dom_attr_prop_handlers); 1002 zend_hash_destroy(&dom_element_prop_handlers); 1003 zend_hash_destroy(&dom_text_prop_handlers); 1004 zend_hash_destroy(&dom_typeinfo_prop_handlers); 1005 zend_hash_destroy(&dom_domerror_prop_handlers); 1006 zend_hash_destroy(&dom_domlocator_prop_handlers); 1007 zend_hash_destroy(&dom_documenttype_prop_handlers); 1008 zend_hash_destroy(&dom_notation_prop_handlers); 1009 zend_hash_destroy(&dom_entity_prop_handlers); 1010 zend_hash_destroy(&dom_processinginstruction_prop_handlers); 1011#if defined(LIBXML_XPATH_ENABLED) 1012 zend_hash_destroy(&dom_xpath_prop_handlers); 1013#endif 1014 zend_hash_destroy(&classes); 1015 1016/* If you want do find memleaks in this module, compile libxml2 with --with-mem-debug and 1017 uncomment the following line, this will tell you the amount of not freed memory 1018 and the total used memory into apaches error_log */ 1019/* xmlMemoryDump();*/ 1020 1021 return SUCCESS; 1022} 1023/* }}} */ 1024 1025/* {{{ node_list_unlink */ 1026void node_list_unlink(xmlNodePtr node TSRMLS_DC) 1027{ 1028 dom_object *wrapper; 1029 1030 while (node != NULL) { 1031 1032 wrapper = php_dom_object_get_data(node); 1033 1034 if (wrapper != NULL ) { 1035 xmlUnlinkNode(node); 1036 } else { 1037 if (node->type == XML_ENTITY_REF_NODE) 1038 break; 1039 node_list_unlink(node->children TSRMLS_CC); 1040 1041 switch (node->type) { 1042 case XML_ATTRIBUTE_DECL: 1043 case XML_DTD_NODE: 1044 case XML_DOCUMENT_TYPE_NODE: 1045 case XML_ENTITY_DECL: 1046 case XML_ATTRIBUTE_NODE: 1047 case XML_TEXT_NODE: 1048 break; 1049 default: 1050 node_list_unlink((xmlNodePtr) node->properties TSRMLS_CC); 1051 } 1052 1053 } 1054 1055 node = node->next; 1056 } 1057} 1058/* }}} end node_list_unlink */ 1059 1060#if defined(LIBXML_XPATH_ENABLED) 1061/* {{{ dom_xpath_objects_free_storage */ 1062void dom_xpath_objects_free_storage(void *object TSRMLS_DC) 1063{ 1064 dom_xpath_object *intern = (dom_xpath_object *)object; 1065 1066 zend_object_std_dtor(&intern->std TSRMLS_CC); 1067 1068 if (intern->ptr != NULL) { 1069 xmlXPathFreeContext((xmlXPathContextPtr) intern->ptr); 1070 php_libxml_decrement_doc_ref((php_libxml_node_object *) intern TSRMLS_CC); 1071 intern->ptr = NULL; 1072 } 1073 1074 if (intern->registered_phpfunctions) { 1075 zend_hash_destroy(intern->registered_phpfunctions); 1076 FREE_HASHTABLE(intern->registered_phpfunctions); 1077 } 1078 1079 if (intern->node_list) { 1080 zend_hash_destroy(intern->node_list); 1081 FREE_HASHTABLE(intern->node_list); 1082 } 1083 1084 efree(object); 1085} 1086/* }}} */ 1087#endif 1088 1089/* {{{ dom_objects_free_storage */ 1090void dom_objects_free_storage(void *object TSRMLS_DC) 1091{ 1092 dom_object *intern = (dom_object *)object; 1093 int retcount; 1094 1095 zend_object_std_dtor(&intern->std TSRMLS_CC); 1096 1097 if (intern->ptr != NULL && ((php_libxml_node_ptr *)intern->ptr)->node != NULL) { 1098 if (((xmlNodePtr) ((php_libxml_node_ptr *)intern->ptr)->node)->type != XML_DOCUMENT_NODE && ((xmlNodePtr) ((php_libxml_node_ptr *)intern->ptr)->node)->type != XML_HTML_DOCUMENT_NODE) { 1099 php_libxml_node_decrement_resource((php_libxml_node_object *) intern TSRMLS_CC); 1100 } else { 1101 php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC); 1102 retcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC); 1103 } 1104 intern->ptr = NULL; 1105 } 1106 1107 efree(object); 1108} 1109/* }}} */ 1110 1111void dom_namednode_iter(dom_object *basenode, int ntype, dom_object *intern, xmlHashTablePtr ht, xmlChar *local, xmlChar *ns TSRMLS_DC) /* {{{ */ 1112{ 1113 dom_nnodemap_object *mapptr; 1114 zval *baseobj = NULL; 1115 1116 mapptr = (dom_nnodemap_object *)intern->ptr; 1117 if (basenode) { 1118 MAKE_STD_ZVAL(baseobj); 1119 baseobj->type = IS_OBJECT; 1120 Z_SET_ISREF_P(baseobj); 1121 baseobj->value.obj.handle = basenode->handle; 1122 baseobj->value.obj.handlers = dom_get_obj_handlers(TSRMLS_C); 1123 zval_copy_ctor(baseobj); 1124 } 1125 mapptr->baseobjptr = baseobj; 1126 mapptr->baseobj = basenode; 1127 mapptr->nodetype = ntype; 1128 mapptr->ht = ht; 1129 mapptr->local = local; 1130 mapptr->ns = ns; 1131 1132} 1133/* }}} */ 1134 1135static dom_object* dom_objects_set_class(zend_class_entry *class_type, zend_bool hash_copy TSRMLS_DC) /* {{{ */ 1136{ 1137 zend_class_entry *base_class; 1138 zval *tmp; 1139 dom_object *intern; 1140 1141 if (instanceof_function(class_type, dom_xpath_class_entry TSRMLS_CC)) { 1142 intern = emalloc(sizeof(dom_xpath_object)); 1143 memset(intern, 0, sizeof(dom_xpath_object)); 1144 } else { 1145 intern = emalloc(sizeof(dom_object)); 1146 } 1147 intern->ptr = NULL; 1148 intern->prop_handler = NULL; 1149 intern->document = NULL; 1150 1151 base_class = class_type; 1152 while(base_class->type != ZEND_INTERNAL_CLASS && base_class->parent != NULL) { 1153 base_class = base_class->parent; 1154 } 1155 1156 zend_hash_find(&classes, base_class->name, base_class->name_length + 1, (void **) &intern->prop_handler); 1157 1158 zend_object_std_init(&intern->std, class_type TSRMLS_CC); 1159 if (hash_copy) { 1160 zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); 1161 } 1162 1163 return intern; 1164} 1165/* }}} */ 1166 1167/* {{{ dom_objects_clone */ 1168void dom_objects_clone(void *object, void **object_clone TSRMLS_DC) 1169{ 1170 dom_object *intern = (dom_object *) object; 1171 dom_object *clone; 1172 xmlNodePtr node; 1173 xmlNodePtr cloned_node; 1174 1175 clone = dom_objects_set_class(intern->std.ce, 0 TSRMLS_CC); 1176 1177 if (instanceof_function(intern->std.ce, dom_node_class_entry TSRMLS_CC)) { 1178 node = (xmlNodePtr)dom_object_get_node((dom_object *) object); 1179 if (node != NULL) { 1180 cloned_node = xmlDocCopyNode(node, node->doc, 1); 1181 if (cloned_node != NULL) { 1182 /* If we cloned a document then we must create new doc proxy */ 1183 if (cloned_node->doc == node->doc) { 1184 clone->document = intern->document; 1185 } 1186 php_libxml_increment_doc_ref((php_libxml_node_object *)clone, cloned_node->doc TSRMLS_CC); 1187 php_libxml_increment_node_ptr((php_libxml_node_object *)clone, cloned_node, (void *)clone TSRMLS_CC); 1188 if (intern->document != clone->document) { 1189 dom_copy_doc_props(intern->document, clone->document); 1190 } 1191 } 1192 1193 } 1194 } 1195 1196 *object_clone = (void *) clone; 1197} 1198/* }}} */ 1199 1200/* {{{ dom_objects_new */ 1201zend_object_value dom_objects_new(zend_class_entry *class_type TSRMLS_DC) 1202{ 1203 zend_object_value retval; 1204 dom_object *intern; 1205 1206 intern = dom_objects_set_class(class_type, 1 TSRMLS_CC); 1207 1208 retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t)dom_objects_free_storage, dom_objects_clone TSRMLS_CC); 1209 intern->handle = retval.handle; 1210 retval.handlers = dom_get_obj_handlers(TSRMLS_C); 1211 1212 return retval; 1213} 1214/* }}} */ 1215 1216#if defined(LIBXML_XPATH_ENABLED) 1217/* {{{ zend_object_value dom_xpath_objects_new(zend_class_entry *class_type TSRMLS_DC) */ 1218zend_object_value dom_xpath_objects_new(zend_class_entry *class_type TSRMLS_DC) 1219{ 1220 zend_object_value retval; 1221 dom_xpath_object *intern; 1222 1223 intern = (dom_xpath_object *)dom_objects_set_class(class_type, 1 TSRMLS_CC); 1224 intern->registerPhpFunctions = 0; 1225 intern->registered_phpfunctions = NULL; 1226 intern->node_list = NULL; 1227 1228 ALLOC_HASHTABLE(intern->registered_phpfunctions); 1229 zend_hash_init(intern->registered_phpfunctions, 0, NULL, ZVAL_PTR_DTOR, 0); 1230 1231 retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t)dom_xpath_objects_free_storage, dom_objects_clone TSRMLS_CC); 1232 intern->handle = retval.handle; 1233 retval.handlers = dom_get_obj_handlers(TSRMLS_C); 1234 1235 return retval; 1236} 1237/* }}} */ 1238#endif 1239 1240static void dom_nnodemap_object_dtor(void *object, zend_object_handle handle TSRMLS_DC) /* {{{ */ 1241{ 1242 zval *baseobj; 1243 dom_object *intern; 1244 dom_nnodemap_object *objmap; 1245 1246 intern = (dom_object *)object; 1247 objmap = (dom_nnodemap_object *)intern->ptr; 1248 1249 if (objmap) { 1250 if (objmap->local) { 1251 xmlFree(objmap->local); 1252 } 1253 if (objmap->ns) { 1254 xmlFree(objmap->ns); 1255 } 1256 if (objmap->baseobjptr) { 1257 baseobj = objmap->baseobjptr; 1258 zval_ptr_dtor((zval **)&baseobj); 1259 } 1260 efree(objmap); 1261 intern->ptr = NULL; 1262 } 1263 1264 1265} 1266/* }}} */ 1267 1268void dom_nnodemap_objects_free_storage(void *object TSRMLS_DC) /* {{{ */ 1269{ 1270 dom_object *intern = (dom_object *)object; 1271 1272 php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC); 1273 1274 zend_object_std_dtor(&intern->std TSRMLS_CC); 1275 1276 efree(object); 1277} 1278/* }}} */ 1279 1280zend_object_value dom_nnodemap_objects_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ 1281{ 1282 zend_object_value retval; 1283 dom_object *intern; 1284 dom_nnodemap_object *objmap; 1285 1286 intern = dom_objects_set_class(class_type, 1 TSRMLS_CC); 1287 intern->ptr = emalloc(sizeof(dom_nnodemap_object)); 1288 objmap = (dom_nnodemap_object *)intern->ptr; 1289 objmap->baseobj = NULL; 1290 objmap->baseobjptr = NULL; 1291 objmap->nodetype = 0; 1292 objmap->ht = NULL; 1293 objmap->local = NULL; 1294 objmap->ns = NULL; 1295 1296 retval.handle = zend_objects_store_put(intern, dom_nnodemap_object_dtor, (zend_objects_free_object_storage_t)dom_nnodemap_objects_free_storage, dom_objects_clone TSRMLS_CC); 1297 intern->handle = retval.handle; 1298 retval.handlers = dom_get_obj_handlers(TSRMLS_C); 1299 1300 return retval; 1301} 1302/* }}} */ 1303 1304void php_dom_create_interator(zval *return_value, int ce_type TSRMLS_DC) /* {{{ */ 1305{ 1306 zend_class_entry *ce; 1307 1308 if (ce_type == DOM_NAMEDNODEMAP) { 1309 ce = dom_namednodemap_class_entry; 1310 } else { 1311 ce = dom_nodelist_class_entry; 1312 } 1313 1314 object_init_ex(return_value, ce); 1315} 1316/* }}} */ 1317 1318/* {{{ php_dom_create_object */ 1319PHP_DOM_EXPORT zval *php_dom_create_object(xmlNodePtr obj, int *found, zval *wrapper_in, zval *return_value, dom_object *domobj TSRMLS_DC) 1320{ 1321 zval *wrapper; 1322 zend_class_entry *ce; 1323 dom_object *intern; 1324 1325 *found = 0; 1326 1327 if (!obj) { 1328 ALLOC_ZVAL(wrapper); 1329 ZVAL_NULL(wrapper); 1330 return wrapper; 1331 } 1332 1333 if ((intern = (dom_object *) php_dom_object_get_data((void *) obj))) { 1334 return_value->type = IS_OBJECT; 1335 Z_SET_ISREF_P(return_value); 1336 return_value->value.obj.handle = intern->handle; 1337 return_value->value.obj.handlers = dom_get_obj_handlers(TSRMLS_C); 1338 zval_copy_ctor(return_value); 1339 *found = 1; 1340 return return_value; 1341 } 1342 1343 wrapper = return_value; 1344 1345 switch (obj->type) { 1346 case XML_DOCUMENT_NODE: 1347 case XML_HTML_DOCUMENT_NODE: 1348 { 1349 ce = dom_document_class_entry; 1350 break; 1351 } 1352 case XML_DTD_NODE: 1353 case XML_DOCUMENT_TYPE_NODE: 1354 { 1355 ce = dom_documenttype_class_entry; 1356 break; 1357 } 1358 case XML_ELEMENT_NODE: 1359 { 1360 ce = dom_element_class_entry; 1361 break; 1362 } 1363 case XML_ATTRIBUTE_NODE: 1364 { 1365 ce = dom_attr_class_entry; 1366 break; 1367 } 1368 case XML_TEXT_NODE: 1369 { 1370 ce = dom_text_class_entry; 1371 break; 1372 } 1373 case XML_COMMENT_NODE: 1374 { 1375 ce = dom_comment_class_entry; 1376 break; 1377 } 1378 case XML_PI_NODE: 1379 { 1380 ce = dom_processinginstruction_class_entry; 1381 break; 1382 } 1383 case XML_ENTITY_REF_NODE: 1384 { 1385 ce = dom_entityreference_class_entry; 1386 break; 1387 } 1388 case XML_ENTITY_DECL: 1389 case XML_ELEMENT_DECL: 1390 { 1391 ce = dom_entity_class_entry; 1392 break; 1393 } 1394 case XML_CDATA_SECTION_NODE: 1395 { 1396 ce = dom_cdatasection_class_entry; 1397 break; 1398 } 1399 case XML_DOCUMENT_FRAG_NODE: 1400 { 1401 ce = dom_documentfragment_class_entry; 1402 break; 1403 } 1404 case XML_NOTATION_NODE: 1405 { 1406 ce = dom_notation_class_entry; 1407 break; 1408 } 1409 case XML_NAMESPACE_DECL: 1410 { 1411 ce = dom_namespace_node_class_entry; 1412 break; 1413 } 1414 default: 1415 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported node type: %d", Z_TYPE_P(obj)); 1416 ZVAL_NULL(wrapper); 1417 return wrapper; 1418 } 1419 1420 if (domobj && domobj->document) { 1421 ce = dom_get_doc_classmap(domobj->document, ce TSRMLS_CC); 1422 } 1423 object_init_ex(wrapper, ce); 1424 1425 intern = (dom_object *)zend_objects_get_address(wrapper TSRMLS_CC); 1426 if (obj->doc != NULL) { 1427 if (domobj != NULL) { 1428 intern->document = domobj->document; 1429 } 1430 php_libxml_increment_doc_ref((php_libxml_node_object *)intern, obj->doc TSRMLS_CC); 1431 } 1432 1433 php_libxml_increment_node_ptr((php_libxml_node_object *)intern, obj, (void *)intern TSRMLS_CC); 1434 return (wrapper); 1435} 1436/* }}} end php_domobject_new */ 1437 1438void php_dom_create_implementation(zval **retval TSRMLS_DC) { 1439 object_init_ex(*retval, dom_domimplementation_class_entry); 1440} 1441 1442/* {{{ int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child) */ 1443int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child) 1444{ 1445 xmlNodePtr nodep; 1446 1447 if (parent == NULL || child == NULL || child->doc != parent->doc) { 1448 return SUCCESS; 1449 } 1450 1451 nodep = parent; 1452 1453 while (nodep) { 1454 if (nodep == child) { 1455 return FAILURE; 1456 } 1457 nodep = nodep->parent; 1458 } 1459 1460 return SUCCESS; 1461} 1462/* }}} end dom_hierarchy */ 1463 1464/* {{{ dom_has_feature(char *feature, char *version) */ 1465int dom_has_feature(char *feature, char *version) 1466{ 1467 int retval = 0; 1468 1469 if (!(strcmp (version, "1.0") && strcmp (version,"2.0") && strcmp(version, ""))) { 1470 if ((!strcasecmp(feature, "Core") && !strcmp (version, "1.0")) || !strcasecmp(feature, "XML")) 1471 retval = 1; 1472 } 1473 1474 return retval; 1475} 1476/* }}} end dom_has_feature */ 1477 1478xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr nodep, char *ns, char *local, int *cur, int index) /* {{{ */ 1479{ 1480 xmlNodePtr ret = NULL; 1481 1482 while (nodep != NULL && (*cur <= index || index == -1)) { 1483 if (nodep->type == XML_ELEMENT_NODE) { 1484 if (xmlStrEqual(nodep->name, (xmlChar *)local) || xmlStrEqual((xmlChar *)"*", (xmlChar *)local)) { 1485 if (ns == NULL || (nodep->ns != NULL && (xmlStrEqual(nodep->ns->href, (xmlChar *)ns) || xmlStrEqual((xmlChar *)"*", (xmlChar *)ns)))) { 1486 if (*cur == index) { 1487 ret = nodep; 1488 break; 1489 } 1490 (*cur)++; 1491 } 1492 } 1493 ret = dom_get_elements_by_tag_name_ns_raw(nodep->children, ns, local, cur, index); 1494 if (ret != NULL) { 1495 break; 1496 } 1497 } 1498 nodep = nodep->next; 1499 } 1500 return ret; 1501} 1502/* }}} */ 1503/* }}} end dom_element_get_elements_by_tag_name_ns_raw */ 1504 1505/* {{{ void dom_normalize (xmlNodePtr nodep TSRMLS_DC) */ 1506void dom_normalize (xmlNodePtr nodep TSRMLS_DC) 1507{ 1508 xmlNodePtr child, nextp, newnextp; 1509 xmlAttrPtr attr; 1510 xmlChar *strContent; 1511 1512 child = nodep->children; 1513 while(child != NULL) { 1514 switch (child->type) { 1515 case XML_TEXT_NODE: 1516 nextp = child->next; 1517 while (nextp != NULL) { 1518 if (nextp->type == XML_TEXT_NODE) { 1519 newnextp = nextp->next; 1520 strContent = xmlNodeGetContent(nextp); 1521 xmlNodeAddContent(child, strContent); 1522 xmlFree(strContent); 1523 xmlUnlinkNode(nextp); 1524 php_libxml_node_free_resource(nextp TSRMLS_CC); 1525 nextp = newnextp; 1526 } else { 1527 break; 1528 } 1529 } 1530 break; 1531 case XML_ELEMENT_NODE: 1532 dom_normalize (child TSRMLS_CC); 1533 attr = child->properties; 1534 while (attr != NULL) { 1535 dom_normalize((xmlNodePtr) attr TSRMLS_CC); 1536 attr = attr->next; 1537 } 1538 break; 1539 case XML_ATTRIBUTE_NODE: 1540 dom_normalize (child TSRMLS_CC); 1541 break; 1542 default: 1543 break; 1544 } 1545 child = child->next; 1546 } 1547} 1548/* }}} end dom_normalize */ 1549 1550 1551/* {{{ void dom_set_old_ns(xmlDoc *doc, xmlNs *ns) */ 1552void dom_set_old_ns(xmlDoc *doc, xmlNs *ns) { 1553 xmlNs *cur; 1554 1555 if (doc == NULL) 1556 return; 1557 1558 if (doc->oldNs == NULL) { 1559 doc->oldNs = (xmlNsPtr) xmlMalloc(sizeof(xmlNs)); 1560 if (doc->oldNs == NULL) { 1561 return; 1562 } 1563 memset(doc->oldNs, 0, sizeof(xmlNs)); 1564 doc->oldNs->type = XML_LOCAL_NAMESPACE; 1565 doc->oldNs->href = xmlStrdup(XML_XML_NAMESPACE); 1566 doc->oldNs->prefix = xmlStrdup((const xmlChar *)"xml"); 1567 } 1568 1569 cur = doc->oldNs; 1570 while (cur->next != NULL) { 1571 cur = cur->next; 1572 } 1573 cur->next = ns; 1574} 1575/* }}} end dom_set_old_ns */ 1576 1577/* 1578http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-DocCrElNS 1579 1580NAMESPACE_ERR: Raised if 1581 15821. the qualifiedName is a malformed qualified name 15832. the qualifiedName has a prefix and the namespaceURI is null 1584*/ 1585 1586/* {{{ int dom_check_qname(char *qname, char **localname, char **prefix, int uri_len, int name_len) */ 1587int dom_check_qname(char *qname, char **localname, char **prefix, int uri_len, int name_len) { 1588 if (name_len == 0) { 1589 return NAMESPACE_ERR; 1590 } 1591 1592 *localname = (char *)xmlSplitQName2((xmlChar *)qname, (xmlChar **) prefix); 1593 if (*localname == NULL) { 1594 *localname = (char *)xmlStrdup((xmlChar *)qname); 1595 if (*prefix == NULL && uri_len == 0) { 1596 return 0; 1597 } 1598 } 1599 1600 /* 1 */ 1601 if (xmlValidateQName((xmlChar *) qname, 0) != 0) { 1602 return NAMESPACE_ERR; 1603 } 1604 1605 /* 2 */ 1606 if (*prefix != NULL && uri_len == 0) { 1607 return NAMESPACE_ERR; 1608 } 1609 1610 return 0; 1611} 1612/* }}} */ 1613 1614/* 1615http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-DocCrElNS 1616 1617NAMESPACE_ERR: Raised if 1618 16193. the qualifiedName has a prefix that is "xml" and the namespaceURI is different from "http://www.w3.org/XML/1998/namespace" [XML Namespaces] 16204. the qualifiedName or its prefix is "xmlns" and the namespaceURI is different from "http://www.w3.org/2000/xmlns/" 16215. the namespaceURI is "http://www.w3.org/2000/xmlns/" and neither the qualifiedName nor its prefix is "xmlns". 1622*/ 1623 1624/* {{{ xmlNsPtr dom_get_ns(xmlNodePtr nodep, char *uri, int *errorcode, char *prefix) */ 1625xmlNsPtr dom_get_ns(xmlNodePtr nodep, char *uri, int *errorcode, char *prefix) { 1626 xmlNsPtr nsptr = NULL; 1627 1628 *errorcode = 0; 1629 1630 if (! ((prefix && !strcmp (prefix, "xml") && strcmp(uri, (char *)XML_XML_NAMESPACE)) || 1631 (prefix && !strcmp (prefix, "xmlns") && strcmp(uri, (char *)DOM_XMLNS_NAMESPACE)) || 1632 (prefix && !strcmp(uri, (char *)DOM_XMLNS_NAMESPACE) && strcmp (prefix, "xmlns")))) { 1633 nsptr = xmlNewNs(nodep, (xmlChar *)uri, (xmlChar *)prefix); 1634 } 1635 1636 if (nsptr == NULL) { 1637 *errorcode = NAMESPACE_ERR; 1638 } 1639 1640 return nsptr; 1641 1642} 1643/* }}} end dom_get_ns */ 1644 1645/* {{{ xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName) */ 1646xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName) { 1647 xmlNsPtr cur; 1648 xmlNs *ret = NULL; 1649 if (node == NULL) 1650 return NULL; 1651 1652 if (localName == NULL || xmlStrEqual(localName, (xmlChar *)"")) { 1653 cur = node->nsDef; 1654 while (cur != NULL) { 1655 if (cur->prefix == NULL && cur->href != NULL) { 1656 ret = cur; 1657 break; 1658 } 1659 cur = cur->next; 1660 } 1661 } else { 1662 cur = node->nsDef; 1663 while (cur != NULL) { 1664 if (cur->prefix != NULL && xmlStrEqual(localName, cur->prefix)) { 1665 ret = cur; 1666 break; 1667 } 1668 cur = cur->next; 1669 } 1670 } 1671 return ret; 1672} 1673/* }}} end dom_get_nsdecl */ 1674 1675#endif /* HAVE_DOM */ 1676 1677/* 1678 * Local variables: 1679 * tab-width: 4 1680 * c-basic-offset: 4 1681 * End: 1682 * vim600: noet sw=4 ts=4 fdm=marker 1683 * vim<600: noet sw=4 ts=4 1684 */ 1685