diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2013-03-14 05:42:27 +0000 |
---|---|---|
committer | <> | 2013-04-03 16:25:08 +0000 |
commit | c4dd7a1a684490673e25aaf4fabec5df138854c4 (patch) | |
tree | 4d57c44caae4480efff02b90b9be86f44bf25409 /ext/dom | |
download | php2-c4dd7a1a684490673e25aaf4fabec5df138854c4.tar.gz |
Imported from /home/lorry/working-area/delta_php2/php-5.4.13.tar.bz2.HEADphp-5.4.13master
Diffstat (limited to 'ext/dom')
241 files changed, 20229 insertions, 0 deletions
diff --git a/ext/dom/CREDITS b/ext/dom/CREDITS new file mode 100644 index 0000000..b78e376 --- /dev/null +++ b/ext/dom/CREDITS @@ -0,0 +1,2 @@ +DOM +Christian Stocker, Rob Richards, Marcus Boerger diff --git a/ext/dom/TODO b/ext/dom/TODO new file mode 100644 index 0000000..52afb18 --- /dev/null +++ b/ext/dom/TODO @@ -0,0 +1,4 @@ +For 5.1 +1) enhance XPath functionality +2) look at auto encoding support for in/output +3) What DOM object types are really needed (i.e. not currently using DOMString) diff --git a/ext/dom/attr.c b/ext/dom/attr.c new file mode 100644 index 0000000..d45ca88 --- /dev/null +++ b/ext/dom/attr.c @@ -0,0 +1,289 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#if HAVE_LIBXML && HAVE_DOM + +#include "php_dom.h" + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_attr_is_id, 0, 0, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_attr_construct, 0, 0, 1) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class DOMAttr extends DOMNode +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-637646024 +* Since: +*/ + +const zend_function_entry php_dom_attr_class_functions[] = { + PHP_FALIAS(isId, dom_attr_is_id, arginfo_dom_attr_is_id) + PHP_ME(domattr, __construct, arginfo_dom_attr_construct, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +/* {{{ proto void DOMAttr::__construct(string name, [string value]); */ +PHP_METHOD(domattr, __construct) +{ + + zval *id; + xmlAttrPtr nodep = NULL; + xmlNodePtr oldnode = NULL; + dom_object *intern; + char *name, *value = NULL; + int name_len, value_len, name_valid; + zend_error_handling error_handling; + + zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC); + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_attr_class_entry, &name, &name_len, &value, &value_len) == FAILURE) { + zend_restore_error_handling(&error_handling TSRMLS_CC); + return; + } + + zend_restore_error_handling(&error_handling TSRMLS_CC); + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + + name_valid = xmlValidateName((xmlChar *) name, 0); + if (name_valid != 0) { + php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC); + RETURN_FALSE; + } + + nodep = xmlNewProp(NULL, (xmlChar *) name, value); + + if (!nodep) { + php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC); + RETURN_FALSE; + } + + if (intern != NULL) { + oldnode = dom_object_get_node(intern); + if (oldnode != NULL) { + php_libxml_node_free_resource(oldnode TSRMLS_CC); + } + php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)nodep, (void *)intern TSRMLS_CC); + } +} + +/* }}} end DOMAttr::__construct */ + +/* {{{ name string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-1112119403 +Since: +*/ +int dom_attr_name_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlAttrPtr attrp; + + attrp = (xmlAttrPtr) dom_object_get_node(obj); + + if (attrp == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + ZVAL_STRING(*retval, (char *) (attrp->name), 1); + + return SUCCESS; +} + +/* }}} */ + +/* {{{ specified boolean +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-862529273 +Since: +*/ +int dom_attr_specified_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + /* TODO */ + ALLOC_ZVAL(*retval); + ZVAL_TRUE(*retval); + return SUCCESS; +} + +/* }}} */ + +/* {{{ value string +readonly=no +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-221662474 +Since: +*/ +int dom_attr_value_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlAttrPtr attrp; + xmlChar *content; + + attrp = (xmlAttrPtr) dom_object_get_node(obj); + + if (attrp == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + + if ((content = xmlNodeGetContent((xmlNodePtr) attrp)) != NULL) { + ZVAL_STRING(*retval, content, 1); + xmlFree(content); + } else { + ZVAL_EMPTY_STRING(*retval); + } + + return SUCCESS; + +} + +int dom_attr_value_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + zval value_copy; + xmlAttrPtr attrp; + + attrp = (xmlAttrPtr) dom_object_get_node(obj); + + if (attrp == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + if (attrp->children) { + node_list_unlink(attrp->children TSRMLS_CC); + } + + if (newval->type != IS_STRING) { + if(Z_REFCOUNT_P(newval) > 1) { + value_copy = *newval; + zval_copy_ctor(&value_copy); + newval = &value_copy; + } + convert_to_string(newval); + } + + xmlNodeSetContentLen((xmlNodePtr) attrp, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1); + + if (newval == &value_copy) { + zval_dtor(newval); + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ ownerElement DOMElement +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Attr-ownerElement +Since: DOM Level 2 +*/ +int dom_attr_owner_element_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNodePtr nodep, nodeparent; + int ret; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + nodeparent = nodep->parent; + if (!nodeparent) { + ZVAL_NULL(*retval); + return SUCCESS; + } + + if (NULL == (*retval = php_dom_create_object(nodeparent, &ret, *retval, obj TSRMLS_CC))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); + return FAILURE; + } + return SUCCESS; + +} + +/* }}} */ + +/* {{{ schemaTypeInfo DOMTypeInfo +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Attr-schemaTypeInfo +Since: DOM Level 3 +*/ +int dom_attr_schema_type_info_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not yet implemented"); + ALLOC_ZVAL(*retval); + ZVAL_NULL(*retval); + return SUCCESS; +} + +/* }}} */ + +/* {{{ proto boolean dom_attr_is_id(); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Attr-isId +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_attr_is_id) +{ + zval *id; + dom_object *intern; + xmlAttrPtr attrp; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_attr_class_entry) == FAILURE) { + return; + } + + DOM_GET_OBJ(attrp, id, xmlAttrPtr, intern); + + if (attrp->atype == XML_ATTRIBUTE_ID) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} end dom_attr_is_id */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/cdatasection.c b/ext/dom/cdatasection.c new file mode 100644 index 0000000..dc8a3f1 --- /dev/null +++ b/ext/dom/cdatasection.c @@ -0,0 +1,94 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_cdatasection_construct, 0, 0, 1) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class DOMCdataSection extends DOMText +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-667469212 +* Since: +*/ + +const zend_function_entry php_dom_cdatasection_class_functions[] = { + PHP_ME(domcdatasection, __construct, arginfo_dom_cdatasection_construct, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +/* {{{ proto void DOMCdataSection::__construct(string value); */ +PHP_METHOD(domcdatasection, __construct) +{ + + zval *id; + xmlNodePtr nodep = NULL, oldnode = NULL; + dom_object *intern; + char *value = NULL; + int value_len; + zend_error_handling error_handling; + + zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC); + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_cdatasection_class_entry, &value, &value_len) == FAILURE) { + zend_restore_error_handling(&error_handling TSRMLS_CC); + return; + } + + zend_restore_error_handling(&error_handling TSRMLS_CC); + nodep = xmlNewCDataBlock(NULL, (xmlChar *) value, value_len); + + if (!nodep) { + php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC); + RETURN_FALSE; + } + + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + if (intern != NULL) { + oldnode = dom_object_get_node(intern); + if (oldnode != NULL) { + php_libxml_node_free_resource(oldnode TSRMLS_CC); + } + php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC); + } +} +/* }}} end DOMCdataSection::__construct */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/characterdata.c b/ext/dom/characterdata.c new file mode 100644 index 0000000..3b1f9b1 --- /dev/null +++ b/ext/dom/characterdata.c @@ -0,0 +1,426 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_substring_data, 0, 0, 2) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, count) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_append_data, 0, 0, 1) + ZEND_ARG_INFO(0, arg) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_insert_data, 0, 0, 2) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, arg) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_delete_data, 0, 0, 2) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, count) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_replace_data, 0, 0, 3) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, count) + ZEND_ARG_INFO(0, arg) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class DOMCharacterData extends DOMNode +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-FF21A306 +* Since: +*/ + +const zend_function_entry php_dom_characterdata_class_functions[] = { + PHP_FALIAS(substringData, dom_characterdata_substring_data, arginfo_dom_characterdata_substring_data) + PHP_FALIAS(appendData, dom_characterdata_append_data, arginfo_dom_characterdata_append_data) + PHP_FALIAS(insertData, dom_characterdata_insert_data, arginfo_dom_characterdata_insert_data) + PHP_FALIAS(deleteData, dom_characterdata_delete_data, arginfo_dom_characterdata_delete_data) + PHP_FALIAS(replaceData, dom_characterdata_replace_data, arginfo_dom_characterdata_replace_data) + PHP_FE_END +}; + +/* {{{ data string +readonly=no +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-72AB8359 +Since: +*/ +int dom_characterdata_data_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNodePtr nodep; + xmlChar *content; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + if ((content = xmlNodeGetContent(nodep)) != NULL) { + ZVAL_STRING(*retval, content, 1); + xmlFree(content); + } else { + ZVAL_EMPTY_STRING(*retval); + } + + return SUCCESS; +} + +int dom_characterdata_data_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + zval value_copy; + xmlNode *nodep; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + if (newval->type != IS_STRING) { + if(Z_REFCOUNT_P(newval) > 1) { + value_copy = *newval; + zval_copy_ctor(&value_copy); + newval = &value_copy; + } + convert_to_string(newval); + } + + xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1); + + if (newval == &value_copy) { + zval_dtor(newval); + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ length long +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7D61178C +Since: +*/ +int dom_characterdata_length_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNodePtr nodep; + xmlChar *content; + long length = 0; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + content = xmlNodeGetContent(nodep); + + if (content) { + length = xmlUTF8Strlen(content); + xmlFree(content); + } + + ZVAL_LONG(*retval, length); + + return SUCCESS; +} + +/* }}} */ + +/* {{{ proto string dom_characterdata_substring_data(int offset, int count); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6531BCCF +Since: +*/ +PHP_FUNCTION(dom_characterdata_substring_data) +{ + zval *id; + xmlChar *cur; + xmlChar *substring; + xmlNodePtr node; + long offset, count; + int length; + dom_object *intern; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll", &id, dom_characterdata_class_entry, &offset, &count) == FAILURE) { + return; + } + + DOM_GET_OBJ(node, id, xmlNodePtr, intern); + + cur = xmlNodeGetContent(node); + if (cur == NULL) { + RETURN_FALSE; + } + + length = xmlUTF8Strlen(cur); + + if (offset < 0 || count < 0 || offset > length) { + xmlFree(cur); + php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + if ((offset + count) > length) { + count = length - offset; + } + + substring = xmlUTF8Strsub(cur, offset, count); + xmlFree(cur); + + if (substring) { + RETVAL_STRING(substring, 1); + xmlFree(substring); + } else { + RETVAL_EMPTY_STRING(); + } +} +/* }}} end dom_characterdata_substring_data */ + +/* {{{ proto void dom_characterdata_append_data(string arg); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-32791A2F +Since: +*/ +PHP_FUNCTION(dom_characterdata_append_data) +{ + zval *id; + xmlNode *nodep; + dom_object *intern; + char *arg; + int arg_len; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_characterdata_class_entry, &arg, &arg_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); +#if LIBXML_VERSION < 20627 +/* Implement logic from libxml xmlTextConcat to add suport for comments and PI */ + if ((nodep->content == (xmlChar *) &(nodep->properties)) || + ((nodep->doc != NULL) && (nodep->doc->dict != NULL) && + xmlDictOwns(nodep->doc->dict, nodep->content))) { + nodep->content = xmlStrncatNew(nodep->content, arg, arg_len); + } else { + nodep->content = xmlStrncat(nodep->content, arg, arg_len); + } + nodep->properties = NULL; +#else + xmlTextConcat(nodep, arg, arg_len); +#endif + RETURN_TRUE; +} +/* }}} end dom_characterdata_append_data */ + +/* {{{ proto void dom_characterdata_insert_data(int offset, string arg); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3EDB695F +Since: +*/ +PHP_FUNCTION(dom_characterdata_insert_data) +{ + zval *id; + xmlChar *cur, *first, *second; + xmlNodePtr node; + char *arg; + long offset; + int length, arg_len; + dom_object *intern; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ols", &id, dom_characterdata_class_entry, &offset, &arg, &arg_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(node, id, xmlNodePtr, intern); + + cur = xmlNodeGetContent(node); + if (cur == NULL) { + RETURN_FALSE; + } + + length = xmlUTF8Strlen(cur); + + if (offset < 0 || offset > length) { + xmlFree(cur); + php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + first = xmlUTF8Strndup(cur, offset); + second = xmlUTF8Strsub(cur, offset, length - offset); + xmlFree(cur); + + xmlNodeSetContent(node, first); + xmlNodeAddContent(node, arg); + xmlNodeAddContent(node, second); + + xmlFree(first); + xmlFree(second); + + RETURN_TRUE; +} +/* }}} end dom_characterdata_insert_data */ + +/* {{{ proto void dom_characterdata_delete_data(int offset, int count); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7C603781 +Since: +*/ +PHP_FUNCTION(dom_characterdata_delete_data) +{ + zval *id; + xmlChar *cur, *substring, *second; + xmlNodePtr node; + long offset, count; + int length; + dom_object *intern; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll", &id, dom_characterdata_class_entry, &offset, &count) == FAILURE) { + return; + } + + DOM_GET_OBJ(node, id, xmlNodePtr, intern); + + cur = xmlNodeGetContent(node); + if (cur == NULL) { + RETURN_FALSE; + } + + length = xmlUTF8Strlen(cur); + + if (offset < 0 || count < 0 || offset > length) { + xmlFree(cur); + php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + if (offset > 0) { + substring = xmlUTF8Strsub(cur, 0, offset); + } else { + substring = NULL; + } + + if ((offset + count) > length) { + count = length - offset; + } + + second = xmlUTF8Strsub(cur, offset + count, length - offset); + substring = xmlStrcat(substring, second); + + xmlNodeSetContent(node, substring); + + xmlFree(cur); + xmlFree(second); + xmlFree(substring); + + RETURN_TRUE; +} +/* }}} end dom_characterdata_delete_data */ + +/* {{{ proto void dom_characterdata_replace_data(int offset, int count, string arg); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-E5CBA7FB +Since: +*/ +PHP_FUNCTION(dom_characterdata_replace_data) +{ + zval *id; + xmlChar *cur, *substring, *second = NULL; + xmlNodePtr node; + char *arg; + long offset, count; + int length, arg_len; + dom_object *intern; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olls", &id, dom_characterdata_class_entry, &offset, &count, &arg, &arg_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(node, id, xmlNodePtr, intern); + + cur = xmlNodeGetContent(node); + if (cur == NULL) { + RETURN_FALSE; + } + + length = xmlUTF8Strlen(cur); + + if (offset < 0 || count < 0 || offset > length) { + xmlFree(cur); + php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + if (offset > 0) { + substring = xmlUTF8Strsub(cur, 0, offset); + } else { + substring = NULL; + } + + if ((offset + count) > length) { + count = length - offset; + } + + if (offset < length) { + second = xmlUTF8Strsub(cur, offset + count, length - offset); + } + + substring = xmlStrcat(substring, arg); + substring = xmlStrcat(substring, second); + + xmlNodeSetContent(node, substring); + + xmlFree(cur); + if (second) { + xmlFree(second); + } + xmlFree(substring); + + RETURN_TRUE; +} +/* }}} end dom_characterdata_replace_data */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/comment.c b/ext/dom/comment.c new file mode 100644 index 0000000..017c2ba --- /dev/null +++ b/ext/dom/comment.c @@ -0,0 +1,94 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_comment_construct, 0, 0, 0) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class DOMComment extends DOMCharacterData +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-1728279322 +* Since: +*/ + +const zend_function_entry php_dom_comment_class_functions[] = { + PHP_ME(domcomment, __construct, arginfo_dom_comment_construct, ZEND_ACC_PUBLIC) + {NULL, NULL, NULL} +}; + +/* {{{ proto void DOMComment::__construct([string value]); */ +PHP_METHOD(domcomment, __construct) +{ + + zval *id; + xmlNodePtr nodep = NULL, oldnode = NULL; + dom_object *intern; + char *value = NULL; + int value_len; + zend_error_handling error_handling; + + zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC); + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|s", &id, dom_comment_class_entry, &value, &value_len) == FAILURE) { + zend_restore_error_handling(&error_handling TSRMLS_CC); + return; + } + + zend_restore_error_handling(&error_handling TSRMLS_CC); + nodep = xmlNewComment((xmlChar *) value); + + if (!nodep) { + php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC); + RETURN_FALSE; + } + + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + if (intern != NULL) { + oldnode = dom_object_get_node(intern); + if (oldnode != NULL) { + php_libxml_node_free_resource(oldnode TSRMLS_CC); + } + php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)nodep, (void *)intern TSRMLS_CC); + } +} +/* }}} end DOMComment::__construct */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/config.m4 b/ext/dom/config.m4 new file mode 100644 index 0000000..7882483 --- /dev/null +++ b/ext/dom/config.m4 @@ -0,0 +1,38 @@ +dnl +dnl $Id$ +dnl + +PHP_ARG_ENABLE(dom, whether to enable DOM support, +[ --disable-dom Disable DOM support], yes) + +if test -z "$PHP_LIBXML_DIR"; then + PHP_ARG_WITH(libxml-dir, libxml2 install dir, + [ --with-libxml-dir[=DIR] DOM: libxml2 install prefix], no, no) +fi + +if test "$PHP_DOM" != "no"; then + + if test "$PHP_LIBXML" = "no"; then + AC_MSG_ERROR([DOM extension requires LIBXML extension, add --enable-libxml]) + fi + + PHP_SETUP_LIBXML(DOM_SHARED_LIBADD, [ + AC_DEFINE(HAVE_DOM,1,[ ]) + PHP_NEW_EXTENSION(dom, [php_dom.c attr.c document.c domerrorhandler.c \ + domstringlist.c domexception.c namelist.c \ + processinginstruction.c cdatasection.c \ + documentfragment.c domimplementation.c \ + element.c node.c string_extend.c characterdata.c \ + documenttype.c domimplementationlist.c entity.c \ + nodelist.c text.c comment.c domconfiguration.c \ + domimplementationsource.c entityreference.c \ + notation.c xpath.c dom_iterators.c \ + typeinfo.c domerror.c domlocator.c namednodemap.c userdatahandler.c], + $ext_shared) + PHP_SUBST(DOM_SHARED_LIBADD) + PHP_INSTALL_HEADERS([ext/dom/xml_common.h]) + PHP_ADD_EXTENSION_DEP(dom, libxml) + ], [ + AC_MSG_ERROR([xml2-config not found. Please check your libxml2 installation.]) + ]) +fi diff --git a/ext/dom/config.w32 b/ext/dom/config.w32 new file mode 100644 index 0000000..cbe15af --- /dev/null +++ b/ext/dom/config.w32 @@ -0,0 +1,27 @@ +// $Id$ +// vim:ft=javascript + +ARG_WITH("dom", "DOM support", "yes"); + +if (PHP_DOM == "yes") { + if (PHP_LIBXML == "yes" && ADD_EXTENSION_DEP('dom', 'libxml')) { + EXTENSION("dom", "php_dom.c attr.c document.c domerrorhandler.c \ + domstringlist.c domexception.c namelist.c processinginstruction.c \ + cdatasection.c documentfragment.c domimplementation.c element.c \ + node.c string_extend.c characterdata.c documenttype.c \ + domimplementationlist.c entity.c nodelist.c text.c comment.c \ + domconfiguration.c domimplementationsource.c entityreference.c \ + notation.c xpath.c dom_iterators.c typeinfo.c domerror.c \ + domlocator.c namednodemap.c userdatahandler.c"); + + AC_DEFINE("HAVE_DOM", 1, "DOM support"); + + if (!PHP_DOM_SHARED) { + ADD_FLAG("CFLAGS_DOM", "/D LIBXML_STATIC "); + } + PHP_INSTALL_HEADERS("ext/dom", "xml_common.h"); + } else { + WARNING("dom support can't be enabled, libxml is not enabled") + PHP_DOM = "no" + } +} diff --git a/ext/dom/document.c b/ext/dom/document.c new file mode 100644 index 0000000..d17c7cb --- /dev/null +++ b/ext/dom/document.c @@ -0,0 +1,2422 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" +#include <libxml/SAX.h> +#ifdef LIBXML_SCHEMAS_ENABLED +#include <libxml/relaxng.h> +#include <libxml/xmlschemas.h> +#endif + +typedef struct _idsIterator idsIterator; +struct _idsIterator { + xmlChar *elementId; + xmlNode *element; +}; + +#define DOM_LOAD_STRING 0 +#define DOM_LOAD_FILE 1 + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_element, 0, 0, 1) + ZEND_ARG_INFO(0, tagName) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_document_fragment, 0, 0, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_text_node, 0, 0, 1) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_comment, 0, 0, 1) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_cdatasection, 0, 0, 1) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_processing_instruction, 0, 0, 2) + ZEND_ARG_INFO(0, target) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_attribute, 0, 0, 1) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_entity_reference, 0, 0, 1) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_get_elements_by_tag_name, 0, 0, 1) + ZEND_ARG_INFO(0, tagName) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_import_node, 0, 0, 2) + ZEND_ARG_OBJ_INFO(0, importedNode, DOMNode, 0) + ZEND_ARG_INFO(0, deep) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_element_ns, 0, 0, 2) + ZEND_ARG_INFO(0, namespaceURI) + ZEND_ARG_INFO(0, qualifiedName) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_attribute_ns, 0, 0, 2) + ZEND_ARG_INFO(0, namespaceURI) + ZEND_ARG_INFO(0, qualifiedName) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_get_elements_by_tag_name_ns, 0, 0, 2) + ZEND_ARG_INFO(0, namespaceURI) + ZEND_ARG_INFO(0, localName) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_get_element_by_id, 0, 0, 1) + ZEND_ARG_INFO(0, elementId) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_adopt_node, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, source, DOMNode, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_normalize_document, 0, 0, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_rename_node, 0, 0, 3) + ZEND_ARG_OBJ_INFO(0, node, DOMNode, 0) + ZEND_ARG_INFO(0, namespaceURI) + ZEND_ARG_INFO(0, qualifiedName) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_load, 0, 0, 1) + ZEND_ARG_INFO(0, source) + ZEND_ARG_INFO(0, options) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_save, 0, 0, 1) + ZEND_ARG_INFO(0, file) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_loadxml, 0, 0, 1) + ZEND_ARG_INFO(0, source) + ZEND_ARG_INFO(0, options) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_savexml, 0, 0, 0) + ZEND_ARG_OBJ_INFO(0, node, DOMNode, 1) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_construct, 0, 0, 0) + ZEND_ARG_INFO(0, version) + ZEND_ARG_INFO(0, encoding) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_validate, 0, 0, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_xinclude, 0, 0, 0) + ZEND_ARG_INFO(0, options) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_loadhtml, 0, 0, 1) + ZEND_ARG_INFO(0, source) + ZEND_ARG_INFO(0, options) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_loadhtmlfile, 0, 0, 1) + ZEND_ARG_INFO(0, source) + ZEND_ARG_INFO(0, options) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_savehtml, 0, 0, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_savehtmlfile, 0, 0, 1) + ZEND_ARG_INFO(0, file) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_schema_validate_file, 0, 0, 1) + ZEND_ARG_INFO(0, filename) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_schema_validate_xml, 0, 0, 1) + ZEND_ARG_INFO(0, source) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_relaxNG_validate_file, 0, 0, 1) + ZEND_ARG_INFO(0, filename) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_relaxNG_validate_xml, 0, 0, 1) + ZEND_ARG_INFO(0, source) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_registernodeclass, 0, 0, 2) + ZEND_ARG_INFO(0, baseClass) + ZEND_ARG_INFO(0, extendedClass) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class DOMDocument extends DOMNode +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-i-Document +* Since: +*/ + +const zend_function_entry php_dom_document_class_functions[] = { /* {{{ */ + PHP_FALIAS(createElement, dom_document_create_element, arginfo_dom_document_create_element) + PHP_FALIAS(createDocumentFragment, dom_document_create_document_fragment, arginfo_dom_document_create_document_fragment) + PHP_FALIAS(createTextNode, dom_document_create_text_node, arginfo_dom_document_create_text_node) + PHP_FALIAS(createComment, dom_document_create_comment, arginfo_dom_document_create_comment) + PHP_FALIAS(createCDATASection, dom_document_create_cdatasection, arginfo_dom_document_create_cdatasection) + PHP_FALIAS(createProcessingInstruction, dom_document_create_processing_instruction, arginfo_dom_document_create_processing_instruction) + PHP_FALIAS(createAttribute, dom_document_create_attribute, arginfo_dom_document_create_attribute) + PHP_FALIAS(createEntityReference, dom_document_create_entity_reference, arginfo_dom_document_create_entity_reference) + PHP_FALIAS(getElementsByTagName, dom_document_get_elements_by_tag_name, arginfo_dom_document_get_elements_by_tag_name) + PHP_FALIAS(importNode, dom_document_import_node, arginfo_dom_document_import_node) + PHP_FALIAS(createElementNS, dom_document_create_element_ns, arginfo_dom_document_create_element_ns) + PHP_FALIAS(createAttributeNS, dom_document_create_attribute_ns, arginfo_dom_document_create_attribute_ns) + PHP_FALIAS(getElementsByTagNameNS, dom_document_get_elements_by_tag_name_ns, arginfo_dom_document_get_elements_by_tag_name_ns) + PHP_FALIAS(getElementById, dom_document_get_element_by_id, arginfo_dom_document_get_element_by_id) + PHP_FALIAS(adoptNode, dom_document_adopt_node, arginfo_dom_document_adopt_node) + PHP_FALIAS(normalizeDocument, dom_document_normalize_document, arginfo_dom_document_normalize_document) + PHP_FALIAS(renameNode, dom_document_rename_node, arginfo_dom_document_rename_node) + PHP_ME(domdocument, load, arginfo_dom_document_load, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC) + PHP_FALIAS(save, dom_document_save, arginfo_dom_document_save) + PHP_ME(domdocument, loadXML, arginfo_dom_document_loadxml, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC) + PHP_FALIAS(saveXML, dom_document_savexml, arginfo_dom_document_savexml) + PHP_ME(domdocument, __construct, arginfo_dom_document_construct, ZEND_ACC_PUBLIC) + PHP_FALIAS(validate, dom_document_validate, arginfo_dom_document_validate) + PHP_FALIAS(xinclude, dom_document_xinclude, arginfo_dom_document_xinclude) +#if defined(LIBXML_HTML_ENABLED) + PHP_ME(domdocument, loadHTML, arginfo_dom_document_loadhtml, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC) + PHP_ME(domdocument, loadHTMLFile, arginfo_dom_document_loadhtmlfile, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC) + PHP_FALIAS(saveHTML, dom_document_save_html, arginfo_dom_document_savehtml) + PHP_FALIAS(saveHTMLFile, dom_document_save_html_file, arginfo_dom_document_savehtmlfile) +#endif /* defined(LIBXML_HTML_ENABLED) */ +#if defined(LIBXML_SCHEMAS_ENABLED) + PHP_FALIAS(schemaValidate, dom_document_schema_validate_file, arginfo_dom_document_schema_validate_file) + PHP_FALIAS(schemaValidateSource, dom_document_schema_validate_xml, arginfo_dom_document_schema_validate_xml) + PHP_FALIAS(relaxNGValidate, dom_document_relaxNG_validate_file, arginfo_dom_document_relaxNG_validate_file) + PHP_FALIAS(relaxNGValidateSource, dom_document_relaxNG_validate_xml, arginfo_dom_document_relaxNG_validate_xml) +#endif + PHP_ME(domdocument, registerNodeClass, arginfo_dom_document_registernodeclass, ZEND_ACC_PUBLIC) + PHP_FE_END +}; +/* }}} */ + +/* {{{ docType DOMDocumentType +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-B63ED1A31 +Since: +*/ +int dom_document_doctype_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlDoc *docp; + xmlDtdPtr dtdptr; + int ret; + + docp = (xmlDocPtr) dom_object_get_node(obj); + + if (docp == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + dtdptr = xmlGetIntSubset(docp); + if (!dtdptr) { + ZVAL_NULL(*retval); + return SUCCESS; + } + + if (NULL == (*retval = php_dom_create_object((xmlNodePtr) dtdptr, &ret, *retval, obj TSRMLS_CC))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); + return FAILURE; + } + return SUCCESS; + +} + +/* }}} */ + +/* {{{ implementation DOMImplementation +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1B793EBA +Since: +*/ +int dom_document_implementation_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + php_dom_create_implementation(retval TSRMLS_CC); + return SUCCESS; +} + +/* }}} */ + +/* {{{ documentElement DOMElement +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-87CD092 +Since: +*/ +int dom_document_document_element_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlDoc *docp; + xmlNode *root; + int ret; + + docp = (xmlDocPtr) dom_object_get_node(obj); + + if (docp == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + root = xmlDocGetRootElement(docp); + if (!root) { + ZVAL_NULL(*retval); + return SUCCESS; + } + + if (NULL == (*retval = php_dom_create_object(root, &ret, *retval, obj TSRMLS_CC))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); + return FAILURE; + } + return SUCCESS; +} + +/* }}} */ + +/* {{{ encoding string +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-encoding +Since: DOM Level 3 +*/ +int dom_document_encoding_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlDoc *docp; + char *encoding; + + docp = (xmlDocPtr) dom_object_get_node(obj); + + if (docp == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + encoding = (char *) docp->encoding; + ALLOC_ZVAL(*retval); + + if (encoding != NULL) { + ZVAL_STRING(*retval, encoding, 1); + } else { + ZVAL_NULL(*retval); + } + + return SUCCESS; +} + +int dom_document_encoding_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + zval value_copy; + xmlDoc *docp; + xmlCharEncodingHandlerPtr handler; + + docp = (xmlDocPtr) dom_object_get_node(obj); + + if (docp == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + if (newval->type != IS_STRING) { + if(Z_REFCOUNT_P(newval) > 1) { + value_copy = *newval; + zval_copy_ctor(&value_copy); + newval = &value_copy; + } + convert_to_string(newval); + } + + handler = xmlFindCharEncodingHandler(Z_STRVAL_P(newval)); + + if (handler != NULL) { + xmlCharEncCloseFunc(handler); + if (docp->encoding != NULL) { + xmlFree((xmlChar *)docp->encoding); + } + docp->encoding = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval)); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Document Encoding"); + } + + if (newval == &value_copy) { + zval_dtor(newval); + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ standalone boolean +readonly=no +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-standalone +Since: DOM Level 3 +*/ +int dom_document_standalone_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlDoc *docp; + int standalone; + + docp = (xmlDocPtr) dom_object_get_node(obj); + + if (docp == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + standalone = docp->standalone; + ZVAL_BOOL(*retval, standalone); + + return SUCCESS; +} + +int dom_document_standalone_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + zval value_copy; + xmlDoc *docp; + int standalone; + + docp = (xmlDocPtr) dom_object_get_node(obj); + + if (docp == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + if(Z_REFCOUNT_P(newval) > 1) { + value_copy = *newval; + zval_copy_ctor(&value_copy); + newval = &value_copy; + } + convert_to_long(newval); + + standalone = Z_LVAL_P(newval); + if (standalone > 0) { + docp->standalone = 1; + } + else if (standalone < 0) { + docp->standalone = -1; + } + else { + docp->standalone = 0; + } + + if (newval == &value_copy) { + zval_dtor(newval); + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ version string +readonly=no +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-version +Since: DOM Level 3 +*/ +int dom_document_version_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlDoc *docp; + char *version; + + docp = (xmlDocPtr) dom_object_get_node(obj); + + if (docp == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + version = (char *) docp->version; + ALLOC_ZVAL(*retval); + + if (version != NULL) { + ZVAL_STRING(*retval, version, 1); + } else { + ZVAL_NULL(*retval); + } + + return SUCCESS; +} + +int dom_document_version_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + zval value_copy; + xmlDoc *docp; + + docp = (xmlDocPtr) dom_object_get_node(obj); + + if (docp == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + if (docp->version != NULL) { + xmlFree((xmlChar *) docp->version ); + } + + if (newval->type != IS_STRING) { + if(Z_REFCOUNT_P(newval) > 1) { + value_copy = *newval; + zval_copy_ctor(&value_copy); + newval = &value_copy; + } + convert_to_string(newval); + } + + docp->version = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval)); + + if (newval == &value_copy) { + zval_dtor(newval); + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ strictErrorChecking boolean +readonly=no +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-strictErrorChecking +Since: DOM Level 3 +*/ +int dom_document_strict_error_checking_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + dom_doc_propsptr doc_prop; + + ALLOC_ZVAL(*retval); + if (obj->document) { + doc_prop = dom_get_doc_props(obj->document); + ZVAL_BOOL(*retval, doc_prop->stricterror); + } else { + ZVAL_FALSE(*retval); + } + return SUCCESS; +} + +int dom_document_strict_error_checking_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + zval value_copy; + dom_doc_propsptr doc_prop; + + if(Z_REFCOUNT_P(newval) > 1) { + value_copy = *newval; + zval_copy_ctor(&value_copy); + newval = &value_copy; + } + convert_to_boolean(newval); + + if (obj->document) { + doc_prop = dom_get_doc_props(obj->document); + doc_prop->stricterror = Z_LVAL_P(newval); + } + + if (newval == &value_copy) { + zval_dtor(newval); + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ formatOutput boolean +readonly=no +*/ +int dom_document_format_output_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + dom_doc_propsptr doc_prop; + + ALLOC_ZVAL(*retval); + if (obj->document) { + doc_prop = dom_get_doc_props(obj->document); + ZVAL_BOOL(*retval, doc_prop->formatoutput); + } else { + ZVAL_FALSE(*retval); + } + return SUCCESS; +} + +int dom_document_format_output_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + zval value_copy; + dom_doc_propsptr doc_prop; + + if(Z_REFCOUNT_P(newval) > 1) { + value_copy = *newval; + zval_copy_ctor(&value_copy); + newval = &value_copy; + } + convert_to_boolean(newval); + + if (obj->document) { + doc_prop = dom_get_doc_props(obj->document); + doc_prop->formatoutput = Z_LVAL_P(newval); + } + + if (newval == &value_copy) { + zval_dtor(newval); + } + + return SUCCESS; +} +/* }}} */ + +/* {{{ validateOnParse boolean +readonly=no +*/ +int dom_document_validate_on_parse_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + dom_doc_propsptr doc_prop; + + ALLOC_ZVAL(*retval); + if (obj->document) { + doc_prop = dom_get_doc_props(obj->document); + ZVAL_BOOL(*retval, doc_prop->validateonparse); + } else { + ZVAL_FALSE(*retval); + } + return SUCCESS; +} + +int dom_document_validate_on_parse_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + zval value_copy; + dom_doc_propsptr doc_prop; + + if(Z_REFCOUNT_P(newval) > 1) { + value_copy = *newval; + zval_copy_ctor(&value_copy); + newval = &value_copy; + } + convert_to_boolean(newval); + + if (obj->document) { + doc_prop = dom_get_doc_props(obj->document); + doc_prop->validateonparse = Z_LVAL_P(newval); + } + + if (newval == &value_copy) { + zval_dtor(newval); + } + + return SUCCESS; +} +/* }}} */ + +/* {{{ resolveExternals boolean +readonly=no +*/ +int dom_document_resolve_externals_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + dom_doc_propsptr doc_prop; + + ALLOC_ZVAL(*retval); + if (obj->document) { + doc_prop = dom_get_doc_props(obj->document); + ZVAL_BOOL(*retval, doc_prop->resolveexternals); + } else { + ZVAL_FALSE(*retval); + } + return SUCCESS; +} + +int dom_document_resolve_externals_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + zval value_copy; + dom_doc_propsptr doc_prop; + + if(Z_REFCOUNT_P(newval) > 1) { + value_copy = *newval; + zval_copy_ctor(&value_copy); + newval = &value_copy; + } + convert_to_boolean(newval); + + if (obj->document) { + doc_prop = dom_get_doc_props(obj->document); + doc_prop->resolveexternals = Z_LVAL_P(newval); + } + + if (newval == &value_copy) { + zval_dtor(newval); + } + + return SUCCESS; +} +/* }}} */ + +/* {{{ preserveWhiteSpace boolean +readonly=no +*/ +int dom_document_preserve_whitespace_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + dom_doc_propsptr doc_prop; + + ALLOC_ZVAL(*retval); + if (obj->document) { + doc_prop = dom_get_doc_props(obj->document); + ZVAL_BOOL(*retval, doc_prop->preservewhitespace); + } else { + ZVAL_FALSE(*retval); + } + return SUCCESS; +} + +int dom_document_preserve_whitespace_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + zval value_copy; + dom_doc_propsptr doc_prop; + + if(Z_REFCOUNT_P(newval) > 1) { + value_copy = *newval; + zval_copy_ctor(&value_copy); + newval = &value_copy; + } + convert_to_boolean(newval); + + if (obj->document) { + doc_prop = dom_get_doc_props(obj->document); + doc_prop->preservewhitespace = Z_LVAL_P(newval); + } + + if (newval == &value_copy) { + zval_dtor(newval); + } + + return SUCCESS; +} +/* }}} */ + +/* {{{ recover boolean +readonly=no +*/ +int dom_document_recover_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + dom_doc_propsptr doc_prop; + + ALLOC_ZVAL(*retval); + if (obj->document) { + doc_prop = dom_get_doc_props(obj->document); + ZVAL_BOOL(*retval, doc_prop->recover); + } else { + ZVAL_FALSE(*retval); + } + return SUCCESS; +} + +int dom_document_recover_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + zval value_copy; + dom_doc_propsptr doc_prop; + + if(Z_REFCOUNT_P(newval) > 1) { + value_copy = *newval; + zval_copy_ctor(&value_copy); + newval = &value_copy; + } + convert_to_boolean(newval); + + if (obj->document) { + doc_prop = dom_get_doc_props(obj->document); + doc_prop->recover = Z_LVAL_P(newval); + } + + if (newval == &value_copy) { + zval_dtor(newval); + } + + return SUCCESS; +} +/* }}} */ + +/* {{{ substituteEntities boolean +readonly=no +*/ +int dom_document_substitue_entities_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + dom_doc_propsptr doc_prop; + + ALLOC_ZVAL(*retval); + if (obj->document) { + doc_prop = dom_get_doc_props(obj->document); + ZVAL_BOOL(*retval, doc_prop->substituteentities); + } else { + ZVAL_FALSE(*retval); + } + return SUCCESS; +} + +int dom_document_substitue_entities_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + zval value_copy; + dom_doc_propsptr doc_prop; + + if(Z_REFCOUNT_P(newval) > 1) { + value_copy = *newval; + zval_copy_ctor(&value_copy); + newval = &value_copy; + } + convert_to_boolean(newval); + + if (obj->document) { + doc_prop = dom_get_doc_props(obj->document); + doc_prop->substituteentities = Z_LVAL_P(newval); + } + + if (newval == &value_copy) { + zval_dtor(newval); + } + + return SUCCESS; +} +/* }}} */ + +/* {{{ documentURI string +readonly=no +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-documentURI +Since: DOM Level 3 +*/ +int dom_document_document_uri_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlDoc *docp; + char *url; + + docp = (xmlDocPtr) dom_object_get_node(obj); + + if (docp == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + url = (char *) docp->URL; + if (url != NULL) { + ZVAL_STRING(*retval, url, 1); + } else { + ZVAL_NULL(*retval); + } + + return SUCCESS; +} + +int dom_document_document_uri_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + zval value_copy; + xmlDoc *docp; + + docp = (xmlDocPtr) dom_object_get_node(obj); + + if (docp == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + if (docp->URL != NULL) { + xmlFree((xmlChar *) docp->URL); + } + + if (newval->type != IS_STRING) { + if(Z_REFCOUNT_P(newval) > 1) { + value_copy = *newval; + zval_copy_ctor(&value_copy); + newval = &value_copy; + } + convert_to_string(newval); + } + + docp->URL = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval)); + + if (newval == &value_copy) { + zval_dtor(newval); + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ config DOMConfiguration +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-config +Since: DOM Level 3 +*/ +int dom_document_config_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_NULL(*retval); + return SUCCESS; +} + +/* }}} */ + +/* {{{ proto DOMElement dom_document_create_element(string tagName [, string value]); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-2141741547 +Since: +*/ +PHP_FUNCTION(dom_document_create_element) +{ + zval *id; + xmlNode *node; + xmlDocPtr docp; + dom_object *intern; + int ret, name_len, value_len; + char *name, *value = NULL; + + 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) { + return; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + if (xmlValidateName((xmlChar *) name, 0) != 0) { + php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + node = xmlNewDocNode(docp, NULL, name, value); + if (!node) { + RETURN_FALSE; + } + + DOM_RET_OBJ(node, &ret, intern); +} +/* }}} end dom_document_create_element */ + +/* {{{ proto DOMDocumentFragment dom_document_create_document_fragment(); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-35CB04B5 +Since: +*/ +PHP_FUNCTION(dom_document_create_document_fragment) +{ + zval *id; + xmlNode *node; + xmlDocPtr docp; + dom_object *intern; + int ret; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_document_class_entry) == FAILURE) { + return; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + node = xmlNewDocFragment(docp); + if (!node) { + RETURN_FALSE; + } + + DOM_RET_OBJ(node, &ret, intern); +} +/* }}} end dom_document_create_document_fragment */ + +/* {{{ proto DOMText dom_document_create_text_node(string data); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1975348127 +Since: +*/ +PHP_FUNCTION(dom_document_create_text_node) +{ + zval *id; + xmlNode *node; + xmlDocPtr docp; + int ret, value_len; + dom_object *intern; + char *value; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + node = xmlNewDocText(docp, (xmlChar *) value); + if (!node) { + RETURN_FALSE; + } + + DOM_RET_OBJ(node, &ret, intern); +} +/* }}} end dom_document_create_text_node */ + +/* {{{ proto DOMComment dom_document_create_comment(string data); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1334481328 +Since: +*/ +PHP_FUNCTION(dom_document_create_comment) +{ + zval *id; + xmlNode *node; + xmlDocPtr docp; + int ret, value_len; + dom_object *intern; + char *value; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + node = xmlNewDocComment(docp, (xmlChar *) value); + if (!node) { + RETURN_FALSE; + } + + DOM_RET_OBJ(node, &ret, intern); +} +/* }}} end dom_document_create_comment */ + +/* {{{ proto DOMCdataSection dom_document_create_cdatasection(string data); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D26C0AF8 +Since: +*/ +PHP_FUNCTION(dom_document_create_cdatasection) +{ + zval *id; + xmlNode *node; + xmlDocPtr docp; + int ret, value_len; + dom_object *intern; + char *value; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + node = xmlNewCDataBlock(docp, (xmlChar *) value, value_len); + if (!node) { + RETURN_FALSE; + } + + DOM_RET_OBJ(node, &ret, intern); +} +/* }}} end dom_document_create_cdatasection */ + +/* {{{ proto DOMProcessingInstruction dom_document_create_processing_instruction(string target, string data); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-135944439 +Since: +*/ +PHP_FUNCTION(dom_document_create_processing_instruction) +{ + zval *id; + xmlNode *node; + xmlDocPtr docp; + int ret, value_len, name_len = 0; + dom_object *intern; + char *name, *value = NULL; + + 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) { + return; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + if (xmlValidateName((xmlChar *) name, 0) != 0) { + php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + node = xmlNewPI((xmlChar *) name, (xmlChar *) value); + if (!node) { + RETURN_FALSE; + } + + node->doc = docp; + + DOM_RET_OBJ(node, &ret, intern); +} +/* }}} end dom_document_create_processing_instruction */ + +/* {{{ proto DOMAttr dom_document_create_attribute(string name); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1084891198 +Since: +*/ +PHP_FUNCTION(dom_document_create_attribute) +{ + zval *id; + xmlAttrPtr node; + xmlDocPtr docp; + int ret, name_len; + dom_object *intern; + char *name; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + if (xmlValidateName((xmlChar *) name, 0) != 0) { + php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + node = xmlNewDocProp(docp, (xmlChar *) name, NULL); + if (!node) { + RETURN_FALSE; + } + + DOM_RET_OBJ((xmlNodePtr) node, &ret, intern); + +} +/* }}} end dom_document_create_attribute */ + +/* {{{ proto DOMEntityReference dom_document_create_entity_reference(string name); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-392B75AE +Since: +*/ +PHP_FUNCTION(dom_document_create_entity_reference) +{ + zval *id; + xmlNode *node; + xmlDocPtr docp = NULL; + dom_object *intern; + int ret, name_len; + char *name; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + if (xmlValidateName((xmlChar *) name, 0) != 0) { + php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + node = xmlNewReference(docp, name); + if (!node) { + RETURN_FALSE; + } + + DOM_RET_OBJ((xmlNodePtr) node, &ret, intern); +} +/* }}} end dom_document_create_entity_reference */ + +/* {{{ proto DOMNodeList dom_document_get_elements_by_tag_name(string tagname); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C9094 +Since: +*/ +PHP_FUNCTION(dom_document_get_elements_by_tag_name) +{ + zval *id; + xmlDocPtr docp; + int name_len; + dom_object *intern, *namednode; + char *name; + xmlChar *local; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC); + namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC); + local = xmlCharStrndup(name, name_len); + dom_namednode_iter(intern, 0, namednode, NULL, local, NULL TSRMLS_CC); +} +/* }}} end dom_document_get_elements_by_tag_name */ + +/* {{{ proto DOMNode dom_document_import_node(DOMNode importedNode, boolean deep); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Core-Document-importNode +Since: DOM Level 2 +*/ +PHP_FUNCTION(dom_document_import_node) +{ + zval *id, *node; + xmlDocPtr docp; + xmlNodePtr nodep, retnodep; + dom_object *intern, *nodeobj; + int ret; + long recursive = 0; + + 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) { + return; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + DOM_GET_OBJ(nodep, node, xmlNodePtr, nodeobj); + + if (nodep->type == XML_HTML_DOCUMENT_NODE || nodep->type == XML_DOCUMENT_NODE + || nodep->type == XML_DOCUMENT_TYPE_NODE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot import: Node Type Not Supported"); + RETURN_FALSE; + } + + if (nodep->doc == docp) { + retnodep = nodep; + } else { + if ((recursive == 0) && (nodep->type == XML_ELEMENT_NODE)) { + recursive = 2; + } + retnodep = xmlDocCopyNode(nodep, docp, recursive); + if (!retnodep) { + RETURN_FALSE; + } + + if ((retnodep->type == XML_ATTRIBUTE_NODE) && (nodep->ns != NULL)) { + xmlNsPtr nsptr = NULL; + xmlNodePtr root = xmlDocGetRootElement(docp); + + nsptr = xmlSearchNsByHref (nodep->doc, root, nodep->ns->href); + if (nsptr == NULL) { + int errorcode; + nsptr = dom_get_ns(root, (char *) nodep->ns->href, &errorcode, (char *) nodep->ns->prefix); + } + xmlSetNs(retnodep, nsptr); + } + } + + DOM_RET_OBJ((xmlNodePtr) retnodep, &ret, intern); +} +/* }}} end dom_document_import_node */ + +/* {{{ proto DOMElement dom_document_create_element_ns(string namespaceURI, string qualifiedName [,string value]); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrElNS +Since: DOM Level 2 +*/ +PHP_FUNCTION(dom_document_create_element_ns) +{ + zval *id; + xmlDocPtr docp; + xmlNodePtr nodep = NULL; + xmlNsPtr nsptr = NULL; + int ret, uri_len = 0, name_len = 0, value_len = 0; + char *uri, *name, *value = NULL; + char *localname = NULL, *prefix = NULL; + int errorcode; + dom_object *intern; + + 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) { + return; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len); + + if (errorcode == 0) { + if (xmlValidateName((xmlChar *) localname, 0) == 0) { + nodep = xmlNewDocNode (docp, NULL, localname, value); + if (nodep != NULL && uri != NULL) { + nsptr = xmlSearchNsByHref (nodep->doc, nodep, uri); + if (nsptr == NULL) { + nsptr = dom_get_ns(nodep, uri, &errorcode, prefix); + } + xmlSetNs(nodep, nsptr); + } + } else { + errorcode = INVALID_CHARACTER_ERR; + } + } + + xmlFree(localname); + if (prefix != NULL) { + xmlFree(prefix); + } + + if (errorcode != 0) { + if (nodep != NULL) { + xmlFreeNode(nodep); + } + php_dom_throw_error(errorcode, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + if (nodep == NULL) { + RETURN_FALSE; + } + + + nodep->ns = nsptr; + + DOM_RET_OBJ(nodep, &ret, intern); +} +/* }}} end dom_document_create_element_ns */ + +/* {{{ proto DOMAttr dom_document_create_attribute_ns(string namespaceURI, string qualifiedName); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrAttrNS +Since: DOM Level 2 +*/ +PHP_FUNCTION(dom_document_create_attribute_ns) +{ + zval *id; + xmlDocPtr docp; + xmlNodePtr nodep = NULL, root; + xmlNsPtr nsptr; + int ret, uri_len = 0, name_len = 0; + char *uri, *name; + char *localname = NULL, *prefix = NULL; + dom_object *intern; + int errorcode; + + 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) { + return; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + root = xmlDocGetRootElement(docp); + if (root != NULL) { + errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len); + if (errorcode == 0) { + if (xmlValidateName((xmlChar *) localname, 0) == 0) { + nodep = (xmlNodePtr) xmlNewDocProp(docp, localname, NULL); + if (nodep != NULL && uri_len > 0) { + nsptr = xmlSearchNsByHref (nodep->doc, root, uri); + if (nsptr == NULL) { + nsptr = dom_get_ns(root, uri, &errorcode, prefix); + } + xmlSetNs(nodep, nsptr); + } + } else { + errorcode = INVALID_CHARACTER_ERR; + } + } + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Missing Root Element"); + RETURN_FALSE; + } + + xmlFree(localname); + if (prefix != NULL) { + xmlFree(prefix); + } + + if (errorcode != 0) { + if (nodep != NULL) { + xmlFreeProp((xmlAttrPtr) nodep); + } + php_dom_throw_error(errorcode, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + if (nodep == NULL) { + RETURN_FALSE; + } + + DOM_RET_OBJ(nodep, &ret, intern); +} +/* }}} end dom_document_create_attribute_ns */ + +/* {{{ proto DOMNodeList dom_document_get_elements_by_tag_name_ns(string namespaceURI, string localName); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBTNNS +Since: DOM Level 2 +*/ +PHP_FUNCTION(dom_document_get_elements_by_tag_name_ns) +{ + zval *id; + xmlDocPtr docp; + int uri_len, name_len; + dom_object *intern, *namednode; + char *uri, *name; + xmlChar *local, *nsuri; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC); + namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC); + local = xmlCharStrndup(name, name_len); + nsuri = xmlCharStrndup(uri, uri_len); + dom_namednode_iter(intern, 0, namednode, NULL, local, nsuri TSRMLS_CC); +} +/* }}} end dom_document_get_elements_by_tag_name_ns */ + +/* {{{ proto DOMElement dom_document_get_element_by_id(string elementId); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBId +Since: DOM Level 2 +*/ +PHP_FUNCTION(dom_document_get_element_by_id) +{ + zval *id; + xmlDocPtr docp; + xmlAttrPtr attrp; + int ret, idname_len; + dom_object *intern; + char *idname; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &idname, &idname_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + attrp = xmlGetID(docp, (xmlChar *) idname); + + if (attrp && attrp->parent) { + DOM_RET_OBJ((xmlNodePtr) attrp->parent, &ret, intern); + } else { + RETVAL_NULL(); + } + +} +/* }}} end dom_document_get_element_by_id */ + +/* {{{ proto DOMNode dom_document_adopt_node(DOMNode source); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-adoptNode +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_document_adopt_node) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_document_adopt_node */ + +/* {{{ proto void dom_document_normalize_document(); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-normalizeDocument +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_document_normalize_document) +{ + zval *id; + xmlDocPtr docp; + dom_object *intern; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_document_class_entry) == FAILURE) { + return; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + dom_normalize((xmlNodePtr) docp TSRMLS_CC); +} +/* }}} end dom_document_normalize_document */ + +/* {{{ proto DOMNode dom_document_rename_node(node n, string namespaceURI, string qualifiedName); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-renameNode +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_document_rename_node) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_document_rename_node */ + +/* {{{ proto void DOMDocument::__construct([string version], [string encoding]); */ +PHP_METHOD(domdocument, __construct) +{ + + zval *id; + xmlDoc *docp = NULL, *olddoc; + dom_object *intern; + char *encoding, *version = NULL; + int encoding_len = 0, version_len = 0, refcount; + zend_error_handling error_handling; + + zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC); + 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) { + zend_restore_error_handling(&error_handling TSRMLS_CC); + return; + } + + zend_restore_error_handling(&error_handling TSRMLS_CC); + docp = xmlNewDoc(version); + + if (!docp) { + php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC); + RETURN_FALSE; + } + + if (encoding_len > 0) { + docp->encoding = (const xmlChar*)xmlStrdup(encoding); + } + + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + if (intern != NULL) { + olddoc = (xmlDocPtr) dom_object_get_node(intern); + if (olddoc != NULL) { + php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC); + refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC); + if (refcount != 0) { + olddoc->_private = NULL; + } + } + intern->document = NULL; + if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, docp TSRMLS_CC) == -1) { + RETURN_FALSE; + } + php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)docp, (void *)intern TSRMLS_CC); + } +} +/* }}} end DOMDocument::__construct */ + +char *_dom_get_valid_file_path(char *source, char *resolved_path, int resolved_path_len TSRMLS_DC) /* {{{ */ +{ + xmlURI *uri; + xmlChar *escsource; + char *file_dest; + int isFileUri = 0; + + uri = xmlCreateURI(); + escsource = xmlURIEscapeStr(source, ":"); + xmlParseURIReference(uri, escsource); + xmlFree(escsource); + + if (uri->scheme != NULL) { + /* absolute file uris - libxml only supports localhost or empty host */ + if (strncasecmp(source, "file:///",8) == 0) { + isFileUri = 1; +#ifdef PHP_WIN32 + source += 8; +#else + source += 7; +#endif + } else if (strncasecmp(source, "file://localhost/",17) == 0) { + isFileUri = 1; +#ifdef PHP_WIN32 + source += 17; +#else + source += 16; +#endif + } + } + + file_dest = source; + + if ((uri->scheme == NULL || isFileUri)) { + /* XXX possible buffer overflow if VCWD_REALPATH does not know size of resolved_path */ + if (!VCWD_REALPATH(source, resolved_path) && !expand_filepath(source, resolved_path TSRMLS_CC)) { + xmlFreeURI(uri); + return NULL; + } + file_dest = resolved_path; + } + + xmlFreeURI(uri); + + return file_dest; +} +/* }}} */ + +static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, int source_len, int options TSRMLS_DC) /* {{{ */ +{ + xmlDocPtr ret; + xmlParserCtxtPtr ctxt = NULL; + dom_doc_propsptr doc_props; + dom_object *intern; + php_libxml_ref_obj *document = NULL; + int validate, recover, resolve_externals, keep_blanks, substitute_ent; + int resolved_path_len; + int old_error_reporting = 0; + char *directory=NULL, resolved_path[MAXPATHLEN]; + + if (id != NULL) { + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + document = intern->document; + } + + doc_props = dom_get_doc_props(document); + validate = doc_props->validateonparse; + resolve_externals = doc_props->resolveexternals; + keep_blanks = doc_props->preservewhitespace; + substitute_ent = doc_props->substituteentities; + recover = doc_props->recover; + + if (document == NULL) { + efree(doc_props); + } + + xmlInitParser(); + + if (mode == DOM_LOAD_FILE) { + char *file_dest = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC); + if (file_dest) { + ctxt = xmlCreateFileParserCtxt(file_dest); + } + + } else { + ctxt = xmlCreateMemoryParserCtxt(source, source_len); + } + + if (ctxt == NULL) { + return(NULL); + } + + /* If loading from memory, we need to set the base directory for the document */ + if (mode != DOM_LOAD_FILE) { +#if HAVE_GETCWD + directory = VCWD_GETCWD(resolved_path, MAXPATHLEN); +#elif HAVE_GETWD + directory = VCWD_GETWD(resolved_path); +#endif + if (directory) { + if(ctxt->directory != NULL) { + xmlFree((char *) ctxt->directory); + } + resolved_path_len = strlen(resolved_path); + if (resolved_path[resolved_path_len - 1] != DEFAULT_SLASH) { + resolved_path[resolved_path_len] = DEFAULT_SLASH; + resolved_path[++resolved_path_len] = '\0'; + } + ctxt->directory = (char *) xmlCanonicPath((const xmlChar *) resolved_path); + } + } + + ctxt->vctxt.error = php_libxml_ctx_error; + ctxt->vctxt.warning = php_libxml_ctx_warning; + + if (ctxt->sax != NULL) { + ctxt->sax->error = php_libxml_ctx_error; + ctxt->sax->warning = php_libxml_ctx_warning; + } + + if (validate && ! (options & XML_PARSE_DTDVALID)) { + options |= XML_PARSE_DTDVALID; + } + if (resolve_externals && ! (options & XML_PARSE_DTDATTR)) { + options |= XML_PARSE_DTDATTR; + } + if (substitute_ent && ! (options & XML_PARSE_NOENT)) { + options |= XML_PARSE_NOENT; + } + if (keep_blanks == 0 && ! (options & XML_PARSE_NOBLANKS)) { + options |= XML_PARSE_NOBLANKS; + } + + xmlCtxtUseOptions(ctxt, options); + + ctxt->recovery = recover; + if (recover) { + old_error_reporting = EG(error_reporting); + EG(error_reporting) = old_error_reporting | E_WARNING; + } + + xmlParseDocument(ctxt); + + if (ctxt->wellFormed || recover) { + ret = ctxt->myDoc; + if (ctxt->recovery) { + EG(error_reporting) = old_error_reporting; + } + /* If loading from memory, set the base reference uri for the document */ + if (ret && ret->URL == NULL && ctxt->directory != NULL) { + ret->URL = xmlStrdup(ctxt->directory); + } + } else { + ret = NULL; + xmlFreeDoc(ctxt->myDoc); + ctxt->myDoc = NULL; + } + + xmlFreeParserCtxt(ctxt); + + return(ret); +} +/* }}} */ + +/* {{{ static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) */ +static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) { + zval *id; + xmlDoc *docp = NULL, *newdoc; + dom_doc_propsptr doc_prop; + dom_object *intern; + char *source; + int source_len, refcount, ret; + long options = 0; + + id = getThis(); + if (id != NULL && ! instanceof_function(Z_OBJCE_P(id), dom_document_class_entry TSRMLS_CC)) { + id = NULL; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &source, &source_len, &options) == FAILURE) { + return; + } + + if (!source_len) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string supplied as input"); + RETURN_FALSE; + } + + newdoc = dom_document_parser(id, mode, source, source_len, options TSRMLS_CC); + + if (!newdoc) + RETURN_FALSE; + + if (id != NULL) { + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + if (intern != NULL) { + docp = (xmlDocPtr) dom_object_get_node(intern); + doc_prop = NULL; + if (docp != NULL) { + php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC); + doc_prop = intern->document->doc_props; + intern->document->doc_props = NULL; + refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC); + if (refcount != 0) { + docp->_private = NULL; + } + } + intern->document = NULL; + if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, newdoc TSRMLS_CC) == -1) { + RETURN_FALSE; + } + intern->document->doc_props = doc_prop; + } + + php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)newdoc, (void *)intern TSRMLS_CC); + + RETURN_TRUE; + } else { + DOM_RET_OBJ((xmlNodePtr) newdoc, &ret, NULL); + } +} +/* }}} end dom_parser_document */ + +/* {{{ proto DOMNode dom_document_load(string source [, int options]); +URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-load +Since: DOM Level 3 +*/ +PHP_METHOD(domdocument, load) +{ + dom_parse_document(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE); +} +/* }}} end dom_document_load */ + +/* {{{ proto DOMNode dom_document_loadxml(string source [, int options]); +URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-loadXML +Since: DOM Level 3 +*/ +PHP_METHOD(domdocument, loadXML) +{ + dom_parse_document(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING); +} +/* }}} end dom_document_loadxml */ + +/* {{{ proto int dom_document_save(string file); +Convenience method to save to file +*/ +PHP_FUNCTION(dom_document_save) +{ + zval *id; + xmlDoc *docp; + int file_len = 0, bytes, format, saveempty = 0; + dom_object *intern; + dom_doc_propsptr doc_props; + char *file; + long options = 0; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|l", &id, dom_document_class_entry, &file, &file_len, &options) == FAILURE) { + return; + } + + if (file_len == 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Filename"); + RETURN_FALSE; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + /* encoding handled by property on doc */ + + doc_props = dom_get_doc_props(intern->document); + format = doc_props->formatoutput; + if (options & LIBXML_SAVE_NOEMPTYTAG) { + saveempty = xmlSaveNoEmptyTags; + xmlSaveNoEmptyTags = 1; + } + bytes = xmlSaveFormatFileEnc(file, docp, NULL, format); + if (options & LIBXML_SAVE_NOEMPTYTAG) { + xmlSaveNoEmptyTags = saveempty; + } + if (bytes == -1) { + RETURN_FALSE; + } + RETURN_LONG(bytes); +} +/* }}} end dom_document_save */ + +/* {{{ proto string dom_document_savexml([node n]); +URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-saveXML +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_document_savexml) +{ + zval *id, *nodep = NULL; + xmlDoc *docp; + xmlNode *node; + xmlBufferPtr buf; + xmlChar *mem; + dom_object *intern, *nodeobj; + dom_doc_propsptr doc_props; + int size, format, saveempty = 0; + long options = 0; + + 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) { + return; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + doc_props = dom_get_doc_props(intern->document); + format = doc_props->formatoutput; + + if (nodep != NULL) { + /* Dump contents of Node */ + DOM_GET_OBJ(node, nodep, xmlNodePtr, nodeobj); + if (node->doc != docp) { + php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + buf = xmlBufferCreate(); + if (!buf) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch buffer"); + RETURN_FALSE; + } + if (options & LIBXML_SAVE_NOEMPTYTAG) { + saveempty = xmlSaveNoEmptyTags; + xmlSaveNoEmptyTags = 1; + } + xmlNodeDump(buf, docp, node, 0, format); + if (options & LIBXML_SAVE_NOEMPTYTAG) { + xmlSaveNoEmptyTags = saveempty; + } + mem = (xmlChar*) xmlBufferContent(buf); + if (!mem) { + xmlBufferFree(buf); + RETURN_FALSE; + } + RETVAL_STRING(mem, 1); + xmlBufferFree(buf); + } else { + if (options & LIBXML_SAVE_NOEMPTYTAG) { + saveempty = xmlSaveNoEmptyTags; + xmlSaveNoEmptyTags = 1; + } + /* Encoding is handled from the encoding property set on the document */ + xmlDocDumpFormatMemory(docp, &mem, &size, format); + if (options & LIBXML_SAVE_NOEMPTYTAG) { + xmlSaveNoEmptyTags = saveempty; + } + if (!size) { + RETURN_FALSE; + } + RETVAL_STRINGL(mem, size, 1); + xmlFree(mem); + } +} +/* }}} end dom_document_savexml */ + +static xmlNodePtr php_dom_free_xinclude_node(xmlNodePtr cur TSRMLS_DC) /* {{{ */ +{ + xmlNodePtr xincnode; + + xincnode = cur; + cur = cur->next; + xmlUnlinkNode(xincnode); + php_libxml_node_free_resource(xincnode TSRMLS_CC); + + return cur; +} +/* }}} */ + +static void php_dom_remove_xinclude_nodes(xmlNodePtr cur TSRMLS_DC) /* {{{ */ +{ + while(cur) { + if (cur->type == XML_XINCLUDE_START) { + cur = php_dom_free_xinclude_node(cur TSRMLS_CC); + + /* XML_XINCLUDE_END node will be a sibling of XML_XINCLUDE_START */ + while(cur && cur->type != XML_XINCLUDE_END) { + /* remove xinclude processing nodes from recursive xincludes */ + if (cur->type == XML_ELEMENT_NODE) { + php_dom_remove_xinclude_nodes(cur->children TSRMLS_CC); + } + cur = cur->next; + } + + if (cur && cur->type == XML_XINCLUDE_END) { + cur = php_dom_free_xinclude_node(cur TSRMLS_CC); + } + } else { + if (cur->type == XML_ELEMENT_NODE) { + php_dom_remove_xinclude_nodes(cur->children TSRMLS_CC); + } + cur = cur->next; + } + } +} +/* }}} */ + +/* {{{ proto int dom_document_xinclude([int options]) + Substitutues xincludes in a DomDocument */ +PHP_FUNCTION(dom_document_xinclude) +{ + zval *id; + xmlDoc *docp; + xmlNodePtr root; + long flags = 0; + int err; + dom_object *intern; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &id, dom_document_class_entry, &flags) == FAILURE) { + return; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + err = xmlXIncludeProcessFlags(docp, flags); + + /* XML_XINCLUDE_START and XML_XINCLUDE_END nodes need to be removed as these + are added via xmlXIncludeProcess to mark beginning and ending of xincluded document + but are not wanted in resulting document - must be done even if err as it could fail after + having processed some xincludes */ + root = (xmlNodePtr) docp->children; + while(root && root->type != XML_ELEMENT_NODE && root->type != XML_XINCLUDE_START) { + root = root->next; + } + if (root) { + php_dom_remove_xinclude_nodes(root TSRMLS_CC); + } + + if (err) { + RETVAL_LONG(err); + } else { + RETVAL_FALSE; + } + +} +/* }}} */ + +/* {{{ proto boolean dom_document_validate(); +Since: DOM extended +*/ +PHP_FUNCTION(dom_document_validate) +{ + zval *id; + xmlDoc *docp; + dom_object *intern; + xmlValidCtxt *cvp; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_document_class_entry) == FAILURE) { + return; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + cvp = xmlNewValidCtxt(); + + cvp->userData = NULL; + cvp->error = (xmlValidityErrorFunc) php_libxml_error_handler; + cvp->warning = (xmlValidityErrorFunc) php_libxml_error_handler; + + if (xmlValidateDocument(cvp, docp)) { + RETVAL_TRUE; + } else { + RETVAL_FALSE; + } + + xmlFreeValidCtxt(cvp); + +} +/* }}} */ + +#if defined(LIBXML_SCHEMAS_ENABLED) +static void _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ +{ + zval *id; + xmlDoc *docp; + dom_object *intern; + char *source = NULL, *valid_file = NULL; + int source_len = 0; + xmlSchemaParserCtxtPtr parser; + xmlSchemaPtr sptr; + xmlSchemaValidCtxtPtr vptr; + int is_valid; + char resolved_path[MAXPATHLEN + 1]; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Op", &id, dom_document_class_entry, &source, &source_len) == FAILURE) { + return; + } + + if (source_len == 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema source"); + RETURN_FALSE; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + switch (type) { + case DOM_LOAD_FILE: + valid_file = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC); + if (!valid_file) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema file source"); + RETURN_FALSE; + } + parser = xmlSchemaNewParserCtxt(valid_file); + break; + case DOM_LOAD_STRING: + parser = xmlSchemaNewMemParserCtxt(source, source_len); + /* If loading from memory, we need to set the base directory for the document + but it is not apparent how to do that for schema's */ + break; + default: + return; + } + + xmlSchemaSetParserErrors(parser, + (xmlSchemaValidityErrorFunc) php_libxml_error_handler, + (xmlSchemaValidityWarningFunc) php_libxml_error_handler, + parser); + sptr = xmlSchemaParse(parser); + xmlSchemaFreeParserCtxt(parser); + if (!sptr) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema"); + RETURN_FALSE; + } + + docp = (xmlDocPtr) dom_object_get_node(intern); + + vptr = xmlSchemaNewValidCtxt(sptr); + if (!vptr) { + xmlSchemaFree(sptr); + php_error(E_ERROR, "Invalid Schema Validation Context"); + RETURN_FALSE; + } + + xmlSchemaSetValidErrors(vptr, php_libxml_error_handler, php_libxml_error_handler, vptr); + is_valid = xmlSchemaValidateDoc(vptr, docp); + xmlSchemaFree(sptr); + xmlSchemaFreeValidCtxt(vptr); + + if (is_valid == 0) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto boolean dom_document_schema_validate_file(string filename); */ +PHP_FUNCTION(dom_document_schema_validate_file) +{ + _dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE); +} +/* }}} end dom_document_schema_validate_file */ + +/* {{{ proto boolean dom_document_schema_validate(string source); */ +PHP_FUNCTION(dom_document_schema_validate_xml) +{ + _dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING); +} +/* }}} end dom_document_schema_validate */ + +static void _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ +{ + zval *id; + xmlDoc *docp; + dom_object *intern; + char *source = NULL, *valid_file = NULL; + int source_len = 0; + xmlRelaxNGParserCtxtPtr parser; + xmlRelaxNGPtr sptr; + xmlRelaxNGValidCtxtPtr vptr; + int is_valid; + char resolved_path[MAXPATHLEN + 1]; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Op", &id, dom_document_class_entry, &source, &source_len) == FAILURE) { + return; + } + + if (source_len == 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema source"); + RETURN_FALSE; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + switch (type) { + case DOM_LOAD_FILE: + valid_file = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC); + if (!valid_file) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid RelaxNG file source"); + RETURN_FALSE; + } + parser = xmlRelaxNGNewParserCtxt(valid_file); + break; + case DOM_LOAD_STRING: + parser = xmlRelaxNGNewMemParserCtxt(source, source_len); + /* If loading from memory, we need to set the base directory for the document + but it is not apparent how to do that for schema's */ + break; + default: + return; + } + + xmlRelaxNGSetParserErrors(parser, + (xmlRelaxNGValidityErrorFunc) php_libxml_error_handler, + (xmlRelaxNGValidityWarningFunc) php_libxml_error_handler, + parser); + sptr = xmlRelaxNGParse(parser); + xmlRelaxNGFreeParserCtxt(parser); + if (!sptr) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid RelaxNG"); + RETURN_FALSE; + } + + docp = (xmlDocPtr) dom_object_get_node(intern); + + vptr = xmlRelaxNGNewValidCtxt(sptr); + if (!vptr) { + xmlRelaxNGFree(sptr); + php_error(E_ERROR, "Invalid RelaxNG Validation Context"); + RETURN_FALSE; + } + + xmlRelaxNGSetValidErrors(vptr, php_libxml_error_handler, php_libxml_error_handler, vptr); + is_valid = xmlRelaxNGValidateDoc(vptr, docp); + xmlRelaxNGFree(sptr); + xmlRelaxNGFreeValidCtxt(vptr); + + if (is_valid == 0) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto boolean dom_document_relaxNG_validate_file(string filename); */ +PHP_FUNCTION(dom_document_relaxNG_validate_file) +{ + _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE); +} +/* }}} end dom_document_relaxNG_validate_file */ + +/* {{{ proto boolean dom_document_relaxNG_validate_xml(string source); */ +PHP_FUNCTION(dom_document_relaxNG_validate_xml) +{ + _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING); +} +/* }}} end dom_document_relaxNG_validate_xml */ + +#endif + +#if defined(LIBXML_HTML_ENABLED) + +static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ +{ + zval *id; + xmlDoc *docp = NULL, *newdoc; + dom_object *intern; + dom_doc_propsptr doc_prop; + char *source; + int source_len, refcount, ret; + long options = 0; + htmlParserCtxtPtr ctxt; + + id = getThis(); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &source, &source_len, &options) == FAILURE) { + return; + } + + if (!source_len) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string supplied as input"); + RETURN_FALSE; + } + + if (mode == DOM_LOAD_FILE) { + ctxt = htmlCreateFileParserCtxt(source, NULL); + } else { + source_len = xmlStrlen(source); + ctxt = htmlCreateMemoryParserCtxt(source, source_len); + } + + if (!ctxt) { + RETURN_FALSE; + } + + if (options) { + htmlCtxtUseOptions(ctxt, options); + } + + ctxt->vctxt.error = php_libxml_ctx_error; + ctxt->vctxt.warning = php_libxml_ctx_warning; + if (ctxt->sax != NULL) { + ctxt->sax->error = php_libxml_ctx_error; + ctxt->sax->warning = php_libxml_ctx_warning; + } + htmlParseDocument(ctxt); + newdoc = ctxt->myDoc; + htmlFreeParserCtxt(ctxt); + + if (!newdoc) + RETURN_FALSE; + + if (id != NULL && instanceof_function(Z_OBJCE_P(id), dom_document_class_entry TSRMLS_CC)) { + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + if (intern != NULL) { + docp = (xmlDocPtr) dom_object_get_node(intern); + doc_prop = NULL; + if (docp != NULL) { + php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC); + doc_prop = intern->document->doc_props; + intern->document->doc_props = NULL; + refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC); + if (refcount != 0) { + docp->_private = NULL; + } + } + intern->document = NULL; + if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, newdoc TSRMLS_CC) == -1) { + RETURN_FALSE; + } + intern->document->doc_props = doc_prop; + } + + php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)newdoc, (void *)intern TSRMLS_CC); + + RETURN_TRUE; + } else { + DOM_RET_OBJ((xmlNodePtr) newdoc, &ret, NULL); + } +} +/* }}} */ + +/* {{{ proto DOMNode dom_document_load_html_file(string source); +Since: DOM extended +*/ +PHP_METHOD(domdocument, loadHTMLFile) +{ + dom_load_html(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE); +} +/* }}} end dom_document_load_html_file */ + +/* {{{ proto DOMNode dom_document_load_html(string source); +Since: DOM extended +*/ +PHP_METHOD(domdocument, loadHTML) +{ + dom_load_html(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING); +} +/* }}} end dom_document_load_html */ + +/* {{{ proto int dom_document_save_html_file(string file); +Convenience method to save to file as html +*/ +PHP_FUNCTION(dom_document_save_html_file) +{ + zval *id; + xmlDoc *docp; + int file_len, bytes, format; + dom_object *intern; + dom_doc_propsptr doc_props; + char *file; + const char *encoding; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &file, &file_len) == FAILURE) { + return; + } + + if (file_len == 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Filename"); + RETURN_FALSE; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + + encoding = (const char *) htmlGetMetaEncoding(docp); + + doc_props = dom_get_doc_props(intern->document); + format = doc_props->formatoutput; + bytes = htmlSaveFileFormat(file, docp, encoding, format); + + if (bytes == -1) { + RETURN_FALSE; + } + RETURN_LONG(bytes); +} +/* }}} end dom_document_save_html_file */ + +/* {{{ proto string dom_document_save_html(); +Convenience method to output as html +*/ +PHP_FUNCTION(dom_document_save_html) +{ + zval *id, *nodep = NULL; + xmlDoc *docp; + xmlNode *node; + xmlBufferPtr buf; + dom_object *intern, *nodeobj; + xmlChar *mem = NULL; + int size, format; + dom_doc_propsptr doc_props; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), + "O|O!", &id, dom_document_class_entry, &nodep, dom_node_class_entry) + == FAILURE) { + return; + } + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + doc_props = dom_get_doc_props(intern->document); + format = doc_props->formatoutput; + + if (nodep != NULL) { + /* Dump contents of Node */ + DOM_GET_OBJ(node, nodep, xmlNodePtr, nodeobj); + if (node->doc != docp) { + php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + buf = xmlBufferCreate(); + if (!buf) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch buffer"); + RETURN_FALSE; + } + + size = htmlNodeDump(buf, docp, node); + if (size >= 0) { + mem = (xmlChar*) xmlBufferContent(buf); + if (!mem) { + RETVAL_FALSE; + } else { + RETVAL_STRINGL((const char*) mem, size, 1); + } + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error dumping HTML node"); + RETVAL_FALSE; + } + xmlBufferFree(buf); + } else { +#if LIBXML_VERSION >= 20623 + htmlDocDumpMemoryFormat(docp, &mem, &size, format); +#else + htmlDocDumpMemory(docp, &mem, &size); +#endif + if (!size) { + RETVAL_FALSE; + } else { + RETVAL_STRINGL((const char*) mem, size, 1); + } + if (mem) + xmlFree(mem); + } + +} +/* }}} end dom_document_save_html */ + +#endif /* defined(LIBXML_HTML_ENABLED) */ + +/* {{{ proto boolean DOMDocument::registerNodeClass(string baseclass, string extendedclass); + Register extended class used to create base node type */ +PHP_METHOD(domdocument, registerNodeClass) +{ + zval *id; + xmlDoc *docp; + char *baseclass = NULL, *extendedclass = NULL; + int baseclass_len = 0, extendedclass_len = 0; + zend_class_entry *basece = NULL, *ce = NULL; + dom_object *intern; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss!", &id, dom_document_class_entry, &baseclass, &baseclass_len, &extendedclass, &extendedclass_len) == FAILURE) { + return; + } + + if (baseclass_len) { + zend_class_entry **pce; + if (zend_lookup_class(baseclass, baseclass_len, &pce TSRMLS_CC) == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s does not exist", baseclass); + return; + } + basece = *pce; + } + + if (basece == NULL || ! instanceof_function(basece, dom_node_class_entry TSRMLS_CC)) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s is not derived from DOMNode.", baseclass); + return; + } + + if (extendedclass_len) { + zend_class_entry **pce; + if (zend_lookup_class(extendedclass, extendedclass_len, &pce TSRMLS_CC) == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s does not exist", extendedclass); + } + ce = *pce; + } + + if (ce == NULL || instanceof_function(ce, basece TSRMLS_CC)) { + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + + if (dom_set_doc_classmap(intern->document, basece, ce TSRMLS_CC) == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s could not be registered.", extendedclass); + } + RETURN_TRUE; + } else { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s is not derived from %s.", extendedclass, baseclass); + } + + RETURN_FALSE; +} +/* }}} */ + +#endif /* HAVE_LIBXML && HAVE_DOM */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/documentfragment.c b/ext/dom/documentfragment.c new file mode 100644 index 0000000..4e8d660 --- /dev/null +++ b/ext/dom/documentfragment.c @@ -0,0 +1,168 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_documentfragement_construct, 0, 0, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_documentfragement_appendXML, 0, 0, 1) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class DOMDocumentFragment extends DOMNode +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-B63ED1A3 +* Since: +*/ + +const zend_function_entry php_dom_documentfragment_class_functions[] = { + PHP_ME(domdocumentfragment, __construct, arginfo_dom_documentfragement_construct, ZEND_ACC_PUBLIC) + PHP_ME(domdocumentfragment, appendXML, arginfo_dom_documentfragement_appendXML, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +/* {{{ proto void DOMDocumentFragment::__construct(); */ +PHP_METHOD(domdocumentfragment, __construct) +{ + + zval *id; + xmlNodePtr nodep = NULL, oldnode = NULL; + dom_object *intern; + zend_error_handling error_handling; + + zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC); + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_documentfragment_class_entry) == FAILURE) { + zend_restore_error_handling(&error_handling TSRMLS_CC); + return; + } + + zend_restore_error_handling(&error_handling TSRMLS_CC); + nodep = xmlNewDocFragment(NULL); + + if (!nodep) { + php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC); + RETURN_FALSE; + } + + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + if (intern != NULL) { + oldnode = dom_object_get_node(intern); + if (oldnode != NULL) { + php_libxml_node_free_resource(oldnode TSRMLS_CC); + } + /* php_dom_set_object(intern, nodep TSRMLS_CC); */ + php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC); + } +} +/* }}} end DOMDocumentFragment::__construct */ + +/* php_dom_xmlSetTreeDoc is a custom implementation of xmlSetTreeDoc + needed for hack in appendXML due to libxml bug - no need to share this function */ +static void php_dom_xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr doc) /* {{{ */ +{ + xmlAttrPtr prop; + xmlNodePtr cur; + + if (tree) { + if(tree->type == XML_ELEMENT_NODE) { + prop = tree->properties; + while (prop != NULL) { + prop->doc = doc; + if (prop->children) { + cur = prop->children; + while (cur != NULL) { + php_dom_xmlSetTreeDoc(cur, doc); + cur = cur->next; + } + } + prop = prop->next; + } + } + if (tree->children != NULL) { + cur = tree->children; + while (cur != NULL) { + php_dom_xmlSetTreeDoc(cur, doc); + cur = cur->next; + } + } + tree->doc = doc; + } +} +/* }}} */ + +/* {{{ proto void DOMDocumentFragment::appendXML(string data); */ +PHP_METHOD(domdocumentfragment, appendXML) { + zval *id; + xmlNode *nodep; + dom_object *intern; + char *data = NULL; + int data_len = 0; + int err; + xmlNodePtr lst; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_documentfragment_class_entry, &data, &data_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + if (dom_node_is_read_only(nodep) == SUCCESS) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + if (data) { + err = xmlParseBalancedChunkMemory(nodep->doc, NULL, NULL, 0, data, &lst); + if (err != 0) { + RETURN_FALSE; + } + /* Following needed due to bug in libxml2 <= 2.6.14 + ifdef after next libxml release as bug is fixed in their cvs */ + php_dom_xmlSetTreeDoc(lst, nodep->doc); + /* End stupid hack */ + + xmlAddChildList(nodep,lst); + } + + RETURN_TRUE; +} +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/documenttype.c b/ext/dom/documenttype.c new file mode 100644 index 0000000..570999a --- /dev/null +++ b/ext/dom/documenttype.c @@ -0,0 +1,235 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + +/* +* class DOMDocumentType extends DOMNode +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-412266927 +* Since: +*/ + +const zend_function_entry php_dom_documenttype_class_functions[] = { + PHP_FE_END +}; + +/* {{{ name string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1844763134 +Since: +*/ +int dom_documenttype_name_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlDtdPtr dtdptr; + + dtdptr = (xmlDtdPtr) dom_object_get_node(obj); + + if (dtdptr == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + ZVAL_STRING(*retval, (char *) (dtdptr->name), 1); + + return SUCCESS; +} + +/* }}} */ + +/* {{{ entities DOMNamedNodeMap +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1788794630 +Since: +*/ +int dom_documenttype_entities_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlDtdPtr doctypep; + xmlHashTable *entityht; + dom_object *intern; + + doctypep = (xmlDtdPtr) dom_object_get_node(obj); + + if (doctypep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + MAKE_STD_ZVAL(*retval); + php_dom_create_interator(*retval, DOM_NAMEDNODEMAP TSRMLS_CC); + + entityht = (xmlHashTable *) doctypep->entities; + + intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC); + dom_namednode_iter(obj, XML_ENTITY_NODE, intern, entityht, NULL, NULL TSRMLS_CC); + + return SUCCESS; +} + +/* }}} */ + +/* {{{ notations DOMNamedNodeMap +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D46829EF +Since: +*/ +int dom_documenttype_notations_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlDtdPtr doctypep; + xmlHashTable *notationht; + dom_object *intern; + + doctypep = (xmlDtdPtr) dom_object_get_node(obj); + + if (doctypep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + MAKE_STD_ZVAL(*retval); + php_dom_create_interator(*retval, DOM_NAMEDNODEMAP TSRMLS_CC); + + notationht = (xmlHashTable *) doctypep->notations; + + intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC); + dom_namednode_iter(obj, XML_NOTATION_NODE, intern, notationht, NULL, NULL TSRMLS_CC); + + return SUCCESS; +} + +/* }}} */ + +/* {{{ publicId string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-Core-DocType-publicId +Since: DOM Level 2 +*/ +int dom_documenttype_public_id_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlDtdPtr dtdptr; + + dtdptr = (xmlDtdPtr) dom_object_get_node(obj); + + if (dtdptr == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + if (dtdptr->ExternalID) { + ZVAL_STRING(*retval, (char *) (dtdptr->ExternalID), 1); + } else { + ZVAL_EMPTY_STRING(*retval); + } + return SUCCESS; + +} + +/* }}} */ + +/* {{{ systemId string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-Core-DocType-systemId +Since: DOM Level 2 +*/ +int dom_documenttype_system_id_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlDtdPtr dtdptr; + + dtdptr = (xmlDtdPtr) dom_object_get_node(obj); + + if (dtdptr == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + if (dtdptr->SystemID) { + ZVAL_STRING(*retval, (char *) (dtdptr->SystemID), 1); + } else { + ZVAL_EMPTY_STRING(*retval); + } + return SUCCESS; +} + +/* }}} */ + +/* {{{ internalSubset string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-Core-DocType-internalSubset +Since: DOM Level 2 +*/ +int dom_documenttype_internal_subset_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + + xmlDtdPtr dtdptr; + xmlDtd *intsubset; + xmlOutputBuffer *buff = NULL; + + dtdptr = (xmlDtdPtr) dom_object_get_node(obj); + + if (dtdptr == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + if (dtdptr->doc != NULL && ((intsubset = dtdptr->doc->intSubset) != NULL)) { + buff = xmlAllocOutputBuffer(NULL); + if (buff != NULL) { + xmlNodeDumpOutput (buff, NULL, (xmlNodePtr) intsubset, 0, 0, NULL); + xmlOutputBufferFlush(buff); +#ifdef LIBXML2_NEW_BUFFER + ZVAL_STRINGL(*retval, xmlOutputBufferGetContent(buff), xmlOutputBufferGetSize(buff), 1); +#else + ZVAL_STRINGL(*retval, buff->buffer->content, buff->buffer->use, 1); +#endif + (void)xmlOutputBufferClose(buff); + return SUCCESS; + } + } + + ZVAL_EMPTY_STRING(*retval); + + return SUCCESS; + +} + +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/dom.dsp b/ext/dom/dom.dsp new file mode 100644 index 0000000..f2ae5b1 --- /dev/null +++ b/ext/dom/dom.dsp @@ -0,0 +1,250 @@ +# Microsoft Developer Studio Project File - Name="dom" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=dom - Win32 Release_TS
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "dom.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "dom.mak" CFG="dom - Win32 Release_TS"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "dom - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "dom - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "dom - Win32 Release_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release_TS"
+# PROP BASE Intermediate_Dir "Release_TS"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_TS"
+# PROP Intermediate_Dir "Release_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\..\Zend" /I "..\..\..\TSRM" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_DOM" /D ZTS=1 /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /D ZEND_DEBUG=0 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DOM_EXPORTS" /D "COMPILE_DL_DOM" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_DOM=1 /D "LIBXML_THREAD_ENABLED" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x406 /d "NDEBUG"
+# ADD RSC /l 0x406 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5ts.lib /nologo /dll /machine:I386
+# ADD LINK32 wsock32.lib php5ts.lib resolv.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:yes /machine:I386 /out:"..\..\Release_TS/php_dom.dll" /implib:"..\..\Release_TS/php_dom.lib" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline" /libpath:"..\..\..\bindlib_w32\Release"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "dom - Win32 Debug_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Debug_TS"
+# PROP BASE Intermediate_Dir "Debug_TS"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Debug_TS"
+# PROP Intermediate_Dir "Debug_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "mssql-70" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_DOM" /D ZTS=1 /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DOM_EXPORTS" /D "COMPILE_DL_DOM" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_DOM=1 /D LIBXML_THREAD_ENABLED=1 /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x406 /d "NDEBUG"
+# ADD RSC /l 0x406 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5ts.lib /nologo /dll /machine:I386
+# ADD LINK32 php5ts_debug.lib ws2_32.lib resolv.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:yes /debug /machine:I386 /nodefaultlib:"msvcrt" /out:"..\..\Debug_TS\php_dom.dll" /implib:"..\..\Debug_TS/php_dom.lib" /libpath:"..\..\Debug_TS" /libpath:"..\..\..\bindlib_w32\Release"
+
+!ENDIF
+
+# Begin Target
+
+# Name "dom - Win32 Release_TS"
+# Name "dom - Win32 Debug_TS"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\attr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\cdatasection.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\characterdata.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\comment.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\document.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\documentfragment.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\documenttype.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\domconfiguration.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\domerror.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\domerrorhandler.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\domexception.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\domimplementation.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\domimplementationlist.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\domimplementationsource.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\domlocator.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\domstringlist.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\element.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\entity.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\entityreference.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\namednodemap.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\namelist.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\node.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\nodelist.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\notation.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\php_dom.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\processinginstruction.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\string_extend.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\text.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\typeinfo.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\userdatahandler.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\xpath.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\dom_ce.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\dom_fe.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\dom_properties.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\php_dom.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\xml_common.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/ext/dom/dom_ce.h b/ext/dom/dom_ce.h new file mode 100644 index 0000000..8caf002 --- /dev/null +++ b/ext/dom/dom_ce.h @@ -0,0 +1,66 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ +#ifndef DOM_CE_H +#define DOM_CE_H + +extern zend_class_entry *dom_domexception_class_entry; +extern zend_class_entry *dom_domstringlist_class_entry; +extern zend_class_entry *dom_namelist_class_entry; +extern zend_class_entry *dom_domimplementationlist_class_entry; +extern zend_class_entry *dom_domimplementationsource_class_entry; +extern zend_class_entry *dom_domimplementation_class_entry; +extern zend_class_entry *dom_documentfragment_class_entry; +extern zend_class_entry *dom_document_class_entry; +extern zend_class_entry *dom_nodelist_class_entry; +extern zend_class_entry *dom_namednodemap_class_entry; +extern zend_class_entry *dom_characterdata_class_entry; +extern zend_class_entry *dom_attr_class_entry; +extern zend_class_entry *dom_element_class_entry; +extern zend_class_entry *dom_text_class_entry; +extern zend_class_entry *dom_comment_class_entry; +extern zend_class_entry *dom_typeinfo_class_entry; +extern zend_class_entry *dom_userdatahandler_class_entry; +extern zend_class_entry *dom_domerror_class_entry; +extern zend_class_entry *dom_domerrorhandler_class_entry; +extern zend_class_entry *dom_domlocator_class_entry; +extern zend_class_entry *dom_domconfiguration_class_entry; +extern zend_class_entry *dom_cdatasection_class_entry; +extern zend_class_entry *dom_documenttype_class_entry; +extern zend_class_entry *dom_notation_class_entry; +extern zend_class_entry *dom_entity_class_entry; +extern zend_class_entry *dom_entityreference_class_entry; +extern zend_class_entry *dom_processinginstruction_class_entry; +extern zend_class_entry *dom_string_extend_class_entry; +#if defined(LIBXML_XPATH_ENABLED) +extern zend_class_entry *dom_xpath_class_entry; +#endif +extern zend_class_entry *dom_namespace_node_class_entry; + +#endif /* DOM_CE_H */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/dom_fe.h b/ext/dom/dom_fe.h new file mode 100644 index 0000000..3778c95 --- /dev/null +++ b/ext/dom/dom_fe.h @@ -0,0 +1,280 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ +#ifndef DOM_FE_H +#define DOM_FE_H + +extern const zend_function_entry php_dom_domexception_class_functions[]; +extern const zend_function_entry php_dom_domstringlist_class_functions[]; +extern const zend_function_entry php_dom_namelist_class_functions[]; +extern const zend_function_entry php_dom_domimplementationlist_class_functions[]; +extern const zend_function_entry php_dom_domimplementationsource_class_functions[]; +extern const zend_function_entry php_dom_domimplementation_class_functions[]; +extern const zend_function_entry php_dom_documentfragment_class_functions[]; +extern const zend_function_entry php_dom_document_class_functions[]; +extern const zend_function_entry php_dom_node_class_functions[]; +extern const zend_function_entry php_dom_nodelist_class_functions[]; +extern const zend_function_entry php_dom_namednodemap_class_functions[]; +extern const zend_function_entry php_dom_characterdata_class_functions[]; +extern const zend_function_entry php_dom_attr_class_functions[]; +extern const zend_function_entry php_dom_element_class_functions[]; +extern const zend_function_entry php_dom_text_class_functions[]; +extern const zend_function_entry php_dom_comment_class_functions[]; +extern const zend_function_entry php_dom_typeinfo_class_functions[]; +extern const zend_function_entry php_dom_userdatahandler_class_functions[]; +extern const zend_function_entry php_dom_domerror_class_functions[]; +extern const zend_function_entry php_dom_domerrorhandler_class_functions[]; +extern const zend_function_entry php_dom_domlocator_class_functions[]; +extern const zend_function_entry php_dom_domconfiguration_class_functions[]; +extern const zend_function_entry php_dom_cdatasection_class_functions[]; +extern const zend_function_entry php_dom_documenttype_class_functions[]; +extern const zend_function_entry php_dom_notation_class_functions[]; +extern const zend_function_entry php_dom_entity_class_functions[]; +extern const zend_function_entry php_dom_entityreference_class_functions[]; +extern const zend_function_entry php_dom_processinginstruction_class_functions[]; +extern const zend_function_entry php_dom_string_extend_class_functions[]; +extern const zend_function_entry php_dom_xpath_class_functions[]; + +/* domexception errors */ +typedef enum { +/* PHP_ERR is non-spec code for PHP errors: */ + PHP_ERR = 0, + INDEX_SIZE_ERR = 1, + DOMSTRING_SIZE_ERR = 2, + HIERARCHY_REQUEST_ERR = 3, + WRONG_DOCUMENT_ERR = 4, + INVALID_CHARACTER_ERR = 5, + NO_DATA_ALLOWED_ERR = 6, + NO_MODIFICATION_ALLOWED_ERR = 7, + NOT_FOUND_ERR = 8, + NOT_SUPPORTED_ERR = 9, + INUSE_ATTRIBUTE_ERR = 10, +/* Introduced in DOM Level 2: */ + INVALID_STATE_ERR = 11, +/* Introduced in DOM Level 2: */ + SYNTAX_ERR = 12, +/* Introduced in DOM Level 2: */ + INVALID_MODIFICATION_ERR = 13, +/* Introduced in DOM Level 2: */ + NAMESPACE_ERR = 14, +/* Introduced in DOM Level 2: */ + INVALID_ACCESS_ERR = 15, +/* Introduced in DOM Level 3: */ + VALIDATION_ERR = 16 +} dom_exception_code; + +/* domstringlist methods */ +PHP_FUNCTION(dom_domstringlist_item); + +/* domnamelist methods */ +PHP_FUNCTION(dom_namelist_get_name); +PHP_FUNCTION(dom_namelist_get_namespace_uri); + +/* domimplementationlist methods */ +PHP_FUNCTION(dom_domimplementationlist_item); + +/* domimplementationsource methods */ +PHP_FUNCTION(dom_domimplementationsource_get_domimplementation); +PHP_FUNCTION(dom_domimplementationsource_get_domimplementations); + +/* domimplementation methods */ +PHP_METHOD(domimplementation, hasFeature); +PHP_METHOD(domimplementation, createDocumentType); +PHP_METHOD(domimplementation, createDocument); +PHP_METHOD(domimplementation, getFeature); + +/* domdocumentfragment methods */ +PHP_METHOD(domdocumentfragment, __construct); +PHP_METHOD(domdocumentfragment, appendXML); + +/* domdocument methods */ +PHP_FUNCTION(dom_document_create_element); +PHP_FUNCTION(dom_document_create_document_fragment); +PHP_FUNCTION(dom_document_create_text_node); +PHP_FUNCTION(dom_document_create_comment); +PHP_FUNCTION(dom_document_create_cdatasection); +PHP_FUNCTION(dom_document_create_processing_instruction); +PHP_FUNCTION(dom_document_create_attribute); +PHP_FUNCTION(dom_document_create_entity_reference); +PHP_FUNCTION(dom_document_get_elements_by_tag_name); +PHP_FUNCTION(dom_document_import_node); +PHP_FUNCTION(dom_document_create_element_ns); +PHP_FUNCTION(dom_document_create_attribute_ns); +PHP_FUNCTION(dom_document_get_elements_by_tag_name_ns); +PHP_FUNCTION(dom_document_get_element_by_id); +PHP_FUNCTION(dom_document_adopt_node); +PHP_FUNCTION(dom_document_normalize_document); +PHP_FUNCTION(dom_document_rename_node); +PHP_METHOD(domdocument, __construct); + /* convienience methods */ +PHP_METHOD(domdocument, load); +PHP_FUNCTION(dom_document_save); +PHP_METHOD(domdocument, loadXML); +PHP_FUNCTION(dom_document_savexml); +PHP_FUNCTION(dom_document_validate); +PHP_FUNCTION(dom_document_xinclude); +PHP_METHOD(domdocument, registerNodeClass); + +#if defined(LIBXML_HTML_ENABLED) +PHP_METHOD(domdocument, loadHTML); +PHP_METHOD(domdocument, loadHTMLFile); +PHP_FUNCTION(dom_document_save_html); +PHP_FUNCTION(dom_document_save_html_file); +#endif /* defined(LIBXML_HTML_ENABLED) */ + +#if defined(LIBXML_SCHEMAS_ENABLED) +PHP_FUNCTION(dom_document_schema_validate_file); +PHP_FUNCTION(dom_document_schema_validate_xml); +PHP_FUNCTION(dom_document_relaxNG_validate_file); +PHP_FUNCTION(dom_document_relaxNG_validate_xml); +#endif + +/* domnode methods */ +PHP_FUNCTION(dom_node_insert_before); +PHP_FUNCTION(dom_node_replace_child); +PHP_FUNCTION(dom_node_remove_child); +PHP_FUNCTION(dom_node_append_child); +PHP_FUNCTION(dom_node_has_child_nodes); +PHP_FUNCTION(dom_node_clone_node); +PHP_FUNCTION(dom_node_normalize); +PHP_FUNCTION(dom_node_is_supported); +PHP_FUNCTION(dom_node_has_attributes); +PHP_FUNCTION(dom_node_compare_document_position); +PHP_FUNCTION(dom_node_is_same_node); +PHP_FUNCTION(dom_node_lookup_prefix); +PHP_FUNCTION(dom_node_is_default_namespace); +PHP_FUNCTION(dom_node_lookup_namespace_uri); +PHP_FUNCTION(dom_node_is_equal_node); +PHP_FUNCTION(dom_node_get_feature); +PHP_FUNCTION(dom_node_set_user_data); +PHP_FUNCTION(dom_node_get_user_data); +PHP_METHOD(domnode, C14N); +PHP_METHOD(domnode, C14NFile); +PHP_METHOD(domnode, getNodePath); +PHP_METHOD(domnode, getLineNo); + +/* domnodelist methods */ +PHP_FUNCTION(dom_nodelist_item); + +/* domnamednodemap methods */ +PHP_FUNCTION(dom_namednodemap_get_named_item); +PHP_FUNCTION(dom_namednodemap_set_named_item); +PHP_FUNCTION(dom_namednodemap_remove_named_item); +PHP_FUNCTION(dom_namednodemap_item); +PHP_FUNCTION(dom_namednodemap_get_named_item_ns); +PHP_FUNCTION(dom_namednodemap_set_named_item_ns); +PHP_FUNCTION(dom_namednodemap_remove_named_item_ns); + +/* domcharacterdata methods */ +PHP_FUNCTION(dom_characterdata_substring_data); +PHP_FUNCTION(dom_characterdata_append_data); +PHP_FUNCTION(dom_characterdata_insert_data); +PHP_FUNCTION(dom_characterdata_delete_data); +PHP_FUNCTION(dom_characterdata_replace_data); + +/* domattr methods */ +PHP_FUNCTION(dom_attr_is_id); +PHP_METHOD(domattr, __construct); + +/* domelement methods */ +PHP_FUNCTION(dom_element_get_attribute); +PHP_FUNCTION(dom_element_set_attribute); +PHP_FUNCTION(dom_element_remove_attribute); +PHP_FUNCTION(dom_element_get_attribute_node); +PHP_FUNCTION(dom_element_set_attribute_node); +PHP_FUNCTION(dom_element_remove_attribute_node); +PHP_FUNCTION(dom_element_get_elements_by_tag_name); +PHP_FUNCTION(dom_element_get_attribute_ns); +PHP_FUNCTION(dom_element_set_attribute_ns); +PHP_FUNCTION(dom_element_remove_attribute_ns); +PHP_FUNCTION(dom_element_get_attribute_node_ns); +PHP_FUNCTION(dom_element_set_attribute_node_ns); +PHP_FUNCTION(dom_element_get_elements_by_tag_name_ns); +PHP_FUNCTION(dom_element_has_attribute); +PHP_FUNCTION(dom_element_has_attribute_ns); +PHP_FUNCTION(dom_element_set_id_attribute); +PHP_FUNCTION(dom_element_set_id_attribute_ns); +PHP_FUNCTION(dom_element_set_id_attribute_node); +PHP_METHOD(domelement, __construct); + +/* domtext methods */ +PHP_FUNCTION(dom_text_split_text); +PHP_FUNCTION(dom_text_is_whitespace_in_element_content); +PHP_FUNCTION(dom_text_replace_whole_text); +PHP_METHOD(domtext, __construct); + +/* domcomment methods */ +PHP_METHOD(domcomment, __construct); + +/* domtypeinfo methods */ + +/* domuserdatahandler methods */ +PHP_FUNCTION(dom_userdatahandler_handle); + +/* domdomerror methods */ + +/* domerrorhandler methods */ +PHP_FUNCTION(dom_domerrorhandler_handle_error); + +/* domlocator methods */ + +/* domconfiguration methods */ +PHP_FUNCTION(dom_domconfiguration_set_parameter); +PHP_FUNCTION(dom_domconfiguration_get_parameter); +PHP_FUNCTION(dom_domconfiguration_can_set_parameter); + +/* domcdatasection methods */ +PHP_METHOD(domcdatasection, __construct); + +/* domdocumenttype methods */ + +/* domnotation methods */ + +/* domentity methods */ + +/* domentityreference methods */ +PHP_METHOD(domentityreference, __construct); + +/* domprocessinginstruction methods */ +PHP_METHOD(domprocessinginstruction, __construct); + +/* string_extend methods */ +PHP_FUNCTION(dom_string_extend_find_offset16); +PHP_FUNCTION(dom_string_extend_find_offset32); + +#if defined(LIBXML_XPATH_ENABLED) +/* xpath methods */ +PHP_METHOD(domxpath, __construct); +PHP_FUNCTION(dom_xpath_register_ns); +PHP_FUNCTION(dom_xpath_query); +PHP_FUNCTION(dom_xpath_evaluate); +PHP_FUNCTION(dom_xpath_register_php_functions); +#endif + +#endif /* DOM_FE_H */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/dom_iterators.c b/ext/dom/dom_iterators.c new file mode 100644 index 0000000..f4183d2 --- /dev/null +++ b/ext/dom/dom_iterators.c @@ -0,0 +1,351 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" +#include "dom_ce.h" + +typedef struct _nodeIterator nodeIterator; +struct _nodeIterator { + int cur; + int index; + xmlNode *node; +}; + +typedef struct _notationIterator notationIterator; +struct _notationIterator { + int cur; + int index; + xmlNotation *notation; +}; + +static void itemHashScanner (void *payload, void *data, xmlChar *name) /* {{{ */ +{ + nodeIterator *priv = (nodeIterator *)data; + + if(priv->cur < priv->index) { + priv->cur++; + } else { + if(priv->node == NULL) { + priv->node = (xmlNode *)payload; + } + } +} +/* }}} */ + +xmlNodePtr create_notation(const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID) /* {{{ */ +{ + xmlEntityPtr ret; + + ret = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity)); + memset(ret, 0, sizeof(xmlEntity)); + ret->type = XML_NOTATION_NODE; + ret->name = xmlStrdup(name); + ret->ExternalID = xmlStrdup(ExternalID); + ret->SystemID = xmlStrdup(SystemID); + ret->length = 0; + ret->content = NULL; + ret->URI = NULL; + ret->orig = NULL; + ret->children = NULL; + ret->parent = NULL; + ret->doc = NULL; + ret->_private = NULL; + ret->last = NULL; + ret->prev = NULL; + return((xmlNodePtr) ret); +} +/* }}} */ + +xmlNode *php_dom_libxml_hash_iter(xmlHashTable *ht, int index) /* {{{ */ +{ + xmlNode *nodep = NULL; + nodeIterator *iter; + int htsize; + + if ((htsize = xmlHashSize(ht)) > 0 && index < htsize) { + iter = emalloc(sizeof(nodeIterator)); + iter->cur = 0; + iter->index = index; + iter->node = NULL; + xmlHashScan(ht, itemHashScanner, iter); + nodep = iter->node; + efree(iter); + return nodep; + } else { + return NULL; + } +} +/* }}} */ + +xmlNode *php_dom_libxml_notation_iter(xmlHashTable *ht, int index) /* {{{ */ +{ + notationIterator *iter; + xmlNotation *notep = NULL; + int htsize; + + if ((htsize = xmlHashSize(ht)) > 0 && index < htsize) { + iter = emalloc(sizeof(notationIterator)); + iter->cur = 0; + iter->index = index; + iter->notation = NULL; + xmlHashScan(ht, itemHashScanner, iter); + notep = iter->notation; + efree(iter); + return create_notation(notep->name, notep->PublicID, notep->SystemID); + } else { + return NULL; + } +} +/* }}} */ + +static void php_dom_iterator_dtor(zend_object_iterator *iter TSRMLS_DC) /* {{{ */ +{ + php_dom_iterator *iterator = (php_dom_iterator *)iter; + + zval_ptr_dtor((zval**)&iterator->intern.data); + + if (iterator->curobj) { + zval_ptr_dtor((zval**)&iterator->curobj); + } + + efree(iterator); +} +/* }}} */ + +static int php_dom_iterator_valid(zend_object_iterator *iter TSRMLS_DC) /* {{{ */ +{ + + php_dom_iterator *iterator = (php_dom_iterator *)iter; + + if (iterator->curobj) { + return SUCCESS; + } else { + return FAILURE; + } +} +/* }}} */ + +static void php_dom_iterator_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) /* {{{ */ +{ + php_dom_iterator *iterator = (php_dom_iterator *)iter; + + *data = &iterator->curobj; +} +/* }}} */ + +static int php_dom_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */ +{ + zval *curobj; + xmlNodePtr curnode = NULL; + dom_object *intern; + zval *object; + int namelen; + + php_dom_iterator *iterator = (php_dom_iterator *)iter; + + object = (zval *)iterator->intern.data; + + if (instanceof_function(Z_OBJCE_P(object), dom_nodelist_class_entry TSRMLS_CC)) { + *int_key = iter->index; + return HASH_KEY_IS_LONG; + } else { + curobj = iterator->curobj; + + intern = (dom_object *)zend_object_store_get_object(curobj TSRMLS_CC); + if (intern != NULL && intern->ptr != NULL) { + curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->ptr)->node; + } else { + return HASH_KEY_NON_EXISTANT; + } + + namelen = xmlStrlen(curnode->name); + *str_key = estrndup(curnode->name, namelen); + *str_key_len = namelen + 1; + return HASH_KEY_IS_STRING; + } +} +/* }}} */ + +static void php_dom_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC) /* {{{ */ +{ + zval *curobj, *curattr = NULL; + zval *object; + xmlNodePtr curnode = NULL, basenode; + dom_object *intern; + dom_object *nnmap; + dom_nnodemap_object *objmap; + int ret, previndex=0; + HashTable *nodeht; + zval **entry; + + php_dom_iterator *iterator = (php_dom_iterator *)iter; + + object = (zval *)iterator->intern.data; + nnmap = (dom_object *)zend_object_store_get_object(object TSRMLS_CC); + objmap = (dom_nnodemap_object *)nnmap->ptr; + + curobj = iterator->curobj; + intern = (dom_object *)zend_object_store_get_object(curobj TSRMLS_CC); + if (intern != NULL && intern->ptr != NULL) { + if (objmap->nodetype != XML_ENTITY_NODE && + objmap->nodetype != XML_NOTATION_NODE) { + if (objmap->nodetype == DOM_NODESET) { + nodeht = HASH_OF(objmap->baseobjptr); + zend_hash_move_forward(nodeht); + if (zend_hash_get_current_data(nodeht, (void **) &entry)==SUCCESS) { + curattr = *entry; + Z_ADDREF_P(curattr); + } + } else { + curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->ptr)->node; + if (objmap->nodetype == XML_ATTRIBUTE_NODE || + objmap->nodetype == XML_ELEMENT_NODE) { + curnode = curnode->next; + } else { + /* Nav the tree evey time as this is LIVE */ + basenode = dom_object_get_node(objmap->baseobj); + if (basenode && (basenode->type == XML_DOCUMENT_NODE || + basenode->type == XML_HTML_DOCUMENT_NODE)) { + basenode = xmlDocGetRootElement((xmlDoc *) basenode); + } else if (basenode) { + basenode = basenode->children; + } else { + goto err; + } + curnode = dom_get_elements_by_tag_name_ns_raw(basenode, objmap->ns, objmap->local, &previndex, iter->index); + } + } + } else { + if (objmap->nodetype == XML_ENTITY_NODE) { + curnode = php_dom_libxml_hash_iter(objmap->ht, iter->index); + } else { + curnode = php_dom_libxml_notation_iter(objmap->ht, iter->index); + } + } + } +err: + zval_ptr_dtor((zval**)&curobj); + if (curnode) { + MAKE_STD_ZVAL(curattr); + curattr = php_dom_create_object(curnode, &ret, curattr, objmap->baseobj TSRMLS_CC); + } + + iterator->curobj = curattr; +} +/* }}} */ + +zend_object_iterator_funcs php_dom_iterator_funcs = { + php_dom_iterator_dtor, + php_dom_iterator_valid, + php_dom_iterator_current_data, + php_dom_iterator_current_key, + php_dom_iterator_move_forward, + NULL +}; + +zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */ +{ + dom_object *intern; + dom_nnodemap_object *objmap; + xmlNodePtr nodep, curnode=NULL; + zval *curattr = NULL; + int ret, curindex = 0; + HashTable *nodeht; + zval **entry; + php_dom_iterator *iterator; + + if (by_ref) { + zend_error(E_ERROR, "An iterator cannot be used with foreach by reference"); + } + iterator = emalloc(sizeof(php_dom_iterator)); + + Z_ADDREF_P(object); + iterator->intern.data = (void*)object; + iterator->intern.funcs = &php_dom_iterator_funcs; + + intern = (dom_object *)zend_object_store_get_object(object TSRMLS_CC); + objmap = (dom_nnodemap_object *)intern->ptr; + if (objmap != NULL) { + if (objmap->nodetype != XML_ENTITY_NODE && + objmap->nodetype != XML_NOTATION_NODE) { + if (objmap->nodetype == DOM_NODESET) { + nodeht = HASH_OF(objmap->baseobjptr); + zend_hash_internal_pointer_reset(nodeht); + if (zend_hash_get_current_data(nodeht, (void **) &entry)==SUCCESS) { + curattr = *entry; + Z_ADDREF_P(curattr); + } + } else { + nodep = (xmlNode *)dom_object_get_node(objmap->baseobj); + if (!nodep) { + goto err; + } + if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) { + if (objmap->nodetype == XML_ATTRIBUTE_NODE) { + curnode = (xmlNodePtr) nodep->properties; + } else { + curnode = (xmlNodePtr) nodep->children; + } + } else { + if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) { + nodep = xmlDocGetRootElement((xmlDoc *) nodep); + } else { + nodep = nodep->children; + } + curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &curindex, 0); + } + } + } else { + if (objmap->nodetype == XML_ENTITY_NODE) { + curnode = php_dom_libxml_hash_iter(objmap->ht, 0); + } else { + curnode = php_dom_libxml_notation_iter(objmap->ht, 0); + } + } + } +err: + if (curnode) { + MAKE_STD_ZVAL(curattr); + curattr = php_dom_create_object(curnode, &ret, curattr, objmap->baseobj TSRMLS_CC); + } + + iterator->curobj = curattr; + + return (zend_object_iterator*)iterator; +} +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/dom_properties.h b/ext/dom/dom_properties.h new file mode 100644 index 0000000..8482502 --- /dev/null +++ b/ext/dom/dom_properties.h @@ -0,0 +1,171 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ +#ifndef DOM_PROPERTIES_H +#define DOM_PROPERTIES_H + +/* attr properties */ +int dom_attr_name_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_attr_specified_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_attr_value_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_attr_value_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_attr_owner_element_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_attr_schema_type_info_read(dom_object *obj, zval **retval TSRMLS_DC); + +/* characterdata properties */ +int dom_characterdata_data_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_characterdata_data_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_characterdata_length_read(dom_object *obj, zval **retval TSRMLS_DC); + +/* document properties */ +int dom_document_doctype_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_implementation_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_document_element_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_actual_encoding_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_actual_encoding_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_document_encoding_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_encoding_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_document_standalone_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_standalone_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_document_version_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_version_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_document_strict_error_checking_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_strict_error_checking_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_document_document_uri_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_document_uri_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_document_config_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_format_output_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_format_output_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_document_validate_on_parse_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_validate_on_parse_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_document_resolve_externals_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_resolve_externals_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_document_preserve_whitespace_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_preserve_whitespace_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_document_recover_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_recover_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_document_substitue_entities_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_substitue_entities_write(dom_object *obj, zval *newval TSRMLS_DC); + +/* documenttype properties */ +int dom_documenttype_name_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_documenttype_entities_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_documenttype_notations_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_documenttype_public_id_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_documenttype_system_id_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_documenttype_internal_subset_read(dom_object *obj, zval **retval TSRMLS_DC); + +/* domerror properties */ +int dom_domerror_severity_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_domerror_message_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_domerror_type_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_domerror_related_exception_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_domerror_related_data_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_domerror_location_read(dom_object *obj, zval **retval TSRMLS_DC); + +/* domimplementationlist properties */ +int dom_domimplementationlist_length_read(dom_object *obj, zval **retval TSRMLS_DC); + +/* domlocator properties */ +int dom_domlocator_line_number_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_domlocator_column_number_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_domlocator_offset_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_domlocator_related_node_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_domlocator_uri_read(dom_object *obj, zval **retval TSRMLS_DC); + +/* domstringlist properties */ +int dom_domstringlist_length_read(dom_object *obj, zval **retval TSRMLS_DC); + +/* element properties */ +int dom_element_tag_name_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_element_schema_type_info_read(dom_object *obj, zval **retval TSRMLS_DC); + +/* entity properties */ +int dom_entity_public_id_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_entity_system_id_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_entity_notation_name_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_entity_actual_encoding_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_entity_actual_encoding_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_entity_encoding_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_entity_encoding_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_entity_version_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_entity_version_write(dom_object *obj, zval *newval TSRMLS_DC); + +/* namednodemap properties */ +int dom_namednodemap_length_read(dom_object *obj, zval **retval TSRMLS_DC); + +/* namelist properties */ +int dom_namelist_length_read(dom_object *obj, zval **retval TSRMLS_DC); + +/* node properties */ +int dom_node_node_name_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_node_node_value_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_node_node_value_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_node_node_type_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_node_parent_node_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_node_child_nodes_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_node_first_child_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_node_last_child_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_node_previous_sibling_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_node_next_sibling_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_node_attributes_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_node_owner_document_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_node_namespace_uri_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_node_prefix_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_node_prefix_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_node_local_name_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_node_base_uri_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_node_text_content_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_node_text_content_write(dom_object *obj, zval *newval TSRMLS_DC); + +/* nodelist properties */ +int dom_nodelist_length_read(dom_object *obj, zval **retval TSRMLS_DC); + +/* notation properties */ +int dom_notation_public_id_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_notation_system_id_read(dom_object *obj, zval **retval TSRMLS_DC); + +/* processinginstruction properties */ +int dom_processinginstruction_target_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_processinginstruction_data_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_processinginstruction_data_write(dom_object *obj, zval *newval TSRMLS_DC); + +/* text properties */ +int dom_text_whole_text_read(dom_object *obj, zval **retval TSRMLS_DC); + +/* typeinfo properties */ +int dom_typeinfo_type_name_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_typeinfo_type_namespace_read(dom_object *obj, zval **retval TSRMLS_DC); + +#if defined(LIBXML_XPATH_ENABLED) +/* xpath properties */ +int dom_xpath_document_read(dom_object *obj, zval **retval TSRMLS_DC); +#endif + +#endif /* DOM_PROPERTIERS_H */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/domconfiguration.c b/ext/dom/domconfiguration.c new file mode 100644 index 0000000..4092d73 --- /dev/null +++ b/ext/dom/domconfiguration.c @@ -0,0 +1,103 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_configuration_set_parameter, 0, 0, 2) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_configuration_get_parameter, 0, 0, 0) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_configuration_can_set_parameter, 0, 0, 0) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class domdomconfiguration +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration +* Since: DOM Level 3 +*/ + +const zend_function_entry php_dom_domconfiguration_class_functions[] = { + PHP_FALIAS(setParameter, dom_domconfiguration_set_parameter, arginfo_dom_configuration_set_parameter) + PHP_FALIAS(getParameter, dom_domconfiguration_get_parameter, arginfo_dom_configuration_get_parameter) + PHP_FALIAS(canSetParameter, dom_domconfiguration_can_set_parameter, arginfo_dom_configuration_can_set_parameter) + PHP_FE_END +}; + +/* {{{ attribute protos, not implemented yet */ + +/* {{{ proto dom_void dom_domconfiguration_set_parameter(string name, domuserdata value); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration-property +Since: +*/ +PHP_FUNCTION(dom_domconfiguration_set_parameter) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_domconfiguration_set_parameter */ + +/* {{{ proto domdomuserdata dom_domconfiguration_get_parameter(string name); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration-getParameter +Since: +*/ +PHP_FUNCTION(dom_domconfiguration_get_parameter) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_domconfiguration_get_parameter */ + +/* {{{ proto boolean dom_domconfiguration_can_set_parameter(string name, domuserdata value); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration-canSetParameter +Since: +*/ +PHP_FUNCTION(dom_domconfiguration_can_set_parameter) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_domconfiguration_can_set_parameter */ + +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/domerror.c b/ext/dom/domerror.c new file mode 100644 index 0000000..92b6622 --- /dev/null +++ b/ext/dom/domerror.c @@ -0,0 +1,139 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class domerror +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ERROR-Interfaces-DOMError +* Since: DOM Level 3 +*/ + +const zend_function_entry php_dom_domerror_class_functions[] = { + PHP_FE_END +}; + +/* {{{ attribute protos, not implemented yet */ + +/* {{{ severity unsigned short +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ERROR-DOMError-severity +Since: +*/ +int dom_domerror_severity_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_STRING(*retval, "TEST", 1); + return SUCCESS; +} + +/* }}} */ + +/* {{{ message string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ERROR-DOMError-message +Since: +*/ +int dom_domerror_message_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_STRING(*retval, "TEST", 1); + return SUCCESS; +} + +/* }}} */ + +/* {{{ type string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ERROR-DOMError-type +Since: +*/ +int dom_domerror_type_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_STRING(*retval, "TEST", 1); + return SUCCESS; +} + +/* }}} */ + +/* {{{ relatedException object +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ERROR-DOMError-relatedException +Since: +*/ +int dom_domerror_related_exception_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_STRING(*retval, "TEST", 1); + return SUCCESS; +} + +/* }}} */ + +/* {{{ relatedData domobject +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ERROR-DOMError-relatedData +Since: +*/ +int dom_domerror_related_data_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_STRING(*retval, "TEST", 1); + return SUCCESS; +} + +/* }}} */ + +/* {{{ location domlocator +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ERROR-DOMError-location +Since: +*/ +int dom_domerror_location_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_STRING(*retval, "TEST", 1); + return SUCCESS; +} + +/* }}} */ + +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/domerrorhandler.c b/ext/dom/domerrorhandler.c new file mode 100644 index 0000000..7af3723 --- /dev/null +++ b/ext/dom/domerrorhandler.c @@ -0,0 +1,71 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_domerrorhandler_handle_error, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, error, DOMDomError, 0) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class domerrorhandler +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ERROR-Interfaces-DOMErrorHandler +* Since: DOM Level 3 +*/ + +const zend_function_entry php_dom_domerrorhandler_class_functions[] = { + PHP_FALIAS(handleError, dom_domerrorhandler_handle_error, arginfo_dom_domerrorhandler_handle_error) + PHP_FE_END +}; + +/* {{{ attribute protos, not implemented yet */ + +/* {{{ proto dom_boolean dom_domerrorhandler_handle_error(domerror error); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-ERRORS-DOMErrorHandler-handleError +Since: +*/ +PHP_FUNCTION(dom_domerrorhandler_handle_error) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_domerrorhandler_handle_error */ + +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/domexception.c b/ext/dom/domexception.c new file mode 100644 index 0000000..9aa878a --- /dev/null +++ b/ext/dom/domexception.c @@ -0,0 +1,125 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + +/* +* class DOMException +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-17189187 +* Since: +*/ + +extern zend_class_entry *dom_domexception_class_entry; + +const zend_function_entry php_dom_domexception_class_functions[] = { + PHP_FE_END +}; + +void php_dom_throw_error_with_message(int error_code, char *error_message, int strict_error TSRMLS_DC) /* {{{ */ +{ + if (strict_error == 1) { + zend_throw_exception(dom_domexception_class_entry, error_message, error_code TSRMLS_CC); + } else { + php_libxml_issue_error(E_WARNING, error_message TSRMLS_CC); + } +} +/* }}} */ + +/* {{{ php_dom_throw_error */ +void php_dom_throw_error(int error_code, int strict_error TSRMLS_DC) +{ + char *error_message; + + switch (error_code) + { + case INDEX_SIZE_ERR: + error_message = "Index Size Error"; + break; + case DOMSTRING_SIZE_ERR: + error_message = "DOM String Size Error"; + break; + case HIERARCHY_REQUEST_ERR: + error_message = "Hierarchy Request Error"; + break; + case WRONG_DOCUMENT_ERR: + error_message = "Wrong Document Error"; + break; + case INVALID_CHARACTER_ERR: + error_message = "Invalid Character Error"; + break; + case NO_DATA_ALLOWED_ERR: + error_message = "No Data Allowed Error"; + break; + case NO_MODIFICATION_ALLOWED_ERR: + error_message = "No Modification Allowed Error"; + break; + case NOT_FOUND_ERR: + error_message = "Not Found Error"; + break; + case NOT_SUPPORTED_ERR: + error_message = "Not Supported Error"; + break; + case INUSE_ATTRIBUTE_ERR: + error_message = "Inuse Attribute Error"; + break; + case INVALID_STATE_ERR: + error_message = "Invalid State Error"; + break; + case SYNTAX_ERR: + error_message = "Syntax Error"; + break; + case INVALID_MODIFICATION_ERR: + error_message = "Invalid Modification Error"; + break; + case NAMESPACE_ERR: + error_message = "Namespace Error"; + break; + case INVALID_ACCESS_ERR: + error_message = "Invalid Access Error"; + break; + case VALIDATION_ERR: + error_message = "Validation Error"; + break; + default: + error_message = "Unhandled Error"; + } + + php_dom_throw_error_with_message(error_code, error_message, strict_error TSRMLS_CC); +} +/* }}} end php_dom_throw_error */ + +#endif /* HAVE_LIBXML && HAVE_DOM */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/domimplementation.c b/ext/dom/domimplementation.c new file mode 100644 index 0000000..5a32c60 --- /dev/null +++ b/ext/dom/domimplementation.c @@ -0,0 +1,268 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementation_get_feature, 0, 0, 2) + ZEND_ARG_INFO(0, feature) + ZEND_ARG_INFO(0, version) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementation_has_feature, 0, 0, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementation_create_documenttype, 0, 0, 3) + ZEND_ARG_INFO(0, qualifiedName) + ZEND_ARG_INFO(0, publicId) + ZEND_ARG_INFO(0, systemId) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementation_create_document, 0, 0, 3) + ZEND_ARG_INFO(0, namespaceURI) + ZEND_ARG_INFO(0, qualifiedName) + ZEND_ARG_OBJ_INFO(0, docType, DOMDocumentType, 0) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class DOMImplementation +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-102161490 +* Since: +*/ + +const zend_function_entry php_dom_domimplementation_class_functions[] = { + PHP_ME(domimplementation, getFeature, arginfo_dom_implementation_get_feature, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC) + PHP_ME(domimplementation, hasFeature, arginfo_dom_implementation_has_feature, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC) + PHP_ME(domimplementation, createDocumentType, arginfo_dom_implementation_create_documenttype, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC) + PHP_ME(domimplementation, createDocument, arginfo_dom_implementation_create_document, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC) + PHP_FE_END +}; + +/* {{{ proto boolean dom_domimplementation_has_feature(string feature, string version); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-5CED94D7 +Since: +*/ +PHP_METHOD(domimplementation, hasFeature) +{ + int feature_len, version_len; + char *feature, *version; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &feature, &feature_len, &version, &version_len) == FAILURE) { + return; + } + + if (dom_has_feature(feature, version)) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} end dom_domimplementation_has_feature */ + +/* {{{ proto DOMDocumentType dom_domimplementation_create_document_type(string qualifiedName, string publicId, string systemId); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocType +Since: DOM Level 2 +*/ +PHP_METHOD(domimplementation, createDocumentType) +{ + xmlDtd *doctype; + int ret, name_len = 0, publicid_len = 0, systemid_len = 0; + char *name = NULL, *publicid = NULL, *systemid = NULL; + xmlChar *pch1 = NULL, *pch2 = NULL, *localname = NULL; + xmlURIPtr uri; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sss", &name, &name_len, &publicid, &publicid_len, &systemid, &systemid_len) == FAILURE) { + return; + } + + if (name_len == 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "qualifiedName is required"); + RETURN_FALSE; + } + + if (publicid_len > 0) + pch1 = publicid; + if (systemid_len > 0) + pch2 = systemid; + + uri = xmlParseURI(name); + if (uri != NULL && uri->opaque != NULL) { + localname = xmlStrdup(uri->opaque); + if (xmlStrchr(localname, (xmlChar) ':') != NULL) { + php_dom_throw_error(NAMESPACE_ERR, 1 TSRMLS_CC); + xmlFreeURI(uri); + xmlFree(localname); + RETURN_FALSE; + } + } else { + localname = xmlStrdup(name); + } + + /* TODO: Test that localname has no invalid chars + php_dom_throw_error(INVALID_CHARACTER_ERR, TSRMLS_CC); + */ + + if (uri) { + xmlFreeURI(uri); + } + + doctype = xmlCreateIntSubset(NULL, localname, pch1, pch2); + xmlFree(localname); + + if (doctype == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create DocumentType"); + RETURN_FALSE; + } + + DOM_RET_OBJ((xmlNodePtr) doctype, &ret, NULL); +} +/* }}} end dom_domimplementation_create_document_type */ + +/* {{{ proto DOMDocument dom_domimplementation_create_document(string namespaceURI, string qualifiedName, DOMDocumentType doctype); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocument +Since: DOM Level 2 +*/ +PHP_METHOD(domimplementation, createDocument) +{ + zval *node = NULL; + xmlDoc *docp; + xmlNode *nodep; + xmlDtdPtr doctype = NULL; + xmlNsPtr nsptr = NULL; + int ret, uri_len = 0, name_len = 0, errorcode = 0; + char *uri = NULL, *name = NULL; + char *prefix = NULL, *localname = NULL; + dom_object *doctobj; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ssO", &uri, &uri_len, &name, &name_len, &node, dom_documenttype_class_entry) == FAILURE) { + return; + } + + if (node != NULL) { + DOM_GET_OBJ(doctype, node, xmlDtdPtr, doctobj); + if (doctype->type == XML_DOCUMENT_TYPE_NODE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid DocumentType object"); + RETURN_FALSE; + } + if (doctype->doc != NULL) { + php_dom_throw_error(WRONG_DOCUMENT_ERR, 1 TSRMLS_CC); + RETURN_FALSE; + } + } else { + doctobj = NULL; + } + + if (name_len > 0) { + errorcode = dom_check_qname(name, &localname, &prefix, 1, name_len); + if (errorcode == 0 && uri_len > 0 && ((nsptr = xmlNewNs(NULL, uri, prefix)) == NULL)) { + errorcode = NAMESPACE_ERR; + } + } + + if (prefix != NULL) { + xmlFree(prefix); + } + + if (errorcode != 0) { + if (localname != NULL) { + xmlFree(localname); + } + php_dom_throw_error(errorcode, 1 TSRMLS_CC); + RETURN_FALSE; + } + + /* currently letting libxml2 set the version string */ + docp = xmlNewDoc(NULL); + if (!docp) { + if (localname != NULL) { + xmlFree(localname); + } + RETURN_FALSE; + } + + if (doctype != NULL) { + docp->intSubset = doctype; + doctype->parent = docp; + doctype->doc = docp; + docp->children = (xmlNodePtr) doctype; + docp->last = (xmlNodePtr) doctype; + } + + if (localname != NULL) { + nodep = xmlNewDocNode (docp, nsptr, localname, NULL); + if (!nodep) { + if (doctype != NULL) { + docp->intSubset = NULL; + doctype->parent = NULL; + doctype->doc = NULL; + docp->children = NULL; + docp->last = NULL; + } + xmlFreeDoc(docp); + xmlFree(localname); + /* Need some type of error here */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unexpected Error"); + RETURN_FALSE; + } + + nodep->nsDef = nsptr; + + xmlDocSetRootElement(docp, nodep); + xmlFree(localname); + } + + DOM_RET_OBJ((xmlNodePtr) docp, &ret, NULL); + + if (doctobj != NULL) { + doctobj->document = ((dom_object *)((php_libxml_node_ptr *)docp->_private)->_private)->document; + php_libxml_increment_doc_ref((php_libxml_node_object *)doctobj, docp TSRMLS_CC); + } +} +/* }}} end dom_domimplementation_create_document */ + +/* {{{ proto DOMNode dom_domimplementation_get_feature(string feature, string version); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementation3-getFeature +Since: DOM Level 3 +*/ +PHP_METHOD(domimplementation, getFeature) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_domimplementation_get_feature */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/domimplementationlist.c b/ext/dom/domimplementationlist.c new file mode 100644 index 0000000..d89d2ff --- /dev/null +++ b/ext/dom/domimplementationlist.c @@ -0,0 +1,85 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementationlist_item, 0, 0, 1) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class domimplementationlist +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementationList +* Since: DOM Level 3 +*/ + +const zend_function_entry php_dom_domimplementationlist_class_functions[] = { + PHP_FALIAS(item, dom_domimplementationlist_item, arginfo_dom_implementationlist_item) + {NULL, NULL, NULL} +}; + +/* {{{ attribute protos, not implemented yet */ + +/* {{{ length unsigned long +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementationList-length +Since: +*/ +int dom_domimplementationlist_length_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_STRING(*retval, "TEST", 1); + return SUCCESS; +} + +/* }}} */ + +/* {{{ proto domdomimplementation dom_domimplementationlist_item(int index); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementationList-item +Since: +*/ +PHP_FUNCTION(dom_domimplementationlist_item) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_domimplementationlist_item */ + +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/domimplementationsource.c b/ext/dom/domimplementationsource.c new file mode 100644 index 0000000..2fb5887 --- /dev/null +++ b/ext/dom/domimplementationsource.c @@ -0,0 +1,87 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementationsource_getdomimplementation, 0, 0, 1) + ZEND_ARG_INFO(0, features) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementationsource_getdomimplementations, 0, 0, 1) + ZEND_ARG_INFO(0, features) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class domimplementationsource +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementationSource +* Since: DOM Level 3 +*/ + +const zend_function_entry php_dom_domimplementationsource_class_functions[] = { + PHP_FALIAS(getDomimplementation, dom_domimplementationsource_get_domimplementation, arginfo_dom_implementationsource_getdomimplementation) + PHP_FALIAS(getDomimplementations, dom_domimplementationsource_get_domimplementations, arginfo_dom_implementationsource_getdomimplementations) + PHP_FE_END +}; + +/* {{{ attribute protos, not implemented yet */ + +/* {{{ proto domdomimplementation dom_domimplementationsource_get_domimplementation(string features); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-getDOMImpl +Since: +*/ +PHP_FUNCTION(dom_domimplementationsource_get_domimplementation) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_domimplementationsource_get_domimplementation */ + +/* {{{ proto domimplementationlist dom_domimplementationsource_get_domimplementations(string features); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-getDOMImpls +Since: +*/ +PHP_FUNCTION(dom_domimplementationsource_get_domimplementations) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_domimplementationsource_get_domimplementations */ + +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/domlocator.c b/ext/dom/domlocator.c new file mode 100644 index 0000000..88c352b --- /dev/null +++ b/ext/dom/domlocator.c @@ -0,0 +1,125 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class domlocator +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Interfaces-DOMLocator +* Since: DOM Level 3 +*/ + +const zend_function_entry php_dom_domlocator_class_functions[] = { + PHP_FE_END +}; + +/* {{{ attribute protos, not implemented yet */ + +/* {{{ line_number long +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMLocator-line-number +Since: +*/ +int dom_domlocator_line_number_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_STRING(*retval, "TEST", 1); + return SUCCESS; +} + +/* }}} */ + +/* {{{ column_number long +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMLocator-column-number +Since: +*/ +int dom_domlocator_column_number_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_STRING(*retval, "TEST", 1); + return SUCCESS; +} + +/* }}} */ + +/* {{{ offset long +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMLocator-offset +Since: +*/ +int dom_domlocator_offset_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_STRING(*retval, "TEST", 1); + return SUCCESS; +} + +/* }}} */ + +/* {{{ related_node node +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMLocator-node +Since: +*/ +int dom_domlocator_related_node_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_STRING(*retval, "TEST", 1); + return SUCCESS; +} + +/* }}} */ + +/* {{{ uri string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMLocator-uri +Since: +*/ +int dom_domlocator_uri_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_STRING(*retval, "TEST", 1); + return SUCCESS; +} + +/* }}} */ + +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/domstringlist.c b/ext/dom/domstringlist.c new file mode 100644 index 0000000..d2ab606 --- /dev/null +++ b/ext/dom/domstringlist.c @@ -0,0 +1,85 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_stringlist_item, 0, 0, 1) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class domstringlist +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMStringList +* Since: DOM Level 3 +*/ + +const zend_function_entry php_dom_domstringlist_class_functions[] = { + PHP_FALIAS(item, dom_domstringlist_item, arginfo_dom_stringlist_item) + PHP_FE_END +}; + +/* {{{ attribute protos, not implemented yet */ + +/* {{{ length unsigned long +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMStringList-length +Since: +*/ +int dom_domstringlist_length_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_STRING(*retval, "TEST", 1); + return SUCCESS; +} + +/* }}} */ + +/* {{{ proto domstring dom_domstringlist_item(int index); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMStringList-item +Since: +*/ +PHP_FUNCTION(dom_domstringlist_item) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_domstringlist_item */ + +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/element.c b/ext/dom/element.c new file mode 100644 index 0000000..f217ca2 --- /dev/null +++ b/ext/dom/element.c @@ -0,0 +1,1254 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_attribute, 0, 0, 1) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_attribute, 0, 0, 2) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_remove_attribute, 0, 0, 1) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_attribute_node, 0, 0, 1) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_attribute_node, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, newAttr, DOMAttr, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_remove_attribute_node, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, oldAttr, DOMAttr, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_elements_by_tag_name, 0, 0, 1) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_attribute_ns, 0, 0, 2) + ZEND_ARG_INFO(0, namespaceURI) + ZEND_ARG_INFO(0, localName) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_attribute_ns, 0, 0, 3) + ZEND_ARG_INFO(0, namespaceURI) + ZEND_ARG_INFO(0, qualifiedName) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_remove_attribute_ns, 0, 0, 2) + ZEND_ARG_INFO(0, namespaceURI) + ZEND_ARG_INFO(0, localName) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_attribute_node_ns, 0, 0, 2) + ZEND_ARG_INFO(0, namespaceURI) + ZEND_ARG_INFO(0, localName) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_attribute_node_ns, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, newAttr, DOMAttr, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_elements_by_tag_name_ns, 0, 0, 2) + ZEND_ARG_INFO(0, namespaceURI) + ZEND_ARG_INFO(0, localName) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_has_attribute, 0, 0, 1) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_has_attribute_ns, 0, 0, 2) + ZEND_ARG_INFO(0, namespaceURI) + ZEND_ARG_INFO(0, localName) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_id_attribute, 0, 0, 2) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, isId) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_id_attribute_ns, 0, 0, 3) + ZEND_ARG_INFO(0, namespaceURI) + ZEND_ARG_INFO(0, localName) + ZEND_ARG_INFO(0, isId) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_id_attribute_node, 0, 0, 2) + ZEND_ARG_OBJ_INFO(0, attr, DOMAttr, 0) + ZEND_ARG_INFO(0, isId) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_construct, 0, 0, 1) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, uri) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class DOMElement extends DOMNode +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-745549614 +* Since: +*/ + +const zend_function_entry php_dom_element_class_functions[] = { /* {{{ */ + PHP_FALIAS(getAttribute, dom_element_get_attribute, arginfo_dom_element_get_attribute) + PHP_FALIAS(setAttribute, dom_element_set_attribute, arginfo_dom_element_set_attribute) + PHP_FALIAS(removeAttribute, dom_element_remove_attribute, arginfo_dom_element_remove_attribute) + PHP_FALIAS(getAttributeNode, dom_element_get_attribute_node, arginfo_dom_element_get_attribute_node) + PHP_FALIAS(setAttributeNode, dom_element_set_attribute_node, arginfo_dom_element_set_attribute_node) + PHP_FALIAS(removeAttributeNode, dom_element_remove_attribute_node, arginfo_dom_element_remove_attribute_node) + PHP_FALIAS(getElementsByTagName, dom_element_get_elements_by_tag_name, arginfo_dom_element_get_elements_by_tag_name) + PHP_FALIAS(getAttributeNS, dom_element_get_attribute_ns, arginfo_dom_element_get_attribute_ns) + PHP_FALIAS(setAttributeNS, dom_element_set_attribute_ns, arginfo_dom_element_set_attribute_ns) + PHP_FALIAS(removeAttributeNS, dom_element_remove_attribute_ns, arginfo_dom_element_remove_attribute_ns) + PHP_FALIAS(getAttributeNodeNS, dom_element_get_attribute_node_ns, arginfo_dom_element_get_attribute_node_ns) + PHP_FALIAS(setAttributeNodeNS, dom_element_set_attribute_node_ns, arginfo_dom_element_set_attribute_node_ns) + PHP_FALIAS(getElementsByTagNameNS, dom_element_get_elements_by_tag_name_ns, arginfo_dom_element_get_elements_by_tag_name_ns) + PHP_FALIAS(hasAttribute, dom_element_has_attribute, arginfo_dom_element_has_attribute) + PHP_FALIAS(hasAttributeNS, dom_element_has_attribute_ns, arginfo_dom_element_has_attribute_ns) + PHP_FALIAS(setIdAttribute, dom_element_set_id_attribute, arginfo_dom_element_set_id_attribute) + PHP_FALIAS(setIdAttributeNS, dom_element_set_id_attribute_ns, arginfo_dom_element_set_id_attribute_ns) + PHP_FALIAS(setIdAttributeNode, dom_element_set_id_attribute_node, arginfo_dom_element_set_id_attribute_node) + PHP_ME(domelement, __construct, arginfo_dom_element_construct, ZEND_ACC_PUBLIC) + PHP_FE_END +}; +/* }}} */ + +/* {{{ proto void DOMElement::__construct(string name, [string value], [string uri]); */ +PHP_METHOD(domelement, __construct) +{ + + zval *id; + xmlNodePtr nodep = NULL, oldnode = NULL; + dom_object *intern; + char *name, *value = NULL, *uri = NULL; + char *localname = NULL, *prefix = NULL; + int errorcode = 0, uri_len = 0; + int name_len, value_len = 0, name_valid; + xmlNsPtr nsptr = NULL; + zend_error_handling error_handling; + + zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC); + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s!s", &id, dom_element_class_entry, &name, &name_len, &value, &value_len, &uri, &uri_len) == FAILURE) { + zend_restore_error_handling(&error_handling TSRMLS_CC); + return; + } + zend_restore_error_handling(&error_handling TSRMLS_CC); + + name_valid = xmlValidateName((xmlChar *) name, 0); + if (name_valid != 0) { + php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC); + RETURN_FALSE; + } + + /* Namespace logic is seperate and only when uri passed in to insure no BC breakage */ + if (uri_len > 0) { + errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len); + if (errorcode == 0) { + nodep = xmlNewNode (NULL, (xmlChar *)localname); + if (nodep != NULL && uri != NULL) { + nsptr = dom_get_ns(nodep, uri, &errorcode, prefix); + xmlSetNs(nodep, nsptr); + } + } + xmlFree(localname); + if (prefix != NULL) { + xmlFree(prefix); + } + if (errorcode != 0) { + if (nodep != NULL) { + xmlFreeNode(nodep); + } + php_dom_throw_error(errorcode, 1 TSRMLS_CC); + RETURN_FALSE; + } + } else { + /* If you don't pass a namespace uri, then you can't set a prefix */ + localname = xmlSplitQName2((xmlChar *)name, (xmlChar **) &prefix); + if (prefix != NULL) { + xmlFree(localname); + xmlFree(prefix); + php_dom_throw_error(NAMESPACE_ERR, 1 TSRMLS_CC); + RETURN_FALSE; + } + nodep = xmlNewNode(NULL, (xmlChar *) name); + } + + if (!nodep) { + php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC); + RETURN_FALSE; + } + + if (value_len > 0) { + xmlNodeSetContentLen(nodep, (xmlChar *) value, value_len); + } + + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + if (intern != NULL) { + oldnode = dom_object_get_node(intern); + if (oldnode != NULL) { + php_libxml_node_free_resource(oldnode TSRMLS_CC); + } + php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC); + } +} +/* }}} end DOMElement::__construct */ + +/* {{{ tagName string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-104682815 +Since: +*/ +int dom_element_tag_name_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNodePtr nodep; + xmlNsPtr ns; + xmlChar *qname; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + ns = nodep->ns; + if (ns != NULL && ns->prefix) { + qname = xmlStrdup(ns->prefix); + qname = xmlStrcat(qname, (xmlChar *)":"); + qname = xmlStrcat(qname, nodep->name); + ZVAL_STRING(*retval, (char *)qname, 1); + xmlFree(qname); + } else { + ZVAL_STRING(*retval, (char *) nodep->name, 1); + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ schemaTypeInfo typeinfo +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Element-schemaTypeInfo +Since: DOM Level 3 +*/ +int dom_element_schema_type_info_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_NULL(*retval); + return SUCCESS; +} + +/* }}} */ + +static xmlNodePtr dom_get_dom1_attribute(xmlNodePtr elem, xmlChar *name) /* {{{ */ +{ + int len; + const xmlChar *nqname; + + nqname = xmlSplitQName3(name, &len); + if (nqname != NULL) { + xmlNsPtr ns; + xmlChar *prefix = xmlStrndup(name, len); + if (prefix && xmlStrEqual(prefix, (xmlChar *)"xmlns")) { + ns = elem->nsDef; + while (ns) { + if (xmlStrEqual(ns->prefix, nqname)) { + break; + } + ns = ns->next; + } + xmlFree(prefix); + return (xmlNodePtr)ns; + } + ns = xmlSearchNs(elem->doc, elem, prefix); + if (prefix != NULL) { + xmlFree(prefix); + } + if (ns != NULL) { + return (xmlNodePtr)xmlHasNsProp(elem, nqname, ns->href); + } + } else { + if (xmlStrEqual(name, (xmlChar *)"xmlns")) { + xmlNsPtr nsPtr = elem->nsDef; + while (nsPtr) { + if (nsPtr->prefix == NULL) { + return (xmlNodePtr)nsPtr; + } + nsPtr = nsPtr->next; + } + return NULL; + } + } + return (xmlNodePtr)xmlHasNsProp(elem, name, NULL); +} +/* }}} */ + +/* {{{ proto string dom_element_get_attribute(string name); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-666EE0F9 +Since: +*/ +PHP_FUNCTION(dom_element_get_attribute) +{ + zval *id; + xmlNode *nodep; + char *name; + xmlChar *value = NULL; + dom_object *intern; + xmlNodePtr attr; + int name_len; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + attr = dom_get_dom1_attribute(nodep, (xmlChar *)name); + if (attr) { + switch (attr->type) { + case XML_ATTRIBUTE_NODE: + value = xmlNodeListGetString(attr->doc, attr->children, 1); + break; + case XML_NAMESPACE_DECL: + value = xmlStrdup(((xmlNsPtr)attr)->href); + break; + default: + value = xmlStrdup(((xmlAttributePtr)attr)->defaultValue); + } + } + + if (value == NULL) { + RETURN_EMPTY_STRING(); + } else { + RETVAL_STRING((char *)value, 1); + xmlFree(value); + } +} +/* }}} end dom_element_get_attribute */ + +/* {{{ proto void dom_element_set_attribute(string name, string value); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68F082 +Since: +*/ +PHP_FUNCTION(dom_element_set_attribute) +{ + zval *id; + xmlNode *nodep; + xmlNodePtr attr = NULL; + int ret, name_len, value_len, name_valid; + dom_object *intern; + char *name, *value; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_element_class_entry, &name, &name_len, &value, &value_len) == FAILURE) { + return; + } + + if (name_len == 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute Name is required"); + RETURN_FALSE; + } + + name_valid = xmlValidateName((xmlChar *) name, 0); + if (name_valid != 0) { + php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC); + RETURN_FALSE; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + if (dom_node_is_read_only(nodep) == SUCCESS) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + attr = dom_get_dom1_attribute(nodep, (xmlChar *)name); + if (attr != NULL) { + switch (attr->type) { + case XML_ATTRIBUTE_NODE: + node_list_unlink(attr->children TSRMLS_CC); + break; + case XML_NAMESPACE_DECL: + RETURN_FALSE; + default: + break; + } + + } + + if (xmlStrEqual((xmlChar *)name, (xmlChar *)"xmlns")) { + if (xmlNewNs(nodep, (xmlChar *)value, NULL)) { + RETURN_TRUE; + } + } else { + attr = (xmlNodePtr)xmlSetProp(nodep, (xmlChar *) name, (xmlChar *)value); + } + if (!attr) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such attribute '%s'", name); + RETURN_FALSE; + } + + DOM_RET_OBJ(attr, &ret, intern); + +} +/* }}} end dom_element_set_attribute */ + +/* {{{ proto void dom_element_remove_attribute(string name); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6D6AC0F9 +Since: +*/ +PHP_FUNCTION(dom_element_remove_attribute) +{ + zval *id; + xmlNodePtr nodep, attrp; + dom_object *intern; + int name_len; + char *name; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + if (dom_node_is_read_only(nodep) == SUCCESS) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + attrp = dom_get_dom1_attribute(nodep, (xmlChar *)name); + if (attrp == NULL) { + RETURN_FALSE; + } + + switch (attrp->type) { + case XML_ATTRIBUTE_NODE: + if (php_dom_object_get_data(attrp) == NULL) { + node_list_unlink(attrp->children TSRMLS_CC); + xmlUnlinkNode(attrp); + xmlFreeProp((xmlAttrPtr)attrp); + } else { + xmlUnlinkNode(attrp); + } + break; + case XML_NAMESPACE_DECL: + RETURN_FALSE; + default: + break; + } + + RETURN_TRUE; +} +/* }}} end dom_element_remove_attribute */ + +/* {{{ proto DOMAttr dom_element_get_attribute_node(string name); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-217A91B8 +Since: +*/ +PHP_FUNCTION(dom_element_get_attribute_node) +{ + zval *id; + xmlNodePtr nodep, attrp; + int name_len, ret; + dom_object *intern; + char *name; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + attrp = dom_get_dom1_attribute(nodep, (xmlChar *)name); + if (attrp == NULL) { + RETURN_FALSE; + } + + if (attrp->type == XML_NAMESPACE_DECL) { + xmlNsPtr curns; + xmlNodePtr nsparent; + + nsparent = attrp->_private; + curns = xmlNewNs(NULL, attrp->name, NULL); + if (attrp->children) { + curns->prefix = xmlStrdup((xmlChar *) attrp->children); + } + if (attrp->children) { + attrp = xmlNewDocNode(nodep->doc, NULL, (xmlChar *) attrp->children, attrp->name); + } else { + attrp = xmlNewDocNode(nodep->doc, NULL, (xmlChar *)"xmlns", attrp->name); + } + attrp->type = XML_NAMESPACE_DECL; + attrp->parent = nsparent; + attrp->ns = curns; + } + + DOM_RET_OBJ((xmlNodePtr) attrp, &ret, intern); +} +/* }}} end dom_element_get_attribute_node */ + +/* {{{ proto DOMAttr dom_element_set_attribute_node(DOMAttr newAttr); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-887236154 +Since: +*/ +PHP_FUNCTION(dom_element_set_attribute_node) +{ + zval *id, *node; + xmlNode *nodep; + xmlAttr *attrp, *existattrp = NULL; + dom_object *intern, *attrobj, *oldobj; + int ret; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_element_class_entry, &node, dom_attr_class_entry) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + if (dom_node_is_read_only(nodep) == SUCCESS) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj); + + if (attrp->type != XML_ATTRIBUTE_NODE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute node is required"); + RETURN_FALSE; + } + + if (!(attrp->doc == NULL || attrp->doc == nodep->doc)) { + php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + existattrp = xmlHasProp(nodep, attrp->name); + if (existattrp != NULL && existattrp->type != XML_ATTRIBUTE_DECL) { + if ((oldobj = php_dom_object_get_data((xmlNodePtr) existattrp)) != NULL && + ((php_libxml_node_ptr *)oldobj->ptr)->node == (xmlNodePtr) attrp) + { + RETURN_NULL(); + } + xmlUnlinkNode((xmlNodePtr) existattrp); + } + + if (attrp->parent != NULL) { + xmlUnlinkNode((xmlNodePtr) attrp); + } + + if (attrp->doc == NULL && nodep->doc != NULL) { + attrobj->document = intern->document; + php_libxml_increment_doc_ref((php_libxml_node_object *)attrobj, NULL TSRMLS_CC); + } + + xmlAddChild(nodep, (xmlNodePtr) attrp); + + /* Returns old property if removed otherwise NULL */ + if (existattrp != NULL) { + DOM_RET_OBJ((xmlNodePtr) existattrp, &ret, intern); + } else { + RETVAL_NULL(); + } + +} +/* }}} end dom_element_set_attribute_node */ + +/* {{{ proto DOMAttr dom_element_remove_attribute_node(DOMAttr oldAttr); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D589198 +Since: +*/ +PHP_FUNCTION(dom_element_remove_attribute_node) +{ + zval *id, *node; + xmlNode *nodep; + xmlAttr *attrp; + dom_object *intern, *attrobj; + int ret; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_element_class_entry, &node, dom_attr_class_entry) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + if (dom_node_is_read_only(nodep) == SUCCESS) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj); + + if (attrp->type != XML_ATTRIBUTE_NODE || attrp->parent != nodep) { + php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + xmlUnlinkNode((xmlNodePtr) attrp); + + DOM_RET_OBJ((xmlNodePtr) attrp, &ret, intern); + +} +/* }}} end dom_element_remove_attribute_node */ + +/* {{{ proto DOMNodeList dom_element_get_elements_by_tag_name(string name); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1938918D +Since: +*/ +PHP_FUNCTION(dom_element_get_elements_by_tag_name) +{ + zval *id; + xmlNodePtr elemp; + int name_len; + dom_object *intern, *namednode; + char *name; + xmlChar *local; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(elemp, id, xmlNodePtr, intern); + + php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC); + namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC); + local = xmlCharStrndup(name, name_len); + dom_namednode_iter(intern, 0, namednode, NULL, local, NULL TSRMLS_CC); +} +/* }}} end dom_element_get_elements_by_tag_name */ + +/* {{{ proto string dom_element_get_attribute_ns(string namespaceURI, string localName); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElGetAttrNS +Since: DOM Level 2 +*/ +PHP_FUNCTION(dom_element_get_attribute_ns) +{ + zval *id; + xmlNodePtr elemp; + xmlNsPtr nsptr; + dom_object *intern; + int uri_len = 0, name_len = 0; + char *uri, *name; + xmlChar *strattr; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(elemp, id, xmlNodePtr, intern); + + strattr = xmlGetNsProp(elemp, (xmlChar *) name, (xmlChar *) uri); + + if (strattr != NULL) { + RETVAL_STRING((char *)strattr, 1); + xmlFree(strattr); + } else { + if (xmlStrEqual((xmlChar *) uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) { + nsptr = dom_get_nsdecl(elemp, (xmlChar *)name); + if (nsptr != NULL) { + RETVAL_STRING((char *) nsptr->href, 1); + } else { + RETVAL_EMPTY_STRING(); + } + } else { + RETVAL_EMPTY_STRING(); + } + } + +} +/* }}} end dom_element_get_attribute_ns */ + +static xmlNsPtr _dom_new_reconNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) /* {{{ */ +{ + xmlNsPtr def; + xmlChar prefix[50]; + int counter = 1; + + if ((tree == NULL) || (ns == NULL) || (ns->type != XML_NAMESPACE_DECL)) { + return NULL; + } + + /* Code taken from libxml2 (2.6.20) xmlNewReconciliedNs + * + * Find a close prefix which is not already in use. + * Let's strip namespace prefixes longer than 20 chars ! + */ + if (ns->prefix == NULL) + snprintf((char *) prefix, sizeof(prefix), "default"); + else + snprintf((char *) prefix, sizeof(prefix), "%.20s", (char *)ns->prefix); + + def = xmlSearchNs(doc, tree, prefix); + while (def != NULL) { + if (counter > 1000) return(NULL); + if (ns->prefix == NULL) + snprintf((char *) prefix, sizeof(prefix), "default%d", counter++); + else + snprintf((char *) prefix, sizeof(prefix), "%.20s%d", + (char *)ns->prefix, counter++); + def = xmlSearchNs(doc, tree, prefix); + } + + /* + * OK, now we are ready to create a new one. + */ + def = xmlNewNs(tree, ns->href, prefix); + return(def); +} +/* }}} */ + +/* {{{ proto void dom_element_set_attribute_ns(string namespaceURI, string qualifiedName, string value); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAttrNS +Since: DOM Level 2 +*/ +PHP_FUNCTION(dom_element_set_attribute_ns) +{ + zval *id; + xmlNodePtr elemp, nodep = NULL; + xmlNsPtr nsptr; + xmlAttr *attr; + int uri_len = 0, name_len = 0, value_len = 0; + char *uri, *name, *value; + char *localname = NULL, *prefix = NULL; + dom_object *intern; + int errorcode = 0, stricterror, is_xmlns = 0, name_valid; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!ss", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len, &value, &value_len) == FAILURE) { + return; + } + + if (name_len == 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute Name is required"); + RETURN_FALSE; + } + + DOM_GET_OBJ(elemp, id, xmlNodePtr, intern); + + stricterror = dom_get_strict_error(intern->document); + + if (dom_node_is_read_only(elemp) == SUCCESS) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC); + RETURN_NULL(); + } + + errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len); + + if (errorcode == 0) { + if (uri_len > 0) { + nodep = (xmlNodePtr) xmlHasNsProp(elemp, (xmlChar *) localname, (xmlChar *) uri); + if (nodep != NULL && nodep->type != XML_ATTRIBUTE_DECL) { + node_list_unlink(nodep->children TSRMLS_CC); + } + + if ((xmlStrEqual((xmlChar *) prefix, (xmlChar *)"xmlns") || + (prefix == NULL && xmlStrEqual((xmlChar *) localname, (xmlChar *)"xmlns"))) && + xmlStrEqual((xmlChar *) uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) { + is_xmlns = 1; + if (prefix == NULL) { + nsptr = dom_get_nsdecl(elemp, NULL); + } else { + nsptr = dom_get_nsdecl(elemp, (xmlChar *)localname); + } + } else { + nsptr = xmlSearchNsByHref(elemp->doc, elemp, (xmlChar *)uri); + if (nsptr && nsptr->prefix == NULL) { + xmlNsPtr tmpnsptr; + + tmpnsptr = nsptr->next; + while (tmpnsptr) { + if ((tmpnsptr->prefix != NULL) && (tmpnsptr->href != NULL) && + (xmlStrEqual(tmpnsptr->href, (xmlChar *) uri))) { + nsptr = tmpnsptr; + break; + } + tmpnsptr = tmpnsptr->next; + } + if (tmpnsptr == NULL) { + nsptr = _dom_new_reconNs(elemp->doc, elemp, nsptr); + } + } + } + + if (nsptr == NULL) { + if (prefix == NULL) { + if (is_xmlns == 1) { + xmlNewNs(elemp, (xmlChar *)value, NULL); + xmlReconciliateNs(elemp->doc, elemp); + } else { + errorcode = NAMESPACE_ERR; + } + } else { + if (is_xmlns == 1) { + xmlNewNs(elemp, (xmlChar *)value, (xmlChar *)localname); + } else { + nsptr = dom_get_ns(elemp, uri, &errorcode, prefix); + } + xmlReconciliateNs(elemp->doc, elemp); + } + } else { + if (is_xmlns == 1) { + if (nsptr->href) { + xmlFree((xmlChar *) nsptr->href); + } + nsptr->href = xmlStrdup((xmlChar *)value); + } + } + + if (errorcode == 0 && is_xmlns == 0) { + xmlSetNsProp(elemp, nsptr, (xmlChar *)localname, (xmlChar *)value); + } + } else { + name_valid = xmlValidateName((xmlChar *) localname, 0); + if (name_valid != 0) { + errorcode = INVALID_CHARACTER_ERR; + stricterror = 1; + } else { + attr = xmlHasProp(elemp, (xmlChar *)localname); + if (attr != NULL && attr->type != XML_ATTRIBUTE_DECL) { + node_list_unlink(attr->children TSRMLS_CC); + } + xmlSetProp(elemp, (xmlChar *)localname, (xmlChar *)value); + } + } + } + + xmlFree(localname); + if (prefix != NULL) { + xmlFree(prefix); + } + + if (errorcode != 0) { + php_dom_throw_error(errorcode, stricterror TSRMLS_CC); + } + + RETURN_NULL(); +} +/* }}} end dom_element_set_attribute_ns */ + +/* {{{ proto void dom_element_remove_attribute_ns(string namespaceURI, string localName); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElRemAtNS +Since: DOM Level 2 +*/ +PHP_FUNCTION(dom_element_remove_attribute_ns) +{ + zval *id; + xmlNode *nodep; + xmlAttr *attrp; + xmlNsPtr nsptr; + dom_object *intern; + int name_len, uri_len; + char *name, *uri; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + if (dom_node_is_read_only(nodep) == SUCCESS) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_NULL(); + } + + attrp = xmlHasNsProp(nodep, (xmlChar *)name, (xmlChar *)uri); + + nsptr = dom_get_nsdecl(nodep, (xmlChar *)name); + if (nsptr != NULL) { + if (xmlStrEqual((xmlChar *)uri, nsptr->href)) { + if (nsptr->href != NULL) { + xmlFree((char *) nsptr->href); + nsptr->href = NULL; + } + if (nsptr->prefix != NULL) { + xmlFree((char *) nsptr->prefix); + nsptr->prefix = NULL; + } + } else { + RETURN_NULL(); + } + } + + if (attrp && attrp->type != XML_ATTRIBUTE_DECL) { + if (php_dom_object_get_data((xmlNodePtr) attrp) == NULL) { + node_list_unlink(attrp->children TSRMLS_CC); + xmlUnlinkNode((xmlNodePtr) attrp); + xmlFreeProp(attrp); + } else { + xmlUnlinkNode((xmlNodePtr) attrp); + } + } + + RETURN_NULL(); +} +/* }}} end dom_element_remove_attribute_ns */ + +/* {{{ proto DOMAttr dom_element_get_attribute_node_ns(string namespaceURI, string localName); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElGetAtNodeNS +Since: DOM Level 2 +*/ +PHP_FUNCTION(dom_element_get_attribute_node_ns) +{ + zval *id; + xmlNodePtr elemp; + xmlAttrPtr attrp; + dom_object *intern; + int uri_len, name_len, ret; + char *uri, *name; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(elemp, id, xmlNodePtr, intern); + + attrp = xmlHasNsProp(elemp, (xmlChar *)name, (xmlChar *)uri); + + if (attrp == NULL) { + RETURN_NULL(); + } + + DOM_RET_OBJ((xmlNodePtr) attrp, &ret, intern); + +} +/* }}} end dom_element_get_attribute_node_ns */ + +/* {{{ proto DOMAttr dom_element_set_attribute_node_ns(DOMAttr newAttr); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAtNodeNS +Since: DOM Level 2 +*/ +PHP_FUNCTION(dom_element_set_attribute_node_ns) +{ + zval *id, *node; + xmlNode *nodep; + xmlNs *nsp; + xmlAttr *attrp, *existattrp = NULL; + dom_object *intern, *attrobj, *oldobj; + int ret; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_element_class_entry, &node, dom_attr_class_entry) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + if (dom_node_is_read_only(nodep) == SUCCESS) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj); + + if (attrp->type != XML_ATTRIBUTE_NODE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute node is required"); + RETURN_FALSE; + } + + if (!(attrp->doc == NULL || attrp->doc == nodep->doc)) { + php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } + + nsp = attrp->ns; + if (nsp != NULL) { + existattrp = xmlHasNsProp(nodep, nsp->href, attrp->name); + } else { + existattrp = xmlHasProp(nodep, attrp->name); + } + + if (existattrp != NULL && existattrp->type != XML_ATTRIBUTE_DECL) { + if ((oldobj = php_dom_object_get_data((xmlNodePtr) existattrp)) != NULL && + ((php_libxml_node_ptr *)oldobj->ptr)->node == (xmlNodePtr) attrp) + { + RETURN_NULL(); + } + xmlUnlinkNode((xmlNodePtr) existattrp); + } + + if (attrp->parent != NULL) { + xmlUnlinkNode((xmlNodePtr) attrp); + } + + if (attrp->doc == NULL && nodep->doc != NULL) { + attrobj->document = intern->document; + php_libxml_increment_doc_ref((php_libxml_node_object *)attrobj, NULL TSRMLS_CC); + } + + xmlAddChild(nodep, (xmlNodePtr) attrp); + + /* Returns old property if removed otherwise NULL */ + if (existattrp != NULL) { + DOM_RET_OBJ((xmlNodePtr) existattrp, &ret, intern); + } else { + RETVAL_NULL(); + } + +} +/* }}} end dom_element_set_attribute_node_ns */ + +/* {{{ proto DOMNodeList dom_element_get_elements_by_tag_name_ns(string namespaceURI, string localName); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C90942 +Since: DOM Level 2 +*/ +PHP_FUNCTION(dom_element_get_elements_by_tag_name_ns) +{ + zval *id; + xmlNodePtr elemp; + int uri_len, name_len; + dom_object *intern, *namednode; + char *uri, *name; + xmlChar *local, *nsuri; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(elemp, id, xmlNodePtr, intern); + + php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC); + namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC); + local = xmlCharStrndup(name, name_len); + nsuri = xmlCharStrndup(uri, uri_len); + dom_namednode_iter(intern, 0, namednode, NULL, local, nsuri TSRMLS_CC); + +} +/* }}} end dom_element_get_elements_by_tag_name_ns */ + +/* {{{ proto boolean dom_element_has_attribute(string name); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElHasAttr +Since: DOM Level 2 +*/ +PHP_FUNCTION(dom_element_has_attribute) +{ + zval *id; + xmlNode *nodep; + dom_object *intern; + char *name; + int name_len; + xmlNodePtr attr; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + attr = dom_get_dom1_attribute(nodep, (xmlChar *)name); + if (attr == NULL) { + RETURN_FALSE; + } else { + RETURN_TRUE; + } +} +/* }}} end dom_element_has_attribute */ + +/* {{{ proto boolean dom_element_has_attribute_ns(string namespaceURI, string localName); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElHasAttrNS +Since: DOM Level 2 +*/ +PHP_FUNCTION(dom_element_has_attribute_ns) +{ + zval *id; + xmlNodePtr elemp; + xmlNs *nsp; + dom_object *intern; + int uri_len, name_len; + char *uri, *name; + xmlChar *value; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(elemp, id, xmlNodePtr, intern); + + value = xmlGetNsProp(elemp, (xmlChar *)name, (xmlChar *)uri); + + if (value != NULL) { + xmlFree(value); + RETURN_TRUE; + } else { + if (xmlStrEqual((xmlChar *)uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) { + nsp = dom_get_nsdecl(elemp, (xmlChar *)name); + if (nsp != NULL) { + RETURN_TRUE; + } + } + } + + RETURN_FALSE; +} +/* }}} end dom_element_has_attribute_ns */ + +static void php_set_attribute_id(xmlAttrPtr attrp, zend_bool is_id) /* {{{ */ +{ + if (is_id == 1 && attrp->atype != XML_ATTRIBUTE_ID) { + xmlChar *id_val; + + id_val = xmlNodeListGetString(attrp->doc, attrp->children, 1); + if (id_val != NULL) { + xmlAddID(NULL, attrp->doc, id_val, attrp); + xmlFree(id_val); + } + } else { + if (attrp->atype == XML_ATTRIBUTE_ID) { + xmlRemoveID(attrp->doc, attrp); + attrp->atype = 0; + } + } +} +/* }}} */ + +/* {{{ proto void dom_element_set_id_attribute(string name, boolean isId); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttr +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_element_set_id_attribute) +{ + zval *id; + xmlNode *nodep; + xmlAttrPtr attrp; + dom_object *intern; + char *name; + int name_len; + zend_bool is_id; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osb", &id, dom_element_class_entry, &name, &name_len, &is_id) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + if (dom_node_is_read_only(nodep) == SUCCESS) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_NULL(); + } + + attrp = xmlHasNsProp(nodep, (xmlChar *)name, NULL); + if (attrp == NULL || attrp->type == XML_ATTRIBUTE_DECL) { + php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + } else { + php_set_attribute_id(attrp, is_id); + } + + RETURN_NULL(); +} +/* }}} end dom_element_set_id_attribute */ + +/* {{{ proto void dom_element_set_id_attribute_ns(string namespaceURI, string localName, boolean isId); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttrNS +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_element_set_id_attribute_ns) +{ + zval *id; + xmlNodePtr elemp; + xmlAttrPtr attrp; + dom_object *intern; + int uri_len, name_len; + char *uri, *name; + zend_bool is_id; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ossb", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len, &is_id) == FAILURE) { + return; + } + + DOM_GET_OBJ(elemp, id, xmlNodePtr, intern); + + if (dom_node_is_read_only(elemp) == SUCCESS) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_NULL(); + } + + attrp = xmlHasNsProp(elemp, (xmlChar *)name, (xmlChar *)uri); + if (attrp == NULL || attrp->type == XML_ATTRIBUTE_DECL) { + php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + } else { + php_set_attribute_id(attrp, is_id); + } + + RETURN_NULL(); +} +/* }}} end dom_element_set_id_attribute_ns */ + +/* {{{ proto void dom_element_set_id_attribute_node(attr idAttr, boolean isId); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttrNode +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_element_set_id_attribute_node) +{ + zval *id, *node; + xmlNode *nodep; + xmlAttrPtr attrp; + dom_object *intern, *attrobj; + zend_bool is_id; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OOb", &id, dom_element_class_entry, &node, dom_attr_class_entry, &is_id) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + if (dom_node_is_read_only(nodep) == SUCCESS) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_NULL(); + } + + DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj); + + if (attrp->parent != nodep) { + php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + } else { + php_set_attribute_id(attrp, is_id); + } + + RETURN_NULL(); +} +/* }}} end dom_element_set_id_attribute_node */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/entity.c b/ext/dom/entity.c new file mode 100644 index 0000000..18e86fc --- /dev/null +++ b/ext/dom/entity.c @@ -0,0 +1,195 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class DOMEntity extends DOMNode +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-527DCFF2 +* Since: +*/ + +const zend_function_entry php_dom_entity_class_functions[] = { + PHP_FE_END +}; + +/* {{{ publicId string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-D7303025 +Since: +*/ +int dom_entity_public_id_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlEntity *nodep; + + nodep = (xmlEntity *) dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + if (nodep->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) { + ZVAL_NULL(*retval); + } else { + ZVAL_STRING(*retval, (char *) (nodep->ExternalID), 1); + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ systemId string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-D7C29F3E +Since: +*/ +int dom_entity_system_id_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlEntity *nodep; + + nodep = (xmlEntity *) dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + if (nodep->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) { + ZVAL_NULL(*retval); + } else { + ZVAL_STRING(*retval, (char *) (nodep->SystemID), 1); + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ notationName string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-6ABAEB38 +Since: +*/ +int dom_entity_notation_name_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlEntity *nodep; + char *content; + + nodep = (xmlEntity *) dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + if (nodep->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) { + ZVAL_NULL(*retval); + } else { + content = xmlNodeGetContent((xmlNodePtr) nodep); + ZVAL_STRING(*retval, content, 1); + xmlFree(content); + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ actualEncoding string +readonly=no +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Entity3-actualEncoding +Since: DOM Level 3 +*/ +int dom_entity_actual_encoding_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_NULL(*retval); + return SUCCESS; +} + +int dom_entity_actual_encoding_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + return SUCCESS; +} + +/* }}} */ + +/* {{{ encoding string +readonly=no +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Entity3-encoding +Since: DOM Level 3 +*/ +int dom_entity_encoding_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_NULL(*retval); + return SUCCESS; +} + +int dom_entity_encoding_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + return SUCCESS; +} + +/* }}} */ + +/* {{{ version string +readonly=no +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Entity3-version +Since: DOM Level 3 +*/ +int dom_entity_version_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_NULL(*retval); + return SUCCESS; +} + +int dom_entity_version_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + return SUCCESS; +} + +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/entityreference.c b/ext/dom/entityreference.c new file mode 100644 index 0000000..4ef526c --- /dev/null +++ b/ext/dom/entityreference.c @@ -0,0 +1,100 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_entityreference_construct, 0, 0, 1) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class DOMEntityReference extends DOMNode +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-11C98490 +* Since: +*/ + +const zend_function_entry php_dom_entityreference_class_functions[] = { + PHP_ME(domentityreference, __construct, arginfo_dom_entityreference_construct, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +/* {{{ proto void DOMEntityReference::__construct(string name); */ +PHP_METHOD(domentityreference, __construct) +{ + zval *id; + xmlNode *node; + xmlNodePtr oldnode = NULL; + dom_object *intern; + char *name; + int name_len, name_valid; + zend_error_handling error_handling; + + zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC); + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_entityreference_class_entry, &name, &name_len) == FAILURE) { + zend_restore_error_handling(&error_handling TSRMLS_CC); + return; + } + + zend_restore_error_handling(&error_handling TSRMLS_CC); + + name_valid = xmlValidateName((xmlChar *) name, 0); + if (name_valid != 0) { + php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC); + RETURN_FALSE; + } + + node = xmlNewReference(NULL, name); + + if (!node) { + php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC); + RETURN_FALSE; + } + + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + if (intern != NULL) { + oldnode = dom_object_get_node(intern); + if (oldnode != NULL) { + php_libxml_node_free_resource(oldnode TSRMLS_CC); + } + php_libxml_increment_node_ptr((php_libxml_node_object *)intern, node, (void *)intern TSRMLS_CC); + } +} +/* }}} end DOMEntityReference::__construct */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/examples/dom1.inc b/ext/dom/examples/dom1.inc new file mode 100644 index 0000000..792d6f2 --- /dev/null +++ b/ext/dom/examples/dom1.inc @@ -0,0 +1,43 @@ +<?PHP +$xmlstr = "<?xml version='1.0' standalone='yes'?> +<!DOCTYPE chapter SYSTEM '/share/sgml/Norman_Walsh/db3xml10/db3xml10.dtd' +[ <!ENTITY sp \"spanish\"> +]> +<!-- lsfj --> +<chapter language='en'><title language='en'>Title</title> +<para language='ge'> +&sp; +<!-- comment --> +<informaltable language='&sp;kkk'> +<tgroup cols='3'> +<tbody> +<row><entry>a1</entry><entry morerows='1'>b1</entry><entry>c1</entry></row> +<row><entry>a2</entry><entry>c2</entry></row> +<row><entry>a3</entry><entry>b3</entry><entry>c3</entry></row> +</tbody> +</tgroup> +</informaltable> +</para> +</chapter> "; + +function print_node($node) +{ + print "Node Name: " . $node->nodeName; + print "\nNode Type: " . $node->nodeType; + $child_count = $node->childNodes->length; + print "\nNum Children: " . $child_count; + if($child_count <= 1){ + print "\nNode Content: " . $node->nodeValue; + } + print "\n\n"; +} + +function print_node_list($nodelist) +{ + foreach($nodelist as $node) + { + print_node($node); + } +} + +?> diff --git a/ext/dom/examples/dom1.php b/ext/dom/examples/dom1.php new file mode 100644 index 0000000..8ea3674 --- /dev/null +++ b/ext/dom/examples/dom1.php @@ -0,0 +1,94 @@ +<?php +require_once("dom1.inc"); + +echo "Test 1: accessing single nodes from php\n"; +$dom = new domDocument; +$dom->loadxml($xmlstr); +if(!$dom) { + echo "Error while parsing the document\n"; + exit; +} + +// children() of of document would result in a memleak +//$children = $dom->children(); +//print_node_list($children); + +echo "--------- root\n"; +$rootnode = $dom->documentElement; +print_node($rootnode); + +echo "--------- children of root\n"; +$children = $rootnode->childNodes; +print_node_list($children); + +// The last node should be identical with the last entry in the children array +echo "--------- last\n"; +$last = $rootnode->lastChild; +print_node($last); + +// The parent of this last node is the root again +echo "--------- parent\n"; +$parent = $last->parentNode; +print_node($parent); + +// The children of this parent are the same children as one above +echo "--------- children of parent\n"; +$children = $parent->childNodes; +print_node_list($children); + +echo "--------- creating a new attribute\n"; +//This is worthless +//$attr = $dom->createAttribute("src", "picture.gif"); +//print_r($attr); + +//$rootnode->set_attributeNode($attr); +$attr = $rootnode->setAttribute("src", "picture.gif"); +$attr = $rootnode->getAttribute("src"); +print_r($attr); +print "\n"; + +echo "--------- Get Attribute Node\n"; +$attr = $rootnode->getAttributeNode("src"); +print_node($attr); + +echo "--------- Remove Attribute Node\n"; +$attr = $rootnode->removeAttribute("src"); +print "Removed " . $attr . " attributes.\n"; + +echo "--------- attributes of rootnode\n"; +$attrs = $rootnode->attributes; +print_node_list($attrs); + +echo "--------- children of an attribute\n"; +$children = $attrs->item(0)->childNodes; +print_node_list($children); + +echo "--------- Add child to root\n"; +$myelement = new domElement("Silly", "Symphony"); +$newchild = $rootnode->appendChild($myelement); +print_node($newchild); +print $dom->saveXML(); +print "\n"; + +echo "--------- Find element by tagname\n"; +echo " Using dom\n"; +$children = $dom->getElementsByTagname("Silly"); +print_node_list($children); + +echo " Using elem\n"; +$children = $rootnode->getElementsByTagName("Silly"); +print_node_list($children); + +echo "--------- Unlink Node\n"; +print_node($children->item(0)); +$rootnode->removeChild($children->item(0)); +print_node_list($rootnode->childNodes); +print $dom->savexml(); + +echo "--------- Find element by id\n"; +print ("Not implemented\n"); + +echo "--------- Check various node_name return values\n"; +print ("Not needed\n"); + +?> diff --git a/ext/dom/examples/note-invalid.xml b/ext/dom/examples/note-invalid.xml new file mode 100644 index 0000000..58d4e65 --- /dev/null +++ b/ext/dom/examples/note-invalid.xml @@ -0,0 +1,9 @@ +<?xml version="1.0"?> +<!DOCTYPE note SYSTEM "note.dtd"> +<note> +<to>PHP User Group</to> +<from>Shane</from> +<heading>Reminder</heading> +<body>Don't forget the meeting tonight!</body> +<footer>Or I'll clobber you!</footer> +</note> diff --git a/ext/dom/examples/note.dtd b/ext/dom/examples/note.dtd new file mode 100644 index 0000000..c2d558e --- /dev/null +++ b/ext/dom/examples/note.dtd @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!ELEMENT note (to,from,heading,body)> +<!ELEMENT to (#PCDATA)> +<!ELEMENT from (#PCDATA)> +<!ELEMENT heading (#PCDATA)> +<!ELEMENT body (#PCDATA)> diff --git a/ext/dom/examples/note.php b/ext/dom/examples/note.php new file mode 100644 index 0000000..a8695f3 --- /dev/null +++ b/ext/dom/examples/note.php @@ -0,0 +1,19 @@ +<?php + +$dom = new domDocument; +$dom->load('note.xml'); +if (!$dom->validate('note.dtd')) { + print "Document note.dtd is not valid\n"; +} else { + print "Document note.dtd is valid\n"; +} + +$dom = new domDocument; +$dom->load('note-invalid.xml'); +if (!$dom->validate('note.dtd')) { + print "Document note-invalid.xml is not valid\n"; +} else { + print "Document note-invalid.xml is valid\n"; +} + +?> diff --git a/ext/dom/examples/note.xml b/ext/dom/examples/note.xml new file mode 100644 index 0000000..49614a1 --- /dev/null +++ b/ext/dom/examples/note.xml @@ -0,0 +1,8 @@ +<?xml version="1.0"?> +<!DOCTYPE note SYSTEM "note.dtd"> +<note> +<to>PHP User Group</to> +<from>Shane</from> +<heading>Reminder</heading> +<body>Don't forget the meeting tonight!</body> +</note> diff --git a/ext/dom/examples/relaxNG.php b/ext/dom/examples/relaxNG.php new file mode 100644 index 0000000..d265fd9 --- /dev/null +++ b/ext/dom/examples/relaxNG.php @@ -0,0 +1,11 @@ +<?php + +$dom = new domDocument; +$dom->load('relaxNG.xml'); +if (!$dom->relaxNGValidate('relaxNG.rng')) { + print "Document is not valid"; +} else { + print "Document is valid"; +} + +?>
\ No newline at end of file diff --git a/ext/dom/examples/relaxNG.rng b/ext/dom/examples/relaxNG.rng new file mode 100644 index 0000000..f4357e0 --- /dev/null +++ b/ext/dom/examples/relaxNG.rng @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<grammar xmlns="http://relaxng.org/ns/structure/1.0" + datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> + +<include href="relaxNG2.rng"> +<define name="TEI.prose"><ref name="INCLUDE"/></define> +</include> +</grammar> + + + diff --git a/ext/dom/examples/relaxNG.xml b/ext/dom/examples/relaxNG.xml new file mode 100644 index 0000000..6b0cac1 --- /dev/null +++ b/ext/dom/examples/relaxNG.xml @@ -0,0 +1 @@ +<TEI.2>hello</TEI.2>
\ No newline at end of file diff --git a/ext/dom/examples/relaxNG2.rng b/ext/dom/examples/relaxNG2.rng new file mode 100644 index 0000000..4adae7b --- /dev/null +++ b/ext/dom/examples/relaxNG2.rng @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<grammar xmlns="http://relaxng.org/ns/structure/1.0" xmlns:t="http://www.thaiopensource.com/ns/annotations" xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> + + <start> + <ref name="TEI.2"/> + </start> + <define name="IGNORE"> + <notAllowed/> + </define> + <define name="INCLUDE"> + <empty/> + </define> + + + <include href="relaxNG3.rng"/> + + <define name="TEI.2"> + <element name="TEI.2"> + <text/> + </element> + </define> + +</grammar>
\ No newline at end of file diff --git a/ext/dom/examples/relaxNG3.rng b/ext/dom/examples/relaxNG3.rng new file mode 100644 index 0000000..73e1eb6 --- /dev/null +++ b/ext/dom/examples/relaxNG3.rng @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<grammar xmlns="http://relaxng.org/ns/structure/1.0" xmlns:t="http://www.thaiopensource.com/ns/annotations" xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> + + <define name="TEI.prose" combine="interleave"> + <ref name="IGNORE"/> + </define> + +</grammar>
\ No newline at end of file diff --git a/ext/dom/examples/shipping.php b/ext/dom/examples/shipping.php new file mode 100644 index 0000000..5205fd2 --- /dev/null +++ b/ext/dom/examples/shipping.php @@ -0,0 +1,11 @@ +<?php + +$dom = new domDocument; +$dom->load('shipping.xml'); +if (!$dom->schemaValidate('shipping.xsd')) { + print "Document is not valid"; +} else { + print "Document is valid"; +} + +?>
\ No newline at end of file diff --git a/ext/dom/examples/shipping.xml b/ext/dom/examples/shipping.xml new file mode 100644 index 0000000..dc8a09e --- /dev/null +++ b/ext/dom/examples/shipping.xml @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<shipOrder> + <shipTo> + <name>Tove Svendson</name> + <street>Ragnhildvei 2</street> + <address>4000 Stavanger</address> + <country>Norway</country> + </shipTo> + <items> + <item> + <title>Empire Burlesque</title> + <quantity>1</quantity> + <price>10.90</price> + </item> + <item> + <title>Hide your heart</title> + <quantity>1</quantity> + <price>9.90</price> + </item> + </items> +</shipOrder>
\ No newline at end of file diff --git a/ext/dom/examples/shipping.xsd b/ext/dom/examples/shipping.xsd new file mode 100644 index 0000000..8b16b7c --- /dev/null +++ b/ext/dom/examples/shipping.xsd @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + + <xsd:element name="shipOrder" type="order"/> + + <xsd:complexType name="order"> + <xsd:all> + <xsd:element name="shipTo" type="shipAddress"/> + <xsd:element name="items" type="cdItems"/> + </xsd:all> + </xsd:complexType> + + <xsd:complexType name="shipAddress"> + <xsd:all> + <xsd:element name="name" type="xsd:string"/> + <xsd:element name="street" type="xsd:string"/> + <xsd:element name="address" type="xsd:string"/> + <xsd:element name="country" type="xsd:string"/> + </xsd:all> + </xsd:complexType> + + <xsd:complexType name="cdItems"> + <xsd:sequence> + <xsd:element name="item" type="cdItem" maxOccurs="unbounded" minOccurs="1"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="cdItem"> + <xsd:all> + <xsd:element name="title" type="xsd:string"/> + <xsd:element name="quantity" type="xsd:positiveInteger"/> + <xsd:element name="price" type="xsd:decimal"/> + </xsd:all> + </xsd:complexType> + +</xsd:schema>
\ No newline at end of file diff --git a/ext/dom/namednodemap.c b/ext/dom/namednodemap.c new file mode 100644 index 0000000..07d7c70 --- /dev/null +++ b/ext/dom/namednodemap.c @@ -0,0 +1,338 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_get_named_item, 0, 0, 1) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_set_named_item, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, arg, DOMNode, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_remove_named_item, 0, 0, 0) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_item, 0, 0, 0) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_get_named_item_ns, 0, 0, 0) + ZEND_ARG_INFO(0, namespaceURI) + ZEND_ARG_INFO(0, localName) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_set_named_item_ns, 0, 0, 0) + ZEND_ARG_OBJ_INFO(0, arg, DOMNode, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_remove_named_item_ns, 0, 0, 0) + ZEND_ARG_INFO(0, namespaceURI) + ZEND_ARG_INFO(0, localName) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class DOMNamedNodeMap +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1780488922 +* Since: +*/ + +const zend_function_entry php_dom_namednodemap_class_functions[] = { /* {{{ */ + PHP_FALIAS(getNamedItem, dom_namednodemap_get_named_item, arginfo_dom_namednodemap_get_named_item) + PHP_FALIAS(setNamedItem, dom_namednodemap_set_named_item, arginfo_dom_namednodemap_set_named_item) + PHP_FALIAS(removeNamedItem, dom_namednodemap_remove_named_item, arginfo_dom_namednodemap_remove_named_item) + PHP_FALIAS(item, dom_namednodemap_item, arginfo_dom_namednodemap_item) + PHP_FALIAS(getNamedItemNS, dom_namednodemap_get_named_item_ns, arginfo_dom_namednodemap_get_named_item_ns) + PHP_FALIAS(setNamedItemNS, dom_namednodemap_set_named_item_ns, arginfo_dom_namednodemap_set_named_item_ns) + PHP_FALIAS(removeNamedItemNS, dom_namednodemap_remove_named_item_ns, arginfo_dom_namednodemap_remove_named_item_ns) + PHP_FE_END +}; +/* }}} */ + +/* {{{ length int +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6D0FB19E +Since: +*/ +int dom_namednodemap_length_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + dom_nnodemap_object *objmap; + xmlAttrPtr curnode; + xmlNodePtr nodep; + int count = 0; + + objmap = (dom_nnodemap_object *)obj->ptr; + + if (objmap != NULL) { + if ((objmap->nodetype == XML_NOTATION_NODE) || + objmap->nodetype == XML_ENTITY_NODE) { + if (objmap->ht) { + count = xmlHashSize(objmap->ht); + } + } else { + nodep = dom_object_get_node(objmap->baseobj); + if (nodep) { + curnode = nodep->properties; + if (curnode) { + count++; + while (curnode->next != NULL) { + count++; + curnode = curnode->next; + } + } + } + } + } + + MAKE_STD_ZVAL(*retval); + ZVAL_LONG(*retval, count); + return SUCCESS; +} + +/* }}} */ + +/* {{{ proto DOMNode dom_namednodemap_get_named_item(string name); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1074577549 +Since: +*/ +PHP_FUNCTION(dom_namednodemap_get_named_item) +{ + zval *id; + int ret, namedlen=0; + dom_object *intern; + xmlNodePtr itemnode = NULL; + char *named; + + dom_nnodemap_object *objmap; + xmlNodePtr nodep; + xmlNotation *notep = NULL; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_namednodemap_class_entry, &named, &namedlen) == FAILURE) { + return; + } + + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + + objmap = (dom_nnodemap_object *)intern->ptr; + + if (objmap != NULL) { + if ((objmap->nodetype == XML_NOTATION_NODE) || + objmap->nodetype == XML_ENTITY_NODE) { + if (objmap->ht) { + if (objmap->nodetype == XML_ENTITY_NODE) { + itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named); + } else { + notep = (xmlNotation *)xmlHashLookup(objmap->ht, named); + if (notep) { + itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID); + } + } + } + } else { + nodep = dom_object_get_node(objmap->baseobj); + if (nodep) { + itemnode = (xmlNodePtr)xmlHasProp(nodep, named); + } + } + } + + if (itemnode) { + DOM_RET_OBJ(itemnode, &ret, objmap->baseobj); + return; + } else { + RETVAL_NULL(); + } +} +/* }}} end dom_namednodemap_get_named_item */ + +/* {{{ proto DOMNode dom_namednodemap_set_named_item(DOMNode arg); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1025163788 +Since: +*/ +PHP_FUNCTION(dom_namednodemap_set_named_item) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_namednodemap_set_named_item */ + +/* {{{ proto DOMNode dom_namednodemap_remove_named_item(string name); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D58B193 +Since: +*/ +PHP_FUNCTION(dom_namednodemap_remove_named_item) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_namednodemap_remove_named_item */ + +/* {{{ proto DOMNode dom_namednodemap_item(int index); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-349467F9 +Since: +*/ +PHP_FUNCTION(dom_namednodemap_item) +{ + zval *id; + long index; + int ret; + dom_object *intern; + xmlNodePtr itemnode = NULL; + + dom_nnodemap_object *objmap; + xmlNodePtr nodep, curnode; + int count; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &id, dom_namednodemap_class_entry, &index) == FAILURE) { + return; + } + if (index >= 0) { + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + + objmap = (dom_nnodemap_object *)intern->ptr; + + if (objmap != NULL) { + if ((objmap->nodetype == XML_NOTATION_NODE) || + objmap->nodetype == XML_ENTITY_NODE) { + if (objmap->ht) { + if (objmap->nodetype == XML_ENTITY_NODE) { + itemnode = php_dom_libxml_hash_iter(objmap->ht, index); + } else { + itemnode = php_dom_libxml_notation_iter(objmap->ht, index); + } + } + } else { + nodep = dom_object_get_node(objmap->baseobj); + if (nodep) { + curnode = (xmlNodePtr)nodep->properties; + count = 0; + while (count < index && curnode != NULL) { + count++; + curnode = (xmlNodePtr)curnode->next; + } + itemnode = curnode; + } + } + } + + if (itemnode) { + DOM_RET_OBJ(itemnode, &ret, objmap->baseobj); + return; + } + } + + RETVAL_NULL(); +} +/* }}} end dom_namednodemap_item */ + +/* {{{ proto DOMNode dom_namednodemap_get_named_item_ns(string namespaceURI, string localName); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getNamedItemNS +Since: DOM Level 2 +*/ +PHP_FUNCTION(dom_namednodemap_get_named_item_ns) +{ + zval *id; + int ret, namedlen=0, urilen=0; + dom_object *intern; + xmlNodePtr itemnode = NULL; + char *uri, *named; + + dom_nnodemap_object *objmap; + xmlNodePtr nodep; + xmlNotation *notep = NULL; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_namednodemap_class_entry, &uri, &urilen, &named, &namedlen) == FAILURE) { + return; + } + + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + + objmap = (dom_nnodemap_object *)intern->ptr; + + if (objmap != NULL) { + if ((objmap->nodetype == XML_NOTATION_NODE) || + objmap->nodetype == XML_ENTITY_NODE) { + if (objmap->ht) { + if (objmap->nodetype == XML_ENTITY_NODE) { + itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named); + } else { + notep = (xmlNotation *)xmlHashLookup(objmap->ht, named); + if (notep) { + itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID); + } + } + } + } else { + nodep = dom_object_get_node(objmap->baseobj); + if (nodep) { + itemnode = (xmlNodePtr)xmlHasNsProp(nodep, named, uri); + } + } + } + + if (itemnode) { + DOM_RET_OBJ(itemnode, &ret, objmap->baseobj); + return; + } else { + RETVAL_NULL(); + } +} +/* }}} end dom_namednodemap_get_named_item_ns */ + +/* {{{ proto DOMNode dom_namednodemap_set_named_item_ns(DOMNode arg); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-setNamedItemNS +Since: DOM Level 2 +*/ +PHP_FUNCTION(dom_namednodemap_set_named_item_ns) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_namednodemap_set_named_item_ns */ + +/* {{{ proto DOMNode dom_namednodemap_remove_named_item_ns(string namespaceURI, string localName); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-removeNamedItemNS +Since: DOM Level 2 +*/ +PHP_FUNCTION(dom_namednodemap_remove_named_item_ns) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_namednodemap_remove_named_item_ns */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/namelist.c b/ext/dom/namelist.c new file mode 100644 index 0000000..5831dde --- /dev/null +++ b/ext/dom/namelist.c @@ -0,0 +1,96 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namelist_get_name, 0, 0, 1) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namelist_get_namespace_uri, 0, 0, 1) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class DOMNameList +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#NameList +* Since: DOM Level 3 +*/ + +const zend_function_entry php_dom_namelist_class_functions[] = { + PHP_FALIAS(getName, dom_namelist_get_name, arginfo_dom_namelist_get_name) + PHP_FALIAS(getNamespaceURI, dom_namelist_get_namespace_uri, arginfo_dom_namelist_get_namespace_uri) + PHP_FE_END +}; + +/* {{{ length int +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#NameList-length +Since: +*/ +int dom_namelist_length_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_STRING(*retval, "TEST", 1); + return SUCCESS; +} + +/* }}} */ + +/* {{{ proto string dom_namelist_get_name(int index); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#NameList-getName +Since: +*/ +PHP_FUNCTION(dom_namelist_get_name) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_namelist_get_name */ + +/* {{{ proto string dom_namelist_get_namespace_uri(int index); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#NameList-getNamespaceURI +Since: +*/ +PHP_FUNCTION(dom_namelist_get_namespace_uri) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_namelist_get_namespace_uri */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/node.c b/ext/dom/node.c new file mode 100644 index 0000000..3279567 --- /dev/null +++ b/ext/dom/node.c @@ -0,0 +1,1990 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_insert_before, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0) + ZEND_ARG_OBJ_INFO(0, refChild, DOMNode, 1) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_replace_child, 0, 0, 2) + ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0) + ZEND_ARG_OBJ_INFO(0, oldChild, DOMNode, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_remove_child, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, oldChild, DOMNode, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_append_child, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_has_child_nodes, 0, 0, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_clone_node, 0, 0, 1) + ZEND_ARG_INFO(0, deep) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_normalize, 0, 0, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_supported, 0, 0, 2) + ZEND_ARG_INFO(0, feature) + ZEND_ARG_INFO(0, version) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_has_attributes, 0, 0, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_compare_document_position, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, other, DOMNode, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_same_node, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, other, DOMNode, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_lookup_prefix, 0, 0, 1) + ZEND_ARG_INFO(0, namespaceURI) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_default_namespace, 0, 0, 1) + ZEND_ARG_INFO(0, namespaceURI) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_lookup_namespace_uri, 0, 0, 1) + ZEND_ARG_INFO(0, prefix) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_equal_node, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, arg, DOMNode, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_get_feature, 0, 0, 2) + ZEND_ARG_INFO(0, feature) + ZEND_ARG_INFO(0, version) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_set_user_data, 0, 0, 3) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, handler) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_get_user_data, 0, 0, 1) + ZEND_ARG_INFO(0, key) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_getNodePath, 0, 0, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_getLineNo, 0, 0, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_C14N, 0, 0, 0) + ZEND_ARG_INFO(0, exclusive) + ZEND_ARG_INFO(0, with_comments) + ZEND_ARG_ARRAY_INFO(0, xpath, 1) + ZEND_ARG_ARRAY_INFO(0, ns_prefixes, 1) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_C14NFile, 0, 0, 1) + ZEND_ARG_INFO(0, uri) + ZEND_ARG_INFO(0, exclusive) + ZEND_ARG_INFO(0, with_comments) + ZEND_ARG_ARRAY_INFO(0, xpath, 1) + ZEND_ARG_ARRAY_INFO(0, ns_prefixes, 1) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class DOMNode +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1950641247 +* Since: +*/ + +const zend_function_entry php_dom_node_class_functions[] = { /* {{{ */ + PHP_FALIAS(insertBefore, dom_node_insert_before, arginfo_dom_node_insert_before) + PHP_FALIAS(replaceChild, dom_node_replace_child, arginfo_dom_node_replace_child) + PHP_FALIAS(removeChild, dom_node_remove_child, arginfo_dom_node_remove_child) + PHP_FALIAS(appendChild, dom_node_append_child, arginfo_dom_node_append_child) + PHP_FALIAS(hasChildNodes, dom_node_has_child_nodes, arginfo_dom_node_has_child_nodes) + PHP_FALIAS(cloneNode, dom_node_clone_node, arginfo_dom_node_clone_node) + PHP_FALIAS(normalize, dom_node_normalize, arginfo_dom_node_normalize) + PHP_FALIAS(isSupported, dom_node_is_supported, arginfo_dom_node_is_supported) + PHP_FALIAS(hasAttributes, dom_node_has_attributes, arginfo_dom_node_has_attributes) + PHP_FALIAS(compareDocumentPosition, dom_node_compare_document_position, arginfo_dom_node_compare_document_position) + PHP_FALIAS(isSameNode, dom_node_is_same_node, arginfo_dom_node_is_same_node) + PHP_FALIAS(lookupPrefix, dom_node_lookup_prefix, arginfo_dom_node_lookup_prefix) + PHP_FALIAS(isDefaultNamespace, dom_node_is_default_namespace, arginfo_dom_node_is_default_namespace) + PHP_FALIAS(lookupNamespaceUri, dom_node_lookup_namespace_uri, arginfo_dom_node_lookup_namespace_uri) + PHP_FALIAS(isEqualNode, dom_node_is_equal_node, arginfo_dom_node_is_equal_node) + PHP_FALIAS(getFeature, dom_node_get_feature, arginfo_dom_node_get_feature) + PHP_FALIAS(setUserData, dom_node_set_user_data, arginfo_dom_node_set_user_data) + PHP_FALIAS(getUserData, dom_node_get_user_data, arginfo_dom_node_get_user_data) + PHP_ME(domnode, getNodePath, arginfo_dom_node_getNodePath, ZEND_ACC_PUBLIC) + PHP_ME(domnode, getLineNo, arginfo_dom_node_getLineNo, ZEND_ACC_PUBLIC) + PHP_ME(domnode, C14N, arginfo_dom_node_C14N, ZEND_ACC_PUBLIC) + PHP_ME(domnode, C14NFile, arginfo_dom_node_C14NFile, ZEND_ACC_PUBLIC) + PHP_FE_END +}; +/* }}} */ + +static void dom_reconcile_ns(xmlDocPtr doc, xmlNodePtr nodep) /* {{{ */ +{ + xmlNsPtr nsptr, nsdftptr, curns, prevns = NULL; + + if (nodep->type == XML_ELEMENT_NODE) { + /* Following if block primarily used for inserting nodes created via createElementNS */ + if (nodep->nsDef != NULL) { + curns = nodep->nsDef; + while (curns) { + nsdftptr = curns->next; + if (curns->href != NULL) { + if((nsptr = xmlSearchNsByHref(doc, nodep->parent, curns->href)) && + (curns->prefix == NULL || xmlStrEqual(nsptr->prefix, curns->prefix))) { + curns->next = NULL; + if (prevns == NULL) { + nodep->nsDef = nsdftptr; + } else { + prevns->next = nsdftptr; + } + dom_set_old_ns(doc, curns); + curns = prevns; + } + } + prevns = curns; + curns = nsdftptr; + } + } + xmlReconciliateNs(doc, nodep); + } +} +/* }}} */ + +/* {{{ nodeName string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68D095 +Since: +*/ +int dom_node_node_name_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNode *nodep; + xmlNsPtr ns; + char *str = NULL; + xmlChar *qname = NULL; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + switch (nodep->type) { + case XML_ATTRIBUTE_NODE: + case XML_ELEMENT_NODE: + ns = nodep->ns; + if (ns != NULL && ns->prefix) { + qname = xmlStrdup(ns->prefix); + qname = xmlStrcat(qname, ":"); + qname = xmlStrcat(qname, nodep->name); + str = qname; + } else { + str = (char *) nodep->name; + } + break; + case XML_NAMESPACE_DECL: + ns = nodep->ns; + if (ns != NULL && ns->prefix) { + qname = xmlStrdup("xmlns"); + qname = xmlStrcat(qname, ":"); + qname = xmlStrcat(qname, nodep->name); + str = qname; + } else { + str = (char *) nodep->name; + } + break; + case XML_DOCUMENT_TYPE_NODE: + case XML_DTD_NODE: + case XML_PI_NODE: + case XML_ENTITY_DECL: + case XML_ENTITY_REF_NODE: + case XML_NOTATION_NODE: + str = (char *) nodep->name; + break; + case XML_CDATA_SECTION_NODE: + str = "#cdata-section"; + break; + case XML_COMMENT_NODE: + str = "#comment"; + break; + case XML_HTML_DOCUMENT_NODE: + case XML_DOCUMENT_NODE: + str = "#document"; + break; + case XML_DOCUMENT_FRAG_NODE: + str = "#document-fragment"; + break; + case XML_TEXT_NODE: + str = "#text"; + break; + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Node Type"); + } + + ALLOC_ZVAL(*retval); + + if(str != NULL) { + ZVAL_STRING(*retval, str, 1); + } else { + ZVAL_EMPTY_STRING(*retval); + } + + if (qname != NULL) { + xmlFree(qname); + } + + return SUCCESS; + +} + +/* }}} */ + +/* {{{ nodeValue string +readonly=no +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68D080 +Since: +*/ +int dom_node_node_value_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNode *nodep; + char *str = NULL; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + /* Access to Element node is implemented as a convience method */ + switch (nodep->type) { + case XML_ATTRIBUTE_NODE: + case XML_TEXT_NODE: + case XML_ELEMENT_NODE: + case XML_COMMENT_NODE: + case XML_CDATA_SECTION_NODE: + case XML_PI_NODE: + str = xmlNodeGetContent(nodep); + break; + case XML_NAMESPACE_DECL: + str = xmlNodeGetContent(nodep->children); + break; + default: + str = NULL; + break; + } + + ALLOC_ZVAL(*retval); + + if(str != NULL) { + ZVAL_STRING(*retval, str, 1); + xmlFree(str); + } else { + ZVAL_NULL(*retval); + } + + + return SUCCESS; + +} + +int dom_node_node_value_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + xmlNode *nodep; + zval value_copy; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + /* Access to Element node is implemented as a convience method */ + switch (nodep->type) { + case XML_ELEMENT_NODE: + case XML_ATTRIBUTE_NODE: + if (nodep->children) { + node_list_unlink(nodep->children TSRMLS_CC); + } + case XML_TEXT_NODE: + case XML_COMMENT_NODE: + case XML_CDATA_SECTION_NODE: + case XML_PI_NODE: + if (newval->type != IS_STRING) { + if(Z_REFCOUNT_P(newval) > 1) { + value_copy = *newval; + zval_copy_ctor(&value_copy); + newval = &value_copy; + } + convert_to_string(newval); + } + xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1); + if (newval == &value_copy) { + zval_dtor(newval); + } + break; + default: + break; + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ nodeType int +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-111237558 +Since: +*/ +int dom_node_node_type_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNode *nodep; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + /* Specs dictate that they are both type XML_DOCUMENT_TYPE_NODE */ + if (nodep->type == XML_DTD_NODE) { + ZVAL_LONG(*retval, XML_DOCUMENT_TYPE_NODE); + } else { + ZVAL_LONG(*retval, nodep->type); + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ parentNode DomNode +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1060184317 +Since: +*/ +int dom_node_parent_node_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNode *nodep, *nodeparent; + int ret; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + nodeparent = nodep->parent; + if (!nodeparent) { + ZVAL_NULL(*retval); + return SUCCESS; + } + + if (NULL == (*retval = php_dom_create_object(nodeparent, &ret, *retval, obj TSRMLS_CC))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); + return FAILURE; + } + return SUCCESS; +} + +/* }}} */ + +/* {{{ childNodes DomNodeList +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1451460987 +Since: +*/ +int dom_node_child_nodes_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNode *nodep; + dom_object *intern; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + if (dom_node_children_valid(nodep) == FAILURE) { + ZVAL_NULL(*retval); + } else { + php_dom_create_interator(*retval, DOM_NODELIST TSRMLS_CC); + intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC); + dom_namednode_iter(obj, XML_ELEMENT_NODE, intern, NULL, NULL, NULL TSRMLS_CC); + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ firstChild DomNode +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-169727388 +Since: +*/ +int dom_node_first_child_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNode *nodep, *first = NULL; + int ret; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + if (dom_node_children_valid(nodep) == SUCCESS) { + first = nodep->children; + } + + ALLOC_ZVAL(*retval); + + if (!first) { + ZVAL_NULL(*retval); + return SUCCESS; + } + + if (NULL == (*retval = php_dom_create_object(first, &ret, *retval, obj TSRMLS_CC))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); + return FAILURE; + } + return SUCCESS; +} + +/* }}} */ + +/* {{{ lastChild DomNode +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-61AD09FB +Since: +*/ +int dom_node_last_child_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNode *nodep, *last = NULL; + int ret; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + if (dom_node_children_valid(nodep) == SUCCESS) { + last = nodep->last; + } + + ALLOC_ZVAL(*retval); + + if (!last) { + ZVAL_NULL(*retval); + return SUCCESS; + } + + if (NULL == (*retval = php_dom_create_object(last, &ret, *retval, obj TSRMLS_CC))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); + return FAILURE; + } + return SUCCESS; +} + +/* }}} */ + +/* {{{ previousSibling DomNode +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-640FB3C8 +Since: +*/ +int dom_node_previous_sibling_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNode *nodep, *prevsib; + int ret; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + prevsib = nodep->prev; + if (!prevsib) { + ZVAL_NULL(*retval); + return SUCCESS; + } + + if (NULL == (*retval = php_dom_create_object(prevsib, &ret, *retval, obj TSRMLS_CC))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); + return FAILURE; + } + return SUCCESS; +} + +/* }}} */ + +/* {{{ nextSibling DomNode +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6AC54C2F +Since: +*/ +int dom_node_next_sibling_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNode *nodep, *nextsib; + int ret; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + nextsib = nodep->next; + if (!nextsib) { + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + if (NULL == (*retval = php_dom_create_object(nextsib, &ret, *retval, obj TSRMLS_CC))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); + return FAILURE; + } + return SUCCESS; +} + +/* }}} */ + +/* {{{ attributes DomNamedNodeMap +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-84CF096 +Since: +*/ +int dom_node_attributes_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNode *nodep; + dom_object *intern; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + if (nodep->type == XML_ELEMENT_NODE) { + php_dom_create_interator(*retval, DOM_NAMEDNODEMAP TSRMLS_CC); + intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC); + dom_namednode_iter(obj, XML_ATTRIBUTE_NODE, intern, NULL, NULL, NULL TSRMLS_CC); + } else { + ZVAL_NULL(*retval); + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ ownerDocument DomDocument +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-node-ownerDoc +Since: +*/ +int dom_node_owner_document_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNode *nodep; + xmlDocPtr docp; + int ret; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) { + ALLOC_ZVAL(*retval); + ZVAL_NULL(*retval); + return SUCCESS; + } + + docp = nodep->doc; + if (!docp) { + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + if (NULL == (*retval = php_dom_create_object((xmlNodePtr) docp, &ret, *retval, obj TSRMLS_CC))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); + return FAILURE; + } + return SUCCESS; +} + +/* }}} */ + +/* {{{ namespaceUri string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSname +Since: DOM Level 2 +*/ +int dom_node_namespace_uri_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNode *nodep; + char *str = NULL; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + switch (nodep->type) { + case XML_ELEMENT_NODE: + case XML_ATTRIBUTE_NODE: + case XML_NAMESPACE_DECL: + if (nodep->ns != NULL) { + str = (char *) nodep->ns->href; + } + break; + default: + str = NULL; + break; + } + + ALLOC_ZVAL(*retval); + + if(str != NULL) { + ZVAL_STRING(*retval, str, 1); + } else { + ZVAL_NULL(*retval); + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ prefix string +readonly=no +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSPrefix +Since: DOM Level 2 +*/ +int dom_node_prefix_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNode *nodep; + xmlNsPtr ns; + char *str = NULL; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + switch (nodep->type) { + case XML_ELEMENT_NODE: + case XML_ATTRIBUTE_NODE: + case XML_NAMESPACE_DECL: + ns = nodep->ns; + if (ns != NULL && ns->prefix) { + str = (char *) ns->prefix; + } + break; + default: + str = NULL; + break; + } + + ALLOC_ZVAL(*retval); + + if (str == NULL) { + ZVAL_EMPTY_STRING(*retval); + } else { + ZVAL_STRING(*retval, str, 1); + } + return SUCCESS; + +} + +int dom_node_prefix_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + zval value_copy; + xmlNode *nodep, *nsnode = NULL; + xmlNsPtr ns = NULL, curns; + char *strURI; + char *prefix; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + switch (nodep->type) { + case XML_ELEMENT_NODE: + nsnode = nodep; + case XML_ATTRIBUTE_NODE: + if (nsnode == NULL) { + nsnode = nodep->parent; + if (nsnode == NULL) { + nsnode = xmlDocGetRootElement(nodep->doc); + } + } + if (newval->type != IS_STRING) { + if(Z_REFCOUNT_P(newval) > 1) { + value_copy = *newval; + zval_copy_ctor(&value_copy); + newval = &value_copy; + } + convert_to_string(newval); + } + prefix = Z_STRVAL_P(newval); + if (nsnode && nodep->ns != NULL && !xmlStrEqual(nodep->ns->prefix, (xmlChar *)prefix)) { + strURI = (char *) nodep->ns->href; + if (strURI == NULL || + (!strcmp (prefix, "xml") && strcmp(strURI, XML_XML_NAMESPACE)) || + (nodep->type == XML_ATTRIBUTE_NODE && !strcmp (prefix, "xmlns") && + strcmp (strURI, DOM_XMLNS_NAMESPACE)) || + (nodep->type == XML_ATTRIBUTE_NODE && !strcmp (nodep->name, "xmlns"))) { + ns = NULL; + } else { + curns = nsnode->nsDef; + while (curns != NULL) { + if (xmlStrEqual((xmlChar *)prefix, curns->prefix) && xmlStrEqual(nodep->ns->href, curns->href)) { + ns = curns; + break; + } + curns = curns->next; + } + if (ns == NULL) { + ns = xmlNewNs(nsnode, nodep->ns->href, (xmlChar *)prefix); + } + } + + if (ns == NULL) { + if (newval == &value_copy) { + zval_dtor(newval); + } + php_dom_throw_error(NAMESPACE_ERR, dom_get_strict_error(obj->document) TSRMLS_CC); + return FAILURE; + } + + xmlSetNs(nodep, ns); + } + if (newval == &value_copy) { + zval_dtor(newval); + } + break; + default: + break; + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ localName string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSLocalN +Since: DOM Level 2 +*/ +int dom_node_local_name_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNode *nodep; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + if (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE || nodep->type == XML_NAMESPACE_DECL) { + ZVAL_STRING(*retval, (char *) (nodep->name), 1); + } else { + ZVAL_NULL(*retval); + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ baseURI string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-baseURI +Since: DOM Level 3 +*/ +int dom_node_base_uri_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNode *nodep; + xmlChar *baseuri; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + baseuri = xmlNodeGetBase(nodep->doc, nodep); + if (baseuri) { + ZVAL_STRING(*retval, (char *) (baseuri), 1); + xmlFree(baseuri); + } else { + ZVAL_NULL(*retval); + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ textContent string +readonly=no +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-textContent +Since: DOM Level 3 +*/ +int dom_node_text_content_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNode *nodep; + char *str = NULL; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + str = xmlNodeGetContent(nodep); + + ALLOC_ZVAL(*retval); + + if(str != NULL) { + ZVAL_STRING(*retval, str, 1); + xmlFree(str); + } else { + ZVAL_EMPTY_STRING(*retval); + } + + return SUCCESS; +} + +int dom_node_text_content_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + return SUCCESS; +} + +/* }}} */ + +static xmlNodePtr _php_dom_insert_fragment(xmlNodePtr nodep, xmlNodePtr prevsib, xmlNodePtr nextsib, xmlNodePtr fragment, dom_object *intern, dom_object *childobj TSRMLS_DC) /* {{{ */ +{ + xmlNodePtr newchild, node; + + newchild = fragment->children; + + if (newchild) { + if (prevsib == NULL) { + nodep->children = newchild; + } else { + prevsib->next = newchild; + } + newchild->prev = prevsib; + if (nextsib == NULL) { + nodep->last = fragment->last; + } else { + fragment->last->next = nextsib; + nextsib->prev = fragment->last; + } + + node = newchild; + while (node != NULL) { + node->parent = nodep; + if (node->doc != nodep->doc) { + xmlSetTreeDoc(node, nodep->doc); + if (node->_private != NULL) { + childobj = node->_private; + childobj->document = intern->document; + php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC); + } + } + if (node == fragment->last) { + break; + } + node = node->next; + } + + fragment->children = NULL; + fragment->last = NULL; + } + + return newchild; +} +/* }}} */ + +/* {{{ proto domnode dom_node_insert_before(DomNode newChild, DomNode refChild); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-952280727 +Since: +*/ +PHP_FUNCTION(dom_node_insert_before) +{ + zval *id, *node, *ref = NULL; + xmlNodePtr child, new_child, parentp, refp; + dom_object *intern, *childobj, *refpobj; + int ret, stricterror; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO|O!", &id, dom_node_class_entry, &node, dom_node_class_entry, &ref, dom_node_class_entry) == FAILURE) { + return; + } + + DOM_GET_OBJ(parentp, id, xmlNodePtr, intern); + + if (dom_node_children_valid(parentp) == FAILURE) { + RETURN_FALSE; + } + + DOM_GET_OBJ(child, node, xmlNodePtr, childobj); + + new_child = NULL; + + stricterror = dom_get_strict_error(intern->document); + + if (dom_node_is_read_only(parentp) == SUCCESS || + (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC); + RETURN_FALSE; + } + + if (dom_hierarchy(parentp, child) == FAILURE) { + php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC); + RETURN_FALSE; + } + + if (child->doc != parentp->doc && child->doc != NULL) { + php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC); + RETURN_FALSE; + } + + if (child->type == XML_DOCUMENT_FRAG_NODE && child->children == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Fragment is empty"); + RETURN_FALSE; + } + + if (child->doc == NULL && parentp->doc != NULL) { + childobj->document = intern->document; + php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC); + } + + if (ref != NULL) { + DOM_GET_OBJ(refp, ref, xmlNodePtr, refpobj); + if (refp->parent != parentp) { + php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC); + RETURN_FALSE; + } + + if (child->parent != NULL) { + xmlUnlinkNode(child); + } + + if (child->type == XML_TEXT_NODE && (refp->type == XML_TEXT_NODE || + (refp->prev != NULL && refp->prev->type == XML_TEXT_NODE))) { + if (child->doc == NULL) { + xmlSetTreeDoc(child, parentp->doc); + } + new_child = child; + new_child->parent = refp->parent; + new_child->next = refp; + new_child->prev = refp->prev; + refp->prev = new_child; + if (new_child->prev != NULL) { + new_child->prev->next = new_child; + } + if (new_child->parent != NULL) { + if (new_child->parent->children == refp) { + new_child->parent->children = new_child; + } + } + + } else if (child->type == XML_ATTRIBUTE_NODE) { + xmlAttrPtr lastattr; + + if (child->ns == NULL) + lastattr = xmlHasProp(refp->parent, child->name); + else + lastattr = xmlHasNsProp(refp->parent, child->name, child->ns->href); + if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) { + if (lastattr != (xmlAttrPtr) child) { + xmlUnlinkNode((xmlNodePtr) lastattr); + php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC); + } else { + DOM_RET_OBJ(child, &ret, intern); + return; + } + } + } else if (child->type == XML_DOCUMENT_FRAG_NODE) { + new_child = _php_dom_insert_fragment(parentp, refp->prev, refp, child, intern, childobj TSRMLS_CC); + } + + if (new_child == NULL) { + new_child = xmlAddPrevSibling(refp, child); + } + } else { + if (child->parent != NULL){ + xmlUnlinkNode(child); + } + if (child->type == XML_TEXT_NODE && parentp->last != NULL && parentp->last->type == XML_TEXT_NODE) { + child->parent = parentp; + if (child->doc == NULL) { + xmlSetTreeDoc(child, parentp->doc); + } + new_child = child; + if (parentp->children == NULL) { + parentp->children = child; + parentp->last = child; + } else { + child = parentp->last; + child->next = new_child; + new_child->prev = child; + parentp->last = new_child; + } + } else if (child->type == XML_ATTRIBUTE_NODE) { + xmlAttrPtr lastattr; + + if (child->ns == NULL) + lastattr = xmlHasProp(parentp, child->name); + else + lastattr = xmlHasNsProp(parentp, child->name, child->ns->href); + if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) { + if (lastattr != (xmlAttrPtr) child) { + xmlUnlinkNode((xmlNodePtr) lastattr); + php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC); + } else { + DOM_RET_OBJ(child, &ret, intern); + return; + } + } + } else if (child->type == XML_DOCUMENT_FRAG_NODE) { + new_child = _php_dom_insert_fragment(parentp, parentp->last, NULL, child, intern, childobj TSRMLS_CC); + } + if (new_child == NULL) { + new_child = xmlAddChild(parentp, child); + } + } + + if (NULL == new_child) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't add newnode as the previous sibling of refnode"); + RETURN_FALSE; + } + + dom_reconcile_ns(parentp->doc, new_child); + + DOM_RET_OBJ(new_child, &ret, intern); + +} +/* }}} end dom_node_insert_before */ + +/* {{{ proto DomNode dom_node_replace_child(DomNode newChild, DomNode oldChild); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-785887307 +Since: +*/ +PHP_FUNCTION(dom_node_replace_child) +{ + zval *id, *newnode, *oldnode; + xmlNodePtr children, newchild, oldchild, nodep; + dom_object *intern, *newchildobj, *oldchildobj; + int foundoldchild = 0, stricterror; + + int ret; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OOO", &id, dom_node_class_entry, &newnode, dom_node_class_entry, &oldnode, dom_node_class_entry) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + if (dom_node_children_valid(nodep) == FAILURE) { + RETURN_FALSE; + } + + DOM_GET_OBJ(newchild, newnode, xmlNodePtr, newchildobj); + DOM_GET_OBJ(oldchild, oldnode, xmlNodePtr, oldchildobj); + + children = nodep->children; + if (!children) { + RETURN_FALSE; + } + + stricterror = dom_get_strict_error(intern->document); + + if (dom_node_is_read_only(nodep) == SUCCESS || + (newchild->parent != NULL && dom_node_is_read_only(newchild->parent) == SUCCESS)) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC); + RETURN_FALSE; + } + + if (newchild->doc != nodep->doc && newchild->doc != NULL) { + php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC); + RETURN_FALSE; + } + + if (dom_hierarchy(nodep, newchild) == FAILURE) { + php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC); + RETURN_FALSE; + } + + /* check for the old child and whether the new child is already a child */ + while (children) { + if (children == oldchild) { + foundoldchild = 1; + break; + } + children = children->next; + } + + if (foundoldchild) { + if (newchild->type == XML_DOCUMENT_FRAG_NODE) { + xmlNodePtr prevsib, nextsib; + prevsib = oldchild->prev; + nextsib = oldchild->next; + + xmlUnlinkNode(oldchild); + + newchild = _php_dom_insert_fragment(nodep, prevsib, nextsib, newchild, intern, newchildobj TSRMLS_CC); + if (newchild) { + dom_reconcile_ns(nodep->doc, newchild); + } + } else if (oldchild != newchild) { + if (newchild->doc == NULL && nodep->doc != NULL) { + xmlSetTreeDoc(newchild, nodep->doc); + newchildobj->document = intern->document; + php_libxml_increment_doc_ref((php_libxml_node_object *)newchildobj, NULL TSRMLS_CC); + } + xmlReplaceNode(oldchild, newchild); + dom_reconcile_ns(nodep->doc, newchild); + } + DOM_RET_OBJ(oldchild, &ret, intern); + return; + } else { + php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); + RETURN_FALSE; + } +} +/* }}} end dom_node_replace_child */ + +/* {{{ proto DomNode dom_node_remove_child(DomNode oldChild); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1734834066 +Since: +*/ +PHP_FUNCTION(dom_node_remove_child) +{ + zval *id, *node; + xmlNodePtr children, child, nodep; + dom_object *intern, *childobj; + int ret, stricterror; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + if (dom_node_children_valid(nodep) == FAILURE) { + RETURN_FALSE; + } + + DOM_GET_OBJ(child, node, xmlNodePtr, childobj); + + stricterror = dom_get_strict_error(intern->document); + + if (dom_node_is_read_only(nodep) == SUCCESS || + (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC); + RETURN_FALSE; + } + + children = nodep->children; + if (!children) { + php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC); + RETURN_FALSE; + } + + while (children) { + if (children == child) { + xmlUnlinkNode(child); + DOM_RET_OBJ(child, &ret, intern); + return; + } + children = children->next; + } + + php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC); + RETURN_FALSE +} +/* }}} end dom_node_remove_child */ + +/* {{{ proto DomNode dom_node_append_child(DomNode newChild); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-184E7107 +Since: +*/ +PHP_FUNCTION(dom_node_append_child) +{ + zval *id, *node; + xmlNodePtr child, nodep, new_child = NULL; + dom_object *intern, *childobj; + int ret, stricterror; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + if (dom_node_children_valid(nodep) == FAILURE) { + RETURN_FALSE; + } + + DOM_GET_OBJ(child, node, xmlNodePtr, childobj); + + stricterror = dom_get_strict_error(intern->document); + + if (dom_node_is_read_only(nodep) == SUCCESS || + (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC); + RETURN_FALSE; + } + + if (dom_hierarchy(nodep, child) == FAILURE) { + php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC); + RETURN_FALSE; + } + + if (!(child->doc == NULL || child->doc == nodep->doc)) { + php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC); + RETURN_FALSE; + } + + if (child->type == XML_DOCUMENT_FRAG_NODE && child->children == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Fragment is empty"); + RETURN_FALSE; + } + + if (child->doc == NULL && nodep->doc != NULL) { + childobj->document = intern->document; + php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC); + } + + if (child->parent != NULL){ + xmlUnlinkNode(child); + } + + if (child->type == XML_TEXT_NODE && nodep->last != NULL && nodep->last->type == XML_TEXT_NODE) { + child->parent = nodep; + if (child->doc == NULL) { + xmlSetTreeDoc(child, nodep->doc); + } + new_child = child; + if (nodep->children == NULL) { + nodep->children = child; + nodep->last = child; + } else { + child = nodep->last; + child->next = new_child; + new_child->prev = child; + nodep->last = new_child; + } + } else if (child->type == XML_ATTRIBUTE_NODE) { + xmlAttrPtr lastattr; + + if (child->ns == NULL) + lastattr = xmlHasProp(nodep, child->name); + else + lastattr = xmlHasNsProp(nodep, child->name, child->ns->href); + if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) { + if (lastattr != (xmlAttrPtr) child) { + xmlUnlinkNode((xmlNodePtr) lastattr); + php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC); + } + } + } else if (child->type == XML_DOCUMENT_FRAG_NODE) { + new_child = _php_dom_insert_fragment(nodep, nodep->last, NULL, child, intern, childobj TSRMLS_CC); + } + + if (new_child == NULL) { + new_child = xmlAddChild(nodep, child); + if (new_child == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't append node"); + RETURN_FALSE; + } + } + + dom_reconcile_ns(nodep->doc, new_child); + + DOM_RET_OBJ(new_child, &ret, intern); +} +/* }}} end dom_node_append_child */ + +/* {{{ proto boolean dom_node_has_child_nodes(); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-810594187 +Since: +*/ +PHP_FUNCTION(dom_node_has_child_nodes) +{ + zval *id; + xmlNode *nodep; + dom_object *intern; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + if (dom_node_children_valid(nodep) == FAILURE) { + RETURN_FALSE; + } + + if (nodep->children) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} end dom_node_has_child_nodes */ + +/* {{{ proto DomNode dom_node_clone_node(boolean deep); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3A0ED0A4 +Since: +*/ +PHP_FUNCTION(dom_node_clone_node) +{ + zval *id; + xmlNode *n, *node; + int ret; + dom_object *intern; + long recursive = 0; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &id, dom_node_class_entry, &recursive) == FAILURE) { + return; + } + + DOM_GET_OBJ(n, id, xmlNodePtr, intern); + + node = xmlDocCopyNode(n, n->doc, recursive); + + if (!node) { + RETURN_FALSE; + } + + /* When deep is false Element nodes still require the attributes + Following taken from libxml as xmlDocCopyNode doesnt do this */ + if (n->type == XML_ELEMENT_NODE && recursive == 0) { + if (n->nsDef != NULL) { + node->nsDef = xmlCopyNamespaceList(n->nsDef); + } + if (n->ns != NULL) { + xmlNsPtr ns; + ns = xmlSearchNs(n->doc, node, n->ns->prefix); + if (ns == NULL) { + ns = xmlSearchNs(n->doc, n, n->ns->prefix); + if (ns != NULL) { + xmlNodePtr root = node; + + while (root->parent != NULL) { + root = root->parent; + } + node->ns = xmlNewNs(root, ns->href, ns->prefix); + } + } else { + node->ns = ns; + } + } + if (n->properties != NULL) { + node->properties = xmlCopyPropList(node, n->properties); + } + } + + /* If document cloned we want a new document proxy */ + if (node->doc != n->doc) { + intern = NULL; + } + + DOM_RET_OBJ(node, &ret, intern); +} +/* }}} end dom_node_clone_node */ + +/* {{{ proto void dom_node_normalize(); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-normalize +Since: +*/ +PHP_FUNCTION(dom_node_normalize) +{ + zval *id; + xmlNode *nodep; + dom_object *intern; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + dom_normalize(nodep TSRMLS_CC); + +} +/* }}} end dom_node_normalize */ + +/* {{{ proto boolean dom_node_is_supported(string feature, string version); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Level-2-Core-Node-supports +Since: DOM Level 2 +*/ +PHP_FUNCTION(dom_node_is_supported) +{ + zval *id; + int feature_len, version_len; + char *feature, *version; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_node_class_entry, &feature, &feature_len, &version, &version_len) == FAILURE) { + return; + } + + if (dom_has_feature(feature, version)) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} end dom_node_is_supported */ + +/* {{{ proto boolean dom_node_has_attributes(); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeHasAttrs +Since: DOM Level 2 +*/ +PHP_FUNCTION(dom_node_has_attributes) +{ + zval *id; + xmlNode *nodep; + dom_object *intern; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + if (nodep->type != XML_ELEMENT_NODE) + RETURN_FALSE; + + if (nodep->properties) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} end dom_node_has_attributes */ + +/* {{{ proto short dom_node_compare_document_position(DomNode other); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-compareDocumentPosition +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_node_compare_document_position) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_node_compare_document_position */ + +/* {{{ proto boolean dom_node_is_same_node(DomNode other); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isSameNode +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_node_is_same_node) +{ + zval *id, *node; + xmlNodePtr nodeotherp, nodep; + dom_object *intern, *nodeotherobj; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + DOM_GET_OBJ(nodeotherp, node, xmlNodePtr, nodeotherobj); + + if (nodep == nodeotherp) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} end dom_node_is_same_node */ + +/* {{{ proto string dom_node_lookup_prefix(string namespaceURI); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-lookupNamespacePrefix +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_node_lookup_prefix) +{ + zval *id; + xmlNodePtr nodep, lookupp = NULL; + dom_object *intern; + xmlNsPtr nsptr; + int uri_len = 0; + char *uri; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_node_class_entry, &uri, &uri_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + if (uri_len > 0) { + switch (nodep->type) { + case XML_ELEMENT_NODE: + lookupp = nodep; + break; + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: + lookupp = xmlDocGetRootElement((xmlDocPtr) nodep); + break; + case XML_ENTITY_NODE : + case XML_NOTATION_NODE: + case XML_DOCUMENT_FRAG_NODE: + case XML_DOCUMENT_TYPE_NODE: + case XML_DTD_NODE: + RETURN_NULL(); + break; + default: + lookupp = nodep->parent; + } + + if (lookupp != NULL && (nsptr = xmlSearchNsByHref(lookupp->doc, lookupp, uri))) { + if (nsptr->prefix != NULL) { + RETURN_STRING((char *) nsptr->prefix, 1); + } + } + } + + RETURN_NULL(); +} +/* }}} end dom_node_lookup_prefix */ + +/* {{{ proto boolean dom_node_is_default_namespace(string namespaceURI); +URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-isDefaultNamespace +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_node_is_default_namespace) +{ + zval *id; + xmlNodePtr nodep; + dom_object *intern; + xmlNsPtr nsptr; + int uri_len = 0; + char *uri; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_node_class_entry, &uri, &uri_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) { + nodep = xmlDocGetRootElement((xmlDocPtr) nodep); + } + + if (nodep && uri_len > 0) { + nsptr = xmlSearchNs(nodep->doc, nodep, NULL); + if (nsptr && xmlStrEqual(nsptr->href, uri)) { + RETURN_TRUE; + } + } + + RETURN_FALSE; +} +/* }}} end dom_node_is_default_namespace */ + +/* {{{ proto string dom_node_lookup_namespace_uri(string prefix); +URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_node_lookup_namespace_uri) +{ + zval *id; + xmlNodePtr nodep; + dom_object *intern; + xmlNsPtr nsptr; + int prefix_len = 0; + char *prefix=NULL; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!", &id, dom_node_class_entry, &prefix, &prefix_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) { + nodep = xmlDocGetRootElement((xmlDocPtr) nodep); + if (nodep == NULL) { + RETURN_NULL(); + } + } + + nsptr = xmlSearchNs(nodep->doc, nodep, prefix); + if (nsptr && nsptr->href != NULL) { + RETURN_STRING((char *) nsptr->href, 1); + } + + RETURN_NULL(); +} +/* }}} end dom_node_lookup_namespace_uri */ + +/* {{{ proto boolean dom_node_is_equal_node(DomNode arg); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isEqualNode +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_node_is_equal_node) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_node_is_equal_node */ + +/* {{{ proto DomNode dom_node_get_feature(string feature, string version); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getFeature +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_node_get_feature) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_node_get_feature */ + +/* {{{ proto mixed dom_node_set_user_data(string key, mixed data, userdatahandler handler); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-setUserData +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_node_set_user_data) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_node_set_user_data */ + +/* {{{ proto mixed dom_node_get_user_data(string key); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getUserData +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_node_get_user_data) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_node_get_user_data */ + +static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ +{ + zval *id; + zval *xpath_array=NULL, *ns_prefixes=NULL; + xmlNodePtr nodep; + xmlDocPtr docp; + xmlNodeSetPtr nodeset = NULL; + dom_object *intern; + zend_bool exclusive=0, with_comments=0; + xmlChar **inclusive_ns_prefixes = NULL; + char *file = NULL; + int ret = -1, file_len = 0; + xmlOutputBufferPtr buf; + xmlXPathContextPtr ctxp=NULL; + xmlXPathObjectPtr xpathobjp=NULL; + + if (mode == 0) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), + "O|bba!a!", &id, dom_node_class_entry, &exclusive, &with_comments, + &xpath_array, &ns_prefixes) == FAILURE) { + return; + } + } else { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), + "Os|bba!a!", &id, dom_node_class_entry, &file, &file_len, &exclusive, + &with_comments, &xpath_array, &ns_prefixes) == FAILURE) { + return; + } + } + + DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); + + docp = nodep->doc; + + if (! docp) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Node must be associated with a document"); + RETURN_FALSE; + } + + if (xpath_array == NULL) { + if (nodep->type != XML_DOCUMENT_NODE) { + ctxp = xmlXPathNewContext(docp); + ctxp->node = nodep; + xpathobjp = xmlXPathEvalExpression("(.//. | .//@* | .//namespace::*)", ctxp); + ctxp->node = NULL; + if (xpathobjp && xpathobjp->type == XPATH_NODESET) { + nodeset = xpathobjp->nodesetval; + } else { + if (xpathobjp) { + xmlXPathFreeObject(xpathobjp); + } + xmlXPathFreeContext(ctxp); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "XPath query did not return a nodeset."); + RETURN_FALSE; + } + } + } else { + /*xpath query from xpath_array */ + HashTable *ht = Z_ARRVAL_P(xpath_array); + zval **tmp; + char *xquery; + + if (zend_hash_find(ht, "query", sizeof("query"), (void**)&tmp) == SUCCESS && + Z_TYPE_PP(tmp) == IS_STRING) { + xquery = Z_STRVAL_PP(tmp); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "'query' missing from xpath array or is not a string"); + RETURN_FALSE; + } + + ctxp = xmlXPathNewContext(docp); + ctxp->node = nodep; + + if (zend_hash_find(ht, "namespaces", sizeof("namespaces"), (void**)&tmp) == SUCCESS && + Z_TYPE_PP(tmp) == IS_ARRAY) { + zval **tmpns; + while (zend_hash_get_current_data(Z_ARRVAL_PP(tmp), (void **)&tmpns) == SUCCESS) { + if (Z_TYPE_PP(tmpns) == IS_STRING) { + char *prefix; + ulong idx; + uint prefix_key_len; + + if (zend_hash_get_current_key_ex(Z_ARRVAL_PP(tmp), + &prefix, &prefix_key_len, &idx, 0, NULL) == HASH_KEY_IS_STRING) { + xmlXPathRegisterNs(ctxp, prefix, Z_STRVAL_PP(tmpns)); + } + } + zend_hash_move_forward(Z_ARRVAL_PP(tmp)); + } + } + + xpathobjp = xmlXPathEvalExpression(xquery, ctxp); + ctxp->node = NULL; + if (xpathobjp && xpathobjp->type == XPATH_NODESET) { + nodeset = xpathobjp->nodesetval; + } else { + if (xpathobjp) { + xmlXPathFreeObject(xpathobjp); + } + xmlXPathFreeContext(ctxp); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "XPath query did not return a nodeset."); + RETURN_FALSE; + } + } + + if (ns_prefixes != NULL) { + if (exclusive) { + zval **tmpns; + int nscount = 0; + + inclusive_ns_prefixes = safe_emalloc(zend_hash_num_elements(Z_ARRVAL_P(ns_prefixes)) + 1, + sizeof(xmlChar *), 0); + while (zend_hash_get_current_data(Z_ARRVAL_P(ns_prefixes), (void **)&tmpns) == SUCCESS) { + if (Z_TYPE_PP(tmpns) == IS_STRING) { + inclusive_ns_prefixes[nscount++] = Z_STRVAL_PP(tmpns); + } + zend_hash_move_forward(Z_ARRVAL_P(ns_prefixes)); + } + inclusive_ns_prefixes[nscount] = NULL; + } else { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, + "Inclusive namespace prefixes only allowed in exclusive mode."); + } + } + + if (mode == 1) { + buf = xmlOutputBufferCreateFilename(file, NULL, 0); + } else { + buf = xmlAllocOutputBuffer(NULL); + } + + if (buf != NULL) { + ret = xmlC14NDocSaveTo(docp, nodeset, exclusive, inclusive_ns_prefixes, + with_comments, buf); + } + + if (inclusive_ns_prefixes != NULL) { + efree(inclusive_ns_prefixes); + } + if (xpathobjp != NULL) { + xmlXPathFreeObject(xpathobjp); + } + if (ctxp != NULL) { + xmlXPathFreeContext(ctxp); + } + + if (buf == NULL || ret < 0) { + RETVAL_FALSE; + } else { + if (mode == 0) { +#ifdef LIBXML2_NEW_BUFFER + ret = xmlOutputBufferGetSize(buf); +#else + ret = buf->buffer->use; +#endif + if (ret > 0) { +#ifdef LIBXML2_NEW_BUFFER + RETVAL_STRINGL((char *) xmlOutputBufferGetContent(buf), ret, 1); +#else + RETVAL_STRINGL((char *) buf->buffer->content, ret, 1); +#endif + } else { + RETVAL_EMPTY_STRING(); + } + } + } + + if (buf) { + int bytes; + + bytes = xmlOutputBufferClose(buf); + if (mode == 1 && (ret >= 0)) { + RETURN_LONG(bytes); + } + } +} +/* }}} */ + +/* {{{ proto string DOMNode::C14N([bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]]) + Canonicalize nodes to a string */ +PHP_METHOD(domnode, C14N) +{ + dom_canonicalization(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} +/* }}} */ + +/* {{{ proto int DOMNode::C14NFile(string uri [, bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]]) + Canonicalize nodes to a file */ +PHP_METHOD(domnode, C14NFile) +{ + dom_canonicalization(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + +/* {{{ proto int DOMNode::getNodePath() + Gets an xpath for a node */ +PHP_METHOD(domnode, getNodePath) +{ + zval *id; + xmlNode *nodep; + dom_object *intern; + char *value; + + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); + + value = xmlGetNodePath(nodep); + if (value == NULL) { + RETURN_NULL(); + } else { + RETVAL_STRING(value, 1); + xmlFree(value); + } +} +/* }}} */ + +/* {{{ proto int DOMNode::getLineNo() + Gets line number for a node */ +PHP_METHOD(domnode, getLineNo) +{ + zval *id; + xmlNode *nodep; + dom_object *intern; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); + + RETURN_LONG(xmlGetLineNo(nodep)); +} +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/nodelist.c b/ext/dom/nodelist.c new file mode 100644 index 0000000..d856f14 --- /dev/null +++ b/ext/dom/nodelist.c @@ -0,0 +1,184 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_nodelist_item, 0, 0, 1) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class DOMNodeList +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-536297177 +* Since: +*/ + +const zend_function_entry php_dom_nodelist_class_functions[] = { + PHP_FALIAS(item, dom_nodelist_item, arginfo_dom_nodelist_item) + PHP_FE_END +}; + +/* {{{ length int +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-203510337 +Since: +*/ +int dom_nodelist_length_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + dom_nnodemap_object *objmap; + xmlNodePtr nodep, curnode; + int count = 0; + HashTable *nodeht; + + objmap = (dom_nnodemap_object *)obj->ptr; + if (objmap != NULL) { + if (objmap->ht) { + count = xmlHashSize(objmap->ht); + } else { + if (objmap->nodetype == DOM_NODESET) { + nodeht = HASH_OF(objmap->baseobjptr); + count = zend_hash_num_elements(nodeht); + } else { + nodep = dom_object_get_node(objmap->baseobj); + if (nodep) { + if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) { + curnode = nodep->children; + if (curnode) { + count++; + while (curnode->next != NULL) { + count++; + curnode = curnode->next; + } + } + } else { + if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) { + nodep = xmlDocGetRootElement((xmlDoc *) nodep); + } else { + nodep = nodep->children; + } + curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, -1); + } + } + } + } + } + + MAKE_STD_ZVAL(*retval); + ZVAL_LONG(*retval, count); + return SUCCESS; +} + +/* }}} */ + +/* {{{ proto DOMNode dom_nodelist_item(int index); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-844377136 +Since: +*/ +PHP_FUNCTION(dom_nodelist_item) +{ + zval *id; + long index; + int ret; + dom_object *intern; + xmlNodePtr itemnode = NULL; + + dom_nnodemap_object *objmap; + xmlNodePtr nodep, curnode; + int count = 0; + HashTable *nodeht; + zval **entry; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &id, dom_nodelist_class_entry, &index) == FAILURE) { + return; + } + + if (index >= 0) { + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + + objmap = (dom_nnodemap_object *)intern->ptr; + if (objmap != NULL) { + if (objmap->ht) { + if (objmap->nodetype == XML_ENTITY_NODE) { + itemnode = php_dom_libxml_hash_iter(objmap->ht, index); + } else { + itemnode = php_dom_libxml_notation_iter(objmap->ht, index); + } + } else { + if (objmap->nodetype == DOM_NODESET) { + nodeht = HASH_OF(objmap->baseobjptr); + if (zend_hash_index_find(nodeht, index, (void **) &entry)==SUCCESS) { + *return_value = **entry; + zval_copy_ctor(return_value); + return; + } + } else if (objmap->baseobj) { + nodep = dom_object_get_node(objmap->baseobj); + if (nodep) { + if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) { + curnode = nodep->children; + while (count < index && curnode != NULL) { + count++; + curnode = curnode->next; + } + itemnode = curnode; + } else { + if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) { + nodep = xmlDocGetRootElement((xmlDoc *) nodep); + } else { + nodep = nodep->children; + } + itemnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, index); + } + } + } + } + } + + if (itemnode) { + DOM_RET_OBJ(itemnode, &ret, objmap->baseobj); + return; + } + } + + RETVAL_NULL(); +} +/* }}} end dom_nodelist_item */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/notation.c b/ext/dom/notation.c new file mode 100644 index 0000000..1fdfe89 --- /dev/null +++ b/ext/dom/notation.c @@ -0,0 +1,110 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + +/* +* class DOMNotation extends DOMNode +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-5431D1B9 +* Since: +*/ + +const zend_function_entry php_dom_notation_class_functions[] = { + PHP_FE_END +}; + +/* {{{ attribute protos, not implemented yet */ + +/* {{{ publicId string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-54F2B4D0 +Since: +*/ +int dom_notation_public_id_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlEntityPtr nodep; + + nodep = (xmlEntityPtr) dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + if (nodep->ExternalID) { + ZVAL_STRING(*retval, (char *) (nodep->ExternalID), 1); + } else { + ZVAL_EMPTY_STRING(*retval); + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ systemId string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-E8AAB1D0 +Since: +*/ +int dom_notation_system_id_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlEntityPtr nodep; + + nodep = (xmlEntityPtr) dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + if (nodep->SystemID) { + ZVAL_STRING(*retval, (char *) (nodep->SystemID), 1); + } else { + ZVAL_EMPTY_STRING(*retval); + } + + return SUCCESS; +} + +/* }}} */ + +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c new file mode 100644 index 0000000..c3b0ee0 --- /dev/null +++ b/ext/dom/php_dom.c @@ -0,0 +1,1682 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + | Marcus Borger <helly@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "ext/standard/php_rand.h" +#include "php_dom.h" +#include "dom_properties.h" +#include "zend_interfaces.h" + +#include "ext/standard/info.h" +#define PHP_XPATH 1 +#define PHP_XPTR 2 + +/* {{{ class entries */ +zend_class_entry *dom_node_class_entry; +zend_class_entry *dom_domexception_class_entry; +zend_class_entry *dom_domstringlist_class_entry; +zend_class_entry *dom_namelist_class_entry; +zend_class_entry *dom_domimplementationlist_class_entry; +zend_class_entry *dom_domimplementationsource_class_entry; +zend_class_entry *dom_domimplementation_class_entry; +zend_class_entry *dom_documentfragment_class_entry; +zend_class_entry *dom_document_class_entry; +zend_class_entry *dom_nodelist_class_entry; +zend_class_entry *dom_namednodemap_class_entry; +zend_class_entry *dom_characterdata_class_entry; +zend_class_entry *dom_attr_class_entry; +zend_class_entry *dom_element_class_entry; +zend_class_entry *dom_text_class_entry; +zend_class_entry *dom_comment_class_entry; +zend_class_entry *dom_typeinfo_class_entry; +zend_class_entry *dom_userdatahandler_class_entry; +zend_class_entry *dom_domerror_class_entry; +zend_class_entry *dom_domerrorhandler_class_entry; +zend_class_entry *dom_domlocator_class_entry; +zend_class_entry *dom_domconfiguration_class_entry; +zend_class_entry *dom_cdatasection_class_entry; +zend_class_entry *dom_documenttype_class_entry; +zend_class_entry *dom_notation_class_entry; +zend_class_entry *dom_entity_class_entry; +zend_class_entry *dom_entityreference_class_entry; +zend_class_entry *dom_processinginstruction_class_entry; +zend_class_entry *dom_string_extend_class_entry; +#if defined(LIBXML_XPATH_ENABLED) +zend_class_entry *dom_xpath_class_entry; +#endif +zend_class_entry *dom_namespace_node_class_entry; +/* }}} */ + +zend_object_handlers dom_object_handlers; + +static HashTable classes; +/* {{{ prop handler tables */ +static HashTable dom_domstringlist_prop_handlers; +static HashTable dom_namelist_prop_handlers; +static HashTable dom_domimplementationlist_prop_handlers; +static HashTable dom_document_prop_handlers; +static HashTable dom_node_prop_handlers; +static HashTable dom_nodelist_prop_handlers; +static HashTable dom_namednodemap_prop_handlers; +static HashTable dom_characterdata_prop_handlers; +static HashTable dom_attr_prop_handlers; +static HashTable dom_element_prop_handlers; +static HashTable dom_text_prop_handlers; +static HashTable dom_typeinfo_prop_handlers; +static HashTable dom_domerror_prop_handlers; +static HashTable dom_domlocator_prop_handlers; +static HashTable dom_documenttype_prop_handlers; +static HashTable dom_notation_prop_handlers; +static HashTable dom_entity_prop_handlers; +static HashTable dom_processinginstruction_prop_handlers; +static HashTable dom_namespace_node_prop_handlers; +#if defined(LIBXML_XPATH_ENABLED) +static HashTable dom_xpath_prop_handlers; +#endif +/* }}} */ + +typedef int (*dom_read_t)(dom_object *obj, zval **retval TSRMLS_DC); +typedef int (*dom_write_t)(dom_object *obj, zval *newval TSRMLS_DC); + +typedef struct _dom_prop_handler { + dom_read_t read_func; + dom_write_t write_func; +} dom_prop_handler; + +/* {{{ int dom_node_is_read_only(xmlNodePtr node) */ +int dom_node_is_read_only(xmlNodePtr node) { + switch (node->type) { + case XML_ENTITY_REF_NODE: + case XML_ENTITY_NODE: + case XML_DOCUMENT_TYPE_NODE: + case XML_NOTATION_NODE: + case XML_DTD_NODE: + case XML_ELEMENT_DECL: + case XML_ATTRIBUTE_DECL: + case XML_ENTITY_DECL: + case XML_NAMESPACE_DECL: + return SUCCESS; + break; + default: + if (node->doc == NULL) { + return SUCCESS; + } else { + return FAILURE; + } + } +} +/* }}} end dom_node_is_read_only */ + +/* {{{ int dom_node_children_valid(xmlNodePtr node) */ +int dom_node_children_valid(xmlNodePtr node) { + switch (node->type) { + case XML_DOCUMENT_TYPE_NODE: + case XML_DTD_NODE: + case XML_PI_NODE: + case XML_COMMENT_NODE: + case XML_TEXT_NODE: + case XML_CDATA_SECTION_NODE: + case XML_NOTATION_NODE: + return FAILURE; + break; + default: + return SUCCESS; + } +} +/* }}} end dom_node_children_valid */ + +/* {{{ dom_get_doc_props() */ +dom_doc_propsptr dom_get_doc_props(php_libxml_ref_obj *document) +{ + dom_doc_propsptr doc_props; + + if (document && document->doc_props) { + return document->doc_props; + } else { + doc_props = emalloc(sizeof(libxml_doc_props)); + doc_props->formatoutput = 0; + doc_props->validateonparse = 0; + doc_props->resolveexternals = 0; + doc_props->preservewhitespace = 1; + doc_props->substituteentities = 0; + doc_props->stricterror = 1; + doc_props->recover = 0; + doc_props->classmap = NULL; + if (document) { + document->doc_props = doc_props; + } + return doc_props; + } +} + +static void dom_copy_doc_props(php_libxml_ref_obj *source_doc, php_libxml_ref_obj *dest_doc) +{ + dom_doc_propsptr source, dest; + + if (source_doc && dest_doc) { + + source = dom_get_doc_props(source_doc); + dest = dom_get_doc_props(dest_doc); + + dest->formatoutput = source->formatoutput; + dest->validateonparse = source->validateonparse; + dest->resolveexternals = source->resolveexternals; + dest->preservewhitespace = source->preservewhitespace; + dest->substituteentities = source->substituteentities; + dest->stricterror = source->stricterror; + dest->recover = source->recover; + if (source->classmap) { + ALLOC_HASHTABLE(dest->classmap); + zend_hash_init(dest->classmap, 0, NULL, NULL, 0); + zend_hash_copy(dest->classmap, source->classmap, NULL, NULL, sizeof(zend_class_entry *)); + } + + } +} + +int dom_set_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece, zend_class_entry *ce TSRMLS_DC) +{ + dom_doc_propsptr doc_props; + + if (document) { + doc_props = dom_get_doc_props(document); + if (doc_props->classmap == NULL) { + if (ce == NULL) { + return SUCCESS; + } + ALLOC_HASHTABLE(doc_props->classmap); + zend_hash_init(doc_props->classmap, 0, NULL, NULL, 0); + } + if (ce) { + return zend_hash_update(doc_props->classmap, basece->name, basece->name_length + 1, &ce, sizeof(zend_class_entry *), NULL); + } else { + zend_hash_del(doc_props->classmap, basece->name, basece->name_length + 1); + } + } + return SUCCESS; +} + +zend_class_entry *dom_get_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece TSRMLS_DC) +{ + dom_doc_propsptr doc_props; + zend_class_entry **ce = NULL; + + if (document) { + doc_props = dom_get_doc_props(document); + if (doc_props->classmap) { + if (zend_hash_find(doc_props->classmap, basece->name, basece->name_length + 1, (void**) &ce) == SUCCESS) { + return *ce; + } + } + } + + return basece; +} +/* }}} */ + +/* {{{ dom_get_strict_error() */ +int dom_get_strict_error(php_libxml_ref_obj *document) { + int stricterror; + dom_doc_propsptr doc_props; + + doc_props = dom_get_doc_props(document); + stricterror = doc_props->stricterror; + if (document == NULL) { + efree(doc_props); + } + + return stricterror; +} +/* }}} */ + +/* {{{ xmlNodePtr dom_object_get_node(dom_object *obj) */ +PHP_DOM_EXPORT xmlNodePtr dom_object_get_node(dom_object *obj) +{ + if (obj && obj->ptr != NULL) { + return ((php_libxml_node_ptr *)obj->ptr)->node; + } else { + return NULL; + } +} +/* }}} end dom_object_get_node */ + +/* {{{ dom_object *php_dom_object_get_data(xmlNodePtr obj) */ +PHP_DOM_EXPORT dom_object *php_dom_object_get_data(xmlNodePtr obj) +{ + if (obj && obj->_private != NULL) { + return (dom_object *) ((php_libxml_node_ptr *) obj->_private)->_private; + } else { + return NULL; + } +} +/* }}} end php_dom_object_get_data */ + +/* {{{ dom_read_na */ +static int dom_read_na(dom_object *obj, zval **retval TSRMLS_DC) +{ + *retval = NULL; + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot read property"); + return FAILURE; +} +/* }}} */ + +/* {{{ dom_write_na */ +static int dom_write_na(dom_object *obj, zval *newval TSRMLS_DC) +{ + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot write property"); + return FAILURE; +} +/* }}} */ + +/* {{{ dom_register_prop_handler */ +static void dom_register_prop_handler(HashTable *prop_handler, char *name, dom_read_t read_func, dom_write_t write_func TSRMLS_DC) +{ + dom_prop_handler hnd; + + hnd.read_func = read_func ? read_func : dom_read_na; + hnd.write_func = write_func ? write_func : dom_write_na; + zend_hash_add(prop_handler, name, strlen(name)+1, &hnd, sizeof(dom_prop_handler), NULL); +} +/* }}} */ + +static zval **dom_get_property_ptr_ptr(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */ +{ + dom_object *obj; + zval tmp_member; + zval **retval = NULL; + dom_prop_handler *hnd; + zend_object_handlers *std_hnd; + int ret = FAILURE; + + if (member->type != IS_STRING) { + tmp_member = *member; + zval_copy_ctor(&tmp_member); + convert_to_string(&tmp_member); + member = &tmp_member; + } + + obj = (dom_object *)zend_objects_get_address(object TSRMLS_CC); + + if (obj->prop_handler != NULL) { + ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); + } + if (ret == FAILURE) { + std_hnd = zend_get_std_object_handlers(); + retval = std_hnd->get_property_ptr_ptr(object, member, key TSRMLS_CC); + } + + if (member == &tmp_member) { + zval_dtor(member); + } + return retval; +} +/* }}} */ + +/* {{{ dom_read_property */ +zval *dom_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) +{ + dom_object *obj; + zval tmp_member; + zval *retval; + dom_prop_handler *hnd; + zend_object_handlers *std_hnd; + int ret; + + if (member->type != IS_STRING) { + tmp_member = *member; + zval_copy_ctor(&tmp_member); + convert_to_string(&tmp_member); + member = &tmp_member; + } + + ret = FAILURE; + obj = (dom_object *)zend_objects_get_address(object TSRMLS_CC); + + if (obj->prop_handler != NULL) { + ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); + } else if (instanceof_function(obj->std.ce, dom_node_class_entry TSRMLS_CC)) { + php_error(E_WARNING, "Couldn't fetch %s. Node no longer exists", obj->std.ce->name); + } + if (ret == SUCCESS) { + ret = hnd->read_func(obj, &retval TSRMLS_CC); + if (ret == SUCCESS) { + /* ensure we're creating a temporary variable */ + Z_SET_REFCOUNT_P(retval, 0); + Z_UNSET_ISREF_P(retval); + } else { + retval = EG(uninitialized_zval_ptr); + } + } else { + std_hnd = zend_get_std_object_handlers(); + retval = std_hnd->read_property(object, member, type, key TSRMLS_CC); + } + + if (member == &tmp_member) { + zval_dtor(member); + } + return retval; +} +/* }}} */ + +/* {{{ dom_write_property */ +void dom_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) +{ + dom_object *obj; + zval tmp_member; + dom_prop_handler *hnd; + zend_object_handlers *std_hnd; + int ret; + + if (member->type != IS_STRING) { + tmp_member = *member; + zval_copy_ctor(&tmp_member); + convert_to_string(&tmp_member); + member = &tmp_member; + } + + ret = FAILURE; + obj = (dom_object *)zend_objects_get_address(object TSRMLS_CC); + + if (obj->prop_handler != NULL) { + ret = zend_hash_find((HashTable *)obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); + } + if (ret == SUCCESS) { + hnd->write_func(obj, value TSRMLS_CC); + } else { + std_hnd = zend_get_std_object_handlers(); + std_hnd->write_property(object, member, value, key TSRMLS_CC); + } + + if (member == &tmp_member) { + zval_dtor(member); + } +} +/* }}} */ + +/* {{{ dom_property_exists */ +static int dom_property_exists(zval *object, zval *member, int check_empty, const zend_literal *key TSRMLS_DC) +{ + dom_object *obj; + zval tmp_member; + dom_prop_handler *hnd; + zend_object_handlers *std_hnd; + int ret, retval=0; + + if (member->type != IS_STRING) { + tmp_member = *member; + zval_copy_ctor(&tmp_member); + convert_to_string(&tmp_member); + member = &tmp_member; + } + + ret = FAILURE; + obj = (dom_object *)zend_objects_get_address(object TSRMLS_CC); + + if (obj->prop_handler != NULL) { + ret = zend_hash_find((HashTable *)obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); + } + if (ret == SUCCESS) { + zval *tmp; + + if (check_empty == 2) { + retval = 1; + } else if (hnd->read_func(obj, &tmp TSRMLS_CC) == SUCCESS) { + Z_SET_REFCOUNT_P(tmp, 1); + Z_UNSET_ISREF_P(tmp); + if (check_empty == 1) { + retval = zend_is_true(tmp); + } else if (check_empty == 0) { + retval = (Z_TYPE_P(tmp) != IS_NULL); + } + zval_ptr_dtor(&tmp); + } + } else { + std_hnd = zend_get_std_object_handlers(); + retval = std_hnd->has_property(object, member, check_empty, key TSRMLS_CC); + } + + if (member == &tmp_member) { + zval_dtor(member); + } + return retval; +} +/* }}} */ + +static HashTable* dom_get_debug_info_helper(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ +{ + dom_object *obj = zend_object_store_get_object(object TSRMLS_CC); + HashTable *debug_info, + *prop_handlers = obj->prop_handler, + *std_props; + HashPosition pos; + dom_prop_handler *entry; + zval *object_value, + *null_value; + + *is_temp = 1; + + ALLOC_HASHTABLE(debug_info); + ZEND_INIT_SYMTABLE_EX(debug_info, 32, 0); + + std_props = zend_std_get_properties(object TSRMLS_CC); + zend_hash_copy(debug_info, std_props, (copy_ctor_func_t)zval_add_ref, + NULL, sizeof(zval*)); + + if (!prop_handlers) { + return debug_info; + } + + ALLOC_INIT_ZVAL(object_value); + ZVAL_STRING(object_value, "(object value omitted)", 1); + + ALLOC_INIT_ZVAL(null_value); + ZVAL_NULL(null_value); + + for (zend_hash_internal_pointer_reset_ex(prop_handlers, &pos); + zend_hash_get_current_data_ex(prop_handlers, (void **)&entry, &pos) + == SUCCESS; + zend_hash_move_forward_ex(prop_handlers, &pos)) { + zval *value; + char *string_key = NULL; + uint string_length = 0; + ulong num_key; + + if (entry->read_func(obj, &value TSRMLS_CC) == FAILURE) { + continue; + } + + if (zend_hash_get_current_key_ex(prop_handlers, &string_key, + &string_length, &num_key, 0, &pos) != HASH_KEY_IS_STRING) { + continue; + } + + if (value == EG(uninitialized_zval_ptr)) { + value = null_value; + } else if (Z_TYPE_P(value) == IS_OBJECT) { + /* these are zvalues create on demand, with refcount and is_ref + * status left in an uninitalized stated */ + zval_dtor(value); + efree(value); + + value = object_value; + } else { + /* see comment above */ + Z_SET_REFCOUNT_P(value, 0); + Z_UNSET_ISREF_P(value); + } + + zval_add_ref(&value); + zend_hash_add(debug_info, string_key, string_length, + &value, sizeof(zval *), NULL); + } + + zval_ptr_dtor(&null_value); + zval_ptr_dtor(&object_value); + + return debug_info; +} +/* }}} */ + +static HashTable* dom_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ +{ + return dom_get_debug_info_helper(object, is_temp TSRMLS_CC); +} +/* }}} */ + +void *php_dom_export_node(zval *object TSRMLS_DC) /* {{{ */ +{ + php_libxml_node_object *intern; + xmlNodePtr nodep = NULL; + + intern = (php_libxml_node_object *)zend_object_store_get_object(object TSRMLS_CC); + if (intern && intern->node) { + nodep = intern->node->node; + } + + return nodep; +} +/* }}} */ + +/* {{{ proto somNode dom_import_simplexml(sxeobject node) + Get a simplexml_element object from dom to allow for processing */ +PHP_FUNCTION(dom_import_simplexml) +{ + zval *node; + xmlNodePtr nodep = NULL; + php_libxml_node_object *nodeobj; + int ret; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &node) == FAILURE) { + return; + } + + nodeobj = (php_libxml_node_object *)zend_object_store_get_object(node TSRMLS_CC); + nodep = php_libxml_import_node(node TSRMLS_CC); + + if (nodep && nodeobj && (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE)) { + DOM_RET_OBJ((xmlNodePtr) nodep, &ret, (dom_object *)nodeobj); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Nodetype to import"); + RETURN_NULL(); + } +} +/* }}} */ + +zend_object_value dom_objects_store_clone_obj(zval *zobject TSRMLS_DC) /* {{{ */ +{ + zend_object_value retval; + void *new_object; + dom_object *intern; + dom_object *old_object; + struct _store_object *obj; + zend_object_handle handle = Z_OBJ_HANDLE_P(zobject); + + obj = &EG(objects_store).object_buckets[handle].bucket.obj; + + if (obj->clone == NULL) { + php_error(E_ERROR, "Trying to clone an uncloneable object of class %s", Z_OBJCE_P(zobject)->name); + } + + obj->clone(obj->object, &new_object TSRMLS_CC); + + retval.handle = zend_objects_store_put(new_object, obj->dtor, obj->free_storage, obj->clone TSRMLS_CC); + intern = (dom_object *) new_object; + intern->handle = retval.handle; + retval.handlers = Z_OBJ_HT_P(zobject); + + old_object = (dom_object *) obj->object; + zend_objects_clone_members(&intern->std, retval, &old_object->std, intern->handle TSRMLS_CC); + + return retval; +} +/* }}} */ + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_import_simplexml, 0, 0, 1) + ZEND_ARG_INFO(0, node) +ZEND_END_ARG_INFO() +/* }}} */ + +static const zend_function_entry dom_functions[] = { + PHP_FE(dom_import_simplexml, arginfo_dom_import_simplexml) + PHP_FE_END +}; + +static zend_object_handlers* dom_get_obj_handlers(TSRMLS_D) { + return &dom_object_handlers; +} + +static const zend_module_dep dom_deps[] = { + ZEND_MOD_REQUIRED("libxml") + ZEND_MOD_CONFLICTS("domxml") + ZEND_MOD_END +}; + +zend_module_entry dom_module_entry = { /* {{{ */ + STANDARD_MODULE_HEADER_EX, NULL, + dom_deps, + "dom", + dom_functions, + PHP_MINIT(dom), + PHP_MSHUTDOWN(dom), + NULL, + NULL, + PHP_MINFO(dom), + DOM_API_VERSION, /* Extension versionnumber */ + STANDARD_MODULE_PROPERTIES +}; +/* }}} */ + +#ifdef COMPILE_DL_DOM +ZEND_GET_MODULE(dom) +#endif + +/* {{{ PHP_MINIT_FUNCTION(dom) */ +PHP_MINIT_FUNCTION(dom) +{ + zend_class_entry ce; + + memcpy(&dom_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + dom_object_handlers.read_property = dom_read_property; + dom_object_handlers.write_property = dom_write_property; + dom_object_handlers.get_property_ptr_ptr = dom_get_property_ptr_ptr; + dom_object_handlers.clone_obj = dom_objects_store_clone_obj; + dom_object_handlers.has_property = dom_property_exists; + dom_object_handlers.get_debug_info = dom_get_debug_info; + + zend_hash_init(&classes, 0, NULL, NULL, 1); + + INIT_CLASS_ENTRY(ce, "DOMException", php_dom_domexception_class_functions); + dom_domexception_class_entry = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC); + dom_domexception_class_entry->ce_flags |= ZEND_ACC_FINAL; + zend_declare_property_long(dom_domexception_class_entry, "code", sizeof("code")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + + REGISTER_DOM_CLASS(ce, "DOMStringList", NULL, php_dom_domstringlist_class_functions, dom_domstringlist_class_entry); + + zend_hash_init(&dom_domstringlist_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_domstringlist_prop_handlers, "length", dom_domstringlist_length_read, NULL TSRMLS_CC); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_domstringlist_prop_handlers, sizeof(dom_domstringlist_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMNameList", NULL, php_dom_namelist_class_functions, dom_namelist_class_entry); + + zend_hash_init(&dom_namelist_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_namelist_prop_handlers, "length", dom_namelist_length_read, NULL TSRMLS_CC); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_namelist_prop_handlers, sizeof(dom_namelist_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMImplementationList", NULL, php_dom_domimplementationlist_class_functions, dom_domimplementationlist_class_entry); + + zend_hash_init(&dom_domimplementationlist_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_domimplementationlist_prop_handlers, "length", dom_domimplementationlist_length_read, NULL TSRMLS_CC); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_domimplementationlist_prop_handlers, sizeof(dom_domimplementationlist_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMImplementationSource", NULL, php_dom_domimplementationsource_class_functions, dom_domimplementationsource_class_entry); + REGISTER_DOM_CLASS(ce, "DOMImplementation", NULL, php_dom_domimplementation_class_functions, dom_domimplementation_class_entry); + + REGISTER_DOM_CLASS(ce, "DOMNode", NULL, php_dom_node_class_functions, dom_node_class_entry); + + zend_hash_init(&dom_node_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_node_prop_handlers, "nodeName", dom_node_node_name_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_node_prop_handlers, "nodeValue", dom_node_node_value_read, dom_node_node_value_write TSRMLS_CC); + dom_register_prop_handler(&dom_node_prop_handlers, "nodeType", dom_node_node_type_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_node_prop_handlers, "parentNode", dom_node_parent_node_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_node_prop_handlers, "childNodes", dom_node_child_nodes_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_node_prop_handlers, "firstChild", dom_node_first_child_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_node_prop_handlers, "lastChild", dom_node_last_child_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_node_prop_handlers, "previousSibling", dom_node_previous_sibling_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_node_prop_handlers, "nextSibling", dom_node_next_sibling_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_node_prop_handlers, "attributes", dom_node_attributes_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_node_prop_handlers, "ownerDocument", dom_node_owner_document_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_node_prop_handlers, "namespaceURI", dom_node_namespace_uri_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_node_prop_handlers, "prefix", dom_node_prefix_read, dom_node_prefix_write TSRMLS_CC); + dom_register_prop_handler(&dom_node_prop_handlers, "localName", dom_node_local_name_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_node_prop_handlers, "baseURI", dom_node_base_uri_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_node_prop_handlers, "textContent", dom_node_text_content_read, dom_node_text_content_write TSRMLS_CC); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_node_prop_handlers, sizeof(dom_node_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMNameSpaceNode", NULL, NULL, dom_namespace_node_class_entry); + + zend_hash_init(&dom_namespace_node_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_namespace_node_prop_handlers, "nodeName", dom_node_node_name_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_namespace_node_prop_handlers, "nodeValue", dom_node_node_value_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_namespace_node_prop_handlers, "nodeType", dom_node_node_type_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_namespace_node_prop_handlers, "prefix", dom_node_prefix_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_namespace_node_prop_handlers, "localName", dom_node_local_name_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_namespace_node_prop_handlers, "namespaceURI", dom_node_namespace_uri_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_namespace_node_prop_handlers, "ownerDocument", dom_node_owner_document_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_namespace_node_prop_handlers, "parentNode", dom_node_parent_node_read, NULL TSRMLS_CC); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_namespace_node_prop_handlers, sizeof(dom_namespace_node_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMDocumentFragment", dom_node_class_entry, php_dom_documentfragment_class_functions, dom_documentfragment_class_entry); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_node_prop_handlers, sizeof(dom_node_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMDocument", dom_node_class_entry, php_dom_document_class_functions, dom_document_class_entry); + zend_hash_init(&dom_document_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_document_prop_handlers, "doctype", dom_document_doctype_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "implementation", dom_document_implementation_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "documentElement", dom_document_document_element_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "actualEncoding", dom_document_encoding_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "encoding", dom_document_encoding_read, dom_document_encoding_write TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "xmlEncoding", dom_document_encoding_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "standalone", dom_document_standalone_read, dom_document_standalone_write TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "xmlStandalone", dom_document_standalone_read, dom_document_standalone_write TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "version", dom_document_version_read, dom_document_version_write TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "xmlVersion", dom_document_version_read, dom_document_version_write TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "strictErrorChecking", dom_document_strict_error_checking_read, dom_document_strict_error_checking_write TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "documentURI", dom_document_document_uri_read, dom_document_document_uri_write TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "config", dom_document_config_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "formatOutput", dom_document_format_output_read, dom_document_format_output_write TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "validateOnParse", dom_document_validate_on_parse_read, dom_document_validate_on_parse_write TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "resolveExternals", dom_document_resolve_externals_read, dom_document_resolve_externals_write TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "preserveWhiteSpace", dom_document_preserve_whitespace_read, dom_document_preserve_whitespace_write TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "recover", dom_document_recover_read, dom_document_recover_write TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "substituteEntities", dom_document_substitue_entities_read, dom_document_substitue_entities_write TSRMLS_CC); + + zend_hash_merge(&dom_document_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_document_prop_handlers, sizeof(dom_document_prop_handlers), NULL); + + INIT_CLASS_ENTRY(ce, "DOMNodeList", php_dom_nodelist_class_functions); + ce.create_object = dom_nnodemap_objects_new; + dom_nodelist_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + dom_nodelist_class_entry->get_iterator = php_dom_get_iterator; + zend_class_implements(dom_nodelist_class_entry TSRMLS_CC, 1, zend_ce_traversable); + + zend_hash_init(&dom_nodelist_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_nodelist_prop_handlers, "length", dom_nodelist_length_read, NULL TSRMLS_CC); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_nodelist_prop_handlers, sizeof(dom_nodelist_prop_handlers), NULL); + + INIT_CLASS_ENTRY(ce, "DOMNamedNodeMap", php_dom_namednodemap_class_functions); + ce.create_object = dom_nnodemap_objects_new; + dom_namednodemap_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + dom_namednodemap_class_entry->get_iterator = php_dom_get_iterator; + zend_class_implements(dom_namednodemap_class_entry TSRMLS_CC, 1, zend_ce_traversable); + + zend_hash_init(&dom_namednodemap_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_namednodemap_prop_handlers, "length", dom_namednodemap_length_read, NULL TSRMLS_CC); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_namednodemap_prop_handlers, sizeof(dom_namednodemap_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMCharacterData", dom_node_class_entry, php_dom_characterdata_class_functions, dom_characterdata_class_entry); + + zend_hash_init(&dom_characterdata_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_characterdata_prop_handlers, "data", dom_characterdata_data_read, dom_characterdata_data_write TSRMLS_CC); + dom_register_prop_handler(&dom_characterdata_prop_handlers, "length", dom_characterdata_length_read, NULL TSRMLS_CC); + zend_hash_merge(&dom_characterdata_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_characterdata_prop_handlers, sizeof(dom_characterdata_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMAttr", dom_node_class_entry, php_dom_attr_class_functions, dom_attr_class_entry); + + zend_hash_init(&dom_attr_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_attr_prop_handlers, "name", dom_attr_name_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_attr_prop_handlers, "specified", dom_attr_specified_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_attr_prop_handlers, "value", dom_attr_value_read, dom_attr_value_write TSRMLS_CC); + dom_register_prop_handler(&dom_attr_prop_handlers, "ownerElement", dom_attr_owner_element_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_attr_prop_handlers, "schemaTypeInfo", dom_attr_schema_type_info_read, NULL TSRMLS_CC); + zend_hash_merge(&dom_attr_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_attr_prop_handlers, sizeof(dom_attr_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMElement", dom_node_class_entry, php_dom_element_class_functions, dom_element_class_entry); + + zend_hash_init(&dom_element_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_element_prop_handlers, "tagName", dom_element_tag_name_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_element_prop_handlers, "schemaTypeInfo", dom_element_schema_type_info_read, NULL TSRMLS_CC); + zend_hash_merge(&dom_element_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_element_prop_handlers, sizeof(dom_element_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMText", dom_characterdata_class_entry, php_dom_text_class_functions, dom_text_class_entry); + + zend_hash_init(&dom_text_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_text_prop_handlers, "wholeText", dom_text_whole_text_read, NULL TSRMLS_CC); + zend_hash_merge(&dom_text_prop_handlers, &dom_characterdata_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_text_prop_handlers, sizeof(dom_text_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMComment", dom_characterdata_class_entry, php_dom_comment_class_functions, dom_comment_class_entry); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_characterdata_prop_handlers, sizeof(dom_typeinfo_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMTypeinfo", NULL, php_dom_typeinfo_class_functions, dom_typeinfo_class_entry); + + zend_hash_init(&dom_typeinfo_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_typeinfo_prop_handlers, "typeName", dom_typeinfo_type_name_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_typeinfo_prop_handlers, "typeNamespace", dom_typeinfo_type_namespace_read, NULL TSRMLS_CC); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_typeinfo_prop_handlers, sizeof(dom_typeinfo_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMUserDataHandler", NULL, php_dom_userdatahandler_class_functions, dom_userdatahandler_class_entry); + REGISTER_DOM_CLASS(ce, "DOMDomError", NULL, php_dom_domerror_class_functions, dom_domerror_class_entry); + + zend_hash_init(&dom_domerror_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_domerror_prop_handlers, "severity", dom_domerror_severity_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_domerror_prop_handlers, "message", dom_domerror_message_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_domerror_prop_handlers, "type", dom_domerror_type_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_domerror_prop_handlers, "relatedException", dom_domerror_related_exception_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_domerror_prop_handlers, "related_data", dom_domerror_related_data_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_domerror_prop_handlers, "location", dom_domerror_location_read, NULL TSRMLS_CC); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_domerror_prop_handlers, sizeof(dom_domerror_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMErrorHandler", NULL, php_dom_domerrorhandler_class_functions, dom_domerrorhandler_class_entry); + REGISTER_DOM_CLASS(ce, "DOMLocator", NULL, php_dom_domlocator_class_functions, dom_domlocator_class_entry); + + zend_hash_init(&dom_domlocator_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_domlocator_prop_handlers, "lineNumber", dom_domlocator_line_number_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_domlocator_prop_handlers, "columnNumber", dom_domlocator_column_number_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_domlocator_prop_handlers, "offset", dom_domlocator_offset_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_domlocator_prop_handlers, "relatedNode", dom_domlocator_related_node_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_domlocator_prop_handlers, "uri", dom_domlocator_uri_read, NULL TSRMLS_CC); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_domlocator_prop_handlers, sizeof(dom_domlocator_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMConfiguration", NULL, php_dom_domconfiguration_class_functions, dom_domconfiguration_class_entry); + REGISTER_DOM_CLASS(ce, "DOMCdataSection", dom_text_class_entry, php_dom_cdatasection_class_functions, dom_cdatasection_class_entry); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_text_prop_handlers, sizeof(dom_documenttype_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMDocumentType", dom_node_class_entry, php_dom_documenttype_class_functions, dom_documenttype_class_entry); + + zend_hash_init(&dom_documenttype_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_documenttype_prop_handlers, "name", dom_documenttype_name_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_documenttype_prop_handlers, "entities", dom_documenttype_entities_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_documenttype_prop_handlers, "notations", dom_documenttype_notations_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_documenttype_prop_handlers, "publicId", dom_documenttype_public_id_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_documenttype_prop_handlers, "systemId", dom_documenttype_system_id_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_documenttype_prop_handlers, "internalSubset", dom_documenttype_internal_subset_read, NULL TSRMLS_CC); + zend_hash_merge(&dom_documenttype_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_documenttype_prop_handlers, sizeof(dom_documenttype_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMNotation", dom_node_class_entry, php_dom_notation_class_functions, dom_notation_class_entry); + + zend_hash_init(&dom_notation_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_notation_prop_handlers, "publicId", dom_notation_public_id_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_notation_prop_handlers, "systemId", dom_notation_system_id_read, NULL TSRMLS_CC); + zend_hash_merge(&dom_notation_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_notation_prop_handlers, sizeof(dom_notation_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMEntity", dom_node_class_entry, php_dom_entity_class_functions, dom_entity_class_entry); + + zend_hash_init(&dom_entity_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_entity_prop_handlers, "publicId", dom_entity_public_id_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_entity_prop_handlers, "systemId", dom_entity_system_id_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_entity_prop_handlers, "notationName", dom_entity_notation_name_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_entity_prop_handlers, "actualEncoding", dom_entity_actual_encoding_read, dom_entity_actual_encoding_write TSRMLS_CC); + dom_register_prop_handler(&dom_entity_prop_handlers, "encoding", dom_entity_encoding_read, dom_entity_encoding_write TSRMLS_CC); + dom_register_prop_handler(&dom_entity_prop_handlers, "version", dom_entity_version_read, dom_entity_version_write TSRMLS_CC); + zend_hash_merge(&dom_entity_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); + + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_entity_prop_handlers, sizeof(dom_entity_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMEntityReference", dom_node_class_entry, php_dom_entityreference_class_functions, dom_entityreference_class_entry); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_node_prop_handlers, sizeof(dom_entity_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMProcessingInstruction", dom_node_class_entry, php_dom_processinginstruction_class_functions, dom_processinginstruction_class_entry); + + zend_hash_init(&dom_processinginstruction_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_processinginstruction_prop_handlers, "target", dom_processinginstruction_target_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_processinginstruction_prop_handlers, "data", dom_processinginstruction_data_read, dom_processinginstruction_data_write TSRMLS_CC); + zend_hash_merge(&dom_processinginstruction_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_processinginstruction_prop_handlers, sizeof(dom_processinginstruction_prop_handlers), NULL); + + REGISTER_DOM_CLASS(ce, "DOMStringExtend", NULL, php_dom_string_extend_class_functions, dom_string_extend_class_entry); + +#if defined(LIBXML_XPATH_ENABLED) + INIT_CLASS_ENTRY(ce, "DOMXPath", php_dom_xpath_class_functions); + ce.create_object = dom_xpath_objects_new; + dom_xpath_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + + zend_hash_init(&dom_xpath_prop_handlers, 0, NULL, NULL, 1); + dom_register_prop_handler(&dom_xpath_prop_handlers, "document", dom_xpath_document_read, NULL TSRMLS_CC); + zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_xpath_prop_handlers, sizeof(dom_xpath_prop_handlers), NULL); +#endif + + REGISTER_LONG_CONSTANT("XML_ELEMENT_NODE", XML_ELEMENT_NODE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_NODE", XML_ATTRIBUTE_NODE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_TEXT_NODE", XML_TEXT_NODE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_CDATA_SECTION_NODE", XML_CDATA_SECTION_NODE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_ENTITY_REF_NODE", XML_ENTITY_REF_NODE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_ENTITY_NODE", XML_ENTITY_NODE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_PI_NODE", XML_PI_NODE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_COMMENT_NODE", XML_COMMENT_NODE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_DOCUMENT_NODE", XML_DOCUMENT_NODE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_DOCUMENT_TYPE_NODE", XML_DOCUMENT_TYPE_NODE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_DOCUMENT_FRAG_NODE", XML_DOCUMENT_FRAG_NODE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_NOTATION_NODE", XML_NOTATION_NODE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_HTML_DOCUMENT_NODE", XML_HTML_DOCUMENT_NODE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_DTD_NODE", XML_DTD_NODE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_ELEMENT_DECL_NODE", XML_ELEMENT_DECL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_DECL_NODE", XML_ATTRIBUTE_DECL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_ENTITY_DECL_NODE", XML_ENTITY_DECL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_NAMESPACE_DECL_NODE", XML_NAMESPACE_DECL, CONST_CS | CONST_PERSISTENT); +#ifdef XML_GLOBAL_NAMESPACE + REGISTER_LONG_CONSTANT("XML_GLOBAL_NAMESPACE", XML_GLOBAL_NAMESPACE, CONST_CS | CONST_PERSISTENT); +#endif + REGISTER_LONG_CONSTANT("XML_LOCAL_NAMESPACE", XML_LOCAL_NAMESPACE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_CDATA", XML_ATTRIBUTE_CDATA, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_ID", XML_ATTRIBUTE_ID, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_IDREF", XML_ATTRIBUTE_IDREF, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_IDREFS", XML_ATTRIBUTE_IDREFS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_ENTITY", XML_ATTRIBUTE_ENTITIES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_NMTOKEN", XML_ATTRIBUTE_NMTOKEN, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_NMTOKENS", XML_ATTRIBUTE_NMTOKENS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_ENUMERATION", XML_ATTRIBUTE_ENUMERATION, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_NOTATION", XML_ATTRIBUTE_NOTATION, CONST_CS | CONST_PERSISTENT); + + /* DOMException Codes */ + REGISTER_LONG_CONSTANT("DOM_PHP_ERR", PHP_ERR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DOM_INDEX_SIZE_ERR", INDEX_SIZE_ERR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DOMSTRING_SIZE_ERR", DOMSTRING_SIZE_ERR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DOM_HIERARCHY_REQUEST_ERR", HIERARCHY_REQUEST_ERR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DOM_WRONG_DOCUMENT_ERR", WRONG_DOCUMENT_ERR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DOM_INVALID_CHARACTER_ERR", INVALID_CHARACTER_ERR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DOM_NO_DATA_ALLOWED_ERR", NO_DATA_ALLOWED_ERR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DOM_NO_MODIFICATION_ALLOWED_ERR", NO_MODIFICATION_ALLOWED_ERR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DOM_NOT_FOUND_ERR", NOT_FOUND_ERR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DOM_NOT_SUPPORTED_ERR", NOT_SUPPORTED_ERR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DOM_INUSE_ATTRIBUTE_ERR", INUSE_ATTRIBUTE_ERR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DOM_INVALID_STATE_ERR", INVALID_STATE_ERR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DOM_SYNTAX_ERR", SYNTAX_ERR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DOM_INVALID_MODIFICATION_ERR", INVALID_MODIFICATION_ERR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DOM_NAMESPACE_ERR", NAMESPACE_ERR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DOM_INVALID_ACCESS_ERR", INVALID_ACCESS_ERR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DOM_VALIDATION_ERR", VALIDATION_ERR, CONST_CS | CONST_PERSISTENT); + + php_libxml_register_export(dom_node_class_entry, php_dom_export_node); + + return SUCCESS; +} +/* }}} */ + +/* {{{ */ +PHP_MINFO_FUNCTION(dom) +{ + php_info_print_table_start(); + php_info_print_table_row(2, "DOM/XML", "enabled"); + php_info_print_table_row(2, "DOM/XML API Version", DOM_API_VERSION); + php_info_print_table_row(2, "libxml Version", LIBXML_DOTTED_VERSION); +#if defined(LIBXML_HTML_ENABLED) + php_info_print_table_row(2, "HTML Support", "enabled"); +#endif +#if defined(LIBXML_XPATH_ENABLED) + php_info_print_table_row(2, "XPath Support", "enabled"); +#endif +#if defined(LIBXML_XPTR_ENABLED) + php_info_print_table_row(2, "XPointer Support", "enabled"); +#endif +#ifdef LIBXML_SCHEMAS_ENABLED + php_info_print_table_row(2, "Schema Support", "enabled"); + php_info_print_table_row(2, "RelaxNG Support", "enabled"); +#endif + php_info_print_table_end(); +} +/* }}} */ + +PHP_MSHUTDOWN_FUNCTION(dom) /* {{{ */ +{ + zend_hash_destroy(&dom_domstringlist_prop_handlers); + zend_hash_destroy(&dom_namelist_prop_handlers); + zend_hash_destroy(&dom_domimplementationlist_prop_handlers); + zend_hash_destroy(&dom_document_prop_handlers); + zend_hash_destroy(&dom_node_prop_handlers); + zend_hash_destroy(&dom_namespace_node_prop_handlers); + zend_hash_destroy(&dom_nodelist_prop_handlers); + zend_hash_destroy(&dom_namednodemap_prop_handlers); + zend_hash_destroy(&dom_characterdata_prop_handlers); + zend_hash_destroy(&dom_attr_prop_handlers); + zend_hash_destroy(&dom_element_prop_handlers); + zend_hash_destroy(&dom_text_prop_handlers); + zend_hash_destroy(&dom_typeinfo_prop_handlers); + zend_hash_destroy(&dom_domerror_prop_handlers); + zend_hash_destroy(&dom_domlocator_prop_handlers); + zend_hash_destroy(&dom_documenttype_prop_handlers); + zend_hash_destroy(&dom_notation_prop_handlers); + zend_hash_destroy(&dom_entity_prop_handlers); + zend_hash_destroy(&dom_processinginstruction_prop_handlers); +#if defined(LIBXML_XPATH_ENABLED) + zend_hash_destroy(&dom_xpath_prop_handlers); +#endif + zend_hash_destroy(&classes); + +/* If you want do find memleaks in this module, compile libxml2 with --with-mem-debug and + uncomment the following line, this will tell you the amount of not freed memory + and the total used memory into apaches error_log */ +/* xmlMemoryDump();*/ + + return SUCCESS; +} +/* }}} */ + +/* {{{ node_list_unlink */ +void node_list_unlink(xmlNodePtr node TSRMLS_DC) +{ + dom_object *wrapper; + + while (node != NULL) { + + wrapper = php_dom_object_get_data(node); + + if (wrapper != NULL ) { + xmlUnlinkNode(node); + } else { + if (node->type == XML_ENTITY_REF_NODE) + break; + node_list_unlink(node->children TSRMLS_CC); + + switch (node->type) { + case XML_ATTRIBUTE_DECL: + case XML_DTD_NODE: + case XML_DOCUMENT_TYPE_NODE: + case XML_ENTITY_DECL: + case XML_ATTRIBUTE_NODE: + case XML_TEXT_NODE: + break; + default: + node_list_unlink((xmlNodePtr) node->properties TSRMLS_CC); + } + + } + + node = node->next; + } +} +/* }}} end node_list_unlink */ + +#if defined(LIBXML_XPATH_ENABLED) +/* {{{ dom_xpath_objects_free_storage */ +void dom_xpath_objects_free_storage(void *object TSRMLS_DC) +{ + dom_xpath_object *intern = (dom_xpath_object *)object; + + zend_object_std_dtor(&intern->std TSRMLS_CC); + + if (intern->ptr != NULL) { + xmlXPathFreeContext((xmlXPathContextPtr) intern->ptr); + php_libxml_decrement_doc_ref((php_libxml_node_object *) intern TSRMLS_CC); + intern->ptr = NULL; + } + + if (intern->registered_phpfunctions) { + zend_hash_destroy(intern->registered_phpfunctions); + FREE_HASHTABLE(intern->registered_phpfunctions); + } + + if (intern->node_list) { + zend_hash_destroy(intern->node_list); + FREE_HASHTABLE(intern->node_list); + } + + efree(object); +} +/* }}} */ +#endif + +/* {{{ dom_objects_free_storage */ +void dom_objects_free_storage(void *object TSRMLS_DC) +{ + dom_object *intern = (dom_object *)object; + int retcount; + + zend_object_std_dtor(&intern->std TSRMLS_CC); + + if (intern->ptr != NULL && ((php_libxml_node_ptr *)intern->ptr)->node != NULL) { + 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) { + php_libxml_node_decrement_resource((php_libxml_node_object *) intern TSRMLS_CC); + } else { + php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC); + retcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC); + } + intern->ptr = NULL; + } + + efree(object); +} +/* }}} */ + +void dom_namednode_iter(dom_object *basenode, int ntype, dom_object *intern, xmlHashTablePtr ht, xmlChar *local, xmlChar *ns TSRMLS_DC) /* {{{ */ +{ + dom_nnodemap_object *mapptr; + zval *baseobj = NULL; + + mapptr = (dom_nnodemap_object *)intern->ptr; + if (basenode) { + MAKE_STD_ZVAL(baseobj); + baseobj->type = IS_OBJECT; + Z_SET_ISREF_P(baseobj); + baseobj->value.obj.handle = basenode->handle; + baseobj->value.obj.handlers = dom_get_obj_handlers(TSRMLS_C); + zval_copy_ctor(baseobj); + } + mapptr->baseobjptr = baseobj; + mapptr->baseobj = basenode; + mapptr->nodetype = ntype; + mapptr->ht = ht; + mapptr->local = local; + mapptr->ns = ns; + +} +/* }}} */ + +static dom_object* dom_objects_set_class(zend_class_entry *class_type, zend_bool hash_copy TSRMLS_DC) /* {{{ */ +{ + zend_class_entry *base_class; + dom_object *intern; + + if (instanceof_function(class_type, dom_xpath_class_entry TSRMLS_CC)) { + intern = emalloc(sizeof(dom_xpath_object)); + memset(intern, 0, sizeof(dom_xpath_object)); + } else { + intern = emalloc(sizeof(dom_object)); + } + intern->ptr = NULL; + intern->prop_handler = NULL; + intern->document = NULL; + + base_class = class_type; + while(base_class->type != ZEND_INTERNAL_CLASS && base_class->parent != NULL) { + base_class = base_class->parent; + } + + zend_hash_find(&classes, base_class->name, base_class->name_length + 1, (void **) &intern->prop_handler); + + zend_object_std_init(&intern->std, class_type TSRMLS_CC); + if (hash_copy) { + object_properties_init(&intern->std, class_type); + } + + return intern; +} +/* }}} */ + +/* {{{ dom_objects_clone */ +void dom_objects_clone(void *object, void **object_clone TSRMLS_DC) +{ + dom_object *intern = (dom_object *) object; + dom_object *clone; + xmlNodePtr node; + xmlNodePtr cloned_node; + + clone = dom_objects_set_class(intern->std.ce, 0 TSRMLS_CC); + + if (instanceof_function(intern->std.ce, dom_node_class_entry TSRMLS_CC)) { + node = (xmlNodePtr)dom_object_get_node((dom_object *) object); + if (node != NULL) { + cloned_node = xmlDocCopyNode(node, node->doc, 1); + if (cloned_node != NULL) { + /* If we cloned a document then we must create new doc proxy */ + if (cloned_node->doc == node->doc) { + clone->document = intern->document; + } + php_libxml_increment_doc_ref((php_libxml_node_object *)clone, cloned_node->doc TSRMLS_CC); + php_libxml_increment_node_ptr((php_libxml_node_object *)clone, cloned_node, (void *)clone TSRMLS_CC); + if (intern->document != clone->document) { + dom_copy_doc_props(intern->document, clone->document); + } + } + + } + } + + *object_clone = (void *) clone; +} +/* }}} */ + +/* {{{ dom_objects_new */ +zend_object_value dom_objects_new(zend_class_entry *class_type TSRMLS_DC) +{ + zend_object_value retval; + dom_object *intern; + + intern = dom_objects_set_class(class_type, 1 TSRMLS_CC); + + 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); + intern->handle = retval.handle; + retval.handlers = dom_get_obj_handlers(TSRMLS_C); + + return retval; +} +/* }}} */ + +#if defined(LIBXML_XPATH_ENABLED) +/* {{{ zend_object_value dom_xpath_objects_new(zend_class_entry *class_type TSRMLS_DC) */ +zend_object_value dom_xpath_objects_new(zend_class_entry *class_type TSRMLS_DC) +{ + zend_object_value retval; + dom_xpath_object *intern; + + intern = (dom_xpath_object *)dom_objects_set_class(class_type, 1 TSRMLS_CC); + intern->registerPhpFunctions = 0; + intern->registered_phpfunctions = NULL; + intern->node_list = NULL; + + ALLOC_HASHTABLE(intern->registered_phpfunctions); + zend_hash_init(intern->registered_phpfunctions, 0, NULL, ZVAL_PTR_DTOR, 0); + + 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); + intern->handle = retval.handle; + retval.handlers = dom_get_obj_handlers(TSRMLS_C); + + return retval; +} +/* }}} */ +#endif + +static void dom_nnodemap_object_dtor(void *object, zend_object_handle handle TSRMLS_DC) /* {{{ */ +{ + zval *baseobj; + dom_object *intern; + dom_nnodemap_object *objmap; + + intern = (dom_object *)object; + objmap = (dom_nnodemap_object *)intern->ptr; + + if (objmap) { + if (objmap->local) { + xmlFree(objmap->local); + } + if (objmap->ns) { + xmlFree(objmap->ns); + } + if (objmap->baseobjptr) { + baseobj = objmap->baseobjptr; + zval_ptr_dtor((zval **)&baseobj); + } + efree(objmap); + intern->ptr = NULL; + } + + +} +/* }}} */ + +void dom_nnodemap_objects_free_storage(void *object TSRMLS_DC) /* {{{ */ +{ + dom_object *intern = (dom_object *)object; + + php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC); + + zend_object_std_dtor(&intern->std TSRMLS_CC); + + efree(object); +} +/* }}} */ + +zend_object_value dom_nnodemap_objects_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ +{ + zend_object_value retval; + dom_object *intern; + dom_nnodemap_object *objmap; + + intern = dom_objects_set_class(class_type, 1 TSRMLS_CC); + intern->ptr = emalloc(sizeof(dom_nnodemap_object)); + objmap = (dom_nnodemap_object *)intern->ptr; + objmap->baseobj = NULL; + objmap->baseobjptr = NULL; + objmap->nodetype = 0; + objmap->ht = NULL; + objmap->local = NULL; + objmap->ns = NULL; + + 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); + intern->handle = retval.handle; + retval.handlers = dom_get_obj_handlers(TSRMLS_C); + + return retval; +} +/* }}} */ + +void php_dom_create_interator(zval *return_value, int ce_type TSRMLS_DC) /* {{{ */ +{ + zend_class_entry *ce; + + if (ce_type == DOM_NAMEDNODEMAP) { + ce = dom_namednodemap_class_entry; + } else { + ce = dom_nodelist_class_entry; + } + + object_init_ex(return_value, ce); +} +/* }}} */ + +/* {{{ php_dom_create_object */ +PHP_DOM_EXPORT zval *php_dom_create_object(xmlNodePtr obj, int *found, zval *return_value, dom_object *domobj TSRMLS_DC) +{ + zval *wrapper; + zend_class_entry *ce; + dom_object *intern; + + *found = 0; + + if (!obj) { + ALLOC_ZVAL(wrapper); + ZVAL_NULL(wrapper); + return wrapper; + } + + if ((intern = (dom_object *) php_dom_object_get_data((void *) obj))) { + return_value->type = IS_OBJECT; + Z_SET_ISREF_P(return_value); + return_value->value.obj.handle = intern->handle; + return_value->value.obj.handlers = dom_get_obj_handlers(TSRMLS_C); + zval_copy_ctor(return_value); + *found = 1; + return return_value; + } + + wrapper = return_value; + + switch (obj->type) { + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: + { + ce = dom_document_class_entry; + break; + } + case XML_DTD_NODE: + case XML_DOCUMENT_TYPE_NODE: + { + ce = dom_documenttype_class_entry; + break; + } + case XML_ELEMENT_NODE: + { + ce = dom_element_class_entry; + break; + } + case XML_ATTRIBUTE_NODE: + { + ce = dom_attr_class_entry; + break; + } + case XML_TEXT_NODE: + { + ce = dom_text_class_entry; + break; + } + case XML_COMMENT_NODE: + { + ce = dom_comment_class_entry; + break; + } + case XML_PI_NODE: + { + ce = dom_processinginstruction_class_entry; + break; + } + case XML_ENTITY_REF_NODE: + { + ce = dom_entityreference_class_entry; + break; + } + case XML_ENTITY_DECL: + case XML_ELEMENT_DECL: + { + ce = dom_entity_class_entry; + break; + } + case XML_CDATA_SECTION_NODE: + { + ce = dom_cdatasection_class_entry; + break; + } + case XML_DOCUMENT_FRAG_NODE: + { + ce = dom_documentfragment_class_entry; + break; + } + case XML_NOTATION_NODE: + { + ce = dom_notation_class_entry; + break; + } + case XML_NAMESPACE_DECL: + { + ce = dom_namespace_node_class_entry; + break; + } + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported node type: %d", Z_TYPE_P(obj)); + ZVAL_NULL(wrapper); + return wrapper; + } + + if (domobj && domobj->document) { + ce = dom_get_doc_classmap(domobj->document, ce TSRMLS_CC); + } + object_init_ex(wrapper, ce); + + intern = (dom_object *)zend_objects_get_address(wrapper TSRMLS_CC); + if (obj->doc != NULL) { + if (domobj != NULL) { + intern->document = domobj->document; + } + php_libxml_increment_doc_ref((php_libxml_node_object *)intern, obj->doc TSRMLS_CC); + } + + php_libxml_increment_node_ptr((php_libxml_node_object *)intern, obj, (void *)intern TSRMLS_CC); + return (wrapper); +} +/* }}} end php_domobject_new */ + +void php_dom_create_implementation(zval **retval TSRMLS_DC) { + object_init_ex(*retval, dom_domimplementation_class_entry); +} + +/* {{{ int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child) */ +int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child) +{ + xmlNodePtr nodep; + + if (parent == NULL || child == NULL || child->doc != parent->doc) { + return SUCCESS; + } + + nodep = parent; + + while (nodep) { + if (nodep == child) { + return FAILURE; + } + nodep = nodep->parent; + } + + return SUCCESS; +} +/* }}} end dom_hierarchy */ + +/* {{{ dom_has_feature(char *feature, char *version) */ +int dom_has_feature(char *feature, char *version) +{ + int retval = 0; + + if (!(strcmp (version, "1.0") && strcmp (version,"2.0") && strcmp(version, ""))) { + if ((!strcasecmp(feature, "Core") && !strcmp (version, "1.0")) || !strcasecmp(feature, "XML")) + retval = 1; + } + + return retval; +} +/* }}} end dom_has_feature */ + +xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr nodep, char *ns, char *local, int *cur, int index) /* {{{ */ +{ + xmlNodePtr ret = NULL; + + while (nodep != NULL && (*cur <= index || index == -1)) { + if (nodep->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(nodep->name, (xmlChar *)local) || xmlStrEqual((xmlChar *)"*", (xmlChar *)local)) { + if (ns == NULL || (nodep->ns != NULL && (xmlStrEqual(nodep->ns->href, (xmlChar *)ns) || xmlStrEqual((xmlChar *)"*", (xmlChar *)ns)))) { + if (*cur == index) { + ret = nodep; + break; + } + (*cur)++; + } + } + ret = dom_get_elements_by_tag_name_ns_raw(nodep->children, ns, local, cur, index); + if (ret != NULL) { + break; + } + } + nodep = nodep->next; + } + return ret; +} +/* }}} */ +/* }}} end dom_element_get_elements_by_tag_name_ns_raw */ + +/* {{{ void dom_normalize (xmlNodePtr nodep TSRMLS_DC) */ +void dom_normalize (xmlNodePtr nodep TSRMLS_DC) +{ + xmlNodePtr child, nextp, newnextp; + xmlAttrPtr attr; + xmlChar *strContent; + + child = nodep->children; + while(child != NULL) { + switch (child->type) { + case XML_TEXT_NODE: + nextp = child->next; + while (nextp != NULL) { + if (nextp->type == XML_TEXT_NODE) { + newnextp = nextp->next; + strContent = xmlNodeGetContent(nextp); + xmlNodeAddContent(child, strContent); + xmlFree(strContent); + xmlUnlinkNode(nextp); + php_libxml_node_free_resource(nextp TSRMLS_CC); + nextp = newnextp; + } else { + break; + } + } + break; + case XML_ELEMENT_NODE: + dom_normalize (child TSRMLS_CC); + attr = child->properties; + while (attr != NULL) { + dom_normalize((xmlNodePtr) attr TSRMLS_CC); + attr = attr->next; + } + break; + case XML_ATTRIBUTE_NODE: + dom_normalize (child TSRMLS_CC); + break; + default: + break; + } + child = child->next; + } +} +/* }}} end dom_normalize */ + + +/* {{{ void dom_set_old_ns(xmlDoc *doc, xmlNs *ns) */ +void dom_set_old_ns(xmlDoc *doc, xmlNs *ns) { + xmlNs *cur; + + if (doc == NULL) + return; + + if (doc->oldNs == NULL) { + doc->oldNs = (xmlNsPtr) xmlMalloc(sizeof(xmlNs)); + if (doc->oldNs == NULL) { + return; + } + memset(doc->oldNs, 0, sizeof(xmlNs)); + doc->oldNs->type = XML_LOCAL_NAMESPACE; + doc->oldNs->href = xmlStrdup(XML_XML_NAMESPACE); + doc->oldNs->prefix = xmlStrdup((const xmlChar *)"xml"); + } + + cur = doc->oldNs; + while (cur->next != NULL) { + cur = cur->next; + } + cur->next = ns; +} +/* }}} end dom_set_old_ns */ + +/* +http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-DocCrElNS + +NAMESPACE_ERR: Raised if + +1. the qualifiedName is a malformed qualified name +2. the qualifiedName has a prefix and the namespaceURI is null +*/ + +/* {{{ int dom_check_qname(char *qname, char **localname, char **prefix, int uri_len, int name_len) */ +int dom_check_qname(char *qname, char **localname, char **prefix, int uri_len, int name_len) { + if (name_len == 0) { + return NAMESPACE_ERR; + } + + *localname = (char *)xmlSplitQName2((xmlChar *)qname, (xmlChar **) prefix); + if (*localname == NULL) { + *localname = (char *)xmlStrdup((xmlChar *)qname); + if (*prefix == NULL && uri_len == 0) { + return 0; + } + } + + /* 1 */ + if (xmlValidateQName((xmlChar *) qname, 0) != 0) { + return NAMESPACE_ERR; + } + + /* 2 */ + if (*prefix != NULL && uri_len == 0) { + return NAMESPACE_ERR; + } + + return 0; +} +/* }}} */ + +/* +http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-DocCrElNS + +NAMESPACE_ERR: Raised if + +3. the qualifiedName has a prefix that is "xml" and the namespaceURI is different from "http://www.w3.org/XML/1998/namespace" [XML Namespaces] +4. the qualifiedName or its prefix is "xmlns" and the namespaceURI is different from "http://www.w3.org/2000/xmlns/" +5. the namespaceURI is "http://www.w3.org/2000/xmlns/" and neither the qualifiedName nor its prefix is "xmlns". +*/ + +/* {{{ xmlNsPtr dom_get_ns(xmlNodePtr nodep, char *uri, int *errorcode, char *prefix) */ +xmlNsPtr dom_get_ns(xmlNodePtr nodep, char *uri, int *errorcode, char *prefix) { + xmlNsPtr nsptr = NULL; + + *errorcode = 0; + + if (! ((prefix && !strcmp (prefix, "xml") && strcmp(uri, (char *)XML_XML_NAMESPACE)) || + (prefix && !strcmp (prefix, "xmlns") && strcmp(uri, (char *)DOM_XMLNS_NAMESPACE)) || + (prefix && !strcmp(uri, (char *)DOM_XMLNS_NAMESPACE) && strcmp (prefix, "xmlns")))) { + nsptr = xmlNewNs(nodep, (xmlChar *)uri, (xmlChar *)prefix); + } + + if (nsptr == NULL) { + *errorcode = NAMESPACE_ERR; + } + + return nsptr; + +} +/* }}} end dom_get_ns */ + +/* {{{ xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName) */ +xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName) { + xmlNsPtr cur; + xmlNs *ret = NULL; + if (node == NULL) + return NULL; + + if (localName == NULL || xmlStrEqual(localName, (xmlChar *)"")) { + cur = node->nsDef; + while (cur != NULL) { + if (cur->prefix == NULL && cur->href != NULL) { + ret = cur; + break; + } + cur = cur->next; + } + } else { + cur = node->nsDef; + while (cur != NULL) { + if (cur->prefix != NULL && xmlStrEqual(localName, cur->prefix)) { + ret = cur; + break; + } + cur = cur->next; + } + } + return ret; +} +/* }}} end dom_get_nsdecl */ + +#endif /* HAVE_DOM */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h new file mode 100644 index 0000000..3559c4b --- /dev/null +++ b/ext/dom/php_dom.h @@ -0,0 +1,165 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + | Marcus Borger <helly@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef PHP_DOM_H +#define PHP_DOM_H + +extern zend_module_entry dom_module_entry; +#define phpext_dom_ptr &dom_module_entry + +#ifdef ZTS +#include "TSRM.h" +#endif + +#include <libxml/parser.h> +#include <libxml/parserInternals.h> +#include <libxml/tree.h> +#include <libxml/uri.h> +#include <libxml/xmlerror.h> +#include <libxml/xinclude.h> +#include <libxml/hash.h> +#include <libxml/c14n.h> +#if defined(LIBXML_HTML_ENABLED) +#include <libxml/HTMLparser.h> +#include <libxml/HTMLtree.h> +#endif +#if defined(LIBXML_XPATH_ENABLED) +#include <libxml/xpath.h> +#include <libxml/xpathInternals.h> +#endif +#if defined(LIBXML_XPTR_ENABLED) +#include <libxml/xpointer.h> +#endif +#ifdef PHP_WIN32 +#ifndef DOM_EXPORTS +#define DOM_EXPORTS +#endif +#endif + +#include "xml_common.h" +#include "ext/libxml/php_libxml.h" +#include "zend_exceptions.h" +#include "dom_ce.h" +/* DOM API_VERSION, please bump it up, if you change anything in the API + therefore it's easier for the script-programmers to check, what's working how + Can be checked with phpversion("dom"); +*/ +#define DOM_API_VERSION "20031129" +/* Define a custom type for iterating using an unused nodetype */ +#define DOM_NODESET XML_XINCLUDE_START + +typedef struct _dom_xpath_object { + zend_object std; + void *ptr; + php_libxml_ref_obj *document; + HashTable *prop_handler; + zend_object_handle handle; + int registerPhpFunctions; + HashTable *registered_phpfunctions; + HashTable *node_list; +} dom_xpath_object; + +typedef struct _dom_nnodemap_object { + dom_object *baseobj; + int nodetype; + xmlHashTable *ht; + xmlChar *local; + xmlChar *ns; + zval *baseobjptr; +} dom_nnodemap_object; + +typedef struct { + zend_object_iterator intern; + zval *curobj; +} php_dom_iterator; + +#include "dom_fe.h" + +dom_object *dom_object_get_data(xmlNodePtr obj); +dom_doc_propsptr dom_get_doc_props(php_libxml_ref_obj *document); +zend_object_value dom_objects_new(zend_class_entry *class_type TSRMLS_DC); +zend_object_value dom_nnodemap_objects_new(zend_class_entry *class_type TSRMLS_DC); +#if defined(LIBXML_XPATH_ENABLED) +zend_object_value dom_xpath_objects_new(zend_class_entry *class_type TSRMLS_DC); +#endif +int dom_get_strict_error(php_libxml_ref_obj *document); +void php_dom_throw_error(int error_code, int strict_error TSRMLS_DC); +void php_dom_throw_error_with_message(int error_code, char *error_message, int strict_error TSRMLS_DC); +void node_list_unlink(xmlNodePtr node TSRMLS_DC); +int dom_check_qname(char *qname, char **localname, char **prefix, int uri_len, int name_len); +xmlNsPtr dom_get_ns(xmlNodePtr node, char *uri, int *errorcode, char *prefix); +void dom_set_old_ns(xmlDoc *doc, xmlNs *ns); +xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName); +void dom_normalize (xmlNodePtr nodep TSRMLS_DC); +xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr nodep, char *ns, char *local, int *cur, int index); +void php_dom_create_implementation(zval **retval TSRMLS_DC); +int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child); +int dom_has_feature(char *feature, char *version); +int dom_node_is_read_only(xmlNodePtr node); +int dom_node_children_valid(xmlNodePtr node); +void php_dom_create_interator(zval *return_value, int ce_type TSRMLS_DC); +void dom_namednode_iter(dom_object *basenode, int ntype, dom_object *intern, xmlHashTablePtr ht, xmlChar *local, xmlChar *ns TSRMLS_DC); +xmlNodePtr create_notation(const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID); +xmlNode *php_dom_libxml_hash_iter(xmlHashTable *ht, int index); +xmlNode *php_dom_libxml_notation_iter(xmlHashTable *ht, int index); +zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC); +int dom_set_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece, zend_class_entry *ce TSRMLS_DC); + +#define REGISTER_DOM_CLASS(ce, name, parent_ce, funcs, entry) \ +INIT_CLASS_ENTRY(ce, name, funcs); \ +ce.create_object = dom_objects_new; \ +entry = zend_register_internal_class_ex(&ce, parent_ce, NULL TSRMLS_CC); + +#define DOM_GET_OBJ(__ptr, __id, __prtype, __intern) { \ + __intern = (dom_object *)zend_object_store_get_object(__id TSRMLS_CC); \ + if (__intern->ptr == NULL || !(__ptr = (__prtype)((php_libxml_node_ptr *)__intern->ptr)->node)) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", __intern->std.ce->name);\ + RETURN_NULL();\ + } \ +} + +#define DOM_NO_ARGS() \ + if (zend_parse_parameters_none() == FAILURE) { \ + return; \ + } + +#define DOM_NOT_IMPLEMENTED() \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not yet implemented"); \ + return; + +#define DOM_NODELIST 0 +#define DOM_NAMEDNODEMAP 1 + +PHP_MINIT_FUNCTION(dom); +PHP_MSHUTDOWN_FUNCTION(dom); +PHP_MINFO_FUNCTION(dom); + +#endif /* PHP_DOM_H */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/processinginstruction.c b/ext/dom/processinginstruction.c new file mode 100644 index 0000000..976b693 --- /dev/null +++ b/ext/dom/processinginstruction.c @@ -0,0 +1,188 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_processinginstruction_construct, 0, 0, 1) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class DOMProcessingInstruction extends DOMNode +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-1004215813 +* Since: +*/ + +const zend_function_entry php_dom_processinginstruction_class_functions[] = { + PHP_ME(domprocessinginstruction, __construct, arginfo_dom_processinginstruction_construct, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +/* {{{ proto void DOMProcessingInstruction::__construct(string name, [string value]); */ +PHP_METHOD(domprocessinginstruction, __construct) +{ + + zval *id; + xmlNodePtr nodep = NULL, oldnode = NULL; + dom_object *intern; + char *name, *value = NULL; + int name_len, value_len, name_valid; + zend_error_handling error_handling; + + zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC); + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_processinginstruction_class_entry, &name, &name_len, &value, &value_len) == FAILURE) { + zend_restore_error_handling(&error_handling TSRMLS_CC); + return; + } + + zend_restore_error_handling(&error_handling TSRMLS_CC); + + name_valid = xmlValidateName((xmlChar *) name, 0); + if (name_valid != 0) { + php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC); + RETURN_FALSE; + } + + nodep = xmlNewPI((xmlChar *) name, (xmlChar *) value); + + if (!nodep) { + php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC); + RETURN_FALSE; + } + + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + if (intern != NULL) { + oldnode = dom_object_get_node(intern); + if (oldnode != NULL) { + php_libxml_node_free_resource(oldnode TSRMLS_CC); + } + php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC); + } +} +/* }}} end DOMProcessingInstruction::__construct */ + +/* {{{ target string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-1478689192 +Since: +*/ +int dom_processinginstruction_target_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNodePtr nodep; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + ZVAL_STRING(*retval, (char *) (nodep->name), 1); + + return SUCCESS; +} + +/* }}} */ + +/* {{{ data string +readonly=no +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-837822393 +Since: +*/ +int dom_processinginstruction_data_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNodePtr nodep; + xmlChar *content; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + + if ((content = xmlNodeGetContent(nodep)) != NULL) { + ZVAL_STRING(*retval, content, 1); + xmlFree(content); + } else { + ZVAL_EMPTY_STRING(*retval); + } + + return SUCCESS; +} + +int dom_processinginstruction_data_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + zval value_copy; + xmlNode *nodep; + + nodep = dom_object_get_node(obj); + + if (nodep == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + if (newval->type != IS_STRING) { + if(Z_REFCOUNT_P(newval) > 1) { + value_copy = *newval; + zval_copy_ctor(&value_copy); + newval = &value_copy; + } + convert_to_string(newval); + } + + xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1); + + if (newval == &value_copy) { + zval_dtor(newval); + } + + return SUCCESS; +} + +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/string_extend.c b/ext/dom/string_extend.c new file mode 100644 index 0000000..2c47362 --- /dev/null +++ b/ext/dom/string_extend.c @@ -0,0 +1,86 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_string_extend_find_offset16, 0, 0, 1) + ZEND_ARG_INFO(0, offset32) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_string_extend_find_offset32, 0, 0, 1) + ZEND_ARG_INFO(0, offset16) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class domstringextend +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#i18n-methods-StringExtend +* Since: +*/ + +const zend_function_entry php_dom_string_extend_class_functions[] = { + PHP_FALIAS(findOffset16, dom_string_extend_find_offset16, arginfo_dom_string_extend_find_offset16) + PHP_FALIAS(findOffset32, dom_string_extend_find_offset32, arginfo_dom_string_extend_find_offset32) + PHP_FE_END +}; + +/* {{{ attribute protos, not implemented yet */ + +/* {{{ proto int dom_string_extend_find_offset16(int offset32); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#i18n-methods-StringExtend-findOffset16 +Since: +*/ +PHP_FUNCTION(dom_string_extend_find_offset16) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_string_extend_find_offset16 */ + +/* {{{ proto int dom_string_extend_find_offset32(int offset16); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#i18n-methods-StringExtend-findOffset32 +Since: +*/ +PHP_FUNCTION(dom_string_extend_find_offset32) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_string_extend_find_offset32 */ + +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/tests/DOMAttr_construct_error_001.phpt b/ext/dom/tests/DOMAttr_construct_error_001.phpt new file mode 100644 index 0000000..08734ca --- /dev/null +++ b/ext/dom/tests/DOMAttr_construct_error_001.phpt @@ -0,0 +1,17 @@ +--TEST-- +DOMAttr __construct() with no arguments. +--CREDITS-- +Josh Sweeney <jsweeney@alt-invest.net> +# TestFest Atlanta 2009-05-14 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$attr = new DOMAttr(); +?> +--EXPECTF-- +Fatal error: Uncaught exception 'DOMException' with message 'DOMAttr::__construct() expects at least 1 parameter, 0 given' in %s:%d +Stack trace: +#0 %s(%d): DOMAttr->__construct() +#1 {main} + thrown in %s on line %d diff --git a/ext/dom/tests/DOMAttr_name_basic_001.phpt b/ext/dom/tests/DOMAttr_name_basic_001.phpt new file mode 100644 index 0000000..29ca8c5 --- /dev/null +++ b/ext/dom/tests/DOMAttr_name_basic_001.phpt @@ -0,0 +1,14 @@ +--TEST-- +DOMAttr read $name property. +--CREDITS-- +Nic Rosental <nicrosental@gmail.com> +# TestFest Atlanta 2009-05-14 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$attr = new DOMAttr('category', 'books'); +print $attr->name; +?> +--EXPECT-- +category
\ No newline at end of file diff --git a/ext/dom/tests/DOMAttr_ownerElement_error_001.phpt b/ext/dom/tests/DOMAttr_ownerElement_error_001.phpt new file mode 100644 index 0000000..a776654 --- /dev/null +++ b/ext/dom/tests/DOMAttr_ownerElement_error_001.phpt @@ -0,0 +1,23 @@ +--TEST-- +Read $ownerElement with null parent. +--CREDITS-- +Travis Pew +# TestFest Atlanta 2009-05-14 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$document = new DOMDocument; +$root = $document->createElement('root'); +$document->appendChild($root); +$attr = $root->setAttribute('category', 'books'); +$document->removeChild($root); +$root = null; +var_dump($attr->ownerElement); +?> +--EXPECTF-- +Warning: Couldn't fetch DOMAttr. Node no longer exists in %s on line %d + +Notice: Undefined property: DOMAttr::$ownerElement in %s on line %d +NULL diff --git a/ext/dom/tests/DOMAttr_value_basic_001.phpt b/ext/dom/tests/DOMAttr_value_basic_001.phpt new file mode 100644 index 0000000..51c4ac9 --- /dev/null +++ b/ext/dom/tests/DOMAttr_value_basic_001.phpt @@ -0,0 +1,16 @@ +--TEST-- +Read empty $value. +--CREDITS-- +Jason Bouffard <jbouffard1@yahoo.com> +# TestFest Atlanta 2009-05-14 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$attr = new DOMAttr('category'); +print $attr->value."\n"; +?> +===DONE=== +--EXPECTF-- +===DONE=== + diff --git a/ext/dom/tests/DOMAttr_value_basic_002.phpt b/ext/dom/tests/DOMAttr_value_basic_002.phpt new file mode 100644 index 0000000..384a9ca --- /dev/null +++ b/ext/dom/tests/DOMAttr_value_basic_002.phpt @@ -0,0 +1,15 @@ +--TEST-- +Write non-string $value property +--CREDITS-- +Eric Berg <ehberg@gmail.com> +# TestFest Atlanta 2009-05-14 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$attr = new DOMAttr('category'); +$attr->value = 1; +print $attr->value; +?> +--EXPECTF-- +1 diff --git a/ext/dom/tests/DOMCDATASection_construct_error_001.phpt b/ext/dom/tests/DOMCDATASection_construct_error_001.phpt new file mode 100644 index 0000000..4db2130 --- /dev/null +++ b/ext/dom/tests/DOMCDATASection_construct_error_001.phpt @@ -0,0 +1,21 @@ +--TEST-- +__construct() with no arguments. +--CREDITS-- +Nic Rosental nicrosental@gmail.com +# TestFest Atlanta 2009-5-14 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + try + { + $section = new DOMCDataSection(); + + } + catch (Exception $e) + { + echo $e->getMessage(); + } +?> +--EXPECT-- +DOMCdataSection::__construct() expects exactly 1 parameter, 0 given
\ No newline at end of file diff --git a/ext/dom/tests/DOMCharacterData_appendData_basic.phpt b/ext/dom/tests/DOMCharacterData_appendData_basic.phpt new file mode 100644 index 0000000..e479c1e --- /dev/null +++ b/ext/dom/tests/DOMCharacterData_appendData_basic.phpt @@ -0,0 +1,37 @@ +--TEST-- +DOMCharacterData::appendData basic functionality test +--CREDITS-- +Mike Sullivan <mike@regexia.com> +#TestFest 2008 (London) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$document = new DOMDocument; +$root = $document->createElement('root'); +$document->appendChild($root); + +$cdata = $document->createElement('cdata'); +$root->appendChild($cdata); + +$cdatanode = $document->createCDATASection(''); +$cdata->appendChild($cdatanode); +$cdatanode->appendData('data'); +echo "CDATA Length (one append): " . $cdatanode->length . "\n"; + +$cdatanode->appendData('><&"'); +echo "CDATA Length (two appends): " . $cdatanode->length . "\n"; + +echo "CDATA Content: " . $cdatanode->data . "\n"; + +echo "\n" . $document->saveXML(); + +?> +--EXPECT-- +CDATA Length (one append): 4 +CDATA Length (two appends): 8 +CDATA Content: data><&" + +<?xml version="1.0"?> +<root><cdata><![CDATA[data><&"]]></cdata></root>
\ No newline at end of file diff --git a/ext/dom/tests/DOMCharacterData_appendData_error_001.phpt b/ext/dom/tests/DOMCharacterData_appendData_error_001.phpt new file mode 100644 index 0000000..4126f99 --- /dev/null +++ b/ext/dom/tests/DOMCharacterData_appendData_error_001.phpt @@ -0,0 +1,19 @@ +--TEST-- +DOMCharacterData::appendData() with no arguments. +--CREDITS-- +Eric Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-24 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$document = new DOMDocument; +$root = $document->createElement('root'); +$document->appendChild($root); + +$cdata = $document->createCDATASection('test'); +$root->appendChild($cdata); +$cdata->appendData(); +?> +--EXPECTF-- +Warning: DOMCharacterData::appendData() expects exactly 1 parameter, 0 given in %s on line %d
\ No newline at end of file diff --git a/ext/dom/tests/DOMCharacterData_data_basic_002.phpt b/ext/dom/tests/DOMCharacterData_data_basic_002.phpt new file mode 100644 index 0000000..394b316 --- /dev/null +++ b/ext/dom/tests/DOMCharacterData_data_basic_002.phpt @@ -0,0 +1,28 @@ +--TEST-- +Create CDATA section and change it using DOMcreateCDATASection +--CREDITS-- +Nic Rosental nicrosental@gmail.com +# TestFest Atlanta 2009-5-28 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$document = new DOMDocument; +$root = $document->createElement('root'); +$document->appendChild($root); + +$cdata = $document->createCDATASection('t'); +$root->appendChild($cdata); +print $document->saveXML()."\n"; + +$cdata->data = 100; +print $document->saveXML()."\n"; + +?> +--EXPECT-- +<?xml version="1.0"?> +<root><![CDATA[t]]></root> + +<?xml version="1.0"?> +<root><![CDATA[100]]></root> diff --git a/ext/dom/tests/DOMCharacterData_data_error_002.phpt b/ext/dom/tests/DOMCharacterData_data_error_002.phpt new file mode 100644 index 0000000..401e0f2 --- /dev/null +++ b/ext/dom/tests/DOMCharacterData_data_error_002.phpt @@ -0,0 +1,14 @@ +--TEST-- +Invalid State Error when getting data on DOMCharacterData out of content. +--CREDITS-- +Eric Berg <ehberg@gmail.com> +# TestFest Atlanta 2009-05-14 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$character_data = new DOMCharacterData(); +print $character_data->data; +?> +--EXPECTF-- +Warning: main(): Invalid State Error in %s on line %d diff --git a/ext/dom/tests/DOMCharacterData_deleteData_basic_001.phpt b/ext/dom/tests/DOMCharacterData_deleteData_basic_001.phpt new file mode 100644 index 0000000..ad104f1 --- /dev/null +++ b/ext/dom/tests/DOMCharacterData_deleteData_basic_001.phpt @@ -0,0 +1,20 @@ +--TEST-- +DOMCharacterData::deleteData() with count exceeding string size. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-24 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$document = new DOMDocument; +$root = $document->createElement('root'); +$document->appendChild($root); + +$cdata = $document->createCDATASection('test'); +$root->appendChild($cdata); +$cdata->deleteData(1, 10); +var_dump($cdata->data); +?> +--EXPECTF-- +%unicode|string%(%d) "t"
\ No newline at end of file diff --git a/ext/dom/tests/DOMCharacterData_deleteData_error_001.phpt b/ext/dom/tests/DOMCharacterData_deleteData_error_001.phpt new file mode 100644 index 0000000..3fa7fba --- /dev/null +++ b/ext/dom/tests/DOMCharacterData_deleteData_error_001.phpt @@ -0,0 +1,19 @@ +--TEST-- +DOMCharacterData::deleteData() with no arguments. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-24 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$document = new DOMDocument; +$root = $document->createElement('root'); +$document->appendChild($root); + +$cdata = $document->createCDATASection('test'); +$root->appendChild($cdata); +$cdata->deleteData(); +?> +--EXPECTF-- +Warning: DOMCharacterData::deleteData() expects exactly 2 parameters, 0 given in %s on line %d
\ No newline at end of file diff --git a/ext/dom/tests/DOMCharacterData_deleteData_error_002.phpt b/ext/dom/tests/DOMCharacterData_deleteData_error_002.phpt new file mode 100644 index 0000000..117d5de --- /dev/null +++ b/ext/dom/tests/DOMCharacterData_deleteData_error_002.phpt @@ -0,0 +1,23 @@ +--TEST-- +DOMCharacterData::deleteData() with offset exceeding string size. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-24 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$document = new DOMDocument; +$root = $document->createElement('root'); +$document->appendChild($root); + +$cdata = $document->createCDATASection('test'); +$root->appendChild($cdata); +$cdata->deleteData(5, 1); +?> +--EXPECTF-- +Fatal error: Uncaught exception 'DOMException' with message 'Index Size Error' in %s:%d +Stack trace: +#0 %s(%d): DOMCharacterData->deleteData(5, 1) +#1 {main} + thrown in %s on line %d
\ No newline at end of file diff --git a/ext/dom/tests/DOMCharacterData_insertData_error_001.phpt b/ext/dom/tests/DOMCharacterData_insertData_error_001.phpt new file mode 100644 index 0000000..813a0be --- /dev/null +++ b/ext/dom/tests/DOMCharacterData_insertData_error_001.phpt @@ -0,0 +1,19 @@ +--TEST-- +DOMCharacterData::insertData() with no arguments. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-24 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$document = new DOMDocument; +$root = $document->createElement('root'); +$document->appendChild($root); + +$cdata = $document->createCDATASection('test'); +$root->appendChild($cdata); +$cdata->insertData(); +?> +--EXPECTF-- +Warning: DOMCharacterData::insertData() expects exactly 2 parameters, 0 given in %s on line %d
\ No newline at end of file diff --git a/ext/dom/tests/DOMCharacterData_length_error_001.phpt b/ext/dom/tests/DOMCharacterData_length_error_001.phpt new file mode 100644 index 0000000..e8bf16a --- /dev/null +++ b/ext/dom/tests/DOMCharacterData_length_error_001.phpt @@ -0,0 +1,17 @@ +--TEST-- +Invalid State Error when getting length on DOMCharacterData out of content. +--CREDITS-- +Jason Bouffard <jbouffard1@yahoo.com> +# TestFest Atlanta 2009-05-14 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$character_data = new DOMCharacterData(); +print $character_data->length; +?> +===DONE=== +--EXPECTF-- +Warning: main(): Invalid State Error in %s +===DONE=== + diff --git a/ext/dom/tests/DOMCharacterData_replaceData_error_001.phpt b/ext/dom/tests/DOMCharacterData_replaceData_error_001.phpt new file mode 100644 index 0000000..45d25dd --- /dev/null +++ b/ext/dom/tests/DOMCharacterData_replaceData_error_001.phpt @@ -0,0 +1,19 @@ +--TEST-- +DOMCharacterData::replaceData() with no arguments. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-24 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$document = new DOMDocument; +$root = $document->createElement('root'); +$document->appendChild($root); + +$cdata = $document->createCDATASection('test'); +$root->appendChild($cdata); +$cdata->replaceData(); +?> +--EXPECTF-- +Warning: DOMCharacterData::replaceData() expects exactly 3 parameters, 0 given in %s on line %d
\ No newline at end of file diff --git a/ext/dom/tests/DOMCharacterData_substringData_basic_001.phpt b/ext/dom/tests/DOMCharacterData_substringData_basic_001.phpt new file mode 100644 index 0000000..b9d73e1 --- /dev/null +++ b/ext/dom/tests/DOMCharacterData_substringData_basic_001.phpt @@ -0,0 +1,21 @@ +--TEST-- +__DOMCharacterData::substringData pull mid section of string +--CREDITS-- +Nic Rosental nicrosental@gmail.com +# TestFest Atlanta 2009-5-28 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$document = new DOMDocument; +$root = $document->createElement('root'); +$document->appendChild($root); + +$cdata = $document->createCDATASection('testfest'); +$root->appendChild($cdata); +print $cdata->substringData(1, 6); + +?> +--EXPECT-- +estfes
\ No newline at end of file diff --git a/ext/dom/tests/DOMComment_appendData_basic.phpt b/ext/dom/tests/DOMComment_appendData_basic.phpt new file mode 100644 index 0000000..c756f16 --- /dev/null +++ b/ext/dom/tests/DOMComment_appendData_basic.phpt @@ -0,0 +1,21 @@ +--TEST-- +Test adding data to a DOMComment +--CREDITS-- +Andrew Larssen <al@larssen.org> +London TestFest 2008 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$dom = new DomDocument(); +$comment = $dom->createComment('test-comment'); +$comment->appendData('-more-data'); +$dom->appendChild($comment); +$dom->saveXML(); +echo $dom->saveXML(); + +?> +--EXPECTF-- +<?xml version="1.0"?> +<!--test-comment-more-data-->
\ No newline at end of file diff --git a/ext/dom/tests/DOMComment_appendData_basic_Sullivan.phpt b/ext/dom/tests/DOMComment_appendData_basic_Sullivan.phpt new file mode 100644 index 0000000..ae06d8a --- /dev/null +++ b/ext/dom/tests/DOMComment_appendData_basic_Sullivan.phpt @@ -0,0 +1,37 @@ +--TEST-- +DOMComment::appendData basic functionality test +--CREDITS-- +Mike Sullivan <mike@regexia.com> +#TestFest 2008 (London) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$document = new DOMDocument; +$root = $document->createElement('root'); +$document->appendChild($root); + +$comment = $document->createElement('comment'); +$root->appendChild($comment); + +$commentnode = $document->createComment(''); +$comment->appendChild($commentnode); +$commentnode->appendData('data'); +echo "Comment Length (one append): " . $commentnode->length . "\n"; + +$commentnode->appendData('><&"'); +echo "Comment Length (two appends): " . $commentnode->length . "\n"; + +echo "Comment Content: " . $commentnode->data . "\n"; + +echo "\n" . $document->saveXML(); + +?> +--EXPECT-- +Comment Length (one append): 4 +Comment Length (two appends): 8 +Comment Content: data><&" + +<?xml version="1.0"?> +<root><comment><!--data><&"--></comment></root>
\ No newline at end of file diff --git a/ext/dom/tests/DOMComment_construct_basic_001.phpt b/ext/dom/tests/DOMComment_construct_basic_001.phpt new file mode 100644 index 0000000..902f7bb --- /dev/null +++ b/ext/dom/tests/DOMComment_construct_basic_001.phpt @@ -0,0 +1,19 @@ +--TEST-- +DOMComment::__construct() with constructor called twice. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-25 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$dom = new DOMDocument('1.0', 'UTF-8'); +$element = $dom->appendChild(new DOMElement('root')); +$comment = new DOMComment("This is the first comment."); +$comment->__construct("This is the second comment."); +$comment = $element->appendChild($comment); +print $dom->saveXML(); +?> +--EXPECT-- +<?xml version="1.0" encoding="UTF-8"?> +<root><!--This is the second comment.--></root> diff --git a/ext/dom/tests/DOMComment_construct_error_001.phpt b/ext/dom/tests/DOMComment_construct_error_001.phpt new file mode 100644 index 0000000..89142fe --- /dev/null +++ b/ext/dom/tests/DOMComment_construct_error_001.phpt @@ -0,0 +1,17 @@ +--TEST-- +DOMComment::__construct() with more arguments than acceptable. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-24 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$comment = new DOMComment("comment1", "comment2"); +?> +--EXPECTF-- +Fatal error: Uncaught exception 'DOMException' with message 'DOMComment::__construct() expects at most 1 parameter, 2 given' in %s:%d +Stack trace: +#0 %s(%d): DOMComment->__construct('comment1', 'comment2') +#1 {main} + thrown in %s on line %d
\ No newline at end of file diff --git a/ext/dom/tests/DOMComment_insertData_basic.phpt b/ext/dom/tests/DOMComment_insertData_basic.phpt new file mode 100644 index 0000000..5a4857d --- /dev/null +++ b/ext/dom/tests/DOMComment_insertData_basic.phpt @@ -0,0 +1,21 @@ +--TEST-- +Test inserting data into a DOMComment basic test +--CREDITS-- +Andrew Larssen <al@larssen.org> +London TestFest 2008 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +//correct offset +$dom = new DomDocument(); +$comment = $dom->createComment('test-comment'); +$comment->insertData(4,'-inserted'); +$dom->appendChild($comment); +echo $dom->saveXML(); + +?> +--EXPECTF-- +<?xml version="1.0"?> +<!--test-inserted-comment--> diff --git a/ext/dom/tests/DOMComment_insertData_error1.phpt b/ext/dom/tests/DOMComment_insertData_error1.phpt new file mode 100644 index 0000000..56922ac --- /dev/null +++ b/ext/dom/tests/DOMComment_insertData_error1.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test inserting data into a DOMComment basic test +--CREDITS-- +Andrew Larssen <al@larssen.org> +London TestFest 2008 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +//Negative offset +$dom = new DomDocument(); +$comment = $dom->createComment('test-comment'); +try { + $comment->insertData(-1,'-inserted'); +} catch (DOMException $e ) { + if ($e->getMessage() == 'Index Size Error'){ + echo "Throws DOMException for -ve offset\n"; + } +} + +?> +--EXPECTF-- +Throws DOMException for -ve offset diff --git a/ext/dom/tests/DOMComment_insertData_error2.phpt b/ext/dom/tests/DOMComment_insertData_error2.phpt new file mode 100644 index 0000000..d2affa8 --- /dev/null +++ b/ext/dom/tests/DOMComment_insertData_error2.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test inserting data into a DOMComment basic test +--CREDITS-- +Andrew Larssen <al@larssen.org> +London TestFest 2008 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +//offset to large +$dom = new DomDocument(); +$comment = $dom->createComment('test-comment'); +try { + $comment->insertData(999,'-inserted'); +} catch (DOMException $e ) { + if ($e->getMessage() == 'Index Size Error'){ + echo "Throws DOMException for offset too large\n"; + } +} + +?> +--EXPECTF-- +Throws DOMException for offset too large
\ No newline at end of file diff --git a/ext/dom/tests/DOMComment_replaceData_basic.phpt b/ext/dom/tests/DOMComment_replaceData_basic.phpt new file mode 100644 index 0000000..2963cb1 --- /dev/null +++ b/ext/dom/tests/DOMComment_replaceData_basic.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test replacing data into a DOMComment basic test +--CREDITS-- +Andrew Larssen <al@larssen.org> +London TestFest 2008 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$dom = new DomDocument(); +$comment = $dom->createComment('test-comment'); +$comment->replaceData(4,1,'replaced'); +$dom->appendChild($comment); +echo $dom->saveXML(); + +// Replaces rest of string if count is greater than length of existing string +$dom = new DomDocument(); +$comment = $dom->createComment('test-comment'); +$comment->replaceData(0,50,'replaced'); +$dom->appendChild($comment); +echo $dom->saveXML(); + +?> +--EXPECTF-- +<?xml version="1.0"?> +<!--testreplacedcomment--> +<?xml version="1.0"?> +<!--replaced--> diff --git a/ext/dom/tests/DOMComment_replaceData_error1.phpt b/ext/dom/tests/DOMComment_replaceData_error1.phpt new file mode 100644 index 0000000..4ae4cb6 --- /dev/null +++ b/ext/dom/tests/DOMComment_replaceData_error1.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test replacing data into a DOMComment basic test +--CREDITS-- +Andrew Larssen <al@larssen.org> +London TestFest 2008 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +//Negative offset +$dom = new DomDocument(); +$comment = $dom->createComment('test-comment'); +try { + $comment->replaceData(-1,4,'-inserted'); +} catch (DOMException $e ) { + if ($e->getMessage() == 'Index Size Error'){ + echo "Throws DOMException for -ve offest\n"; + } +} + +?> +--EXPECTF-- +Throws DOMException for -ve offest diff --git a/ext/dom/tests/DOMComment_replaceData_error2.phpt b/ext/dom/tests/DOMComment_replaceData_error2.phpt new file mode 100644 index 0000000..89614f9 --- /dev/null +++ b/ext/dom/tests/DOMComment_replaceData_error2.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test replacing data into a DOMComment basic test +--CREDITS-- +Andrew Larssen <al@larssen.org> +London TestFest 2008 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +//offset to large +$dom = new DomDocument(); +$comment = $dom->createComment('test-comment'); +try { + $comment->replaceData(999,4,'-inserted'); +} catch (DOMException $e ) { + if ($e->getMessage() == 'Index Size Error'){ + echo "Throws DOMException for offest too large\n"; + } +} + +?> +--EXPECTF-- +Throws DOMException for offest too large
\ No newline at end of file diff --git a/ext/dom/tests/DOMDocumentFragment_appendXML_basic_001.phpt b/ext/dom/tests/DOMDocumentFragment_appendXML_basic_001.phpt new file mode 100644 index 0000000..a6f381b --- /dev/null +++ b/ext/dom/tests/DOMDocumentFragment_appendXML_basic_001.phpt @@ -0,0 +1,22 @@ +--TEST-- +DOMDocumentFragment::appendXML() with children with properties. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-24 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$document = new DOMDocument; +$root = $document->createElement('root'); +$document->appendChild($root); + +$fragment = $document->createDocumentFragment(); +$fragment->appendXML('<foo id="baz">bar</foo>'); +$root->appendChild($fragment); + +print $document->saveXML(); +?> +--EXPECT-- +<?xml version="1.0"?> +<root><foo id="baz">bar</foo></root> diff --git a/ext/dom/tests/DOMDocumentFragment_appendXML_error_001.phpt b/ext/dom/tests/DOMDocumentFragment_appendXML_error_001.phpt new file mode 100644 index 0000000..6ffe510 --- /dev/null +++ b/ext/dom/tests/DOMDocumentFragment_appendXML_error_001.phpt @@ -0,0 +1,14 @@ +--TEST-- +DOMDocumentFragment::appendXML() with no arguments. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-24 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$fragment = new DOMDocumentFragment(); +$fragment->appendXML(); +?> +--EXPECTF-- +Warning: DOMDocumentFragment::appendXML() expects exactly 1 parameter, 0 given in %s on line %d
\ No newline at end of file diff --git a/ext/dom/tests/DOMDocumentFragment_appendXML_error_002.phpt b/ext/dom/tests/DOMDocumentFragment_appendXML_error_002.phpt new file mode 100644 index 0000000..c02c920 --- /dev/null +++ b/ext/dom/tests/DOMDocumentFragment_appendXML_error_002.phpt @@ -0,0 +1,19 @@ +--TEST-- +DOMDocumentFragment::appendXML() with unbound fragment. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-24 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$fragment = new DOMDocumentFragment(); +$fragment->appendXML('<bait>crankbait</bait>'); +$document->appendChild($fragment); +?> +--EXPECTF-- +Fatal error: Uncaught exception 'DOMException' with message 'No Modification Allowed Error' in %s:%d +Stack trace: +#0 %s(%d): DOMDocumentFragment->appendXML('<bait>crankbait...') +#1 {main} + thrown in %s on line %d
\ No newline at end of file diff --git a/ext/dom/tests/DOMDocumentFragment_appendXML_error_003.phpt b/ext/dom/tests/DOMDocumentFragment_appendXML_error_003.phpt new file mode 100644 index 0000000..8735ae6 --- /dev/null +++ b/ext/dom/tests/DOMDocumentFragment_appendXML_error_003.phpt @@ -0,0 +1,19 @@ +--TEST-- +DOMDocumentFragment::appendXML() with unbalanced chunks. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-24 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$document = new DOMDocument; +$root = $document->createElement('root'); +$document->appendChild($root); + +$fragment = $document->createDocumentFragment(); +@$fragment->appendXML('<foo>is<bar>great</foo>'); +$root->appendChild($fragment); +?> +--EXPECTF-- +Warning: DOMNode::appendChild(): Document Fragment is empty in %s on line %d
\ No newline at end of file diff --git a/ext/dom/tests/DOMDocumentFragment_appendXML_hasChildNodes_basic.phpt b/ext/dom/tests/DOMDocumentFragment_appendXML_hasChildNodes_basic.phpt new file mode 100644 index 0000000..c82a73b --- /dev/null +++ b/ext/dom/tests/DOMDocumentFragment_appendXML_hasChildNodes_basic.phpt @@ -0,0 +1,23 @@ +--TEST-- +Testing DOMDocumentFragment::appendXML and DOMDocumentFragment::hasChildNodes +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$doc = new DOMDocument(); + +$fragment = $doc->createDocumentFragment(); +if ($fragment->hasChildNodes()) { + echo "has child nodes\n"; +} else { + echo "has no child nodes\n"; +} +$fragment->appendXML('<foo>bar</foo>'); +if ($fragment->hasChildNodes()) { + echo "has child nodes\n"; +} else { + echo "has no child nodes\n"; +} +--EXPECT-- +has no child nodes +has child nodes diff --git a/ext/dom/tests/DOMDocumentFragment_construct_basic_001.phpt b/ext/dom/tests/DOMDocumentFragment_construct_basic_001.phpt new file mode 100644 index 0000000..63de771 --- /dev/null +++ b/ext/dom/tests/DOMDocumentFragment_construct_basic_001.phpt @@ -0,0 +1,14 @@ +--TEST-- +DOMDocumentFragment::__construct(). +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-24 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$fragment = new DOMDocumentFragment(); +var_dump(get_class($fragment)); +?> +--EXPECT-- +string(19) "DOMDocumentFragment" diff --git a/ext/dom/tests/DOMDocumentFragment_construct_basic_002.phpt b/ext/dom/tests/DOMDocumentFragment_construct_basic_002.phpt new file mode 100644 index 0000000..0d73445 --- /dev/null +++ b/ext/dom/tests/DOMDocumentFragment_construct_basic_002.phpt @@ -0,0 +1,16 @@ +--TEST-- +DOMDocumentFragment::__construct() called twice. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-24 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$fragment = new DOMDocumentFragment(); +$fragment->__construct(); +var_dump($fragment); +?> +--EXPECTF-- +object(DOMDocumentFragment)#%d (%d) { +} diff --git a/ext/dom/tests/DOMDocumentFragment_construct_error_001.phpt b/ext/dom/tests/DOMDocumentFragment_construct_error_001.phpt new file mode 100644 index 0000000..91173c4 --- /dev/null +++ b/ext/dom/tests/DOMDocumentFragment_construct_error_001.phpt @@ -0,0 +1,17 @@ +--TEST-- +DOMDocumentFragment::__construct() with too many errors. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-24 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$fragment = new DOMDocumentFragment("root"); +?> +--EXPECTF-- +Fatal error: Uncaught exception 'DOMException' with message 'DOMDocumentFragment::__construct() expects exactly 0 parameters, 1 given' in %s:%d +Stack trace: +#0 %s(%d): DOMDocumentFragment->__construct('root') +#1 {main} + thrown in %s on line %d
\ No newline at end of file diff --git a/ext/dom/tests/DOMDocumentType_basic_001.phpt b/ext/dom/tests/DOMDocumentType_basic_001.phpt new file mode 100644 index 0000000..8991ed9 --- /dev/null +++ b/ext/dom/tests/DOMDocumentType_basic_001.phpt @@ -0,0 +1,48 @@ +--TEST-- +DOMDocumentType: basic access to all properties. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-25 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +// Access publicId, systemId, name, internalSubset all with values. +$xml = '<?xml version="1.0" encoding="UTF-8" ?>'; +$xml .= '<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML//EN" "docbookx.dtd">'; +$xml .= '<chapter>1</chapter>'; +$doc = new DOMDocument(); +$doc->loadXML($xml); +$doctype = $doc->doctype; +print "publicId: ".$doctype->publicId."\n"; +print "systemId: ".$doctype->systemId."\n"; +print "name: ".$doctype->name."\n"; +print "internalSubset: ".$doctype->internalSubset."\n"; + + +// Access entities and notations with values. +$xml = '<?xml version="1.0" encoding="UTF-8" ?>'; +$xml .= '<!DOCTYPE img ['; +$xml .= ' <!ELEMENT img EMPTY>'; +$xml .= ' <!ATTLIST img src ENTITY #REQUIRED>'; +$xml .= ' <!ENTITY logo SYSTEM "http://www.xmlwriter.net/logo.gif" NDATA gif>'; +$xml .= ' <!NOTATION gif PUBLIC "gif viewer">'; +$xml .= ']>'; +$xml .= '<img src="logo"/>'; +$doc = new DOMDocument(); +$doc->loadXML($xml); +$doctype = $doc->doctype; +$entities = $doctype->entities; +$entity = $entities->item(0); +print 'entity: '.$entity->nodeName."\n"; +$notations = $doctype->notations; +$notation = $notations->item(0); +print 'notation: '.$notation->nodeName."\n"; +?> +--EXPECT-- +publicId: -//OASIS//DTD DocBook XML//EN +systemId: docbookx.dtd +name: chapter +internalSubset: <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML//EN" "docbookx.dtd"> +entity: logo +notation: gif
\ No newline at end of file diff --git a/ext/dom/tests/DOMDocumentType_entities_error_001.phpt b/ext/dom/tests/DOMDocumentType_entities_error_001.phpt new file mode 100644 index 0000000..73655b0 --- /dev/null +++ b/ext/dom/tests/DOMDocumentType_entities_error_001.phpt @@ -0,0 +1,14 @@ +--TEST-- +DOMDocumentType::entities with invalid state. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-25 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$doctype = new DOMDocumentType(); +$entities = $doctype->entities; +?> +--EXPECTF-- +Warning: main(): Invalid State Error in %s on line %d
\ No newline at end of file diff --git a/ext/dom/tests/DOMDocumentType_internalSubset_error_001.phpt b/ext/dom/tests/DOMDocumentType_internalSubset_error_001.phpt new file mode 100644 index 0000000..c1f7d9b --- /dev/null +++ b/ext/dom/tests/DOMDocumentType_internalSubset_error_001.phpt @@ -0,0 +1,14 @@ +--TEST-- +DOMDocumentType::internalSubset with invalid state. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-25 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$doctype = new DOMDocumentType(); +$internalSubset = $doctype->internalSubset; +?> +--EXPECTF-- +Warning: main(): Invalid State Error in %s on line %d
\ No newline at end of file diff --git a/ext/dom/tests/DOMDocumentType_name_error_001.phpt b/ext/dom/tests/DOMDocumentType_name_error_001.phpt new file mode 100644 index 0000000..d2426e8 --- /dev/null +++ b/ext/dom/tests/DOMDocumentType_name_error_001.phpt @@ -0,0 +1,14 @@ +--TEST-- +DOMDocumentType::name with invalid state. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-25 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$doctype = new DOMDocumentType(); +$name = $doctype->name; +?> +--EXPECTF-- +Warning: main(): Invalid State Error in %s on line %d
\ No newline at end of file diff --git a/ext/dom/tests/DOMDocumentType_notations_error_001.phpt b/ext/dom/tests/DOMDocumentType_notations_error_001.phpt new file mode 100644 index 0000000..e4d1c3c --- /dev/null +++ b/ext/dom/tests/DOMDocumentType_notations_error_001.phpt @@ -0,0 +1,14 @@ +--TEST-- +DOMDocumentType::notations with invalid state. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-25 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$doctype = new DOMDocumentType(); +$notations = $doctype->notations; +?> +--EXPECTF-- +Warning: main(): Invalid State Error in %s on line %d
\ No newline at end of file diff --git a/ext/dom/tests/DOMDocumentType_publicId_basic_001.phpt b/ext/dom/tests/DOMDocumentType_publicId_basic_001.phpt new file mode 100644 index 0000000..49a7eec --- /dev/null +++ b/ext/dom/tests/DOMDocumentType_publicId_basic_001.phpt @@ -0,0 +1,19 @@ +--TEST-- +DOMDocumentType::publicId with empty value. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-25 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$xml = '<?xml version="1.0" encoding="UTF-8" ?>'; +$xml .= '<!DOCTYPE chapter SYSTEM "http://www.xmlwriter.net/logo.gif">'; +$xml .= '<chapter>1</chapter>'; +$doc = new DOMDocument(); +$doc->loadXML($xml); +$doctype = $doc->doctype; +var_dump($doctype->publicId); +?> +--EXPECT-- +string(0) ""
\ No newline at end of file diff --git a/ext/dom/tests/DOMDocumentType_publicId_error_001.phpt b/ext/dom/tests/DOMDocumentType_publicId_error_001.phpt new file mode 100644 index 0000000..275bb65 --- /dev/null +++ b/ext/dom/tests/DOMDocumentType_publicId_error_001.phpt @@ -0,0 +1,14 @@ +--TEST-- +DOMDocumentType::publicId with invalid state. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-25 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$doctype = new DOMDocumentType(); +$publicId = $doctype->publicId; +?> +--EXPECTF-- +Warning: main(): Invalid State Error in %s on line %d
\ No newline at end of file diff --git a/ext/dom/tests/DOMDocumentType_systemId_basic_001.phpt b/ext/dom/tests/DOMDocumentType_systemId_basic_001.phpt new file mode 100644 index 0000000..56f7ddd --- /dev/null +++ b/ext/dom/tests/DOMDocumentType_systemId_basic_001.phpt @@ -0,0 +1,19 @@ +--TEST-- +DOMDocumentType::systemId with empty value. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-25 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$xml = '<?xml version="1.0" encoding="UTF-8" ?>'; +$xml .= '<!DOCTYPE chapter>'; +$xml .= '<chapter>1</chapter>'; +$doc = new DOMDocument(); +$doc->loadXML($xml); +$doctype = $doc->doctype; +var_dump($doctype->systemId); +?> +--EXPECT-- +string(0) ""
\ No newline at end of file diff --git a/ext/dom/tests/DOMDocumentType_systemId_error_001.phpt b/ext/dom/tests/DOMDocumentType_systemId_error_001.phpt new file mode 100644 index 0000000..a4aadd7 --- /dev/null +++ b/ext/dom/tests/DOMDocumentType_systemId_error_001.phpt @@ -0,0 +1,14 @@ +--TEST-- +DOMDocumentType::systemId with invalid state. +--CREDITS-- +Eric Lee Stewart <ericleestewart@gmail.com> +# TestFest Atlanta 2009-05-25 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$doctype = new DOMDocumentType(); +$systemId = $doctype->systemId; +?> +--EXPECTF-- +Warning: main(): Invalid State Error in %s on line %d
\ No newline at end of file diff --git a/ext/dom/tests/DOMDocument_config_basic.phpt b/ext/dom/tests/DOMDocument_config_basic.phpt new file mode 100644 index 0000000..947743a --- /dev/null +++ b/ext/dom/tests/DOMDocument_config_basic.phpt @@ -0,0 +1,26 @@ +--TEST-- +Tests DOMDocument::config read +--CREDITS-- +Chris Snyder <chsnyder@gmail.com> +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +// create dom document +$dom = new DOMDocument; +echo "DOMDocument created\n"; + +$test = $dom->config; +echo "Read config:\n"; +var_dump( $test ); + +// note -- will always be null as DOMConfiguration is not implemented in PHP + +echo "Done\n"; +?> +--EXPECT-- +DOMDocument created +Read config: +NULL +Done diff --git a/ext/dom/tests/DOMDocument_createAttribute_basic.phpt b/ext/dom/tests/DOMDocument_createAttribute_basic.phpt new file mode 100644 index 0000000..4dd181b --- /dev/null +++ b/ext/dom/tests/DOMDocument_createAttribute_basic.phpt @@ -0,0 +1,26 @@ +--TEST-- +DomDocument::createAttribute() - basic test for DomDocument::createAttribute() +--CREDITS-- +Muhammad Khalid Adnan +# TestFest 2008 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument; + +$node = $doc->createElement("para"); +$newnode = $doc->appendChild($node); + +// A pass case. +$test_attribute = $doc->createAttribute("hahaha"); +$node->appendChild($test_attribute); + +echo $doc->saveXML(); + +?> +--EXPECT-- +<?xml version="1.0"?> +<para hahaha=""/> + diff --git a/ext/dom/tests/DOMDocument_createAttribute_error.phpt b/ext/dom/tests/DOMDocument_createAttribute_error.phpt new file mode 100644 index 0000000..bf71d55 --- /dev/null +++ b/ext/dom/tests/DOMDocument_createAttribute_error.phpt @@ -0,0 +1,27 @@ +--TEST-- +Test DOMDocument::createAttribute() for expected expection thrown when wrong parameter passed +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$dom = new DOMDocument(); + +try { + $attr = $dom->createAttribute(0); +} +catch(DOMException $e) { + $code = $e->getCode(); + if(DOM_INVALID_CHARACTER_ERR === $code) { + echo "PASS"; + } + else { + echo 'Wrong exception code'; + } +} +catch(Exception $e) { + echo 'Wrong exception thrown'; +} + +?> +--EXPECTF-- +PASS diff --git a/ext/dom/tests/DOMDocument_createAttribute_error1.phpt b/ext/dom/tests/DOMDocument_createAttribute_error1.phpt new file mode 100644 index 0000000..745873a --- /dev/null +++ b/ext/dom/tests/DOMDocument_createAttribute_error1.phpt @@ -0,0 +1,29 @@ +--TEST-- +DomDocument::createAttribute() - error test for DomDocument::createAttribute() +--CREDITS-- +Muhammad Khalid Adnan +# TestFest 2008 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument; + +$node = $doc->createElement("para"); +$newnode = $doc->appendChild($node); + +try { + $failed_test_attribute = $doc->createAttribute("ha haha"); + $node->appendChild($failed_test_attribute); + + echo $doc->saveXML(); +} +catch (DOMException $e) { + echo 'Test failed!', PHP_EOL; +} + +?> +--EXPECT-- +Test failed! + diff --git a/ext/dom/tests/DOMDocument_createAttribute_variation.phpt b/ext/dom/tests/DOMDocument_createAttribute_variation.phpt new file mode 100644 index 0000000..ff81343 --- /dev/null +++ b/ext/dom/tests/DOMDocument_createAttribute_variation.phpt @@ -0,0 +1,14 @@ +--TEST-- +Test DOMDocument::createAttribute() for expected return value +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$dom = new DOMDocument(); + +$attr = $dom->createAttribute('string'); +echo get_class($attr); + +?> +--EXPECTF-- +DOMAttr diff --git a/ext/dom/tests/DOMDocument_createEntityReference_basic.phpt b/ext/dom/tests/DOMDocument_createEntityReference_basic.phpt new file mode 100644 index 0000000..4f4ddf1 --- /dev/null +++ b/ext/dom/tests/DOMDocument_createEntityReference_basic.phpt @@ -0,0 +1,19 @@ +--TEST-- +DOMDocument::createEntityReference() should create a new entity reference node +--CREDITS-- +Knut Urdalen <knut@php.net> +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- +<?php +require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php +$dom = new DOMDocument('1.0'); +$ref = $dom->createEntityReference('nbsp'); +$dom->appendChild($ref); +echo $dom->saveXML(); +?> +--EXPECTF-- +<?xml version="1.0"?> + diff --git a/ext/dom/tests/DOMDocument_createProcessingInstruction_basic.phpt b/ext/dom/tests/DOMDocument_createProcessingInstruction_basic.phpt new file mode 100644 index 0000000..9f45f12 --- /dev/null +++ b/ext/dom/tests/DOMDocument_createProcessingInstruction_basic.phpt @@ -0,0 +1,30 @@ +--TEST-- +DomDocument::createProcessingInstruction() - basic test for DomDocument::createProcessingInstruction() +--CREDITS-- +Muhammad Khalid Adnan +# TestFest 2008 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument; + +$node = $doc->createElement("para"); +$newnode = $doc->appendChild($node); + +$test_proc_inst0 = + $doc->createProcessingInstruction( "blablabla" ); +$node->appendChild($test_proc_inst0); + +$test_proc_inst1 = + $doc->createProcessingInstruction( "blablabla", "datadata" ); +$node->appendChild($test_proc_inst1); + +echo $doc->saveXML(); + +?> +--EXPECT-- +<?xml version="1.0"?> +<para><?blablabla?><?blablabla datadata?></para> + diff --git a/ext/dom/tests/DOMDocument_createProcessingInstruction_error.phpt b/ext/dom/tests/DOMDocument_createProcessingInstruction_error.phpt new file mode 100644 index 0000000..a0c12b1 --- /dev/null +++ b/ext/dom/tests/DOMDocument_createProcessingInstruction_error.phpt @@ -0,0 +1,31 @@ +--TEST-- +DomDocument::createProcessingInstruction() - error test for DomDocument::createProcessingInstruction() +--CREDITS-- +Muhammad Khalid Adnan +# TestFest 2008 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument; + +$node = $doc->createElement("para"); +$newnode = $doc->appendChild($node); + +try { + $test_proc_inst = + $doc->createProcessingInstruction( "bla bla bla" ); + $node->appendChild($test_proc_inst); + + echo $doc->saveXML(); +} +catch (DOMException $e) +{ + echo 'Test failed!', PHP_EOL; +} + +?> +--EXPECT-- +Test failed! + diff --git a/ext/dom/tests/DOMDocument_documentURI_basic.phpt b/ext/dom/tests/DOMDocument_documentURI_basic.phpt new file mode 100644 index 0000000..e40a42b --- /dev/null +++ b/ext/dom/tests/DOMDocument_documentURI_basic.phpt @@ -0,0 +1,39 @@ +--TEST-- +Tests DOMDocument::documentURI read and write +--CREDITS-- +Chris Snyder <chsnyder@gmail.com> +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +// create dom document +$dom = new DOMDocument; +$xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!DOCTYPE s1 PUBLIC "http://www.ibm.com/example.dtd" "example.dtd"> +<s1>foo</s1>'; +$dom->loadXML($xml); +if(!$dom) { + echo "Error while parsing the document\n"; + exit; +} +echo "DOMDocument created\n"; + +$test = $dom->documentURI; +echo "Read initial documentURI:\n"; +echo $test."\n"; + +$dom->documentURI = 'http://dom.example.org/example.xml'; +$test = $dom->documentURI; +echo "Set documentURI to a URL, reading again:\n"; +var_dump( $test ); + +echo "Done\n"; +?> +--EXPECTF-- +DOMDocument created +Read initial documentURI: +%s +Set documentURI to a URL, reading again: +string(34) "http://dom.example.org/example.xml" +Done diff --git a/ext/dom/tests/DOMDocument_encoding_basic.phpt b/ext/dom/tests/DOMDocument_encoding_basic.phpt new file mode 100644 index 0000000..9fc099b --- /dev/null +++ b/ext/dom/tests/DOMDocument_encoding_basic.phpt @@ -0,0 +1,52 @@ +--TEST-- +DOMDocument::$encoding - read/write tests (dom_document_encoding_read/dom_document_encoding_write) +--CREDITS-- +Hans Zaunere +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +require_once('dom_test.inc'); + +$dom = new DOMDocument; +$dom->loadXML($xmlstr); + +if( !$dom ) +{ + echo "Error while parsing the document\n"; + exit; +} + +echo "Empty Encoding Read: {$dom->encoding}\n"; + +$ret = $dom->encoding = 'NYPHP DOMinatrix'; +echo "Adding invalid encoding: $ret\n"; + +$ret = $dom->encoding = 'ISO-8859-1'; +echo "Adding ISO-8859-1 encoding: $ret\n"; +echo "ISO-8859-1 Encoding Read: {$dom->encoding}\n"; + +$ret = $dom->encoding = 'UTF-8'; +echo "Adding UTF-8 encoding: $ret\n"; +echo "UTF-8 Encoding Read: {$dom->encoding}\n"; + +$ret = $dom->encoding = 'UTF-16'; +echo "Adding UTF-16 encoding: $ret\n"; +echo "UTF-16 Encoding Read: {$dom->encoding}\n"; + + +?> +--EXPECTF-- +Empty Encoding Read: + +Warning: main(): Invalid Document Encoding in %s on line %d +Adding invalid encoding: NYPHP DOMinatrix +Adding ISO-8859-1 encoding: ISO-8859-1 +ISO-8859-1 Encoding Read: ISO-8859-1 +Adding UTF-8 encoding: UTF-8 +UTF-8 Encoding Read: UTF-8 +Adding UTF-16 encoding: UTF-16 +UTF-16 Encoding Read: UTF-16 + diff --git a/ext/dom/tests/DOMDocument_implementationRead_basic.phpt b/ext/dom/tests/DOMDocument_implementationRead_basic.phpt new file mode 100644 index 0000000..17daddf --- /dev/null +++ b/ext/dom/tests/DOMDocument_implementationRead_basic.phpt @@ -0,0 +1,21 @@ +--TEST-- +DOMDocument::DOMImplementation - basic test for DomDocument::DOMImplementation +--CREDITS-- +Lev Radin <prokurator@gmail.com> +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument; +$doc->load(dirname(__FILE__)."/book.xml"); + +var_dump($doc->implementation); + + +?> +--EXPECTF-- +object(DOMImplementation)#%d (0) { +} + diff --git a/ext/dom/tests/DOMDocument_loadHTML_basic.phpt b/ext/dom/tests/DOMDocument_loadHTML_basic.phpt new file mode 100644 index 0000000..616d1d8 --- /dev/null +++ b/ext/dom/tests/DOMDocument_loadHTML_basic.phpt @@ -0,0 +1,18 @@ +--TEST-- +DOMDocument::loadHTML +--CREDITS-- +Frank Cassedanne franck@ouarz.net +#London TestFest 2008 +--SKIPIF-- +<?php +require_once('skipif.inc'); +?> +--FILE-- +<?php +$doc = new DOMDocument(); +$doc->loadHTML("<html><body><p>Test<br></p></body></html>"); +echo $doc->saveHTML(); +?> +--EXPECTF-- +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> +<html><body><p>Test<br></p></body></html> diff --git a/ext/dom/tests/DOMDocument_loadHTML_error1.phpt b/ext/dom/tests/DOMDocument_loadHTML_error1.phpt new file mode 100644 index 0000000..de8d349 --- /dev/null +++ b/ext/dom/tests/DOMDocument_loadHTML_error1.phpt @@ -0,0 +1,15 @@ +--TEST-- +DOMDocument::loadHTML() should fail if no parameter is given +--CREDITS-- +Knut Urdalen <knut@php.net> +--SKIPIF-- +<?php +require_once('skipif.inc'); +?> +--FILE-- +<?php +$doc = new DOMDocument(); +$doc->loadHTML(); +?> +--EXPECTF-- +Warning: DOMDocument::loadHTML() expects at least 1 parameter, 0 given in %s on line %d diff --git a/ext/dom/tests/DOMDocument_loadHTML_error2.phpt b/ext/dom/tests/DOMDocument_loadHTML_error2.phpt new file mode 100644 index 0000000..3167c01 --- /dev/null +++ b/ext/dom/tests/DOMDocument_loadHTML_error2.phpt @@ -0,0 +1,15 @@ +--TEST-- +DOMDocument::loadHTML() should fail if empty string provided as input +--CREDITS-- +Knut Urdalen <knut@php.net> +--SKIPIF-- +<?php +require_once('skipif.inc'); +?> +--FILE-- +<?php +$doc = new DOMDocument(); +$doc->loadHTML(''); +?> +--EXPECTF-- +Warning: DOMDocument::loadHTML(): Empty string supplied as input in %s on line %d diff --git a/ext/dom/tests/DOMDocument_preserveWhiteSpace_basic.phpt b/ext/dom/tests/DOMDocument_preserveWhiteSpace_basic.phpt new file mode 100644 index 0000000..a772bc8 --- /dev/null +++ b/ext/dom/tests/DOMDocument_preserveWhiteSpace_basic.phpt @@ -0,0 +1,23 @@ +--TEST-- +DOMDocument::$preserveWhiteSpace - test ability to read and write property +--CREDITS-- +Lev Radin <prokurator@gmail.com> +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument; +$doc->load(dirname(__FILE__)."/book.xml"); + +var_dump($doc->preserveWhiteSpace); + +$doc->preserveWhiteSpace = false; +var_dump($doc->preserveWhiteSpace); + +?> +--EXPECT-- +bool(true) +bool(false) + diff --git a/ext/dom/tests/DOMDocument_preserveWhiteSpace_variations.phpt b/ext/dom/tests/DOMDocument_preserveWhiteSpace_variations.phpt new file mode 100644 index 0000000..e467f56 --- /dev/null +++ b/ext/dom/tests/DOMDocument_preserveWhiteSpace_variations.phpt @@ -0,0 +1,40 @@ +--TEST-- +DOMDocument::$preserveWhiteSpace - test ability to read and write property +--CREDITS-- +Lev Radin <prokurator@gmail.com> +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +echo "Load document with preserveWhiteSpace on\n"; +$doc = new DOMDocument; +$doc->load(dirname(__FILE__)."/book.xml"); +echo $doc->saveXML(); + + +echo "\nLoad document with preserveWhiteSpace off\n"; +$doc = new DOMDocument; +$doc->preserveWhiteSpace = false; +$doc->load(dirname(__FILE__)."/book.xml"); +echo $doc->saveXML(); + +?> +--EXPECT-- +Load document with preserveWhiteSpace on +<?xml version="1.0"?> +<books> + <book> + <title>The Grapes of Wrath</title> + <author>John Steinbeck</author> + </book> + <book> + <title>The Pearl</title> + <author>John Steinbeck</author> + </book> +</books> + +Load document with preserveWhiteSpace off +<?xml version="1.0"?> +<books><book><title>The Grapes of Wrath</title><author>John Steinbeck</author></book><book><title>The Pearl</title><author>John Steinbeck</author></book></books> diff --git a/ext/dom/tests/DOMDocument_relaxNGValidateSource_basic.phpt b/ext/dom/tests/DOMDocument_relaxNGValidateSource_basic.phpt new file mode 100644 index 0000000..93b9cf7 --- /dev/null +++ b/ext/dom/tests/DOMDocument_relaxNGValidateSource_basic.phpt @@ -0,0 +1,39 @@ +--TEST-- +DOMDocument::relaxNGValidateSource() +--CREDITS-- +Knut Urdalen <knut@php.net> +--SKIPIF-- +<?php +require_once('skipif.inc'); +?> +--FILE-- +<?php +$rng = <<< RNG +<?xml version="1.0" encoding="UTF-8"?> +<grammar ns="" xmlns="http://relaxng.org/ns/structure/1.0" + datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> + <start> + <element name="apple"> + <element name="pear"> + <data type="NCName"/> + </element> + </element> + </start> +</grammar> +RNG; + +$good_xml = <<< GOOD_XML +<?xml version="1.0"?> +<apple> + <pear>Pear</pear> +</apple> +GOOD_XML; + +$doc = new DOMDocument(); +$doc->loadXML($good_xml); +$result = $doc->relaxNGValidateSource($rng); +var_dump($result); + +?> +--EXPECTF-- +bool(true) diff --git a/ext/dom/tests/DOMDocument_relaxNGValidateSource_error1.phpt b/ext/dom/tests/DOMDocument_relaxNGValidateSource_error1.phpt new file mode 100644 index 0000000..7da71a5 --- /dev/null +++ b/ext/dom/tests/DOMDocument_relaxNGValidateSource_error1.phpt @@ -0,0 +1,41 @@ +--TEST-- +DOMDocument::relaxNGValidateSource() should fail if document doesn't validate +--CREDITS-- +Knut Urdalen <knut@php.net> +--SKIPIF-- +<?php +require_once('skipif.inc'); +?> +--FILE-- +<?php +$rng = <<< RNG +<?xml version="1.0" encoding="UTF-8"?> +<grammar ns="" xmlns="http://relaxng.org/ns/structure/1.0" + datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> + <start> + <element name="apple"> + <element name="pear"> + <data type="NCName"/> + </element> + </element> + </start> +</grammar> +RNG; + +$bad_xml = <<< BAD_XML +<?xml version="1.0"?> +<apple> + <pear>Pear</pear> + <pear>Pear</pear> +</apple> +BAD_XML; + +$doc = new DOMDocument(); +$doc->loadXML($bad_xml); +$result = $doc->relaxNGValidateSource($rng); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::relaxNGValidateSource(): Did not expect element pear there in %s on line %d +bool(false) diff --git a/ext/dom/tests/DOMDocument_relaxNGValidateSource_error2.phpt b/ext/dom/tests/DOMDocument_relaxNGValidateSource_error2.phpt new file mode 100644 index 0000000..d689934 --- /dev/null +++ b/ext/dom/tests/DOMDocument_relaxNGValidateSource_error2.phpt @@ -0,0 +1,39 @@ +--TEST-- +DOMDocument::relaxNGValidateSource() should fail on invalid RNG schema +--CREDITS-- +Knut Urdalen <knut@php.net> +--SKIPIF-- +<?php +require_once('skipif.inc'); +?> +--FILE-- +<?php +$rng = <<< RNG +<?xml version="1.0" encoding="UTF-8"?> +<grammar ns="" xmlns="http://relaxng.org/ns/structure/1.0" + datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> + <start> + <element name="apple"> + </element> + </start> +</grammar> +RNG; + +$xml = <<< XML +<?xml version="1.0"?> +<apple> + <pear>Pear</pear> +</apple> +XML; + +$doc = new DOMDocument(); +$doc->loadXML($xml); +$result = $doc->relaxNGValidateSource($rng); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::relaxNGValidateSource(): xmlRelaxNGParseElement: element has no content in %s on line %d + +Warning: DOMDocument::relaxNGValidateSource(): Invalid RelaxNG in %s on line %d +bool(false) diff --git a/ext/dom/tests/DOMDocument_relaxNGValidate_basic.phpt b/ext/dom/tests/DOMDocument_relaxNGValidate_basic.phpt new file mode 100644 index 0000000..76a6442 --- /dev/null +++ b/ext/dom/tests/DOMDocument_relaxNGValidate_basic.phpt @@ -0,0 +1,24 @@ +--TEST-- +DOMDocument::relaxNGValidate() +--CREDITS-- +Knut Urdalen <knut@php.net> +--SKIPIF-- +<?php +require_once('skipif.inc'); +?> +--FILE-- +<?php +$rng = dirname(__FILE__).'/DOMDocument_relaxNGValidate_basic.rng'; +$xml = <<< XML +<?xml version="1.0"?> +<apple> + <pear>Pear</pear> +</apple> +XML; +$doc = new DOMDocument(); +$doc->loadXML($xml); +$result = $doc->relaxNGValidate($rng); +var_dump($result); +?> +--EXPECTF-- +bool(true) diff --git a/ext/dom/tests/DOMDocument_relaxNGValidate_basic.rng b/ext/dom/tests/DOMDocument_relaxNGValidate_basic.rng new file mode 100644 index 0000000..35e3518 --- /dev/null +++ b/ext/dom/tests/DOMDocument_relaxNGValidate_basic.rng @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<grammar ns="" xmlns="http://relaxng.org/ns/structure/1.0" + datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> + <start> + <element name="apple"> + <element name="pear"> + <data type="NCName"/> + </element> + </element> + </start> +</grammar> diff --git a/ext/dom/tests/DOMDocument_relaxNGValidate_error1.phpt b/ext/dom/tests/DOMDocument_relaxNGValidate_error1.phpt new file mode 100644 index 0000000..82957c3 --- /dev/null +++ b/ext/dom/tests/DOMDocument_relaxNGValidate_error1.phpt @@ -0,0 +1,26 @@ +--TEST-- +DOMDocument::relaxNGValidate() should fail if document doesn't validate +--CREDITS-- +Knut Urdalen <knut@php.net> +--SKIPIF-- +<?php +require_once('skipif.inc'); +?> +--FILE-- +<?php +$rng = dirname(__FILE__).'/DOMDocument_relaxNGValidate_basic.rng'; +$xml = <<< XML +<?xml version="1.0"?> +<apple> + <pear>Pear</pear> + <pear>Pear</pear> +</apple> +XML; +$doc = new DOMDocument(); +$doc->loadXML($xml); +$result = $doc->relaxNGValidate($rng); +var_dump($result); +?> +--EXPECTF-- +Warning: DOMDocument::relaxNGValidate(): Did not expect element pear there in %s on line %d +bool(false) diff --git a/ext/dom/tests/DOMDocument_relaxNGValidate_error2.phpt b/ext/dom/tests/DOMDocument_relaxNGValidate_error2.phpt new file mode 100644 index 0000000..7c5f890 --- /dev/null +++ b/ext/dom/tests/DOMDocument_relaxNGValidate_error2.phpt @@ -0,0 +1,31 @@ +--TEST-- +DOMDocument::relaxNGValidate() should fail on invalid RelaxNG file source +--CREDITS-- +Knut Urdalen <knut@php.net> +--SKIPIF-- +<?php +require_once('skipif.inc'); +?> +--FILE-- +<?php +$rng = dirname(__FILE__).'/foo.rng'; +$xml = <<< XML +<?xml version="1.0"?> +<apple> + <pear>Pear</pear> + <pear>Pear</pear> +</apple> +XML; +$doc = new DOMDocument(); +$doc->loadXML($xml); +$result = $doc->relaxNGValidate($rng); +var_dump($result); +?> +--EXPECTF-- + +Warning: DOMDocument::relaxNGValidate(): I/O warning : failed to load external entity "%s/foo.rng" in %s on line %d + +Warning: DOMDocument::relaxNGValidate(): xmlRelaxNGParse: could not load %s/foo.rng in %s on line %d + +Warning: DOMDocument::relaxNGValidate(): Invalid RelaxNG in %s on line %d +bool(false) diff --git a/ext/dom/tests/DOMDocument_resolveExternals_basic.phpt b/ext/dom/tests/DOMDocument_resolveExternals_basic.phpt new file mode 100644 index 0000000..ccada3f --- /dev/null +++ b/ext/dom/tests/DOMDocument_resolveExternals_basic.phpt @@ -0,0 +1,49 @@ +--TEST-- +Tests DOMDocument::resoleExternals get and set +--CREDITS-- +Chris Snyder <chsnyder@gmail.com> +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +// create dom document +$dom = new DOMDocument; +$xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<h1>"Foo"</h1>'; +$dom->loadXML($xml); +if(!$dom) { + echo "Error while parsing the document\n"; + exit; +} +echo "DOMDocument with external entities created\n"; + +$test = $dom->resolveExternals; +echo "Read initial resolveExternals:\n"; +var_dump( $test ); + +$dom->resolveExternals = TRUE; +$test = $dom->resolveExternals; +echo "Set resolveExternals to TRUE, reading again:\n"; +var_dump( $test ); + +/** + * Don't bother testing the resolveExternals functionality here, it throws warnings on html dtd + * +echo "Reloading xml with resolveExternals turned on\n"; +$dom->loadXML($xml); +$test = $dom->saveXML(); +var_dump( $test ); + */ + +echo "Done"; +?> +--EXPECT-- +DOMDocument with external entities created +Read initial resolveExternals: +bool(false) +Set resolveExternals to TRUE, reading again: +bool(true) +Done
\ No newline at end of file diff --git a/ext/dom/tests/DOMDocument_saveHTMLFile_basic.phpt b/ext/dom/tests/DOMDocument_saveHTMLFile_basic.phpt new file mode 100644 index 0000000..dd0824b --- /dev/null +++ b/ext/dom/tests/DOMDocument_saveHTMLFile_basic.phpt @@ -0,0 +1,29 @@ +--TEST-- +DOMDocument::saveHTMLFile() should dump the internal document into a file using HTML formatting +--CREDITS-- +Knut Urdalen <knut@php.net> +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- +<?php +require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php +$filename = dirname(__FILE__)."/tmp_savehtmlfile".time().".html"; +$doc = new DOMDocument('1.0'); +$root = $doc->createElement('html'); +$root = $doc->appendChild($root); +$head = $doc->createElement('head'); +$head = $root->appendChild($head); +$title = $doc->createElement('title'); +$title = $head->appendChild($title); +$text = $doc->createTextNode('This is the title'); +$text = $title->appendChild($text); +$bytes = $doc->saveHTMLFile($filename); +var_dump($bytes); +echo file_get_contents($filename); +unlink($filename); +?> +--EXPECTF-- +int(126) +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>This is the title</title></head></html> diff --git a/ext/dom/tests/DOMDocument_saveHTMLFile_error1.phpt b/ext/dom/tests/DOMDocument_saveHTMLFile_error1.phpt new file mode 100644 index 0000000..d4dfbe8 --- /dev/null +++ b/ext/dom/tests/DOMDocument_saveHTMLFile_error1.phpt @@ -0,0 +1,24 @@ +--TEST-- +DOMDocument::saveHTMLFile() should fail if no parameter is given +--CREDITS-- +Knut Urdalen <knut@php.net> +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- +<?php +require_once('skipif.inc'); +?> +--FILE-- +<?php +$doc = new DOMDocument('1.0'); +$root = $doc->createElement('html'); +$root = $doc->appendChild($root); +$head = $doc->createElement('head'); +$head = $root->appendChild($head); +$title = $doc->createElement('title'); +$title = $head->appendChild($title); +$text = $doc->createTextNode('This is the title'); +$text = $title->appendChild($text); +$doc->saveHTMLFile(); +?> +--EXPECTF-- +Warning: DOMDocument::saveHTMLFile() expects exactly 1 parameter, 0 given in %s on line %d diff --git a/ext/dom/tests/DOMDocument_saveHTMLFile_error2.phpt b/ext/dom/tests/DOMDocument_saveHTMLFile_error2.phpt new file mode 100644 index 0000000..33e07c6 --- /dev/null +++ b/ext/dom/tests/DOMDocument_saveHTMLFile_error2.phpt @@ -0,0 +1,15 @@ +--TEST-- +DOMDocument::saveHTMLFile() should fail if called statically +--CREDITS-- +Knut Urdalen <knut@php.net> +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- +<?php +require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php +DOMDocument::saveHTMLFile(); +?> +--EXPECTF-- +Fatal error: Non-static method DOMDocument::saveHTMLFile() cannot be called statically in %s on line %d diff --git a/ext/dom/tests/DOMDocument_saveHTMLFile_formatOutput.phpt b/ext/dom/tests/DOMDocument_saveHTMLFile_formatOutput.phpt new file mode 100644 index 0000000..5aece37 --- /dev/null +++ b/ext/dom/tests/DOMDocument_saveHTMLFile_formatOutput.phpt @@ -0,0 +1,33 @@ +--TEST-- +DOMDocument::saveHTMLFile() should format output on demand +--CREDITS-- +Knut Urdalen <knut@php.net> +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- +<?php +require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php +$filename = dirname(__FILE__)."/tmp_savehtmlfile".time().".html"; +$doc = new DOMDocument('1.0'); +$doc->formatOutput = true; +$root = $doc->createElement('html'); +$root = $doc->appendChild($root); +$head = $doc->createElement('head'); +$head = $root->appendChild($head); +$title = $doc->createElement('title'); +$title = $head->appendChild($title); +$text = $doc->createTextNode('This is the title'); +$text = $title->appendChild($text); +$bytes = $doc->saveHTMLFile($filename); +var_dump($bytes); +echo file_get_contents($filename); +unlink($filename); +?> +--EXPECTF-- +int(129) +<html><head> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<title>This is the title</title> +</head></html> diff --git a/ext/dom/tests/DOMDocument_saveHTMLFile_invalid_filename.phpt b/ext/dom/tests/DOMDocument_saveHTMLFile_invalid_filename.phpt new file mode 100644 index 0000000..d5c6a79 --- /dev/null +++ b/ext/dom/tests/DOMDocument_saveHTMLFile_invalid_filename.phpt @@ -0,0 +1,25 @@ +--TEST-- +DOMDocument::saveHTMLFile() should fail with invalid filename +--CREDITS-- +Knut Urdalen <knut@php.net> +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- +<?php +require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php +$filename = null; +$doc = new DOMDocument('1.0'); +$root = $doc->createElement('html'); +$root = $doc->appendChild($root); +$head = $doc->createElement('head'); +$head = $root->appendChild($head); +$title = $doc->createElement('title'); +$title = $head->appendChild($title); +$text = $doc->createTextNode('This is the title'); +$text = $title->appendChild($text); +$bytes = $doc->saveHTMLFile($filename); +?> +--EXPECTF-- +Warning: DOMDocument::saveHTMLFile(): Invalid Filename in %s on line %d diff --git a/ext/dom/tests/DOMDocument_saveHTML_basic.phpt b/ext/dom/tests/DOMDocument_saveHTML_basic.phpt new file mode 100644 index 0000000..76f1ed0 --- /dev/null +++ b/ext/dom/tests/DOMDocument_saveHTML_basic.phpt @@ -0,0 +1,24 @@ +--TEST-- +DOMDocument::saveHTML() should dump the internal document into a string using HTML formatting +--CREDITS-- +Knut Urdalen <knut@php.net> +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- +<?php +require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php +$doc = new DOMDocument('1.0'); +$root = $doc->createElement('html'); +$root = $doc->appendChild($root); +$head = $doc->createElement('head'); +$head = $root->appendChild($head); +$title = $doc->createElement('title'); +$title = $head->appendChild($title); +$text = $doc->createTextNode('This is the title'); +$text = $title->appendChild($text); +echo $doc->saveHTML(); +?> +--EXPECTF-- +<html><head><title>This is the title</title></head></html> diff --git a/ext/dom/tests/DOMDocument_saveHTML_error2.phpt b/ext/dom/tests/DOMDocument_saveHTML_error2.phpt new file mode 100644 index 0000000..614605b --- /dev/null +++ b/ext/dom/tests/DOMDocument_saveHTML_error2.phpt @@ -0,0 +1,15 @@ +--TEST-- +DOMDocument::saveHTML() should fail if called statically +--CREDITS-- +Knut Urdalen <knut@php.net> +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- +<?php +require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php +DOMDocument::saveHTML(true); +?> +--EXPECTF-- +Fatal error: Non-static method DOMDocument::saveHTML() cannot be called statically in %s on line %d diff --git a/ext/dom/tests/DOMDocument_saveHTML_variant1.phpt b/ext/dom/tests/DOMDocument_saveHTML_variant1.phpt new file mode 100644 index 0000000..d169113 --- /dev/null +++ b/ext/dom/tests/DOMDocument_saveHTML_variant1.phpt @@ -0,0 +1,24 @@ +--TEST-- +DOMDocument::saveHTML() optional parameters +--SKIPIF-- +<?php +require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php +$doc = new DOMDocument('1.0'); +$root = $doc->createElement('html'); +$root = $doc->appendChild($root); +$head = $doc->createElement('head'); +$head = $root->appendChild($head); +$title = $doc->createElement('title'); +$title = $head->appendChild($title); +$text = $doc->createTextNode('This is the title'); +$text = $title->appendChild($text); +echo $doc->saveHTML(NULL), "\n"; +echo $doc->saveHTML($title), "\n"; +?> +--EXPECTF-- +<html><head><title>This is the title</title></head></html> + +<title>This is the title</title> diff --git a/ext/dom/tests/DOMDocument_saveHTML_variant2.phpt b/ext/dom/tests/DOMDocument_saveHTML_variant2.phpt new file mode 100644 index 0000000..54ccda1 --- /dev/null +++ b/ext/dom/tests/DOMDocument_saveHTML_variant2.phpt @@ -0,0 +1,26 @@ +--TEST-- +DOMDocument::saveHTML() vs DOMDocumet::saveXML() +--SKIPIF-- +<?php +require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php +$d = new DOMDocument(); +$str = <<<EOD +<html> +<head> +</head> +<body> +<p>Hi.<br/>there</p> +</body> +</html> +EOD; +$d->loadHTML($str); +$e = $d->getElementsByTagName("p"); +$e = $e->item(0); +echo $d->saveXml($e),"\n"; +echo $d->saveHtml($e),"\n"; +--EXPECTF-- +<p>Hi.<br/>there</p> +<p>Hi.<br>there</p> diff --git a/ext/dom/tests/DOMDocument_save_basic.phpt b/ext/dom/tests/DOMDocument_save_basic.phpt new file mode 100644 index 0000000..c7d1ead --- /dev/null +++ b/ext/dom/tests/DOMDocument_save_basic.phpt @@ -0,0 +1,33 @@ +--TEST-- +DOMDocument::save Test basic function of save method +--SKIPIF-- +<?php +require_once('skipif.inc'); +?> +--FILE-- +<?php +$doc = new DOMDocument('1.0'); +$doc->formatOutput = true; + +$root = $doc->createElement('book'); + +$root = $doc->appendChild($root); + +$title = $doc->createElement('title'); +$title = $root->appendChild($title); + +$text = $doc->createTextNode('This is the title'); +$text = $title->appendChild($text); + +$temp_filename = dirname(__FILE__)."/DomDocument_save_basic.tmp"; + +echo 'Wrote: ' . $doc->save($temp_filename) . ' bytes'; // Wrote: 72 bytes +?> +--CLEAN-- +<?php + $temp_filename = dirname(__FILE__)."/DomDocument_save_basic.tmp"; + unlink($temp_filename); +?> +--EXPECTF-- +Wrote: 72 bytes + diff --git a/ext/dom/tests/DOMDocument_savexml_basic.phpt b/ext/dom/tests/DOMDocument_savexml_basic.phpt new file mode 100644 index 0000000..10f748c --- /dev/null +++ b/ext/dom/tests/DOMDocument_savexml_basic.phpt @@ -0,0 +1,39 @@ +--TEST-- +DOM Document : save and saveXML +--CREDITS-- +Sami Greenbury (sami@patabugen.co.uk) +# TestFest 2008 +--SKIPIF-- +<?php +require_once('skipif.inc'); +?> +--FILE-- +<?php + +$xml = <<< EOXML +<?xml version="1.0" encoding="utf-8"?> +<courses> + <!-- Hello World! --> + <aNode> + <childNode> + <childlessNode /> + </childNode> + </aNode> +</courses> +EOXML; + +$dom = new DOMDocument(); +$dom->loadXML($xml); +$root = $dom->documentElement; +$directory = dirname(__FILE__); + +$filename = $directory."/tmp_dom_savexml".time(); +var_dump($dom->save($filename)); +$result = file_get_contents($filename); +var_dump($result == $dom->saveXML()); + +unlink($filename); + +--EXPECTF-- +int(151) +bool(true)
\ No newline at end of file diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_basic.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_basic.phpt new file mode 100644 index 0000000..38bc3fa --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidateSource_basic.phpt @@ -0,0 +1,22 @@ +--TEST-- +DomDocument::schemaValidateSource() - basic +--CREDITS-- +Daniel Convissor <danielc@php.net> +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument; + +$doc->load(dirname(__FILE__)."/book.xml"); + +$xsd = file_get_contents(dirname(__FILE__)."/book.xsd"); + +$result = $doc->schemaValidateSource($xsd); +var_dump($result); + +?> +--EXPECT-- +bool(true) diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_error1.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_error1.phpt new file mode 100644 index 0000000..51eb82e --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidateSource_error1.phpt @@ -0,0 +1,29 @@ +--TEST-- +DomDocument::schemaValidateSource() - string that is not a schema +--CREDITS-- +Daniel Convissor <danielc@php.net> +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument; + +$doc->load(dirname(__FILE__)."/book.xml"); + +$result = $doc->schemaValidateSource('string that is not a schema'); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::schemaValidateSource(): Entity: line 1: parser error : Start tag expected, '<' not found in %s.php on line %d + +Warning: DOMDocument::schemaValidateSource(): string that is not a schema in %s.php on line %d + +Warning: DOMDocument::schemaValidateSource(): ^ in %s.php on line %d + +Warning: DOMDocument::schemaValidateSource(): Failed to parse the XML resource 'in_memory_buffer'. in %s.php on line %d + +Warning: DOMDocument::schemaValidateSource(): Invalid Schema in %s.php on line %d +bool(false) diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_error2.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_error2.phpt new file mode 100644 index 0000000..41a833b --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidateSource_error2.phpt @@ -0,0 +1,23 @@ +--TEST-- +DomDocument::schemaValidateSource() - non-conforming schema +--CREDITS-- +Daniel Convissor <danielc@php.net> +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument; + +$doc->load(dirname(__FILE__)."/book.xml"); + +$xsd = file_get_contents(dirname(__FILE__)."/book-non-conforming-schema.xsd"); + +$result = $doc->schemaValidateSource($xsd); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::schemaValidateSource(): Element 'books': No matching global declaration available for the validation root. in %s.php on line %d +bool(false) diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt new file mode 100644 index 0000000..93dd792 --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt @@ -0,0 +1,21 @@ +--TEST-- +DomDocument::schemaValidateSource() - empty string for schema string +--CREDITS-- +Daniel Convissor <danielc@php.net> +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument; + +$doc->load(dirname(__FILE__)."/book.xml"); + +$result = $doc->schemaValidateSource(''); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::schemaValidateSource(): Invalid Schema source in %s.php on line %d +bool(false) diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_error4.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_error4.phpt new file mode 100644 index 0000000..65c8d86 --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidateSource_error4.phpt @@ -0,0 +1,21 @@ +--TEST-- +DomDocument::schemaValidateSource() - pass no parameters +--CREDITS-- +Daniel Convissor <danielc@php.net> +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument; + +$doc->load(dirname(__FILE__)."/book.xml"); + +$result = $doc->schemaValidateSource(); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::schemaValidateSource() expects exactly 1 parameter, 0 given in %s.php on line %d +NULL diff --git a/ext/dom/tests/DOMDocument_schemaValidate_basic.phpt b/ext/dom/tests/DOMDocument_schemaValidate_basic.phpt new file mode 100644 index 0000000..eec790d --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidate_basic.phpt @@ -0,0 +1,20 @@ +--TEST-- +DomDocument::schemaValidate() - basic +--CREDITS-- +Daniel Convissor <danielc@php.net> +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument; + +$doc->load(dirname(__FILE__)."/book.xml"); + +$result = $doc->schemaValidate(dirname(__FILE__)."/book.xsd"); +var_dump($result); + +?> +--EXPECT-- +bool(true) diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error1.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error1.phpt new file mode 100644 index 0000000..594c3c4 --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidate_error1.phpt @@ -0,0 +1,29 @@ +--TEST-- +DomDocument::schemaValidate() - file that is not a schema +--CREDITS-- +Daniel Convissor <danielc@php.net> +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument; + +$doc->load(dirname(__FILE__)."/book.xml"); + +$result = $doc->schemaValidate(dirname(__FILE__)."/book-not-a-schema.xsd"); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::schemaValidate(): %sbook-not-a-schema.xsd:1: parser error : Start tag expected, '<' not found in %s.php on line %d + +Warning: DOMDocument::schemaValidate(): Let's see what happens upon parsing a file that doesn't contain a schema. in %s.php on line %d + +Warning: DOMDocument::schemaValidate(): ^ in %s.php on line %d + +Warning: DOMDocument::schemaValidate(): Failed to parse the XML resource '%sbook-not-a-schema.xsd'. in %s.php on line %d + +Warning: DOMDocument::schemaValidate(): Invalid Schema in %s.php on line %d +bool(false) diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error2.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error2.phpt new file mode 100644 index 0000000..5ffd533 --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidate_error2.phpt @@ -0,0 +1,21 @@ +--TEST-- +DomDocument::schemaValidate() - non-conforming schema file +--CREDITS-- +Daniel Convissor <danielc@php.net> +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument; + +$doc->load(dirname(__FILE__)."/book.xml"); + +$result = $doc->schemaValidate(dirname(__FILE__)."/book-non-conforming-schema.xsd"); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::schemaValidate(): Element 'books': No matching global declaration available for the validation root. in %s.php on line %d +bool(false) diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt new file mode 100644 index 0000000..275204f --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt @@ -0,0 +1,21 @@ +--TEST-- +DomDocument::schemaValidate() - empty string for schema file name +--CREDITS-- +Daniel Convissor <danielc@php.net> +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument; + +$doc->load(dirname(__FILE__)."/book.xml"); + +$result = $doc->schemaValidate(''); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::schemaValidate(): Invalid Schema source in %s.php on line %d +bool(false) diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error4.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error4.phpt new file mode 100644 index 0000000..d4817de --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidate_error4.phpt @@ -0,0 +1,21 @@ +--TEST-- +DomDocument::schemaValidate() - pass no parameters +--CREDITS-- +Daniel Convissor <danielc@php.net> +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument; + +$doc->load(dirname(__FILE__)."/book.xml"); + +$result = $doc->schemaValidate(); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::schemaValidate() expects exactly 1 parameter, 0 given in %s.php on line %d +NULL diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error5.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error5.phpt new file mode 100644 index 0000000..d3f0658 --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidate_error5.phpt @@ -0,0 +1,25 @@ +--TEST-- +DomDocument::schemaValidate() - non-existant schema file +--CREDITS-- +Daniel Convissor <danielc@php.net> +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument; + +$doc->load(dirname(__FILE__)."/book.xml"); + +$result = $doc->schemaValidate(dirname(__FILE__)."/non-existant-file"); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::schemaValidate(): I/O warning : failed to load external entity "%snon-existant-file" in %s.php on line %d + +Warning: DOMDocument::schemaValidate(): Failed to locate the main schema resource at '%s/non-existant-file'. in %s.php on line %d + +Warning: DOMDocument::schemaValidate(): Invalid Schema in %s.php on line %d +bool(false) diff --git a/ext/dom/tests/DOMDocument_standalone_basic.phpt b/ext/dom/tests/DOMDocument_standalone_basic.phpt new file mode 100644 index 0000000..2316a38 --- /dev/null +++ b/ext/dom/tests/DOMDocument_standalone_basic.phpt @@ -0,0 +1,48 @@ +--TEST-- +Tests DOMDocument::standalone get, set, and functionality +--CREDITS-- +Chris Snyder <chsnyder@gmail.com> +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +// create dom document +$dom = new DOMDocument; +$xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!DOCTYPE s1 PUBLIC "http://www.ibm.com/example.dtd" "example.dtd"> +<s1>foo</s1>'; +$dom->loadXML($xml); +if(!$dom) { + echo "Error while parsing the document\n"; + exit; +} +echo "Standalone DOMDocument created\n"; + +$test = $dom->standalone; +echo "Read initial standalone:\n"; +var_dump( $test ); + +$dom->standalone = FALSE; +$test = $dom->standalone; +echo "Set standalone to FALSE, reading again:\n"; +var_dump( $test ); + +$test = $dom->saveXML(); +echo "Document is no longer standalone\n"; +var_dump( $test ); + +echo "Done"; +?> +--EXPECT-- +Standalone DOMDocument created +Read initial standalone: +bool(true) +Set standalone to FALSE, reading again: +bool(false) +Document is no longer standalone +string(136) "<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE s1 PUBLIC "http://www.ibm.com/example.dtd" "example.dtd"> +<s1>foo</s1> +" +Done
\ No newline at end of file diff --git a/ext/dom/tests/DOMDocument_strictErrorChecking_basic.phpt b/ext/dom/tests/DOMDocument_strictErrorChecking_basic.phpt new file mode 100644 index 0000000..9ad55a4 --- /dev/null +++ b/ext/dom/tests/DOMDocument_strictErrorChecking_basic.phpt @@ -0,0 +1,22 @@ +--TEST-- +DomDocument::$strictErrorChecking - basic test +--CREDITS-- +Vincent Tsao <notes4vincent@gmail.com> +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument; +$doc->load(dirname(__FILE__)."/book.xml"); + +var_dump($doc->strictErrorChecking); + +$doc->strictErrorChecking = false; +var_dump($doc->strictErrorChecking); + +?> +--EXPECT-- +bool(true) +bool(false) diff --git a/ext/dom/tests/DOMDocument_strictErrorChecking_variation.phpt b/ext/dom/tests/DOMDocument_strictErrorChecking_variation.phpt new file mode 100644 index 0000000..b6d94f9 --- /dev/null +++ b/ext/dom/tests/DOMDocument_strictErrorChecking_variation.phpt @@ -0,0 +1,59 @@ +--TEST-- +DomDocument::$strictErrorChecking - ensure turning off actually works +--CREDITS-- +Vincent Tsao <notes4vincent@gmail.com> +(and Dan Convissor) +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +echo "Load document\n"; +$doc = new DOMDocument; +$doc->load(dirname(__FILE__)."/book.xml"); + +echo "See if strictErrorChecking is on\n"; +var_dump($doc->strictErrorChecking); + +echo "Should throw DOMException when strictErrorChecking is on\n"; +try { + $attr = $doc->createAttribute(0); +} catch (DOMException $e) { + echo "GOOD. DOMException thrown\n"; + echo $e->getMessage() ."\n"; +} catch (Exception $e) { + echo "OOPS. Other exception thrown\n"; +} + + +echo "Turn strictErrorChecking off\n"; +$doc->strictErrorChecking = false; + +echo "See if strictErrorChecking is off\n"; +var_dump($doc->strictErrorChecking); + +echo "Should raise PHP error because strictErrorChecking is off\n"; +try { + $attr = $doc->createAttribute(0); +} catch (DOMException $e) { + echo "OOPS. DOMException thrown\n"; + echo $e->getMessage() ."\n"; +} catch (Exception $e) { + echo "OOPS. Other exception thrown\n"; +} + +?> +--EXPECTF-- +Load document +See if strictErrorChecking is on +bool(true) +Should throw DOMException when strictErrorChecking is on +GOOD. DOMException thrown +Invalid Character Error +Turn strictErrorChecking off +See if strictErrorChecking is off +bool(false) +Should raise PHP error because strictErrorChecking is off + +Warning: DOMDocument::createAttribute(): Invalid Character Error in %sDOMDocument_strictErrorChecking_variation.php on line %d diff --git a/ext/dom/tests/DOMDocument_validate_basic.phpt b/ext/dom/tests/DOMDocument_validate_basic.phpt new file mode 100644 index 0000000..7c0eec8 --- /dev/null +++ b/ext/dom/tests/DOMDocument_validate_basic.phpt @@ -0,0 +1,31 @@ +--TEST-- +DOMDocument::validate() should validate an internal DTD declaration +--CREDITS-- +Knut Urdalen <knut@php.net> +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- +<?php +require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php +$xml = "<?xml version=\"1.0\"?> +<!DOCTYPE note [ +<!ELEMENT note (to,from,heading,body)> +<!ELEMENT to (#PCDATA)> +<!ELEMENT from (#PCDATA)> +<!ELEMENT heading (#PCDATA)> +<!ELEMENT body (#PCDATA)> +]> +<note> +<to>Tove</to> +<from>Jani</from> +<heading>Reminder</heading> +<body>Don't forget me this weekend</body> +</note>"; +$dom = new DOMDocument('1.0'); +$dom->loadXML($xml); +var_dump($dom->validate()); +?> +--EXPECTF-- +bool(true) diff --git a/ext/dom/tests/DOMDocument_validate_error1.phpt b/ext/dom/tests/DOMDocument_validate_error1.phpt new file mode 100644 index 0000000..8e1e72f --- /dev/null +++ b/ext/dom/tests/DOMDocument_validate_error1.phpt @@ -0,0 +1,16 @@ +--TEST-- +DOMDocument::validate() should fail if any parameter is given +--CREDITS-- +Knut Urdalen <knut@php.net> +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- +<?php +require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php +$dom = new DOMDocument('1.0'); +$dom->validate(true); +?> +--EXPECTF-- +Warning: DOMDocument::validate() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/dom/tests/DOMDocument_validate_error2.phpt b/ext/dom/tests/DOMDocument_validate_error2.phpt new file mode 100644 index 0000000..fe7e4fc --- /dev/null +++ b/ext/dom/tests/DOMDocument_validate_error2.phpt @@ -0,0 +1,15 @@ +--TEST-- +DOMDocument::validate() should fail if called statically +--CREDITS-- +Knut Urdalen <knut@php.net> +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- +<?php +require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php +DOMDocument::validate(); +?> +--EXPECTF-- +Fatal error: Non-static method DOMDocument::validate() cannot be called statically in %s on line %d diff --git a/ext/dom/tests/DOMDocument_validate_external_dtd.phpt b/ext/dom/tests/DOMDocument_validate_external_dtd.phpt new file mode 100644 index 0000000..51a044c --- /dev/null +++ b/ext/dom/tests/DOMDocument_validate_external_dtd.phpt @@ -0,0 +1,19 @@ +--TEST-- +DOMDocument::validate() should validate an external DTD declaration +--CREDITS-- +Knut Urdalen <knut@php.net> +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- +<?php +require_once dirname(__FILE__) .'/skipif.inc'; +?> +--FILE-- +<?php +// reusing existing xml: http://cvs.php.net/viewvc.cgi/php-src/ext/dom/tests/dom.xml?view=co&content-type=text%2Fplain +// reusing existing dtd: http://cvs.php.net/viewvc.cgi/php-src/ext/dom/tests/dom.ent?view=co&content-type=text%2Fplain +$dom = new DOMDocument('1.0'); +$dom->load(dirname(__FILE__).'/dom.xml'); +var_dump($dom->validate()); +?> +--EXPECTF-- +bool(true) diff --git a/ext/dom/tests/DOMDocument_validate_on_parse_basic.phpt b/ext/dom/tests/DOMDocument_validate_on_parse_basic.phpt new file mode 100644 index 0000000..a95b0a3 --- /dev/null +++ b/ext/dom/tests/DOMDocument_validate_on_parse_basic.phpt @@ -0,0 +1,38 @@ +--TEST-- +DOMDocument::$validateOnParse - read/write tests (dom_document_validate_on_parse_read/dom_document_validate_on_parse_write) +--CREDITS-- +Hans Zaunere +# TestFest 2009 NYPHP +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +require_once('dom_test.inc'); + +$dom = new DOMDocument; +$dom->loadXML($xmlstr); + +if( !$dom ) +{ + echo "Error while parsing the document\n"; + exit; +} + +echo "Checking documented default value: "; +var_dump($dom->validateOnParse); + +$dom->validateOnParse = TRUE; +echo "Setting validateOnParse to TRUE: "; +var_dump($dom->validateOnParse); + +$dom->validateOnParse = FALSE; +echo "Setting validateOnParse to FALSE: "; +var_dump($dom->validateOnParse); + +?> +--EXPECT-- +Checking documented default value: bool(false) +Setting validateOnParse to TRUE: bool(true) +Setting validateOnParse to FALSE: bool(false) + diff --git a/ext/dom/tests/DOMDocument_validate_on_parse_variation.phpt b/ext/dom/tests/DOMDocument_validate_on_parse_variation.phpt new file mode 100644 index 0000000..d0cea29 --- /dev/null +++ b/ext/dom/tests/DOMDocument_validate_on_parse_variation.phpt @@ -0,0 +1,46 @@ +--TEST-- +DOMDocument::$validateOnParse - effectual determination (dom_document_validate_on_parse_read/dom_document_validate_on_parse_write) +--CREDITS-- +Hans Zaunere +# TestFest 2009 NYPHP +--SKIPIF-- +<?php +require_once('skipif.inc'); +?> +--FILE-- +<?php + +require_once('dom_test.inc'); + +chdir(__DIR__); +$XMLStringGood = file_get_contents('note.xml'); + +$dom = new DOMDocument; +$dom->resolveExternals = TRUE; + +$dom->validateOnParse = FALSE; +echo "validateOnParse set to FALSE: \n"; +$dom->loadXML($XMLStringGood); +echo "No Error Report Above\n"; + +$BogusElement = $dom->createElement('NYPHP','DOMinatrix'); +$Body = $dom->getElementsByTagName('from')->item(0); +$Body->appendChild($BogusElement); +$XMLStringBad = $dom->saveXML(); + +echo "validateOnParse set to TRUE: \n"; +$dom->validateOnParse = TRUE; +$dom->loadXML($XMLStringBad); +echo "Error Report Above\n"; + +?> +--EXPECTF-- +validateOnParse set to FALSE: +No Error Report Above +validateOnParse set to TRUE: + +Warning: DOMDocument::loadXML(): No declaration for element NYPHP in Entity, line: %d in %s on line %d + +Warning: DOMDocument::loadXML(): Element from was declared #PCDATA but contains non text nodes in Entity, line: %d in %s on line %d +Error Report Above + diff --git a/ext/dom/tests/DOMElement_hasAttributes_basic.phpt b/ext/dom/tests/DOMElement_hasAttributes_basic.phpt new file mode 100644 index 0000000..8e804be --- /dev/null +++ b/ext/dom/tests/DOMElement_hasAttributes_basic.phpt @@ -0,0 +1,49 @@ +--TEST-- +DOMNode: hasAttributes() +--CREDITS-- +James Lewis <james@s-1.com> +#TestFest 2008 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +require_once("dom_test.inc"); + +$dom = new DOMDocument; +$dom->loadXML($xmlstr); +if(!$dom) { + echo "Error while parsing the document\n"; + exit; +} + +$element = $dom->documentElement; + +echo "Verify that we have a DOMElement object:\n"; +echo get_class($element), "\n"; + +echo "\nElement should have attributes:\n"; +var_dump($element->hasAttributes()); + +$nodelist=$dom->getElementsByTagName('tbody') ; +$element = $nodelist->item(0); + +echo "\nVerify that we have a DOMElement object:\n"; +echo get_class($element), "\n"; + +echo "\nElement should have no attributes:\n"; +var_dump($element->hasAttributes()); + + +?> +--EXPECTF-- +Verify that we have a DOMElement object: +DOMElement + +Element should have attributes: +bool(true) + +Verify that we have a DOMElement object: +DOMElement + +Element should have no attributes: +bool(false) diff --git a/ext/dom/tests/DOMImplementation_createDocumentType_basic.phpt b/ext/dom/tests/DOMImplementation_createDocumentType_basic.phpt new file mode 100644 index 0000000..3b19ea4 --- /dev/null +++ b/ext/dom/tests/DOMImplementation_createDocumentType_basic.phpt @@ -0,0 +1,18 @@ +--TEST-- +DOMImplementation::createDocumentType() +--SKIPIF-- +<?php +include('skipif.inc'); +?> +--FILE-- +<?php +$imp = new DOMImplementation(); +$doctype = $imp->createDocumentType("html", + "-//W3C//DTD XHTML 1.0 Strict//EN", + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"); +$doc = $imp->createDocument(null, 'html', $doctype); +echo $doc->saveHTML(); +?> +--EXPECTF-- +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html></html> diff --git a/ext/dom/tests/DOMImplementation_createDocument_basic.phpt b/ext/dom/tests/DOMImplementation_createDocument_basic.phpt new file mode 100644 index 0000000..78d20ae --- /dev/null +++ b/ext/dom/tests/DOMImplementation_createDocument_basic.phpt @@ -0,0 +1,14 @@ +--TEST-- +DOMImplementation::createDocument() +--SKIPIF-- +<?php +include('skipif.inc'); +?> +--FILE-- +<?php +$x = new DOMImplementation(); +$doc = $x->createDocument(null, 'html'); +echo $doc->saveHTML(); +?> +--EXPECTF-- +<html></html> diff --git a/ext/dom/tests/DOMImplementation_hasFeature_basic.phpt b/ext/dom/tests/DOMImplementation_hasFeature_basic.phpt new file mode 100644 index 0000000..b53e912 --- /dev/null +++ b/ext/dom/tests/DOMImplementation_hasFeature_basic.phpt @@ -0,0 +1,15 @@ +--TEST-- +DOMImplementation::hasFeature() +--SKIPIF-- +<?php +include('skipif.inc'); +?> +--FILE-- +<?php +$imp = new DOMImplementation(); +var_dump($imp->hasFeature('Core', '1.0')); +var_dump($imp->hasFeature('XML', '2.0')); +?> +--EXPECTF-- +bool(true) +bool(true) diff --git a/ext/dom/tests/DOMNode_C14NFile_basic.phpt b/ext/dom/tests/DOMNode_C14NFile_basic.phpt new file mode 100644 index 0000000..6af6e3e --- /dev/null +++ b/ext/dom/tests/DOMNode_C14NFile_basic.phpt @@ -0,0 +1,38 @@ +--TEST-- +DOMNode::C14NFile() +--SKIPIF-- +<?php +include('skipif.inc'); +?> +--FILE-- +<?php +$xml = <<< XML +<?xml version="1.0" ?> +<books> + <book> + <title>The Grapes of Wrath</title> + <author>John Steinbeck</author> + </book> + <book> + <title>The Pearl</title> + <author>John Steinbeck</author> + </book> +</books> +XML; + +$output = dirname(__FILE__).'/DOMNode_C14NFile_basic.tmp'; +$doc = new DOMDocument(); +$doc->loadXML($xml); +$node = $doc->getElementsByTagName('title')->item(0); +var_dump($node->C14NFile($output)); +$content = file_get_contents($output); +var_dump($content); +?> +--CLEAN-- +<?php +$output = dirname(__FILE__).'/DOMNode_C14NFile_basic.tmp'; +unlink($output); +?> +--EXPECTF-- +int(34) +string(34) "<title>The Grapes of Wrath</title>" diff --git a/ext/dom/tests/DOMNode_C14N_basic.phpt b/ext/dom/tests/DOMNode_C14N_basic.phpt new file mode 100644 index 0000000..52a47a1 --- /dev/null +++ b/ext/dom/tests/DOMNode_C14N_basic.phpt @@ -0,0 +1,29 @@ +--TEST-- +DOMNode::C14N() +--SKIPIF-- +<?php +include('skipif.inc'); +?> +--FILE-- +<?php +$xml = <<< XML +<?xml version="1.0" ?> +<books> + <book> + <title>The Grapes of Wrath</title> + <author>John Steinbeck</author> + </book> + <book> + <title>The Pearl</title> + <author>John Steinbeck</author> + </book> +</books> +XML; + +$doc = new DOMDocument(); +$doc->loadXML($xml); +$node = $doc->getElementsByTagName('title')->item(0); +var_dump($node->C14N()); +?> +--EXPECTF-- +string(34) "<title>The Grapes of Wrath</title>" diff --git a/ext/dom/tests/DOMNode_cloneNode_basic.phpt b/ext/dom/tests/DOMNode_cloneNode_basic.phpt new file mode 100644 index 0000000..cba3c17 --- /dev/null +++ b/ext/dom/tests/DOMNode_cloneNode_basic.phpt @@ -0,0 +1,106 @@ +--TEST-- +DOM cloneNode : Basic Functionality +--SKIPIF-- +<?php +require_once('skipif.inc'); +?> +--CREDITS-- +Simon Hughes <odbc3@hotmail.com> +--FILE-- +<?php + +$xml = <<< EOXML +<?xml version="1.0" encoding="ISO-8859-1"?> +<courses> + <course title="one"> + <notes> + <note>c1n1</note> + <note>c1n2</note> + </notes> + </course> + <course title="two"> + <notes> + <note>c2n1</note> + <note>c2n2</note> + </notes> + </course> +</courses> +EOXML; + +function dumpcourse($current) { + $title = ($current->nodeType != XML_TEXT_NODE && $current->hasAttribute('title')) ? $current->getAttribute('title'):"no title"; + echo "Course: $title:";echo(get_class($current)), "\n"; + echo "~";var_dump($current->textContent); +} + +$dom = new DOMDocument(); +$dom->loadXML($xml); +$root = $dom->documentElement; + +// strip all text nodes from this tree +$children = $root->childNodes; +$len = $children->length; +for ($index = $children->length - 1; $index >=0; $index--) { + $current = $children->item($index); + if ($current->nodeType == XML_TEXT_NODE) { + $noderemoved = $root->removeChild($current); + } +} + +echo "Start cloneNode test\n"; +$first_course = $children->item(0); +$cloned_first_course_default = $first_course->cloneNode(); +$first_course->setAttribute('title', 'new title1'); + +$cloned_first_course_true = $first_course->cloneNode(true); +$first_course->setAttribute('title', 'new title2'); + +$cloned_first_course_false = $first_course->cloneNode(false); +$first_course->setAttribute('title', 'new title3'); + +$cloned_first_course_default->setAttribute('title', 'new title default'); +$cloned_first_course_true->setAttribute('title', 'new title true'); +$cloned_first_course_false->setAttribute('title', 'new title false'); + +$root->appendChild($cloned_first_course_default); +$root->appendChild($cloned_first_course_true); +$root->appendChild($cloned_first_course_false); + +$children = $root->childNodes; +for ($index = 0; $index < $children->length; $index++) { + echo "node $index\n"; + dumpcourse($children->item($index)); +} + +--EXPECTF-- +Start cloneNode test +node 0 +Course: new title3:DOMElement +~string(24) " + + c1n1 + c1n2 + + " +node 1 +Course: two:DOMElement +~string(24) " + + c2n1 + c2n2 + + " +node 2 +Course: new title default:DOMElement +~string(0) "" +node 3 +Course: new title true:DOMElement +~string(24) " + + c1n1 + c1n2 + + " +node 4 +Course: new title false:DOMElement +~string(0) "" diff --git a/ext/dom/tests/DOMNode_getLineNo_basic.phpt b/ext/dom/tests/DOMNode_getLineNo_basic.phpt new file mode 100644 index 0000000..3f57681 --- /dev/null +++ b/ext/dom/tests/DOMNode_getLineNo_basic.phpt @@ -0,0 +1,19 @@ +--TEST-- +DOMNode::getLineNo() +--SKIPIF-- +<?php +include('skipif.inc'); +?> +--FILE-- +<?php +$file = dirname(__FILE__).'/book.xml'; +$doc = new DOMDocument(); +$doc->load($file); +$nodes = $doc->getElementsByTagName('title'); +foreach($nodes as $node) { + var_dump($node->getLineNo()); +} +?> +--EXPECTF-- +int(4) +int(8) diff --git a/ext/dom/tests/DOMNode_getNodePath_basic.phpt b/ext/dom/tests/DOMNode_getNodePath_basic.phpt new file mode 100644 index 0000000..7c14ffa --- /dev/null +++ b/ext/dom/tests/DOMNode_getNodePath_basic.phpt @@ -0,0 +1,19 @@ +--TEST-- +DOMNode::getNodePath() +--SKIPIF-- +<?php +include('skipif.inc'); +?> +--FILE-- +<?php +$file = dirname(__FILE__).'/book.xml'; +$doc = new DOMDocument(); +$doc->load($file); +$nodes = $doc->getElementsByTagName('title'); +foreach($nodes as $node) { + var_dump($node->getNodePath()); +} +?> +--EXPECTF-- +string(20) "/books/book[1]/title" +string(20) "/books/book[2]/title" diff --git a/ext/dom/tests/DOMNode_hasChildNodes.phpt b/ext/dom/tests/DOMNode_hasChildNodes.phpt new file mode 100644 index 0000000..5c1d714 --- /dev/null +++ b/ext/dom/tests/DOMNode_hasChildNodes.phpt @@ -0,0 +1,49 @@ +--TEST-- +Tests DOMNode::hasChildNodes() +--CREDITS-- +Michael Stillwell <mjs@beebo.org> +# TestFest 2008 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$dom = new DOMDocument(); + +$dom->loadXML('<root/>'); + +echo $dom->saveXML(); + +echo "Document has child nodes\n"; +var_dump($dom->documentElement->hasChildNodes()); + +echo "Document has child nodes\n"; +$dom->loadXML('<root><a/></root>'); +var_dump($dom->documentElement->hasChildNodes()); + +echo "Remove node and save\n"; +$dom->documentElement->removeChild($dom->documentElement->firstChild); +echo $dom->saveXML(); + +echo "Document has child nodes\n"; +var_dump($dom->documentElement->hasChildNodes()); + +echo "Document with 2 child nodes\n"; +$dom->loadXML('<root><a/><b/></root>'); +var_dump($dom->documentElement->hasChildNodes()); + +?> +--EXPECTF-- +<?xml version="1.0"?> +<root/> +Document has child nodes +bool(false) +Document has child nodes +bool(true) +Remove node and save +<?xml version="1.0"?> +<root/> +Document has child nodes +bool(false) +Document with 2 child nodes +bool(true) diff --git a/ext/dom/tests/DOMNode_hasChildNodes_basic.phpt b/ext/dom/tests/DOMNode_hasChildNodes_basic.phpt new file mode 100644 index 0000000..3a6f6b4 --- /dev/null +++ b/ext/dom/tests/DOMNode_hasChildNodes_basic.phpt @@ -0,0 +1,43 @@ +--TEST-- +Test whether a node has child nodes: hasChildNodes() +--SKIPIF-- +<?php +include('skipif.inc'); +?> +--FILE-- +<?php + +/* Create an XML document + * with strcuture + * <book> + * <title>This is the title</title> + * </book> + * Check for child nodes of the <book>, <title> and This is the title + * +*/ + +$doc = new DOMDocument(); + +$root = $doc->createElement('book'); +$doc->appendChild($root); + +$title = $doc->createElement('title'); +$root->appendChild($title); + +$text = $doc->createTextNode('This is the title'); +$title->appendChild($text); + +echo "Root has child nodes: "; +var_dump($root->hasChildNodes()); + +echo "Title has child nodes: "; +var_dump($title->hasChildNodes()); + +echo "Text has child nodes: "; +var_dump($text->hasChildNodes()); + +?> +--EXPECTF-- +Root has child nodes: bool(true) +Title has child nodes: bool(true) +Text has child nodes: bool(false)
\ No newline at end of file diff --git a/ext/dom/tests/DOMNode_insertBefore.phpt b/ext/dom/tests/DOMNode_insertBefore.phpt new file mode 100644 index 0000000..d371aaf --- /dev/null +++ b/ext/dom/tests/DOMNode_insertBefore.phpt @@ -0,0 +1,34 @@ +--TEST-- +Tests DOMNode::insertBefore() +--CREDITS-- +Michael Stillwell <mjs@beebo.org> +# TestFest 2008 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$dom = new DOMDocument(); +$dom->loadXML('<root/>'); +echo $dom->saveXML(); + +$e1 = $dom->createElement("A"); +$e2 = $dom->documentElement->appendChild($dom->createElement("B")); + +echo "Add new node B\n"; +echo $dom->saveXML(); + +echo "Add new node A before B\n"; +$e2->parentNode->insertBefore($e1, $e2); +echo $dom->saveXML(); + +?> +--EXPECTF-- +<?xml version="1.0"?> +<root/> +Add new node B +<?xml version="1.0"?> +<root><B/></root> +Add new node A before B +<?xml version="1.0"?> +<root><A/><B/></root> diff --git a/ext/dom/tests/DOMNode_insertBefore_error1.phpt b/ext/dom/tests/DOMNode_insertBefore_error1.phpt new file mode 100644 index 0000000..d655479 --- /dev/null +++ b/ext/dom/tests/DOMNode_insertBefore_error1.phpt @@ -0,0 +1,24 @@ +--TEST-- +DOMNode::insertBefore() should fail if node belongs to another document +--CREDITS-- +Knut Urdalen <knut@php.net> +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc1 = new DOMDocument(); +$doc2 = new DOMDocument(); + +$node_in_doc1 = $doc1->createElement("foo"); +$node_in_doc2 = $doc2->createElement("bar"); + +try { + $node_in_doc2->insertBefore($node_in_doc1); +} catch(DOMException $e) { + echo $e->getMessage(); +} + +?> +--EXPECTF-- +Wrong Document Error diff --git a/ext/dom/tests/DOMNode_issamenode_basic.phpt b/ext/dom/tests/DOMNode_issamenode_basic.phpt new file mode 100644 index 0000000..e008340 --- /dev/null +++ b/ext/dom/tests/DOMNode_issamenode_basic.phpt @@ -0,0 +1,37 @@ +--TEST-- +DOMNode: isSameNode() +--CREDITS-- +James Lewis <james@s-1.com> +#TestFest 2008 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +require_once("dom_test.inc"); + +$dom = new DOMDocument; +$dom->loadXML($xmlstr); +if(!$dom) { + echo "Error while parsing the document\n"; + exit; +} + +$node = $dom->documentElement; +if($node->isSameNode($node)) + echo "EXPECTING SAME NODE, PASSED\n" ; +else + echo "EXPECTING SAME NODE, FAILED\n" ; + +$nodelist=$dom->getElementsByTagName('tbody') ; + +if($nodelist->item(0)->isSameNode($node)) + echo "EXPECTING NOT SAME NODE, FAILED\n" ; +else + echo "EXPECTING NOT SAME NODE, PASSED\n" ; + +?> +===DONE=== +--EXPECT-- +EXPECTING SAME NODE, PASSED +EXPECTING NOT SAME NODE, PASSED +===DONE=== diff --git a/ext/dom/tests/DOMNode_normalize_basic.phpt b/ext/dom/tests/DOMNode_normalize_basic.phpt new file mode 100644 index 0000000..e413fb0 --- /dev/null +++ b/ext/dom/tests/DOMNode_normalize_basic.phpt @@ -0,0 +1,64 @@ +--TEST-- +DOMNode::normalize() +--SKIPIF-- +<?php +include('skipif.inc'); +?> +--FILE-- +<?php + +/* Create an XML document + * with structure + * <book> + * <author></author> + * <title>This is the title</title> + * </book> + * Calculate the number of title text nodes (1). + * Add another text node to title. Calculate the number of title text nodes (2). + * Normalize author. Calculate the number of title text nodes (2). + * Normalize title. Calculate the number of title text nodes (1). +*/ + +$doc = new DOMDocument(); + +$root = $doc->createElement('book'); +$doc->appendChild($root); + +$title = $doc->createElement('title'); +$root->appendChild($title); + +$author = $doc->createElement('author'); +$root->appendChild($author); + +$text = $doc->createTextNode('This is the first title'); +$title->appendChild($text); + +echo "Number of child nodes of title = "; +var_dump($title->childNodes->length); + +// add a second text node to title +$text = $doc->createTextNode('This is the second title'); +$title->appendChild($text); + +echo "Number of child nodes of title after adding second title = "; +var_dump($title->childNodes->length); + +// should do nothing +$author->normalize(); + +echo "Number of child nodes of title after normalizing author = "; +var_dump($title->childNodes->length); + + +// should concatenate first and second title text nodes +$title->normalize(); + +echo "Number of child nodes of title after normalizing title = "; +var_dump($title->childNodes->length); + +?> +--EXPECTF-- +Number of child nodes of title = int(1) +Number of child nodes of title after adding second title = int(2) +Number of child nodes of title after normalizing author = int(2) +Number of child nodes of title after normalizing title = int(1)
\ No newline at end of file diff --git a/ext/dom/tests/DOMNode_removeChild_basic.phpt b/ext/dom/tests/DOMNode_removeChild_basic.phpt new file mode 100644 index 0000000..384eb47 --- /dev/null +++ b/ext/dom/tests/DOMNode_removeChild_basic.phpt @@ -0,0 +1,106 @@ +--TEST-- +DOM removeChild : Basic Functionality +--SKIPIF-- +<?php +require_once('skipif.inc'); +?> +--CREDITS-- +Simon Hughes <odbc3@hotmail.com> +--FILE-- +<?php + +$xml = <<< EOXML +<?xml version="1.0" encoding="ISO-8859-1"?> +<courses> + <course title="one"> + <notes> + <note>c1n1</note> + <note>c1n2</note> + </notes> + </course> + <course title="two"> + <notes> + <note>c2n1</note> + <note>c2n2</note> + </notes> + </course> +</courses> +EOXML; + +function dumpcourse($current) { + $title = ($current->nodeType != XML_TEXT_NODE && $current->hasAttribute('title')) ? $current->getAttribute('title'):"no title"; + echo "Course: $title:";echo get_class($current), "\n"; + echo "~";var_dump($current->textContent); +} + +$dom = new DOMDocument(); +$dom->loadXML($xml); +$root = $dom->documentElement; + +$children = $root->childNodes; +$len = $children->length; +echo "orignal has $len nodes\n"; +for ($index = $children->length - 1; $index >=0; $index--) { + echo "node $index\n"; + $current = $children->item($index); + dumpcourse($current); + if ($current->nodeType == XML_TEXT_NODE) { + $noderemoved = $root->removeChild($current); + } +} +$children = $root->childNodes; +$len = $children->length; +echo "after text removed it now has $len nodes\n"; +for ($index = 0; $index < $children->length; $index++) { + echo "node $index\n"; + $current = $children->item($index); + dumpcourse($current); +} + +--EXPECTF-- +orignal has 5 nodes +node 4 +Course: no title:DOMText +~string(1) " +" +node 3 +Course: two:DOMElement +~string(24) " + + c2n1 + c2n2 + + " +node 2 +Course: no title:DOMText +~string(2) " + " +node 1 +Course: one:DOMElement +~string(24) " + + c1n1 + c1n2 + + " +node 0 +Course: no title:DOMText +~string(2) " + " +after text removed it now has 2 nodes +node 0 +Course: one:DOMElement +~string(24) " + + c1n1 + c1n2 + + " +node 1 +Course: two:DOMElement +~string(24) " + + c2n1 + c2n2 + + " diff --git a/ext/dom/tests/DOMNode_replaceChild_basic.phpt b/ext/dom/tests/DOMNode_replaceChild_basic.phpt new file mode 100644 index 0000000..49fc055 --- /dev/null +++ b/ext/dom/tests/DOMNode_replaceChild_basic.phpt @@ -0,0 +1,44 @@ +--TEST-- +Replacing a child node +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--CREDITS-- +Matt Raines <matt@raines.me.uk> +#London TestFest 2008 +--FILE-- +<?php +$document = new DOMDocument(); +$document->loadXML('<?xml version="1.0" encoding="utf-8"?> +<root><foo><bar/><baz/></foo><spam><eggs/><eggs/></spam></root>'); + +// Replaces the child node oldChild with newChild in the list of children, and +// returns the oldChild node. +$parent = $document->getElementsByTagName('foo')->item(0); +$new_child = $document->createElement('qux'); +$old_child = $parent->replaceChild($new_child, $parent->firstChild); +echo "New child replaces old child:\n" . $document->saveXML(); +echo "Old child is returned:\n" . $old_child->tagName . "\n"; + +// If the newChild is already in the tree, it is first removed. +$parent = $document->getElementsByTagName('spam')->item(0); +$parent->replaceChild($new_child, $parent->firstChild); +echo "Existing child is removed from tree:\n" . $document->saveXML(); + +// Children are inserted in the correct order. +$new_child = $document->getElementsByTagName('spam')->item(0); +$parent = $document->getElementsByTagName('foo')->item(0); +$parent->replaceChild($new_child, $parent->firstChild); +echo "Children are inserted in order:\n" . $document->saveXML(); +?> +--EXPECT-- +New child replaces old child: +<?xml version="1.0" encoding="utf-8"?> +<root><foo><qux/><baz/></foo><spam><eggs/><eggs/></spam></root> +Old child is returned: +bar +Existing child is removed from tree: +<?xml version="1.0" encoding="utf-8"?> +<root><foo><baz/></foo><spam><qux/><eggs/></spam></root> +Children are inserted in order: +<?xml version="1.0" encoding="utf-8"?> +<root><foo><spam><qux/><eggs/></spam></foo></root> diff --git a/ext/dom/tests/DOMText_appendData_basic.phpt b/ext/dom/tests/DOMText_appendData_basic.phpt new file mode 100644 index 0000000..0eea699 --- /dev/null +++ b/ext/dom/tests/DOMText_appendData_basic.phpt @@ -0,0 +1,40 @@ +--TEST-- +DOMText::appendData basic functionality test +--CREDITS-- +Mike Sullivan <mike@regexia.com> +#TestFest 2008 (London) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$document = new DOMDocument; +$root = $document->createElement('root'); +$document->appendChild($root); + +$text = $document->createElement('text'); +$root->appendChild($text); + +$textnode = $document->createTextNode(''); +$text->appendChild($textnode); +$textnode->appendData('data'); +echo "Text Length (one append): " . $textnode->length . "\n"; + +$textnode->appendData('><&"'); +echo "Text Length (two appends): " . $textnode->length . "\n"; + +echo "Text Content: " . $textnode->data . "\n"; + +echo "\n" . $document->saveXML(); + +?> +===DONE=== +--EXPECT-- +Text Length (one append): 4 +Text Length (two appends): 8 +Text Content: data><&" + +<?xml version="1.0"?> +<root><text>data><&"</text></root> +===DONE=== +
\ No newline at end of file diff --git a/ext/dom/tests/book-non-conforming-schema.xsd b/ext/dom/tests/book-non-conforming-schema.xsd new file mode 100755 index 0000000..d1ecbef --- /dev/null +++ b/ext/dom/tests/book-non-conforming-schema.xsd @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <xs:element name="make_it_fail"> + <xs:complexType> + <xs:sequence> + <xs:element name="book" minOccurs="1" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:element name="title" type="xs:string"/> + <xs:element name="author" type="xs:string"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> +</xs:schema> diff --git a/ext/dom/tests/book-not-a-schema.xsd b/ext/dom/tests/book-not-a-schema.xsd new file mode 100755 index 0000000..d89e3bb --- /dev/null +++ b/ext/dom/tests/book-not-a-schema.xsd @@ -0,0 +1 @@ +Let's see what happens upon parsing a file that doesn't contain a schema. diff --git a/ext/dom/tests/book.xml b/ext/dom/tests/book.xml new file mode 100644 index 0000000..95de0da --- /dev/null +++ b/ext/dom/tests/book.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" ?> +<books> + <book> + <title>The Grapes of Wrath</title> + <author>John Steinbeck</author> + </book> + <book> + <title>The Pearl</title> + <author>John Steinbeck</author> + </book> +</books> diff --git a/ext/dom/tests/book.xml.gz b/ext/dom/tests/book.xml.gz Binary files differnew file mode 100644 index 0000000..2c97807 --- /dev/null +++ b/ext/dom/tests/book.xml.gz diff --git a/ext/dom/tests/book.xsd b/ext/dom/tests/book.xsd new file mode 100755 index 0000000..45986fc --- /dev/null +++ b/ext/dom/tests/book.xsd @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <xs:element name="books"> + <xs:complexType> + <xs:sequence> + <xs:element name="book" minOccurs="1" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:element name="title" type="xs:string"/> + <xs:element name="author" type="xs:string"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> +</xs:schema> diff --git a/ext/dom/tests/bug28721.phpt b/ext/dom/tests/bug28721.phpt new file mode 100644 index 0000000..464498e --- /dev/null +++ b/ext/dom/tests/bug28721.phpt @@ -0,0 +1,485 @@ +--TEST-- +Bug #28721 (appendChild() and insertBefore() unset DOMText) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +function print_node(DomNode $node) { + echo "name (value): " . $node->nodeName . " (" . $node->nodeValue . ")\n"; +} + +function print_node_r(DomNode $node) { + static $indent = ""; + echo "\n" . $indent; + print_node($node); + + echo $indent . "parent: "; + if ( $node->parentNode ) + print_node($node->parentNode); + else + echo "NULL\n"; + + echo $indent . "previousSibling: "; + if ( $node->previousSibling ) + print_node($node->previousSibling); + else + echo "NULL\n"; + + echo $indent . "nextSibling: "; + if ( $node->nextSibling ) + print_node($node->nextSibling); + else + echo "NULL\n"; + + if ( !$node->hasChildNodes() ) + return; + + foreach ($node->childNodes as $child) { + + $old_indent = $indent; + $indent .= " "; + print_node_r($child); + $indent = $old_indent; + } +} + +function err_handler($errno, $errstr, $errfile, $errline) { + echo "Error ($errno) on line $errline: $errstr\n"; +} + +// Record 'DocumentFragment is empty' warnings +set_error_handler("err_handler", E_WARNING); + +$xml = new DomDocument(); + +$p = $xml->createElement("p"); + +$p->appendChild($t1 = $xml->createTextNode(" t1 ")); +$p->appendChild($b = $xml->createElement("b")); +$b->appendChild($xml->createTextNode("X")); +$p->appendChild($t2 = $xml->createTextNode(" t2 ")); +$p->appendChild($xml->createTextNode(" xxx ")); + +print_node_r($p); + +echo "\nAppend t1 to p:\n"; +$ret = $p->appendChild($t1); + +print_node_r($p); +echo "\n"; + +echo "t1 == ret: "; +var_dump( $t1 === $ret ); + + +$d = $xml->createElement("div"); +$d->appendChild($t3 = $xml->createTextNode(" t3 ")); +$d->appendChild($b = $xml->createElement("b")); +$b->appendChild($xml->createElement("X")); +$d->appendChild($t4 = $xml->createTextNode(" t4 ")); +$d->appendChild($xml->createTextNode(" xxx ")); + +echo "\ndiv:\n"; +print_node_r($d); + +echo "\nInsert t4 before t3:\n"; + +$ret = $d->insertBefore($t4, $t3); + +print_node_r($d); +echo "\n"; + +$frag = $xml->createDocumentFragment(); + +$t5 = $frag->appendChild($xml->createTextNode(" t5 ")); +$frag->appendChild($i = $xml->createElement("i")); +$i->appendChild($xml->createTextNode(" frob ")); +$frag->appendChild($xml->createTextNOde(" t6 ")); + +echo "\np:\n"; +print_node_r($p); +echo "\nFragment:\n"; +print_node_r($frag); + +echo "\nAppending fragment to p:\n"; +$p->appendChild($frag); + +print_node_r($p); +echo "\nFragment:\n"; +print_node_r($frag); + +echo "\ndiv:\n"; +print_node_r($d); +echo "\nInserting fragment before t4\n"; +$d->insertBefore($frag, $t4); +print_node_r($d); + +echo "\np:\n"; +print_node_r($p); + +?> +--EXPECT-- + +name (value): p ( t1 X t2 xxx ) +parent: NULL +previousSibling: NULL +nextSibling: NULL + + name (value): #text ( t1 ) + parent: name (value): p ( t1 X t2 xxx ) + previousSibling: NULL + nextSibling: name (value): b (X) + + name (value): b (X) + parent: name (value): p ( t1 X t2 xxx ) + previousSibling: name (value): #text ( t1 ) + nextSibling: name (value): #text ( t2 ) + + name (value): #text (X) + parent: name (value): b (X) + previousSibling: NULL + nextSibling: NULL + + name (value): #text ( t2 ) + parent: name (value): p ( t1 X t2 xxx ) + previousSibling: name (value): b (X) + nextSibling: name (value): #text ( xxx ) + + name (value): #text ( xxx ) + parent: name (value): p ( t1 X t2 xxx ) + previousSibling: name (value): #text ( t2 ) + nextSibling: NULL + +Append t1 to p: + +name (value): p (X t2 xxx t1 ) +parent: NULL +previousSibling: NULL +nextSibling: NULL + + name (value): b (X) + parent: name (value): p (X t2 xxx t1 ) + previousSibling: NULL + nextSibling: name (value): #text ( t2 ) + + name (value): #text (X) + parent: name (value): b (X) + previousSibling: NULL + nextSibling: NULL + + name (value): #text ( t2 ) + parent: name (value): p (X t2 xxx t1 ) + previousSibling: name (value): b (X) + nextSibling: name (value): #text ( xxx ) + + name (value): #text ( xxx ) + parent: name (value): p (X t2 xxx t1 ) + previousSibling: name (value): #text ( t2 ) + nextSibling: name (value): #text ( t1 ) + + name (value): #text ( t1 ) + parent: name (value): p (X t2 xxx t1 ) + previousSibling: name (value): #text ( xxx ) + nextSibling: NULL + +t1 == ret: bool(true) + +div: + +name (value): div ( t3 t4 xxx ) +parent: NULL +previousSibling: NULL +nextSibling: NULL + + name (value): #text ( t3 ) + parent: name (value): div ( t3 t4 xxx ) + previousSibling: NULL + nextSibling: name (value): b () + + name (value): b () + parent: name (value): div ( t3 t4 xxx ) + previousSibling: name (value): #text ( t3 ) + nextSibling: name (value): #text ( t4 ) + + name (value): X () + parent: name (value): b () + previousSibling: NULL + nextSibling: NULL + + name (value): #text ( t4 ) + parent: name (value): div ( t3 t4 xxx ) + previousSibling: name (value): b () + nextSibling: name (value): #text ( xxx ) + + name (value): #text ( xxx ) + parent: name (value): div ( t3 t4 xxx ) + previousSibling: name (value): #text ( t4 ) + nextSibling: NULL + +Insert t4 before t3: + +name (value): div ( t4 t3 xxx ) +parent: NULL +previousSibling: NULL +nextSibling: NULL + + name (value): #text ( t4 ) + parent: name (value): div ( t4 t3 xxx ) + previousSibling: NULL + nextSibling: name (value): #text ( t3 ) + + name (value): #text ( t3 ) + parent: name (value): div ( t4 t3 xxx ) + previousSibling: name (value): #text ( t4 ) + nextSibling: name (value): b () + + name (value): b () + parent: name (value): div ( t4 t3 xxx ) + previousSibling: name (value): #text ( t3 ) + nextSibling: name (value): #text ( xxx ) + + name (value): X () + parent: name (value): b () + previousSibling: NULL + nextSibling: NULL + + name (value): #text ( xxx ) + parent: name (value): div ( t4 t3 xxx ) + previousSibling: name (value): b () + nextSibling: NULL + + +p: + +name (value): p (X t2 xxx t1 ) +parent: NULL +previousSibling: NULL +nextSibling: NULL + + name (value): b (X) + parent: name (value): p (X t2 xxx t1 ) + previousSibling: NULL + nextSibling: name (value): #text ( t2 ) + + name (value): #text (X) + parent: name (value): b (X) + previousSibling: NULL + nextSibling: NULL + + name (value): #text ( t2 ) + parent: name (value): p (X t2 xxx t1 ) + previousSibling: name (value): b (X) + nextSibling: name (value): #text ( xxx ) + + name (value): #text ( xxx ) + parent: name (value): p (X t2 xxx t1 ) + previousSibling: name (value): #text ( t2 ) + nextSibling: name (value): #text ( t1 ) + + name (value): #text ( t1 ) + parent: name (value): p (X t2 xxx t1 ) + previousSibling: name (value): #text ( xxx ) + nextSibling: NULL + +Fragment: + +name (value): #document-fragment () +parent: NULL +previousSibling: NULL +nextSibling: NULL + + name (value): #text ( t5 ) + parent: name (value): #document-fragment () + previousSibling: NULL + nextSibling: name (value): i ( frob ) + + name (value): i ( frob ) + parent: name (value): #document-fragment () + previousSibling: name (value): #text ( t5 ) + nextSibling: name (value): #text ( t6 ) + + name (value): #text ( frob ) + parent: name (value): i ( frob ) + previousSibling: NULL + nextSibling: NULL + + name (value): #text ( t6 ) + parent: name (value): #document-fragment () + previousSibling: name (value): i ( frob ) + nextSibling: NULL + +Appending fragment to p: + +name (value): p (X t2 xxx t1 t5 frob t6 ) +parent: NULL +previousSibling: NULL +nextSibling: NULL + + name (value): b (X) + parent: name (value): p (X t2 xxx t1 t5 frob t6 ) + previousSibling: NULL + nextSibling: name (value): #text ( t2 ) + + name (value): #text (X) + parent: name (value): b (X) + previousSibling: NULL + nextSibling: NULL + + name (value): #text ( t2 ) + parent: name (value): p (X t2 xxx t1 t5 frob t6 ) + previousSibling: name (value): b (X) + nextSibling: name (value): #text ( xxx ) + + name (value): #text ( xxx ) + parent: name (value): p (X t2 xxx t1 t5 frob t6 ) + previousSibling: name (value): #text ( t2 ) + nextSibling: name (value): #text ( t1 ) + + name (value): #text ( t1 ) + parent: name (value): p (X t2 xxx t1 t5 frob t6 ) + previousSibling: name (value): #text ( xxx ) + nextSibling: name (value): #text ( t5 ) + + name (value): #text ( t5 ) + parent: name (value): p (X t2 xxx t1 t5 frob t6 ) + previousSibling: name (value): #text ( t1 ) + nextSibling: name (value): i ( frob ) + + name (value): i ( frob ) + parent: name (value): p (X t2 xxx t1 t5 frob t6 ) + previousSibling: name (value): #text ( t5 ) + nextSibling: name (value): #text ( t6 ) + + name (value): #text ( frob ) + parent: name (value): i ( frob ) + previousSibling: NULL + nextSibling: NULL + + name (value): #text ( t6 ) + parent: name (value): p (X t2 xxx t1 t5 frob t6 ) + previousSibling: name (value): i ( frob ) + nextSibling: NULL + +Fragment: + +name (value): #document-fragment () +parent: NULL +previousSibling: NULL +nextSibling: NULL + +div: + +name (value): div ( t4 t3 xxx ) +parent: NULL +previousSibling: NULL +nextSibling: NULL + + name (value): #text ( t4 ) + parent: name (value): div ( t4 t3 xxx ) + previousSibling: NULL + nextSibling: name (value): #text ( t3 ) + + name (value): #text ( t3 ) + parent: name (value): div ( t4 t3 xxx ) + previousSibling: name (value): #text ( t4 ) + nextSibling: name (value): b () + + name (value): b () + parent: name (value): div ( t4 t3 xxx ) + previousSibling: name (value): #text ( t3 ) + nextSibling: name (value): #text ( xxx ) + + name (value): X () + parent: name (value): b () + previousSibling: NULL + nextSibling: NULL + + name (value): #text ( xxx ) + parent: name (value): div ( t4 t3 xxx ) + previousSibling: name (value): b () + nextSibling: NULL + +Inserting fragment before t4 +Error (2) on line 109: DOMNode::insertBefore(): Document Fragment is empty + +name (value): div ( t4 t3 xxx ) +parent: NULL +previousSibling: NULL +nextSibling: NULL + + name (value): #text ( t4 ) + parent: name (value): div ( t4 t3 xxx ) + previousSibling: NULL + nextSibling: name (value): #text ( t3 ) + + name (value): #text ( t3 ) + parent: name (value): div ( t4 t3 xxx ) + previousSibling: name (value): #text ( t4 ) + nextSibling: name (value): b () + + name (value): b () + parent: name (value): div ( t4 t3 xxx ) + previousSibling: name (value): #text ( t3 ) + nextSibling: name (value): #text ( xxx ) + + name (value): X () + parent: name (value): b () + previousSibling: NULL + nextSibling: NULL + + name (value): #text ( xxx ) + parent: name (value): div ( t4 t3 xxx ) + previousSibling: name (value): b () + nextSibling: NULL + +p: + +name (value): p (X t2 xxx t1 t5 frob t6 ) +parent: NULL +previousSibling: NULL +nextSibling: NULL + + name (value): b (X) + parent: name (value): p (X t2 xxx t1 t5 frob t6 ) + previousSibling: NULL + nextSibling: name (value): #text ( t2 ) + + name (value): #text (X) + parent: name (value): b (X) + previousSibling: NULL + nextSibling: NULL + + name (value): #text ( t2 ) + parent: name (value): p (X t2 xxx t1 t5 frob t6 ) + previousSibling: name (value): b (X) + nextSibling: name (value): #text ( xxx ) + + name (value): #text ( xxx ) + parent: name (value): p (X t2 xxx t1 t5 frob t6 ) + previousSibling: name (value): #text ( t2 ) + nextSibling: name (value): #text ( t1 ) + + name (value): #text ( t1 ) + parent: name (value): p (X t2 xxx t1 t5 frob t6 ) + previousSibling: name (value): #text ( xxx ) + nextSibling: name (value): #text ( t5 ) + + name (value): #text ( t5 ) + parent: name (value): p (X t2 xxx t1 t5 frob t6 ) + previousSibling: name (value): #text ( t1 ) + nextSibling: name (value): i ( frob ) + + name (value): i ( frob ) + parent: name (value): p (X t2 xxx t1 t5 frob t6 ) + previousSibling: name (value): #text ( t5 ) + nextSibling: name (value): #text ( t6 ) + + name (value): #text ( frob ) + parent: name (value): i ( frob ) + previousSibling: NULL + nextSibling: NULL + + name (value): #text ( t6 ) + parent: name (value): p (X t2 xxx t1 t5 frob t6 ) + previousSibling: name (value): i ( frob ) + nextSibling: NULL diff --git a/ext/dom/tests/bug28817.phpt b/ext/dom/tests/bug28817.phpt new file mode 100644 index 0000000..a250bff --- /dev/null +++ b/ext/dom/tests/bug28817.phpt @@ -0,0 +1,38 @@ +--TEST-- +Bug #28817 (properties in extended class) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +class z extends domDocument{ + /** variable can have name */ + public $p_array; + public $p_variable; + + function __construct(){ + $this->p_array[] = 'bonus'; + $this->p_array[] = 'vir'; + $this->p_array[] = 'semper'; + $this->p_array[] = 'tiro'; + + $this->p_variable = 'Cessante causa cessat effectus'; + } +} + +$z=new z(); +var_dump($z->p_array); +var_dump($z->p_variable); +?> +--EXPECTF-- +array(4) { + [0]=> + string(5) "bonus" + [1]=> + string(3) "vir" + [2]=> + string(6) "semper" + [3]=> + string(4) "tiro" +} +string(30) "Cessante causa cessat effectus" diff --git a/ext/dom/tests/bug32615.phpt b/ext/dom/tests/bug32615.phpt new file mode 100644 index 0000000..c6f2b5b --- /dev/null +++ b/ext/dom/tests/bug32615.phpt @@ -0,0 +1,84 @@ +--TEST-- +Bug #32615 (Replacing and inserting Fragments) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$dom = new DomDocument; +$frag = $dom->createDocumentFragment(); +$frag->appendChild(new DOMElement('root')); +$dom->appendChild($frag); +$root = $dom->documentElement; + +$frag->appendChild(new DOMElement('first')); +$root->appendChild($frag); + +$frag->appendChild(new DOMElement('second')); +$root->appendChild($frag); + +$node = $dom->createElement('newfirst'); +$frag->appendChild($node); +$root->replaceChild($frag, $root->firstChild); + +unset($frag); +$frag = $dom->createDocumentFragment(); + +$frag->appendChild(new DOMElement('newsecond')); +$root->replaceChild($frag, $root->lastChild); + +$node = $frag->appendChild(new DOMElement('fourth')); +$root->insertBefore($frag, NULL); + +$frag->appendChild(new DOMElement('third')); +$node = $root->insertBefore($frag, $node); + +$frag->appendChild(new DOMElement('start')); +$root->insertBefore($frag, $root->firstChild); + +$frag->appendChild(new DOMElement('newthird')); +$root->replaceChild($frag, $node); + +$frag->appendChild(new DOMElement('newfourth')); +$root->replaceChild($frag, $root->lastChild); + +$frag->appendChild(new DOMElement('first')); +$root->replaceChild($frag, $root->firstChild->nextSibling); + +$root->removeChild($root->firstChild); + +echo $dom->saveXML()."\n"; + +while ($root->hasChildNodes()) { + $root->removeChild($root->firstChild); +} + +$frag->appendChild(new DOMElement('first')); +$root->insertBefore($frag, $root->firstChild); + +$node = $frag->appendChild(new DOMElement('fourth')); +$root->appendChild($frag); + +$frag->appendChild(new DOMElement('second')); +$frag->appendChild(new DOMElement('third')); +$root->insertBefore($frag, $node); + +echo $dom->saveXML()."\n"; + +$frag = $dom->createDocumentFragment(); +$root = $dom->documentElement; +$root->replaceChild($frag, $root->firstChild); + +echo $dom->saveXML(); + +?> +--EXPECT-- + +<?xml version="1.0"?> +<root><first/><newsecond/><newthird/><newfourth/></root> + +<?xml version="1.0"?> +<root><first/><second/><third/><fourth/></root> + +<?xml version="1.0"?> +<root><second/><third/><fourth/></root> + diff --git a/ext/dom/tests/bug34276.phpt b/ext/dom/tests/bug34276.phpt new file mode 100644 index 0000000..6959d90 --- /dev/null +++ b/ext/dom/tests/bug34276.phpt @@ -0,0 +1,43 @@ +--TEST-- +Bug #34276 (setAttributeNS and default namespace) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$xml = <<<HERE +<?xml version="1.0" encoding="ISO-8859-1" ?> +<foo xmlns="http://www.example.com/ns/foo" + xmlns:fubar="http://www.example.com/ns/fubar" attra="attra" /> +HERE; + +function dump($elems) { + foreach ($elems as $elem) { + var_dump($elem->nodeName); + dump($elem->childNodes); + } +} + +$dom = new DOMDocument(); +$dom->loadXML($xml); +$foo = $dom->documentElement; +var_dump($foo->hasAttributeNS('http://www.example.com/ns/foo', 'attra')); +var_dump($foo->getAttributeNS('http://www.example.com/ns/foo', 'attra')); + +$foo->setAttributeNS('http://www.example.com/ns/foo', 'attra', 'attranew'); +$foo->setAttributeNS('http://www.example.com/ns/fubar', 'attrb', 'attrbnew'); +$foo->setAttributeNS('http://www.example.com/ns/foo', 'attrc', 'attrc'); + +var_dump($foo->getAttributeNS('http://www.example.com/ns/foo', 'attra')); +var_dump($foo->getAttributeNS('http://www.example.com/ns/fubar', 'attrb')); +var_dump($foo->getAttributeNS('http://www.example.com/ns/foo', 'attrc')); + +print $dom->saveXML(); +?> +--EXPECT-- +bool(false) +string(0) "" +string(8) "attranew" +string(8) "attrbnew" +string(5) "attrc" +<?xml version="1.0" encoding="ISO-8859-1"?> +<foo xmlns="http://www.example.com/ns/foo" xmlns:fubar="http://www.example.com/ns/fubar" xmlns:default="http://www.example.com/ns/foo" attra="attra" default:attra="attranew" fubar:attrb="attrbnew" default:attrc="attrc"/> diff --git a/ext/dom/tests/bug35342.phpt b/ext/dom/tests/bug35342.phpt new file mode 100644 index 0000000..f93c062 --- /dev/null +++ b/ext/dom/tests/bug35342.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #35342 (isset(DOMNodeList->length) returns false) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$dom = new DOMDocument(); +$dom->loadXML("<root><foo>foobar</foo><foo>foobar#2</foo></root>"); + +$nodelist = $dom->getElementsByTagName("foo"); + +var_dump($nodelist->length, isset($nodelist->length), isset($nodelist->foo)); +var_dump(empty($nodelist->length), empty($nodelist->foo)); +?> +--EXPECT-- +int(2) +bool(true) +bool(false) +bool(false) +bool(true) diff --git a/ext/dom/tests/bug35673.phpt b/ext/dom/tests/bug35673.phpt new file mode 100644 index 0000000..a29ae96 --- /dev/null +++ b/ext/dom/tests/bug35673.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #35673 (formatOutput does not work with saveHTML). +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$html = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<title>This is the title</title></head></html>'; + +$htmldoc = new DOMDocument(); +$htmldoc->loadHTML($html); +$htmldoc->formatOutput = true; +echo $htmldoc->saveHTML(); +?> +--EXPECT-- +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> +<html><head> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<title>This is the title</title> +</head></html> diff --git a/ext/dom/tests/bug36756.phpt b/ext/dom/tests/bug36756.phpt new file mode 100644 index 0000000..4e47b86 --- /dev/null +++ b/ext/dom/tests/bug36756.phpt @@ -0,0 +1,35 @@ +--TEST-- +Bug #36756 (DOMDocument::removeChild corrupts node) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +/* Node is preserved from removeChild */ +$dom = new DOMDocument(); +$dom->loadXML('<root><child/></root>'); +$xpath = new DOMXpath($dom); +$node = $xpath->query('/root')->item(0); +echo $node->nodeName . "\n"; +$dom->removeChild($GLOBALS['dom']->firstChild); +echo "nodeType: " . $node->nodeType . "\n"; + +/* Node gets destroyed during removeChild */ +$dom->loadXML('<root><child/></root>'); +$xpath = new DOMXpath($dom); +$node = $xpath->query('//child')->item(0); +echo $node->nodeName . "\n"; +$GLOBALS['dom']->removeChild($GLOBALS['dom']->firstChild); + +echo "nodeType: " . $node->nodeType . "\n"; + +?> +--EXPECTF-- +root +nodeType: 1 +child + +Warning: Couldn't fetch DOMElement. Node no longer exists in %sbug36756.php on line %d + +Notice: Undefined property: DOMElement::$nodeType in %sbug36756.php on line %d +nodeType: diff --git a/ext/dom/tests/bug37277.phpt b/ext/dom/tests/bug37277.phpt new file mode 100644 index 0000000..112b9f4 --- /dev/null +++ b/ext/dom/tests/bug37277.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #37277 (cloning Dom Documents or Nodes does not work) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$dom1 = new DomDocument('1.0', 'UTF-8'); + +$xml = '<foo />'; +$dom1->loadXml($xml); + +$node = clone $dom1->documentElement; + +$dom2 = new DomDocument('1.0', 'UTF-8'); +$dom2->appendChild($dom2->importNode($node->cloneNode(true), TRUE)); + +print $dom2->saveXML(); + + +?> +--EXPECT-- + +<?xml version="1.0" encoding="UTF-8"?> +<foo/> + diff --git a/ext/dom/tests/bug37456.phpt b/ext/dom/tests/bug37456.phpt new file mode 100644 index 0000000..5f0fc28 --- /dev/null +++ b/ext/dom/tests/bug37456.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #37456 (DOMElement->setAttribute() loops forever) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument(); +$doc->resolveExternals = true; +$doc->load(dirname(__FILE__)."/dom.xml"); + +$root = $doc->getElementsByTagName('foo')->item(0); +$root->setAttribute('bar', '>'); +$attr = $root->setAttribute('bar', 'newval'); +print $attr->nodeValue; + + +?> +--EXPECT-- + +newval + diff --git a/ext/dom/tests/bug38438.phpt b/ext/dom/tests/bug38438.phpt new file mode 100644 index 0000000..f512528 --- /dev/null +++ b/ext/dom/tests/bug38438.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #38438 (DOMNodeList->item(0) segfault on empty NodeList) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$list = new DOMNodeList(); +var_dump($list->item(0)); +echo "OK\n"; +?> +--EXPECT-- +NULL +OK diff --git a/ext/dom/tests/bug38474.phpt b/ext/dom/tests/bug38474.phpt new file mode 100644 index 0000000..54226ef --- /dev/null +++ b/ext/dom/tests/bug38474.phpt @@ -0,0 +1,46 @@ +--TEST-- +Bug #38474 (getAttribute select attribute by order, even when prefixed) (OK to fail with libxml2 < 2.6.2x) +--SKIPIF-- +<?php +require_once('skipif.inc'); +if (version_compare(LIBXML_DOTTED_VERSION, "2.6.20", "<")) { + print "skip libxml version " . LIBXML_DOTTED_VERSION; +} +?> +--FILE-- +<?php +$xml = '<node xmlns:pre="http://foo.com/tr/pre" + xmlns:post="http://foo.com/tr/post" + pre:type="bar" type="foo" ><sub /></node>'; +$dom = new DomDocument(); +$dom->loadXML($xml); +echo $dom->firstChild->getAttribute('type')."\n"; +echo $dom->firstChild->getAttribute('pre:type')."\n"; + +$dom->firstChild->setAttribute('pre:type', 'bar2'); +$dom->firstChild->setAttribute('type', 'foo2'); +$dom->firstChild->setAttribute('post:type', 'baz'); +$dom->firstChild->setAttribute('new:type', 'baz2'); + +echo $dom->firstChild->getAttribute('type')."\n"; +echo $dom->firstChild->getAttribute('pre:type')."\n"; +echo $dom->firstChild->getAttribute('post:type')."\n"; + +$dom->firstChild->removeAttribute('pre:type'); +$dom->firstChild->removeAttribute('type'); + +echo $dom->firstChild->getAttribute('type')."\n"; +echo $dom->firstChild->getAttribute('pre:type')."\n"; +echo $dom->firstChild->getAttribute('post:type')."\n"; +echo $dom->firstChild->getAttribute('new:type'); +?> +--EXPECT-- +foo +bar +foo2 +bar2 +baz + + +baz +baz2 diff --git a/ext/dom/tests/bug38850.phpt b/ext/dom/tests/bug38850.phpt new file mode 100644 index 0000000..b0de90b --- /dev/null +++ b/ext/dom/tests/bug38850.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #38850 (lookupNamespaceURI does not return default namespace) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$xml = <<<HERE +<?xml version="1.0" ?> +<foo xmlns="http://www.example.com/ns/foo" /> +HERE; + +$doc = new DOMDocument(); +$doc->loadXML($xml); + +$root = $doc->documentElement; + +print $root->lookupNamespaceURI(NULL); + + +?> +--EXPECT-- +http://www.example.com/ns/foo diff --git a/ext/dom/tests/bug38949.phpt b/ext/dom/tests/bug38949.phpt new file mode 100644 index 0000000..4c81d9b --- /dev/null +++ b/ext/dom/tests/bug38949.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #38949 (Cannot get xmlns value attribute) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument(); +$doc->load(dirname(__FILE__)."/nsdoc.xml"); + +$root = $doc->documentElement; + +echo $root->getAttribute("xmlns")."\n"; +echo $root->getAttribute("xmlns:ns2")."\n"; + +$child = $root->firstChild->nextSibling; +echo $child->getAttribute("xmlns")."\n"; +echo $child->getAttribute("xmlns:ns2")."\n"; + +echo "DONE\n"; +?> +--EXPECT-- +http://ns +http://ns2 + + +DONE diff --git a/ext/dom/tests/bug40836.phpt b/ext/dom/tests/bug40836.phpt new file mode 100644 index 0000000..b96b39c --- /dev/null +++ b/ext/dom/tests/bug40836.phpt @@ -0,0 +1,29 @@ +--TEST-- +Bug #40836 (Segfault in insertBefore) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$dom = new DOMDocument("1.0", "UTF-8"); +$dom->preserveWhiteSpace = false; +$xml = (binary)'<?xml version="1.0" encoding="utf-8"?> +<feed xmlns="http://www.w3.org/2005/Atom"> + <entry xmlns="http://www.w3.org/2005/Atom"> + <updated>2007-02-14T00:00:00+01:00</updated> + <content> + <div xmlns="http://www.w3.org/1999/xhtml"> + <p>paragraph</p> + </div> + </content> + </entry> +</feed>'; +$dom->loadXML($xml); +$entry = $dom->getElementsByTagNameNS("http://www.w3.org/2005/Atom", "entry")->item(0); +$contentNode = $entry->getElementsByTagName("content")->item(0)->firstChild; +$dateNode = $entry->getElementsByTagName("updated")->item(0)->firstChild; +$contentNode->firstChild->insertBefore($dateNode); +echo $dom->saveXML(); +?> +--EXPECT-- +<?xml version="1.0" encoding="utf-8"?> +<feed xmlns="http://www.w3.org/2005/Atom"><entry xmlns="http://www.w3.org/2005/Atom"><updated/><content><div xmlns="http://www.w3.org/1999/xhtml"><p>paragraph2007-02-14T00:00:00+01:00</p></div></content></entry></feed> diff --git a/ext/dom/tests/bug41257.phpt b/ext/dom/tests/bug41257.phpt new file mode 100644 index 0000000..edf62a5 --- /dev/null +++ b/ext/dom/tests/bug41257.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #41257 (lookupNamespaceURI does not work as expected) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument(); +$doc->load(dirname(__FILE__)."/nsdoc.xml"); + +$root = $doc->documentElement; + +$duri = $doc->lookupNamespaceURI("ns2")."\n"; +$euri = $root->lookupNamespaceURI("ns2")."\n"; + +var_dump($duri == $euri); + +$dpref = $doc->lookupPrefix("http://ns2")."\n"; +$epref = $root->lookupPrefix("http://ns2")."\n"; + +var_dump($dpref == $epref); + +$disdef = $doc->isDefaultNamespace("http://ns")."\n"; +$eisdef = $root->isDefaultNamespace("http://ns")."\n"; + +var_dump($dpref === $epref); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) diff --git a/ext/dom/tests/bug41374.phpt b/ext/dom/tests/bug41374.phpt new file mode 100644 index 0000000..21fc345 --- /dev/null +++ b/ext/dom/tests/bug41374.phpt @@ -0,0 +1,32 @@ +--TEST-- +Bug #41374 (wholetext concats values of wrong nodes) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$xml = (binary)<<<EOXML +<?xml version="1.0" encoding="ISO-8859-1" ?> +<root>foo<child />baz</root> +EOXML; + +$doc = new DOMDocument(); +$doc->loadXML($xml); + +$root = $doc->documentElement; +$foo = $root->firstChild; + +var_dump($foo->wholeText == "foo"); + +$bar = $root->insertBefore($doc->createTextNode("bar"), $foo->nextSibling); + +var_dump($foo->wholeText == "foobar"); +var_dump($foo->wholeText == $bar->wholeText); +$baz = $bar->nextSibling->nextSibling; + +var_dump($baz->wholeText === $foo->wholeText); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(false) diff --git a/ext/dom/tests/bug42082.phpt b/ext/dom/tests/bug42082.phpt new file mode 100644 index 0000000..b5fc893 --- /dev/null +++ b/ext/dom/tests/bug42082.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #42082 (NodeList length zero should be empty) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$doc = new DOMDocument(); +$xpath = new DOMXPath($doc); +$nodes = $xpath->query('*'); +echo get_class($nodes), "\n"; +var_dump($nodes->length); +$length = $nodes->length; +var_dump(empty($nodes->length), empty($length)); + +$doc->loadXML("<element></element>"); +var_dump($doc->firstChild->nodeValue, empty($doc->firstChild->nodeValue), isset($doc->firstChild->nodeValue)); +var_dump(empty($doc->nodeType), empty($doc->firstChild->nodeType)) +?> +===DONE=== +--EXPECTF-- +DOMNodeList +int(0) +bool(true) +bool(true) +string(0) "" +bool(true) +bool(true) +bool(false) +bool(false) +===DONE=== + diff --git a/ext/dom/tests/bug43364.phpt b/ext/dom/tests/bug43364.phpt new file mode 100644 index 0000000..6e08ffc --- /dev/null +++ b/ext/dom/tests/bug43364.phpt @@ -0,0 +1,42 @@ +--TEST-- +Bug #43364 (recursive xincludes don't remove internal xml nodes properly) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +function loopElements($nodes) +{ + $count = 0; + foreach($nodes as $node) { + if($node instanceof DOMElement) { + $count++; + if($node->childNodes->length > 0) { + $count += loopElements($node->childNodes); + } + } + } + return $count; +} + +$xml = <<<DOC +<?xml version="1.0" encoding="UTF-8"?> +<root xmlns:xi="http://www.w3.org/2001/XInclude"> + <a> + <a_child1>ac1</a_child1> + <a_child2>ac2</a_child2> + </a> + <b><xi:include xpointer="xpointer(/root/a)" /></b> + <c><xi:include xpointer="xpointer(/root/b)" /></c> +</root> +DOC; + +$doc = new DomDocument(); +$doc->loadXml($xml); +$doc->xinclude(); + +$count = loopElements(array($doc->documentElement)); + +var_dump($count); +?> +--EXPECT-- +int(13) diff --git a/ext/dom/tests/bug44648.phpt b/ext/dom/tests/bug44648.phpt new file mode 100644 index 0000000..d04f590 --- /dev/null +++ b/ext/dom/tests/bug44648.phpt @@ -0,0 +1,45 @@ +--TEST-- +Bug #44648 (Attribute names not checked for wellformedness) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument(); +$doc->loadXML('<root/>'); + +$root = $doc->documentElement; + +try { + $attr = new DOMAttr('@acb', '123'); + $root->setAttributeNode($attr); +} catch (DOMException $e) { + echo $e->getMessage()."\n"; +} + +try { + $root->setAttribute('@def', '456'); +} catch (DOMException $e) { + echo $e->getMessage()."\n"; +} + +try { + $root->setAttributeNS(NULL, '@ghi', '789'); +} catch (DOMException $e) { + echo $e->getMessage()."\n"; +} + +try { + $root->setAttributeNS('urn::test', 'a:g@hi', '789'); +} catch (DOMException $e) { + echo $e->getMessage()."\n"; +} + +echo $doc->saveXML($root); +?> +--EXPECT-- +Invalid Character Error +Invalid Character Error +Invalid Character Error +Namespace Error +<root/>
\ No newline at end of file diff --git a/ext/dom/tests/bug45251.phpt b/ext/dom/tests/bug45251.phpt new file mode 100644 index 0000000..652e3b2 --- /dev/null +++ b/ext/dom/tests/bug45251.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #45251 (double free or corruption with setAttributeNode()) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$doc = new DOMDocument; +$doc->loadXml(<<<EOF +<?xml version="1.0" encoding="utf-8" ?> +<aaa> + <bbb foo="bar"/> +</aaa> +EOF +); + +$xpath = new DOMXPath($doc); + +$bbb = $xpath->query('bbb', $doc->documentElement)->item(0); + +$ccc = $doc->createElement('ccc'); +foreach ($bbb->attributes as $attr) +{ + $ccc->setAttributeNode($attr); +} + +echo $attr->parentNode->localName; + +?> +--EXPECT-- +ccc diff --git a/ext/dom/tests/bug46185.phpt b/ext/dom/tests/bug46185.phpt new file mode 100644 index 0000000..02117cd --- /dev/null +++ b/ext/dom/tests/bug46185.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #46185 (importNode changes the namespace of an XML element). +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$aDOM = new DOMDocument(); +$aDOM->loadXML('<?xml version="1.0"?> +<ns1:a xmlns:ns1="urn::ns"/>'); +$a= $aDOM->firstChild; + +$ok = new DOMDocument(); +$ok->loadXML('<?xml version="1.0"?> +<ns1:ok xmlns:ns1="urn::ns" xmlns="urn::REAL"><watch-me xmlns:default="urn::BOGUS"/></ns1:ok>'); + +$imported= $aDOM->importNode($ok->firstChild, true); +$a->appendChild($imported); + +echo $aDOM->saveXML(); +?> +--EXPECT-- +<?xml version="1.0"?> +<ns1:a xmlns:ns1="urn::ns"><ns1:ok xmlns="urn::REAL"><watch-me xmlns:default="urn::BOGUS"/></ns1:ok></ns1:a>
\ No newline at end of file diff --git a/ext/dom/tests/bug46335.phpt b/ext/dom/tests/bug46335.phpt new file mode 100644 index 0000000..bea4ae9 --- /dev/null +++ b/ext/dom/tests/bug46335.phpt @@ -0,0 +1,35 @@ +--TEST-- +Bug #46335 (DOMText::splitText doesn't handle multibyte characters). +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$textascii = 'This is an "example" of using DOM splitText'; +$text = 'This is an ‘example’ of using DOM splitText'; +$start = 30; +$length = 3; + +$dom = new DOMDocument('1.0', 'UTF-8'); +$node = $dom->createTextNode($textascii); +$dom->appendChild($node); + +print "Text: $node->textContent\n"; + +$matched = $node->splitText($start); +$matched->splitText($length); +print "splitText (ASCII): $matched->textContent\n"; + +$node = $dom->createTextNode($text); +$dom->appendChild($node); + +print "Text: $node->textContent\n"; + +$matched = $node->splitText($start); +$matched->splitText($length); +print "splitText (UTF-8): $matched->textContent\n"; +?> +--EXPECT-- +Text: This is an "example" of using DOM splitText +splitText (ASCII): DOM +Text: This is an ‘example’ of using DOM splitText +splitText (UTF-8): DOM diff --git a/ext/dom/tests/bug46849.phpt b/ext/dom/tests/bug46849.phpt new file mode 100644 index 0000000..c51c96e --- /dev/null +++ b/ext/dom/tests/bug46849.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #46849 (Cloning DOMDocument doesn't clone the properties). +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$dom = new DOMDocument; +$dom->formatOutput = 1; +var_dump($dom->formatOutput); + +$dom2 = clone $dom; +var_dump($dom2->formatOutput); +?> +--EXPECT-- +bool(true) +bool(true) diff --git a/ext/dom/tests/bug47430.phpt b/ext/dom/tests/bug47430.phpt new file mode 100644 index 0000000..243fe84 --- /dev/null +++ b/ext/dom/tests/bug47430.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #47430 (Errors after writing to nodeValue parameter of an absent previousSibling). +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$xml = '<?xml +version="1.0"?><html><p><i>Hello</i></p><p><i>World!</i></p></html>'; +$dom = new DOMDocument(); +$dom->loadXML($xml); + +$elements = $dom->getElementsByTagName('i'); +foreach ($elements as $i) { + $i->previousSibling->nodeValue = ''; +} + +$arr = array(); +$arr[0] = 'Value'; + +print_r($arr); + +?> +--EXPECTF-- +Warning: Creating default object from empty value in %s on line %d + +Warning: Creating default object from empty value in %s on line %d +Array +( + [0] => Value +) diff --git a/ext/dom/tests/bug47848.phpt b/ext/dom/tests/bug47848.phpt new file mode 100644 index 0000000..b4453c7 --- /dev/null +++ b/ext/dom/tests/bug47848.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #47848 (importNode doesn't preserve attribute namespaces) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$aDOM = new DOMDocument(); +$aDOM->appendChild($aDOM->createElementNS('http://friend2friend.net/','f2f:a')); + +$fromdom = new DOMDocument(); +$fromdom->loadXML('<data xmlns:ai="http://altruists.org" ai:attr="namespaced" />'); + +$attr= $fromdom->firstChild->attributes->item(0); + +$att = $aDOM->importNode($attr); + +$aDOM->documentElement->appendChild($aDOM->importNode($attr, true)); + +echo $aDOM->saveXML(); + +?> +--EXPECT-- +<?xml version="1.0"?> +<f2f:a xmlns:f2f="http://friend2friend.net/" xmlns:ai="http://altruists.org" ai:attr="namespaced"/>
\ No newline at end of file diff --git a/ext/dom/tests/bug47849.phpt b/ext/dom/tests/bug47849.phpt new file mode 100644 index 0000000..7e6b02c --- /dev/null +++ b/ext/dom/tests/bug47849.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #47849 (Non-deep import loses the namespace). +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$aDOM= new DOMDocument(); +$aDOM->appendChild($aDOM->createElementNS('urn::root','r:root')); + +$fromdom= new DOMDocument(); +$fromdom->loadXML('<data xmlns="urn::data">aaa</data>'); + +$data= $fromdom->documentElement; +$aDOM->documentElement->appendChild($aDOM->importNode($data)); + +echo $aDOM->saveXML(); + +?> +--EXPECT-- +<?xml version="1.0"?> +<r:root xmlns:r="urn::root"><data xmlns="urn::data"/></r:root> diff --git a/ext/dom/tests/bug49463.phpt b/ext/dom/tests/bug49463.phpt new file mode 100644 index 0000000..4f232e3 --- /dev/null +++ b/ext/dom/tests/bug49463.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #49463 (setAttributeNS fails setting default namespace). +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$doc = new DOMDocument('1.0', 'utf-8'); +$root = $doc->createElementNS('http://purl.org/rss/1.0/','rdf:RDF'); +$doc->appendChild($root); +$root->setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns","http://purl.org/rss/1.0/" ); + +echo $doc->saveXML()."\n"; +?> +--EXPECT-- +<?xml version="1.0" encoding="utf-8"?> +<rdf:RDF xmlns:rdf="http://purl.org/rss/1.0/" xmlns="http://purl.org/rss/1.0/"/> diff --git a/ext/dom/tests/bug49490.phpt b/ext/dom/tests/bug49490.phpt new file mode 100644 index 0000000..897cfee --- /dev/null +++ b/ext/dom/tests/bug49490.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #49490 (XPath namespace prefix conflict). +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$doc = new DOMDocument(); +$doc->loadXML('<prefix:root xmlns:prefix="urn:a" />'); + +$xp = new DOMXPath($doc); +$xp->registerNamespace('prefix', 'urn:b'); + +echo($xp->query('//prefix:root', null, false)->length . "\n"); + +?> +--EXPECT-- +0 diff --git a/ext/dom/tests/bug50661.phpt b/ext/dom/tests/bug50661.phpt new file mode 100644 index 0000000..3760db9 --- /dev/null +++ b/ext/dom/tests/bug50661.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #50661 (DOMDocument::loadXML does not allow UTF-16). +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$data = "\xFE\xFF\x00\x3C\x00\x66\x00\x6F\x00\x6F\x00\x2F\x00\x3E"; + +$dom = new DOMDocument(); +$dom->loadXML($data); +echo $dom->saveXML(); + +?> +--EXPECT-- +<?xml version="1.0"?> +<foo/> diff --git a/ext/dom/tests/bug52656.phpt b/ext/dom/tests/bug52656.phpt new file mode 100644 index 0000000..9ec2610 --- /dev/null +++ b/ext/dom/tests/bug52656.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #52656 (DOMCdataSection does not work with splitText). +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$CData = new DOMCdataSection('splithere!'); +$CDataSplit = $CData->splitText(5); +echo get_class($CDataSplit), "\n"; +var_dump($CDataSplit->data); +?> +--EXPECT-- +DOMText +string(5) "here!" diff --git a/ext/dom/tests/bug54601.phpt b/ext/dom/tests/bug54601.phpt new file mode 100644 index 0000000..012302b --- /dev/null +++ b/ext/dom/tests/bug54601.phpt @@ -0,0 +1,29 @@ +--TEST-- +Segfault when removing the Doctype node +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$xml = <<< XML +<?xml version='1.0' encoding='utf-8' ?> +<!DOCTYPE set PUBLIC "-//OASIS//DTD DocBook XML V5.0//EN" "http://www.docbook.org/xml/5.0/dtd/docbook.dtd" [ +<!ENTITY foo '<foo>footext</foo>'> +<!ENTITY bar '<bar>bartext</bar>'> +]> +<set>&foo;&bar;</set> +XML; + +$doc = new DOMDocument(); +$doc->loadXML($xml, LIBXML_NOENT); +$n = $doc->doctype; +$doc->removeChild($n); +echo get_class($n), "\n"; +print $doc->saveXML(); +?> +===DONE=== +<?php exit(0); ?> +--EXPECTF-- +DOMDocumentType +<?xml version="1.0" encoding="utf-8"?> +<set><foo>footext</foo><bar>bartext</bar></set> +===DONE=== diff --git a/ext/dom/tests/canonicalization.phpt b/ext/dom/tests/canonicalization.phpt new file mode 100644 index 0000000..cf1a81f --- /dev/null +++ b/ext/dom/tests/canonicalization.phpt @@ -0,0 +1,102 @@ +--TEST-- +Test: Canonicalization - C14N() +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$xml = <<<EOXML +<?xml version="1.0" encoding="ISO-8859-1" ?> +<foo xmlns="http://www.example.com/ns/foo" + xmlns:fubar="http://www.example.com/ns/fubar" xmlns:test="urn::test"><contain> + <bar><test1 /></bar> + <bar><test2 /></bar> + <fubar:bar xmlns:fubar="http://www.example.com/ns/fubar"><test3 /></fubar:bar> + <fubar:bar><test4 /></fubar:bar> +<!-- this is a comment --> +</contain> +</foo> +EOXML; + +$dom = new DOMDocument(); +$dom->loadXML($xml); +$doc = $dom->documentElement->firstChild; + +/* inclusive/without comments first child element of doc element is context. */ +echo $doc->C14N()."\n\n"; + +/* exclusive/without comments first child element of doc element is context. */ +echo $doc->c14N(TRUE)."\n\n"; + +/* inclusive/with comments first child element of doc element is context. */ +echo $doc->C14N(FALSE, TRUE)."\n\n"; + +/* exclusive/with comments first child element of doc element is context. */ +echo $doc->C14N(TRUE, TRUE)."\n\n"; + +/* exclusive/without comments using xpath query. */ +echo $doc->c14N(TRUE, FALSE, array('query'=>'(//. | //@* | //namespace::*)'))."\n\n"; + +/* exclusive/without comments first child element of doc element is context. + using xpath query with registered namespace. + test namespace prefix is also included. */ +echo $doc->c14N(TRUE, FALSE, + array('query'=>'(//a:contain | //a:bar | .//namespace::*)', + 'namespaces'=>array('a'=>'http://www.example.com/ns/foo')), + array('test'))."\n\n"; + +/* exclusive/without comments first child element of doc element is context. + test namespace prefix is also included */ +echo $doc->C14N(TRUE, FALSE, NULL, array('test')); +?> +--EXPECTF-- + +<contain xmlns="http://www.example.com/ns/foo" xmlns:fubar="http://www.example.com/ns/fubar" xmlns:test="urn::test"> + <bar><test1></test1></bar> + <bar><test2></test2></bar> + <fubar:bar><test3></test3></fubar:bar> + <fubar:bar><test4></test4></fubar:bar> + +</contain> + +<contain xmlns="http://www.example.com/ns/foo"> + <bar><test1></test1></bar> + <bar><test2></test2></bar> + <fubar:bar xmlns:fubar="http://www.example.com/ns/fubar"><test3></test3></fubar:bar> + <fubar:bar xmlns:fubar="http://www.example.com/ns/fubar"><test4></test4></fubar:bar> + +</contain> + +<contain xmlns="http://www.example.com/ns/foo" xmlns:fubar="http://www.example.com/ns/fubar" xmlns:test="urn::test"> + <bar><test1></test1></bar> + <bar><test2></test2></bar> + <fubar:bar><test3></test3></fubar:bar> + <fubar:bar><test4></test4></fubar:bar> +<!-- this is a comment --> +</contain> + +<contain xmlns="http://www.example.com/ns/foo"> + <bar><test1></test1></bar> + <bar><test2></test2></bar> + <fubar:bar xmlns:fubar="http://www.example.com/ns/fubar"><test3></test3></fubar:bar> + <fubar:bar xmlns:fubar="http://www.example.com/ns/fubar"><test4></test4></fubar:bar> +<!-- this is a comment --> +</contain> + +<foo xmlns="http://www.example.com/ns/foo"><contain> + <bar><test1></test1></bar> + <bar><test2></test2></bar> + <fubar:bar xmlns:fubar="http://www.example.com/ns/fubar"><test3></test3></fubar:bar> + <fubar:bar xmlns:fubar="http://www.example.com/ns/fubar"><test4></test4></fubar:bar> + +</contain> +</foo> + +<contain xmlns="http://www.example.com/ns/foo" xmlns:test="urn::test"><bar></bar><bar></bar></contain> + +<contain xmlns="http://www.example.com/ns/foo" xmlns:test="urn::test"> + <bar><test1></test1></bar> + <bar><test2></test2></bar> + <fubar:bar xmlns:fubar="http://www.example.com/ns/fubar"><test3></test3></fubar:bar> + <fubar:bar xmlns:fubar="http://www.example.com/ns/fubar"><test4></test4></fubar:bar> + +</contain> diff --git a/ext/dom/tests/dom.ent b/ext/dom/tests/dom.ent new file mode 100644 index 0000000..987ff9d --- /dev/null +++ b/ext/dom/tests/dom.ent @@ -0,0 +1,8 @@ +<!ENTITY amp "&#38;"> +<!ENTITY gt ">"> +<!ENTITY % coreattrs "title CDATA #IMPLIED"> +<!ENTITY % attrs "%coreattrs;"> +<!ATTLIST foo bar CDATA #IMPLIED> +<!ELEMENT foo (#PCDATA)> +<!ELEMENT root (foo)+> +<!ATTLIST th %attrs; >
\ No newline at end of file diff --git a/ext/dom/tests/dom.xml b/ext/dom/tests/dom.xml new file mode 100644 index 0000000..09ac674 --- /dev/null +++ b/ext/dom/tests/dom.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<!DOCTYPE root [ +<!ENTITY % incent SYSTEM "dom.ent"> +%incent; +]> +<root> + <foo bar="" /> +</root>
\ No newline at end of file diff --git a/ext/dom/tests/dom001.phpt b/ext/dom/tests/dom001.phpt new file mode 100644 index 0000000..a0c78fb --- /dev/null +++ b/ext/dom/tests/dom001.phpt @@ -0,0 +1,275 @@ +--TEST-- +Test 1: Accessing single node +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +require_once("dom_test.inc"); + +echo "Test 1: accessing single nodes from php\n"; +$dom = new domDocument; +$dom->loadxml($xmlstr); +if(!$dom) { + echo "Error while parsing the document\n"; + exit; +} + +// children() of of document would result in a memleak +//$children = $dom->children(); +//print_node_list($children); + +echo "--------- root\n"; +$rootnode = $dom->documentElement; +print_node($rootnode); + +echo "--------- children of root\n"; +$children = $rootnode->childNodes; +print_node_list($children); + +// The last node should be identical with the last entry in the children array +echo "--------- last\n"; +$last = $rootnode->lastChild; +print_node($last); + +// The parent of this last node is the root again +echo "--------- parent\n"; +$parent = $last->parentNode; +print_node($parent); + +// The children of this parent are the same children as one above +echo "--------- children of parent\n"; +$children = $parent->childNodes; +print_node_list($children); + +echo "--------- creating a new attribute\n"; +//This is worthless +//$attr = $dom->createAttribute("src", "picture.gif"); +//print_r($attr); + +//$rootnode->set_attributeNode($attr); +$attr = $rootnode->setAttribute("src", "picture.gif"); +$attr = $rootnode->getAttribute("src"); +print_r($attr); +print "\n"; + +echo "--------- Get Attribute Node\n"; +$attr = $rootnode->getAttributeNode("src"); +print_node($attr); + +echo "--------- Remove Attribute Node\n"; +$attr = $rootnode->removeAttribute("src"); +print "Removed " . $attr . " attributes.\n"; + +echo "--------- attributes of rootnode\n"; +$attrs = $rootnode->attributes; +print_node_list($attrs); + +echo "--------- children of an attribute\n"; +$children = $attrs->item(0)->childNodes; +print_node_list($children); + +echo "--------- Add child to root\n"; +$myelement = new domElement("Silly", "Symphony"); +$newchild = $rootnode->appendChild($myelement); +print_node($newchild); +print $dom->saveXML(); +print "\n"; + +echo "--------- Find element by tagname\n"; +echo " Using dom\n"; +$children = $dom->getElementsByTagname("Silly"); +print_node_list($children); + +echo " Using elem\n"; +$children = $rootnode->getElementsByTagName("Silly"); +print_node_list($children); + +echo "--------- Unlink Node\n"; +print_node($children->item(0)); +$rootnode->removeChild($children->item(0)); +print_node_list($rootnode->childNodes); +print $dom->savexml(); + +echo "--------- Find element by id\n"; +print ("Not implemented\n"); + +echo "--------- Check various node_name return values\n"; +print ("Not needed\n"); + +?> +--EXPECT-- +Test 1: accessing single nodes from php +--------- root +Node Name: chapter +Node Type: 1 +Num Children: 4 + +--------- children of root +Node Name: title +Node Type: 1 +Num Children: 1 +Node Content: Title + +Node Name: #text +Node Type: 3 +Num Children: 0 +Node Content: + + +Node Name: para +Node Type: 1 +Num Children: 7 + +Node Name: #text +Node Type: 3 +Num Children: 0 +Node Content: + + +--------- last +Node Name: #text +Node Type: 3 +Num Children: 0 +Node Content: + + +--------- parent +Node Name: chapter +Node Type: 1 +Num Children: 4 + +--------- children of parent +Node Name: title +Node Type: 1 +Num Children: 1 +Node Content: Title + +Node Name: #text +Node Type: 3 +Num Children: 0 +Node Content: + + +Node Name: para +Node Type: 1 +Num Children: 7 + +Node Name: #text +Node Type: 3 +Num Children: 0 +Node Content: + + +--------- creating a new attribute +picture.gif +--------- Get Attribute Node +Node Name: src +Node Type: 2 +Num Children: 1 +Node Content: picture.gif + +--------- Remove Attribute Node +Removed 1 attributes. +--------- attributes of rootnode +Node Name: language +Node Type: 2 +Num Children: 1 +Node Content: en + +--------- children of an attribute +Node Name: #text +Node Type: 3 +Num Children: 0 +Node Content: en + +--------- Add child to root +Node Name: Silly +Node Type: 1 +Num Children: 1 +Node Content: Symphony + +<?xml version="1.0" standalone="yes"?> +<!DOCTYPE chapter SYSTEM "/share/sgml/Norman_Walsh/db3xml10/db3xml10.dtd" [ +<!ENTITY sp "spanish"> +]> +<!-- lsfj --> +<chapter language="en"><title language="en">Title</title> +<para language="ge"> +&sp; +<!-- comment --> +<informaltable language="&sp;kkk"> +<tgroup cols="3"> +<tbody> +<row><entry>a1</entry><entry morerows="1">b1</entry><entry>c1</entry></row> +<row><entry>a2</entry><entry>c2</entry></row> +<row><entry>a3</entry><entry>b3</entry><entry>c3</entry></row> +</tbody> +</tgroup> +</informaltable> +</para> +<Silly>Symphony</Silly></chapter> + +--------- Find element by tagname + Using dom +Node Name: Silly +Node Type: 1 +Num Children: 1 +Node Content: Symphony + + Using elem +Node Name: Silly +Node Type: 1 +Num Children: 1 +Node Content: Symphony + +--------- Unlink Node +Node Name: Silly +Node Type: 1 +Num Children: 1 +Node Content: Symphony + +Node Name: title +Node Type: 1 +Num Children: 1 +Node Content: Title + +Node Name: #text +Node Type: 3 +Num Children: 0 +Node Content: + + +Node Name: para +Node Type: 1 +Num Children: 7 + +Node Name: #text +Node Type: 3 +Num Children: 0 +Node Content: + + +<?xml version="1.0" standalone="yes"?> +<!DOCTYPE chapter SYSTEM "/share/sgml/Norman_Walsh/db3xml10/db3xml10.dtd" [ +<!ENTITY sp "spanish"> +]> +<!-- lsfj --> +<chapter language="en"><title language="en">Title</title> +<para language="ge"> +&sp; +<!-- comment --> +<informaltable language="&sp;kkk"> +<tgroup cols="3"> +<tbody> +<row><entry>a1</entry><entry morerows="1">b1</entry><entry>c1</entry></row> +<row><entry>a2</entry><entry>c2</entry></row> +<row><entry>a3</entry><entry>b3</entry><entry>c3</entry></row> +</tbody> +</tgroup> +</informaltable> +</para> +</chapter> +--------- Find element by id +Not implemented +--------- Check various node_name return values +Not needed diff --git a/ext/dom/tests/dom002.phpt b/ext/dom/tests/dom002.phpt new file mode 100644 index 0000000..3343a17 --- /dev/null +++ b/ext/dom/tests/dom002.phpt @@ -0,0 +1,57 @@ +--TEST-- +Test 2: getElementsByTagName() / getElementsByTagNameNS() +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$xml = <<<HERE +<?xml version="1.0" encoding="ISO-8859-1" ?> +<foo xmlns="http://www.example.com/ns/foo" + xmlns:fubar="http://www.example.com/ns/fubar"> + <bar><test1 /></bar> + <bar><test2 /></bar> + <fubar:bar><test3 /></fubar:bar> + <fubar:bar><test4 /></fubar:bar> +</foo> +HERE; + +function dump($elems) { + foreach ($elems as $elem) { + var_dump($elem->nodeName); + dump($elem->childNodes); + } +} + +$dom = new DOMDocument(); +$dom->loadXML($xml); +$doc = $dom->documentElement; +dump($dom->getElementsByTagName('bar')); +dump($doc->getElementsByTagName('bar')); +dump($dom->getElementsByTagNameNS('http://www.example.com/ns/fubar', 'bar')); +dump($doc->getElementsByTagNameNS('http://www.example.com/ns/fubar', 'bar')); +?> +--EXPECT-- +string(3) "bar" +string(5) "test1" +string(3) "bar" +string(5) "test2" +string(9) "fubar:bar" +string(5) "test3" +string(9) "fubar:bar" +string(5) "test4" +string(3) "bar" +string(5) "test1" +string(3) "bar" +string(5) "test2" +string(9) "fubar:bar" +string(5) "test3" +string(9) "fubar:bar" +string(5) "test4" +string(9) "fubar:bar" +string(5) "test3" +string(9) "fubar:bar" +string(5) "test4" +string(9) "fubar:bar" +string(5) "test3" +string(9) "fubar:bar" +string(5) "test4" diff --git a/ext/dom/tests/dom003.phpt b/ext/dom/tests/dom003.phpt new file mode 100644 index 0000000..060a2c1 --- /dev/null +++ b/ext/dom/tests/dom003.phpt @@ -0,0 +1,69 @@ +--TEST-- +Test 3: Exception Test +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +$dom = new domdocument; +$dom->load(dirname(__FILE__)."/book.xml"); +$rootNode = $dom->documentElement; +print "--- Catch exception with try/catch\n"; +try { + $rootNode->appendChild($rootNode); +} catch (domexception $e) { + ob_start(); + var_dump($e); + $contents = ob_get_contents(); + ob_end_clean(); + echo preg_replace('/object\(DOMElement\).+\{.*?\}/s', 'DOMElement', $contents); +} +print "--- Don't catch exception with try/catch\n"; +$rootNode->appendChild($rootNode); + + +?> +--EXPECTF-- +--- Catch exception with try/catch +object(DOMException)#%d (%d) { + ["message":protected]=> + string(23) "Hierarchy Request Error" + ["string":"Exception":private]=> + string(0) "" + ["file":protected]=> + string(%d) "%sdom003.php" + ["line":protected]=> + int(8) + ["trace":"Exception":private]=> + array(1) { + [0]=> + array(6) { + ["file"]=> + string(%d) "%sdom003.php" + ["line"]=> + int(8) + ["function"]=> + string(11) "appendChild" + ["class"]=> + string(7) "DOMNode" + ["type"]=> + string(2) "->" + ["args"]=> + array(1) { + [0]=> + DOMElement + } + } + } + ["previous":"Exception":private]=> + NULL + ["code"]=> + int(3) +} +--- Don't catch exception with try/catch + +Fatal error: Uncaught exception 'DOMException' with message 'Hierarchy Request Error' in %sdom003.php:%d +Stack trace: +#0 %sdom003.php(%d): DOMNode->appendChild(Object(DOMElement)) +#1 {main} + thrown in %sdom003.php on line %d diff --git a/ext/dom/tests/dom004.phpt b/ext/dom/tests/dom004.phpt new file mode 100644 index 0000000..5b65f24 --- /dev/null +++ b/ext/dom/tests/dom004.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test 4: Streams Test +--SKIPIF-- +<?php +require_once('skipif.inc'); +in_array('compress.zlib', stream_get_wrappers()) or die('skip compress.zlib wrapper is not available'); +?> +--FILE-- +<?php +$dom = new domdocument; +$dom->load("compress.zlib://".dirname(__FILE__)."/book.xml.gz"); +print $dom->saveXML(); + +--EXPECT-- +<?xml version="1.0"?> +<books> + <book> + <title>The Grapes of Wrath</title> + <author>John Steinbeck</author> + </book> + <book> + <title>The Pearl</title> + <author>John Steinbeck</author> + </book> +</books> diff --git a/ext/dom/tests/dom005.phpt b/ext/dom/tests/dom005.phpt new file mode 100644 index 0000000..715aec4 --- /dev/null +++ b/ext/dom/tests/dom005.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test 5: HTML Test +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$dom = new domdocument; +$dom->loadHTMLFile(dirname(__FILE__)."/test.html"); +print "--- save as XML\n"; + +print adjustDoctype($dom->saveXML()); +print "--- save as HTML\n"; + +print adjustDoctype($dom->saveHTML()); + +function adjustDoctype($xml) { + return str_replace(array("DOCTYPE HTML",'<p>','</p>'),array("DOCTYPE html",'',''),$xml); +} + +--EXPECT-- +--- save as XML +<?xml version="1.0" standalone="yes"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> +<html><head><title>Hello world</title></head><body> +This is a not well-formed<br/> +html files with undeclared entities  +</body></html> +--- save as HTML +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> +<html><head><title>Hello world</title></head><body> +This is a not well-formed<br> +html files with undeclared entities +</body></html> diff --git a/ext/dom/tests/dom006.phpt b/ext/dom/tests/dom006.phpt new file mode 100644 index 0000000..b8e8ed1 --- /dev/null +++ b/ext/dom/tests/dom006.phpt @@ -0,0 +1,40 @@ +--TEST-- +Test 6: Extends Test +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +Class books extends domDocument { + function addBook($title, $author) { + $titleElement = $this->createElement("title"); + $titleElement->appendChild($this->createTextNode($title)); + $authorElement = $this->createElement("author"); + $authorElement->appendChild($this->createTextNode($author)); + + $bookElement = $this->createElement("book"); + + $bookElement->appendChild($titleElement); + $bookElement->appendChild($authorElement); + $this->documentElement->appendChild($bookElement); + } + +} + +$dom = new books; + +$dom->load(dirname(__FILE__)."/book.xml"); +$dom->addBook("PHP de Luxe", "Richard Samar, Christian Stocker"); +print $dom->saveXML(); +--EXPECT-- +<?xml version="1.0"?> +<books> + <book> + <title>The Grapes of Wrath</title> + <author>John Steinbeck</author> + </book> + <book> + <title>The Pearl</title> + <author>John Steinbeck</author> + </book> +<book><title>PHP de Luxe</title><author>Richard Samar, Christian Stocker</author></book></books> diff --git a/ext/dom/tests/dom007.phpt b/ext/dom/tests/dom007.phpt new file mode 100644 index 0000000..5d12aa3 --- /dev/null +++ b/ext/dom/tests/dom007.phpt @@ -0,0 +1,111 @@ +--TEST-- +Test 7: DTD tests +--SKIPIF-- +<?php +require_once('skipif.inc'); +?> +--FILE-- +<?php +$xml = <<< EOXML +<?xml version="1.0" encoding="ISO-8859-1"?> +<!DOCTYPE courses [ +<!ELEMENT courses (course+)> +<!ELEMENT course (title, description, temp*)> +<!ATTLIST course cid ID #REQUIRED> +<!ELEMENT title (#PCDATA)> +<!ELEMENT description (#PCDATA)> +<!ELEMENT temp (#PCDATA)> +<!ATTLIST temp vid ID #REQUIRED> +<!ENTITY test 'http://www.hpl.hp.com/semweb/2003/query_tester#'> +<!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'> +<!NOTATION GIF PUBLIC "-" "image/gif"> +<!ENTITY myimage PUBLIC "-" "mypicture.gif" NDATA GIF> +]> +<courses> + <course cid="c1"> + <title>Basic Languages</title> + <description>Introduction to Languages</description> + </course> + <course cid="c6"> + <title>French I</title> + <description>Introduction to French</description> + <temp vid="c7"> + </temp> + </course> +</courses> +EOXML; + +$dom = new DOMDocument(); +$dom->loadXML($xml); + +$dtd = $dom->doctype; + +/* Notation Tests */ +$nots = $dtd->notations; + +$length = $nots->length; +echo "Length: ".$length."\n"; + +foreach ($nots AS $key=>$node) { + echo "Key $key: ".$node->nodeName." (".$node->systemId.") (".$node->publicId.")\n"; +} +print "\n"; +for($x=0; $x < $length; $x++) { + echo "Index $x: ".$nots->item($x)->nodeName." (".$nots->item($x)->systemId.") (".$nots->item($x)->publicId.")\n"; +} + +echo "\n"; +$node = $nots->getNamedItem('xxx'); +var_dump($node); + +echo "\n"; +/* Entity Decl Tests */ +$ents = $dtd->entities; +$length = $ents->length; +echo "Length: ".$length."\n"; + +$xkeys = array(); +foreach ($ents AS $key=>$node) { + $xkeys[] = "Key: $key Name: ".$node->nodeName."\n"; +} +sort($xkeys); // fix inconsistent output ordering (bug #61810) +foreach ($xkeys as $key => $node) { + echo $node; +} +echo "\n"; + +$xkeys = array(); +for($x=0; $x < $length; $x++) { + $xkeys[] = "Index: ".$ents->item($x)->nodeName."\n"; +} +sort($xkeys); // fix inconsistent output ordering (bug #61810) +foreach ($xkeys as $key => $node) { + echo $node; +} + +echo "\n"; +$node = $ents->item(3); +var_dump($node); +$node = $ents->getNamedItem('xxx'); +var_dump($node); + + +--EXPECT-- +Length: 1 +Key GIF: GIF (image/gif) (-) + +Index 0: GIF (image/gif) (-) + +NULL + +Length: 3 +Key: myimage Name: myimage +Key: rdf Name: rdf +Key: test Name: test + +Index: myimage +Index: rdf +Index: test + +NULL +NULL diff --git a/ext/dom/tests/dom_comment_basic.phpt b/ext/dom/tests/dom_comment_basic.phpt new file mode 100644 index 0000000..3a69705 --- /dev/null +++ b/ext/dom/tests/dom_comment_basic.phpt @@ -0,0 +1,43 @@ +--TEST-- +DOM Comment : Basic Functionality +--SKIPIF-- +<?php +require_once('skipif.inc'); +?> +--FILE-- +<?php + +$xml = <<< EOXML +<?xml version="1.0" encoding="ISO-8859-1"?> +<courses> + <!-- Hello World! --> +</courses> +EOXML; + +$dom = new DOMDocument(); +$dom->loadXML($xml); +$root = $dom->documentElement; +var_dump($root->hasChildNodes()); +$children = $root->childNodes; + +for ($index = 0; $index < $children->length; $index++) { + echo "--- child $index ---\n"; + $current = $children->item($index); + echo get_class($current), "\n"; + var_dump($current->textContent); +} + +--EXPECTF-- +bool(true) +--- child 0 --- +DOMText +string(2) " + " +--- child 1 --- +DOMComment +string(14) " Hello World! " +--- child 2 --- +DOMText +string(1) " +" + diff --git a/ext/dom/tests/dom_comment_variation.phpt b/ext/dom/tests/dom_comment_variation.phpt new file mode 100644 index 0000000..1f30e7c --- /dev/null +++ b/ext/dom/tests/dom_comment_variation.phpt @@ -0,0 +1,32 @@ +--TEST-- +DOM Comment : Variation +--SKIPIF-- +<?php +require_once('skipif.inc'); +?> +--FILE-- +<?php + +$xml = <<< EOXML +<?xml version="1.0" encoding="ISO-8859-1"?><courses><!-- Hello World! --></courses> +EOXML; + +$dom = new DOMDocument(); +$dom->loadXML($xml); +$root = $dom->documentElement; +var_dump($root->hasChildNodes()); +$children = $root->childNodes; + +for ($index = 0; $index < $children->length; $index++) { + echo "--- child $index ---\n"; + $current = $children->item($index); + echo get_class($current), "\n"; + var_dump($current->textContent); +} + +--EXPECTF-- +bool(true) +--- child 0 --- +DOMComment +string(14) " Hello World! " + diff --git a/ext/dom/tests/dom_create_element.phpt b/ext/dom/tests/dom_create_element.phpt new file mode 100644 index 0000000..3f30709 --- /dev/null +++ b/ext/dom/tests/dom_create_element.phpt @@ -0,0 +1,394 @@ +--TEST-- +Test 1: Creating Elements with and without Namespaces +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + +print " 1 DOMDocument::createElement('valid')\n"; +try { + $dom = new domDocument; + $dom->createElement('valid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print " 2 DOMDocument::createElement('-invalid')\n"; +try { + $dom = new domDocument; + $dom->createElement('-invalid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print " 3 DOMDocument::createElement(' ')\n"; +try { + $dom = new domDocument; + $dom->createElement(' '); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print " 4 DOMDocument::createElement('prefix:valid')\n"; +try { + $dom = new domDocument; + $dom->createElement('prefix:valid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print " 5 DOMDocument::createElementNS('http://valid.com', 'valid')\n"; +try { + $dom = new domDocument; + $dom->createElementNS('http://valid.com', 'valid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print " 6 DOMDocument::createElementNS('http://valid.com', 'prefix:valid')\n"; +try { + $dom = new domDocument; + $dom->createElementNS('http://valid.com', 'prefix:valid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print " 7 DOMDocument::createElementNS('http://valid.com', '-invalid')\n"; +try { + $dom = new domDocument; + $dom->createElementNS('http://valid.com', '-invalid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print " 8 DOMDocument::createElementNS('http://valid.com', 'prefix:-invalid')\n"; +try { + $dom = new domDocument; + $dom->createElementNS('http://valid.com', 'prefix:-invalid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print " 9 DOMDocument::createElementNS('', 'prefix:invalid')\n"; +try { + $dom = new domDocument; + $dom->createElementNS('', 'prefix:invalid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print "10 DOMDocument::createElementNS('http://valid.com', 'prefix:valid:invalid')\n"; +try { + $dom = new domDocument; + $dom->createElementNS('http://valid.com', 'prefix:valid:invalid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print "11 DOMDocument::createElementNS('http://valid.com', '-prefix:valid')\n"; +try { + $dom = new domDocument; + $dom->createElementNS('http://valid.com', '-prefix:valid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print "12 DOMDocument::createElementNS('-', 'prefix:valid')\n"; +try { + $dom = new domDocument; + $dom->createElementNS('-', 'prefix:valid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + + +print "13 DOMElement::__construct('valid')\n"; +try { + $element = new DomElement('valid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print "14 DOMElement::__construct('-invalid')\n"; +try { + $element = new DomElement('-invalid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print "15 DOMElement::__construct(' ')\n"; +try { + $element = new DomElement(' '); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print "16 DOMElement::__construct('prefix:valid')\n"; +try { + $element = new DomElement('prefix:valid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print "17 DOMElement::__construct('valid', '', 'http://valid.com')\n"; +try { + $element = new DomElement('valid', '', 'http://valid.com'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print "18 DOMElement::__construct('prefix:valid', '', 'http://valid.com')\n"; +try { + $element = new DomElement('prefix:valid', '', 'http://valid.com'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print "19 DOMElement::__construct('-invalid', '', 'http://valid.com')\n"; +try { + $element = new DomElement('-invalid', '', 'http://valid.com'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print "20 DOMElement::__construct('prefix:-invalid', '', 'http://valid.com')\n"; +try { + $element = new DomElement('prefix:-invalid', '', 'http://valid.com'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print "21 DOMElement::__construct('prefix:invalid', '', '')\n"; +try { + $element = new DomElement('prefix:invalid', '', ''); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print "22 DOMElement::__construct('prefix:valid:invalid', '', 'http://valid.com')\n"; +try { + $element = new DomElement('prefix:valid:invalid', '', 'http://valid.com'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print "23 DOMElement::__construct('-prefix:valid', '', 'http://valid.com')\n"; +try { + $element = new DomElement('-prefix:valid', '', 'http://valid.com'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print "24 DOMElement::__construct('prefix:valid', '', '-')\n"; +try { + $element = new DomElement('prefix:valid', '', '-'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +/* the qualifiedName has a prefix and the namespaceURI is null */ + +print "25 DOMDocument::createElementNS('', 'prefix:valid')\n"; +try { + $dom = new domDocument; + $dom->createElementNS('', 'prefix:valid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +/* the qualifiedName has a prefix that is "xml" and the namespaceURI + is different from "http://www.w3.org/XML/1998/namespace" [XML Namespaces] */ + +print "26 DOMDocument::createElementNS('http://wrong.namespaceURI.com', 'xml:valid')\n"; +try { + $dom = new domDocument; + $dom->createElementNS('http://wrong.namespaceURI.com', 'xml:valid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print "27 DOMElement::__construct('xml:valid', '', 'http://wrong.namespaceURI.com')\n"; +try { + $element = new DomElement('xml:valid', '', 'http://wrong.namespaceURI.com'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +/* This is okay because we reuse the xml namespace from the document */ +print "28 DOMDocument::createElementNS('http://www.w3.org/XML/1998/namespace', 'xml:valid')\n"; +try { + $dom = new domDocument; + $dom->createElementNS('http://www.w3.org/XML/1998/namespace', 'xml:valid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +/* This isn't because the xml namespace isn't there and we can't create it */ +print "29 DOMElement::__construct('xml:valid', '', 'http://www.w3.org/XML/1998/namespace')\n"; +try { + $element = new DomElement('xml:valid', '', 'http://www.w3.org/XML/1998/namespace'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + + +/* the qualifiedName or its prefix is "xmlns" and the namespaceURI is + different from "http://www.w3.org/2000/xmlns/" */ + +print "30 DOMDocument::createElementNS('http://wrong.namespaceURI.com', 'xmlns:valid')\n"; +try { + $dom = new domDocument; + $dom->createElementNS('http://wrong.namespaceURI.com', 'xmlns:valid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print "31 DOMElement::__construct('xmlns:valid', '', 'http://wrong.namespaceURI.com')\n"; +try { + $element = new DomElement('xmlns:valid', '', 'http://wrong.namespaceURI.com'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print "32 DOMDocument::createElementNS('http://www.w3.org/2000/xmlns/', 'xmlns:valid')\n"; +try { + $dom = new domDocument; + $dom->createElementNS('http://www.w3.org/2000/xmlns/', 'xmlns:valid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print "33 DOMElement::__construct('xmlns:valid', '', 'http://www.w3.org/2000/xmlns/')\n"; +try { + $element = new DomElement('xmlns:valid', '', 'http://www.w3.org/2000/xmlns/'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +/* the namespaceURI is "http://www.w3.org/2000/xmlns/" and neither the + qualifiedName nor its prefix is "xmlns". */ + +print "34 DOMDocument::createElementNS('http://www.w3.org/2000/xmlns/', 'wrongprefix:valid')\n"; +try { + $dom = new domDocument; + $dom->createElementNS('http://www.w3.org/2000/xmlns/', 'wrongprefix:valid'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + +print "35 DOMElement::__construct('wrongprefix:valid', '', 'http://www.w3.org/2000/xmlns/')\n"; +try { + $element = new DomElement('wrongprefix:valid', '', 'http://www.w3.org/2000/xmlns/'); + print "valid\n"; +} catch (Exception $e) { + print $e->getMessage() . "\n"; +} + + + +?> +--EXPECT-- + 1 DOMDocument::createElement('valid') +valid + 2 DOMDocument::createElement('-invalid') +Invalid Character Error + 3 DOMDocument::createElement(' ') +Invalid Character Error + 4 DOMDocument::createElement('prefix:valid') +valid + 5 DOMDocument::createElementNS('http://valid.com', 'valid') +valid + 6 DOMDocument::createElementNS('http://valid.com', 'prefix:valid') +valid + 7 DOMDocument::createElementNS('http://valid.com', '-invalid') +Namespace Error + 8 DOMDocument::createElementNS('http://valid.com', 'prefix:-invalid') +Namespace Error + 9 DOMDocument::createElementNS('', 'prefix:invalid') +Namespace Error +10 DOMDocument::createElementNS('http://valid.com', 'prefix:valid:invalid') +Namespace Error +11 DOMDocument::createElementNS('http://valid.com', '-prefix:valid') +Namespace Error +12 DOMDocument::createElementNS('-', 'prefix:valid') +valid +13 DOMElement::__construct('valid') +valid +14 DOMElement::__construct('-invalid') +Invalid Character Error +15 DOMElement::__construct(' ') +Invalid Character Error +16 DOMElement::__construct('prefix:valid') +Namespace Error +17 DOMElement::__construct('valid', '', 'http://valid.com') +valid +18 DOMElement::__construct('prefix:valid', '', 'http://valid.com') +valid +19 DOMElement::__construct('-invalid', '', 'http://valid.com') +Invalid Character Error +20 DOMElement::__construct('prefix:-invalid', '', 'http://valid.com') +Namespace Error +21 DOMElement::__construct('prefix:invalid', '', '') +Namespace Error +22 DOMElement::__construct('prefix:valid:invalid', '', 'http://valid.com') +Namespace Error +23 DOMElement::__construct('-prefix:valid', '', 'http://valid.com') +Invalid Character Error +24 DOMElement::__construct('prefix:valid', '', '-') +valid +25 DOMDocument::createElementNS('', 'prefix:valid') +Namespace Error +26 DOMDocument::createElementNS('http://wrong.namespaceURI.com', 'xml:valid') +Namespace Error +27 DOMElement::__construct('xml:valid', '', 'http://wrong.namespaceURI.com') +Namespace Error +28 DOMDocument::createElementNS('http://www.w3.org/XML/1998/namespace', 'xml:valid') +valid +29 DOMElement::__construct('xml:valid', '', 'http://www.w3.org/XML/1998/namespace') +Namespace Error +30 DOMDocument::createElementNS('http://wrong.namespaceURI.com', 'xmlns:valid') +Namespace Error +31 DOMElement::__construct('xmlns:valid', '', 'http://wrong.namespaceURI.com') +Namespace Error +32 DOMDocument::createElementNS('http://www.w3.org/2000/xmlns/', 'xmlns:valid') +valid +33 DOMElement::__construct('xmlns:valid', '', 'http://www.w3.org/2000/xmlns/') +valid +34 DOMDocument::createElementNS('http://www.w3.org/2000/xmlns/', 'wrongprefix:valid') +Namespace Error +35 DOMElement::__construct('wrongprefix:valid', '', 'http://www.w3.org/2000/xmlns/') +Namespace Error diff --git a/ext/dom/tests/dom_import_simplexml.phpt b/ext/dom/tests/dom_import_simplexml.phpt new file mode 100644 index 0000000..81744aa --- /dev/null +++ b/ext/dom/tests/dom_import_simplexml.phpt @@ -0,0 +1,27 @@ +--TEST-- +Interop Test: Import from SimpleXML +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +<?php if (!extension_loaded('simplexml')) die('skip simplexml extension not available');?> +--FILE-- +<?php +$s = simplexml_load_file(dirname(__FILE__)."/book.xml"); +if(!$s) { + echo "Error while loading the document\n"; + exit; +} +$dom = dom_import_simplexml($s); +print $dom->ownerDocument->saveXML(); +?> +--EXPECT-- +<?xml version="1.0"?> +<books> + <book> + <title>The Grapes of Wrath</title> + <author>John Steinbeck</author> + </book> + <book> + <title>The Pearl</title> + <author>John Steinbeck</author> + </book> +</books> diff --git a/ext/dom/tests/dom_set_attr_node.phpt b/ext/dom/tests/dom_set_attr_node.phpt new file mode 100644 index 0000000..1916cd5 --- /dev/null +++ b/ext/dom/tests/dom_set_attr_node.phpt @@ -0,0 +1,74 @@ +--TEST-- +Test: setAttributeNode() +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--INI-- +error_reporting = E_ALL & ~E_WARNING +--FILE-- +<?php + +$xml = <<<HERE +<?xml version="1.0" ?> +<root a="b" /> +HERE; + +$xml2 = <<<HERE +<?xml version="1.0" ?> +<doc2 /> +HERE; + +$dom = new DOMDocument(); +$dom->loadXML($xml); +$root = $dom->documentElement; +$attr = $root->getAttributeNode('a'); + +$dom2 = new DOMDocument(); +$dom2->loadXML($xml2); +$root2 = $dom2->documentElement; +try { + $root2->setAttributeNode($attr); +} catch (domexception $e) { +ob_start(); + var_dump($e); + $contents = ob_get_contents(); + ob_end_clean(); + echo preg_replace('/object\(DOMAttr\).+\{.*?\}/s', 'DOMAttr', $contents); +} + +?> +--EXPECTF-- +object(DOMException)#%d (7) { + ["message":protected]=> + string(20) "Wrong Document Error" + ["string":"Exception":private]=> + string(0) "" + ["file":protected]=> + string(%d) "%sdom_set_attr_node.php" + ["line":protected]=> + int(%d) + ["trace":"Exception":private]=> + array(1) { + [0]=> + array(6) { + ["file"]=> + string(%d) "%sdom_set_attr_node.php" + ["line"]=> + int(%d) + ["function"]=> + string(16) "setAttributeNode" + ["class"]=> + string(10) "DOMElement" + ["type"]=> + string(2) "->" + ["args"]=> + array(1) { + [0]=> + DOMAttr + } + } + } + ["previous":"Exception":private]=> + NULL + ["code"]=> + int(4) +} diff --git a/ext/dom/tests/dom_test.inc b/ext/dom/tests/dom_test.inc new file mode 100644 index 0000000..86b426f --- /dev/null +++ b/ext/dom/tests/dom_test.inc @@ -0,0 +1,47 @@ +<?PHP +$xmlstr = "<?xml version='1.0' standalone='yes'?> +<!DOCTYPE chapter SYSTEM '/share/sgml/Norman_Walsh/db3xml10/db3xml10.dtd' +[ <!ENTITY sp \"spanish\"> +]> +<!-- lsfj --> +<chapter language='en'><title language='en'>Title</title> +<para language='ge'> +&sp; +<!-- comment --> +<informaltable language='&sp;kkk'> +<tgroup cols='3'> +<tbody> +<row><entry>a1</entry><entry morerows='1'>b1</entry><entry>c1</entry></row> +<row><entry>a2</entry><entry>c2</entry></row> +<row><entry>a3</entry><entry>b3</entry><entry>c3</entry></row> +</tbody> +</tgroup> +</informaltable> +</para> +</chapter> "; + +function print_node($node) +{ + print "Node Name: " . $node->nodeName; + print "\nNode Type: " . $node->nodeType; + if ($node->nodeType != 3) { + $child_count = $node->childNodes->length; + } else { + $child_count = 0; + } + print "\nNum Children: " . $child_count; + if($child_count <= 1){ + print "\nNode Content: " . $node->nodeValue; + } + print "\n\n"; +} + +function print_node_list($nodelist) +{ + foreach($nodelist as $node) + { + print_node($node); + } +} + +?> diff --git a/ext/dom/tests/dom_xinclude.phpt b/ext/dom/tests/dom_xinclude.phpt new file mode 100644 index 0000000..5d8906e --- /dev/null +++ b/ext/dom/tests/dom_xinclude.phpt @@ -0,0 +1,42 @@ +--TEST-- +Test: Xinclude and Streams +--SKIPIF-- +<?php +require_once('skipif.inc'); +in_array('compress.zlib', stream_get_wrappers()) or die('skip compress.zlib wrapper is not available'); +?> +--FILE-- +<?php +$dom = new domdocument; + +$data = file_get_contents(dirname(__FILE__)."/xinclude.xml"); +$reldir = str_replace(getcwd(),".",dirname(__FILE__)); +if (DIRECTORY_SEPARATOR == '\\') { + $reldir = str_replace('\\',"/", $reldir); +} +$data = str_replace('compress.zlib://ext/dom/tests/','compress.zlib://'.$reldir."/", $data); + + +$dom->loadXML($data); +$dom->xinclude(); +print $dom->saveXML()."\n"; +foreach ($dom->documentElement->childNodes as $node) { + print $node->nodeName."\n"; +} +?> +--EXPECTF-- +<?xml version="1.0"?> +<foo xmlns:xi="http://www.w3.org/2001/XInclude"> + <book xml:base="compress.zlib://%sbook.xml"> + <title>The Grapes of Wrath</title> + <author>John Steinbeck</author> + </book><book xml:base="compress.zlib://%sbook.xml"> + <title>The Pearl</title> + <author>John Steinbeck</author> + </book> + </foo> + +#text +book +book +#text diff --git a/ext/dom/tests/domattributes.phpt b/ext/dom/tests/domattributes.phpt new file mode 100644 index 0000000..9097a88 --- /dev/null +++ b/ext/dom/tests/domattributes.phpt @@ -0,0 +1,43 @@ +--TEST-- +Attributes: DOMAttribute functionality +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +require_once("dom_test.inc"); + +$dom = new DOMDocument; +$dom->loadXML($xmlstr); +if(!$dom) { + echo "Error while parsing the document\n"; + exit; +} + +$node = $dom->documentElement; + +$lang = $node->getAttributeNode('language'); +echo "Language: ".$lang->value."\n"; + +$lang->value = 'en-US'; +echo "Language: ".$lang->value."\n"; + +$parent = $lang->ownerElement; + +$chapter = new DOMAttr("num", "1"); +$parent->setAttributeNode($chapter); + +echo "Is ID?: ".($chapter->isId()?'YES':'NO')."\n"; + +$top_element = $node->cloneNode(); + +print $dom->saveXML($top_element); + + +?> +--EXPECT-- + +Language: en +Language: en-US +Is ID?: NO +<chapter language="en-US" num="1"/> + diff --git a/ext/dom/tests/domchardata.phpt b/ext/dom/tests/domchardata.phpt new file mode 100644 index 0000000..6baff6d --- /dev/null +++ b/ext/dom/tests/domchardata.phpt @@ -0,0 +1,76 @@ +--TEST-- +CharData: DOMCharacterData and related functionality +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +require_once("dom_test.inc"); + +$dom = new DOMDocument; +$dom->loadXML($xmlstr); +if(!$dom) { + echo "Error while parsing the document\n"; + exit; +} + +$node = $dom->documentElement; + +$charnode = $dom->createElement('charnode'); +$node->appendChild($charnode); + +/* DOMComment */ +$comment = new DOMComment('Testing character data and extending nodes'); +$charnode->appendChild($comment); + +echo "Comment Length: ".$comment->length."\n"; + +$comment->data = 'Updated comment'; +echo "New Comment Length: ".$comment->length."\n"; +echo "New Comment Data: ".$comment->data."\n"; + +/* DOMCDataSection */ +$cdata = new DOMCDataSection('Chars: <>&"'); +$charnode->appendChild($cdata); + +echo "Substring: ".$cdata->substringData(7, 4)."\n"; +$cdata->replaceData(10, 1, "'"); +echo "New Substring: ".$cdata->substringData(7, 4)."\n"; + +/* DOMCharacterData using DOMComment */ +$comment = new DOMComment('instructions'); +echo "Comment Value: ".$comment->data."\n"; +$comment->data = 'some more instructions'; +echo "New Comment Value: ".$comment->data."\n"; + +$comment->insertData(10, 'pi '); +$comment->replaceData(18, 5, 'i'); +$comment->insertData(20, 'g'); +$comment->deleteData(13, 2); +$comment->deleteData(10, 3); +$comment->insertData(10, 'comment '); +echo "Updated Comment Value: ".$comment->data."\n"; + +/* DOMText */ +$text = new DOMText('some text characters'); + +echo "Whole Text: ".$text->wholeText."\n"; +$text2 = $text->splitText(9); + +echo "Split text: ".$text2->wholeText."\n"; +$text3 = $text2->splitText(1); + +echo "Is Whitespace?: ".($text2->isElementContentWhitespace()?'YES':'NO'); +?> +--EXPECT-- + +Comment Length: 42 +New Comment Length: 15 +New Comment Data: Updated comment +Substring: <>&" +New Substring: <>&' +Comment Value: instructions +New Comment Value: some more instructions +Updated Comment Value: some more comment strings +Whole Text: some text characters +Split text: characters +Is Whitespace?: YES diff --git a/ext/dom/tests/domdocument_createcomment_error_001.phpt b/ext/dom/tests/domdocument_createcomment_error_001.phpt new file mode 100644 index 0000000..24104a1 --- /dev/null +++ b/ext/dom/tests/domdocument_createcomment_error_001.phpt @@ -0,0 +1,16 @@ +--TEST-- +DomDocument::CreateComment() - Incorrect Parameters +--CREDITS-- +Clint Priest @ PhpTek09 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + $x = new DomDocument(); + $x->createComment(); +?> +===DONE=== +--EXPECTF-- +Warning: DOMDocument::createComment() expects exactly 1 parameter, 0 given in %s +===DONE=== +
\ No newline at end of file diff --git a/ext/dom/tests/domdocument_createentityreference_001.phpt b/ext/dom/tests/domdocument_createentityreference_001.phpt new file mode 100644 index 0000000..7343e74 --- /dev/null +++ b/ext/dom/tests/domdocument_createentityreference_001.phpt @@ -0,0 +1,18 @@ +--TEST-- +DomDocument::CreateEntityReference() - Creates an entity reference with the appropriate name +--CREDITS-- +Clint Priest @ PhpTek09 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + $objDoc = new DomDocument(); + + $objRef = $objDoc->createEntityReference('Test'); + echo $objRef->nodeName . "\n"; +?> +===DONE=== +--EXPECT-- +Test +===DONE=== +
\ No newline at end of file diff --git a/ext/dom/tests/domdocument_createentityreference_002.phpt b/ext/dom/tests/domdocument_createentityreference_002.phpt new file mode 100644 index 0000000..a2416c2 --- /dev/null +++ b/ext/dom/tests/domdocument_createentityreference_002.phpt @@ -0,0 +1,17 @@ +--TEST-- +DomDocument::CreateEntityReference() - Empty Arguments +--CREDITS-- +Clint Priest @ PhpTek09 +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php + $objDoc = new DomDocument(); + + $objRef = $objDoc->createEntityReference(); +?> +===DONE=== +--EXPECTF-- +Warning: DOMDocument::createEntityReference() expects exactly 1 parameter, 0 given in %s +===DONE=== +
\ No newline at end of file diff --git a/ext/dom/tests/domelement.phpt b/ext/dom/tests/domelement.phpt new file mode 100644 index 0000000..bc69af6 --- /dev/null +++ b/ext/dom/tests/domelement.phpt @@ -0,0 +1,114 @@ +--TEST-- +Elements: DOMElement functionality +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +require_once("dom_test.inc"); + +$dom = new DOMDocument; +$dom->loadXML($xmlstr); +if(!$dom) { + echo "Error while parsing the document\n"; + exit; +} + +$node = $dom->documentElement; +echo "Tag Name: ".$node->tagName."\n"; + + +$node->setAttribute('num', '1'); +echo "Chapter: ".$node->getAttribute('num')."\n"; +echo 'Attribute num exists?: '.($node->hasAttribute('num')?'Yes':'No')."\n"; +$node->removeAttribute('num'); +echo "Chapter: ".$node->getAttribute('num')."\n"; +echo 'Attribute num exists?: '.($node->hasAttribute('num')?'Yes':'No')."\n"; + +echo "Language: ".$node->getAttribute('language')."\n"; +$lang = $node->getAttributeNode('language'); +$lang->nodeValue = 'en-US'; +$node->setAttributeNode($lang); +echo "Language: ".$node->getAttribute('language')."\n"; +$node->removeAttributeNode($lang); +echo "Language: ".$node->getAttribute('language')."\n"; + +echo "\n-- xml:lang --\n"; +$node->setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:lang', 'en'); +echo "Language: ".$node->getAttributeNS('http://www.w3.org/XML/1998/namespace', 'lang')."\n"; +echo 'Attribute xml:lang exists?: '.($node->hasAttributeNS('http://www.w3.org/XML/1998/namespace', 'lang')?'Yes':'No')."\n"; + +$node->removeAttributeNS('http://www.w3.org/XML/1998/namespace', 'lang'); +echo "Language: ".$node->getAttributeNS('http://www.w3.org/XML/1998/namespace', 'lang')."\n"; +echo 'Attribute xml:lang exists?: '.($node->hasAttributeNS('http://www.w3.org/XML/1998/namespace', 'lang')?'Yes':'No')."\n"; + +$lang = $dom->createAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:lang'); +$lang->nodeValue = 'en-GB'; +$node->setAttributeNodeNS($lang); +unset($lang); +echo "Language: ".$node->getAttributeNS('http://www.w3.org/XML/1998/namespace', 'lang')."\n"; +$lang = $node->getAttributeNodeNS('http://www.w3.org/XML/1998/namespace', 'lang'); +echo "Language: ".$lang->value."\n"; + +echo "\n-- Elements --\n"; +$rows = $node->getElementsByTagName('row'); +echo "Row Count: ".$rows->length."\n"; + +$element_ns = new DOMElement('newns:myelement', 'default content', 'urn::dummyns'); +$node->appendChild($element_ns); +$element_ns = new DOMElement('newns2:myelement', 'second default content', 'urn::dummyns'); +$node->appendChild($element_ns); + +$myelements = $node->getElementsByTagNameNS('urn::dummyns', 'myelement'); +$mylen = $myelements->length; +echo "myelements Count: ".$mylen."\n"; + +echo "\n-- IDs --\n"; +$node->setAttribute('idatt', 'n1'); +$node->setIdAttribute('idatt', TRUE); + +for ($x = 0; $x < $mylen; $x++) { + $current = $myelements->item($x); + $current->setAttributeNS('urn::dummyns', 'newns:idatt', 'n'.($x+2))."\n"; + $current->setIdAttributeNS('urn::dummyns', 'idatt', TRUE); +} + +echo 'Element Name: '.(($elem = $dom->getElementByID('n1'))?$elem->localName:'Not Found')."\n"; +$idatt = $node->getAttributeNode('idatt'); +$node->setIdAttributeNode($idatt, FALSE); +echo 'Element Name: '.(($elem = $dom->getElementByID('n1'))?$elem->localName:'Not Found')."\n"; + +echo 'Element Name: '.(($elem = $dom->getElementByID('n3'))?$elem->nodeName:'Not Found')."\n"; +for ($x = 0; $x < $mylen; $x++) { + $node = $myelements->item($x); + $node->setIdAttributeNS('urn::dummyns', 'idatt', FALSE); +} +echo 'Element Name: '.(($elem = $dom->getElementByID('n3'))?$elem->nodeName:'Not Found')."\n"; +?> +--EXPECT-- + +Tag Name: chapter +Chapter: 1 +Attribute num exists?: Yes +Chapter: +Attribute num exists?: No +Language: en +Language: en-US +Language: + +-- xml:lang -- +Language: en +Attribute xml:lang exists?: Yes +Language: +Attribute xml:lang exists?: No +Language: en-GB +Language: en-GB + +-- Elements -- +Row Count: 3 +myelements Count: 2 + +-- IDs -- +Element Name: chapter +Element Name: Not Found +Element Name: newns2:myelement +Element Name: Not Found diff --git a/ext/dom/tests/domobject_debug_handler.phpt b/ext/dom/tests/domobject_debug_handler.phpt new file mode 100644 index 0000000..3c9f133 --- /dev/null +++ b/ext/dom/tests/domobject_debug_handler.phpt @@ -0,0 +1,59 @@ +--TEST-- +Objects of DOM extension: debug info object handler. +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +$xml = <<<XML +<foo> + <bar>foobar</bar> +</foo> +XML; +$d = new domdocument; +$d->dynamicProperty = new stdclass; +$d->loadXML($xml); +print_r($d); +--EXPECTF-- +DOMDocument Object +( + [dynamicProperty] => stdClass Object + ( + ) + + [doctype] => + [implementation] => (object value omitted) + [documentElement] => (object value omitted) + [actualEncoding] => + [encoding] => + [xmlEncoding] => + [standalone] => 1 + [xmlStandalone] => 1 + [version] => 1.0 + [xmlVersion] => 1.0 + [strictErrorChecking] => 1 + [documentURI] => %s + [config] => + [formatOutput] => + [validateOnParse] => + [resolveExternals] => + [preserveWhiteSpace] => 1 + [recover] => + [substituteEntities] => + [nodeName] => #document + [nodeValue] => + [nodeType] => 9 + [parentNode] => + [childNodes] => (object value omitted) + [firstChild] => (object value omitted) + [lastChild] => (object value omitted) + [previousSibling] => + [attributes] => + [ownerDocument] => + [namespaceURI] => + [prefix] => + [localName] => + [baseURI] => %s + [textContent] => + foobar + +) diff --git a/ext/dom/tests/domxpath.phpt b/ext/dom/tests/domxpath.phpt new file mode 100644 index 0000000..82396b5 --- /dev/null +++ b/ext/dom/tests/domxpath.phpt @@ -0,0 +1,58 @@ +--TEST-- +DOMXPath Tests +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +require_once("dom_test.inc"); + +function MyAverage($nodelist) { + $count = 0; + $val = 0; + foreach ($nodelist AS $node) { + $count++; + $val += $node->textContent; + } + if ($val > 0) { + return $val/$count; + } else { + return 0; + } +} + +$dom = new DOMDocument; +$dom->loadXML(b'<root xmlns="urn::default"><child>myval</child></root>'); + +$xpath = new DOMXPath($dom); + +$xpath->registerPHPFunctions('MyAverage'); +$xpath->registerNamespace("php", "http://php.net/xpath"); + +$xpath->registerNamespace("def", "urn::default"); +$nodelist = $xpath->query("//def:child"); +if ($node = $nodelist->item(0)) { + print $node->textContent."\n"; +} + +$count = $xpath->evaluate("count(//def:child)"); + +var_dump($count); + +$xpathdoc = $xpath->document; + +var_dump($xpathdoc instanceof DOMDocument); + +$root = $dom->documentElement; +$root->appendChild($dom->createElementNS("urn::default", "testnode", 3)); +$root->appendChild($dom->createElementNS("urn::default", "testnode", 4)); +$root->appendChild($dom->createElementNS("urn::default", "testnode", 4)); +$root->appendChild($dom->createElementNS("urn::default", "testnode", 5)); + +$avg = $xpath->evaluate('number(php:function("MyAverage", //def:testnode))'); +var_dump($avg); +?> +--EXPECT-- +myval +float(1) +bool(true) +float(4)
\ No newline at end of file diff --git a/ext/dom/tests/note.dtd b/ext/dom/tests/note.dtd new file mode 100644 index 0000000..c2d558e --- /dev/null +++ b/ext/dom/tests/note.dtd @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!ELEMENT note (to,from,heading,body)> +<!ELEMENT to (#PCDATA)> +<!ELEMENT from (#PCDATA)> +<!ELEMENT heading (#PCDATA)> +<!ELEMENT body (#PCDATA)> diff --git a/ext/dom/tests/note.xml b/ext/dom/tests/note.xml new file mode 100644 index 0000000..49614a1 --- /dev/null +++ b/ext/dom/tests/note.xml @@ -0,0 +1,8 @@ +<?xml version="1.0"?> +<!DOCTYPE note SYSTEM "note.dtd"> +<note> +<to>PHP User Group</to> +<from>Shane</from> +<heading>Reminder</heading> +<body>Don't forget the meeting tonight!</body> +</note> diff --git a/ext/dom/tests/nsdoc.xml b/ext/dom/tests/nsdoc.xml new file mode 100644 index 0000000..9503fd8 --- /dev/null +++ b/ext/dom/tests/nsdoc.xml @@ -0,0 +1,4 @@ +<?xml version="1.0"?> +<root xmlns="http://ns" xmlns:ns2="http://ns2"> + <ns2:child /> +</root>
\ No newline at end of file diff --git a/ext/dom/tests/regsiter_node_class.phpt b/ext/dom/tests/regsiter_node_class.phpt new file mode 100644 index 0000000..c632c61 --- /dev/null +++ b/ext/dom/tests/regsiter_node_class.phpt @@ -0,0 +1,40 @@ +--TEST-- +Test: registerNodeClass() +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +class myAttribute extends DOMAttr { + function testit() { return "HELLO Attribute"; } +} + +class myElement extends DOMElement { + function testit() { return "HELLO Element"; } +} + +$doc = new DOMDocument(); +$doc->registerNodeClass('DOMAttr', 'myAttribute'); +$doc->registerNodeClass('DOMElement', 'myElement'); +$doc->appendChild(new DOMElement('root')); +$root = $doc->documentElement; +$root->setAttribute('a', 'a1'); +echo get_class($root), "\n"; +print $root->testit()."\n"; +$attr = $root->getAttributeNode('a'); +echo get_class($attr), "\n"; +print $attr->testit()."\n"; +unset($attr); +$doc->registerNodeClass('DOMAttr', NULL); +$attr = $root->getAttributeNode('a'); +echo get_class($attr), "\n"; +print $attr->testit()."\n"; +?> +--EXPECTF-- + +myElement +HELLO Element +myAttribute +HELLO Attribute +DOMAttr + +Fatal error: Call to undefined method DOMAttr::testit() in %s on line 25 diff --git a/ext/dom/tests/skipif.inc b/ext/dom/tests/skipif.inc new file mode 100644 index 0000000..08fd695 --- /dev/null +++ b/ext/dom/tests/skipif.inc @@ -0,0 +1 @@ +<?php if (!extension_loaded('dom')) die('skip dom extension not available');?>
\ No newline at end of file diff --git a/ext/dom/tests/test.html b/ext/dom/tests/test.html new file mode 100644 index 0000000..fe6d0d3 --- /dev/null +++ b/ext/dom/tests/test.html @@ -0,0 +1,9 @@ +<html> +<head> +<title>Hello world</title> +</head> +<body> +This is a not well-formed<br> +html files with undeclared entities +</body> +</html> diff --git a/ext/dom/tests/xinclude.xml b/ext/dom/tests/xinclude.xml new file mode 100644 index 0000000..27efa91 --- /dev/null +++ b/ext/dom/tests/xinclude.xml @@ -0,0 +1,4 @@ +<?xml version="1.0"?> +<foo xmlns:xi="http://www.w3.org/2001/XInclude"> + <xi:include href="compress.zlib://ext/dom/tests/book.xml#xpointer(/books/book)"/> + </foo> diff --git a/ext/dom/text.c b/ext/dom/text.c new file mode 100644 index 0000000..f608997 --- /dev/null +++ b/ext/dom/text.c @@ -0,0 +1,245 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" +#include "dom_ce.h" + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_text_split_text, 0, 0, 1) + ZEND_ARG_INFO(0, offset) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_text_is_whitespace_in_element_content, 0, 0, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_text_replace_whole_text, 0, 0, 1) + ZEND_ARG_INFO(0, content) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_text_construct, 0, 0, 0) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO(); +/* }}} */ + +/* +* class DOMText extends DOMCharacterData +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-1312295772 +* Since: +*/ + +const zend_function_entry php_dom_text_class_functions[] = { + PHP_FALIAS(splitText, dom_text_split_text, arginfo_dom_text_split_text) + PHP_FALIAS(isWhitespaceInElementContent, dom_text_is_whitespace_in_element_content, arginfo_dom_text_is_whitespace_in_element_content) + PHP_FALIAS(isElementContentWhitespace, dom_text_is_whitespace_in_element_content, arginfo_dom_text_is_whitespace_in_element_content) + PHP_FALIAS(replaceWholeText, dom_text_replace_whole_text, arginfo_dom_text_replace_whole_text) + PHP_ME(domtext, __construct, arginfo_dom_text_construct, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +/* {{{ proto void DOMText::__construct([string value]); */ +PHP_METHOD(domtext, __construct) +{ + + zval *id; + xmlNodePtr nodep = NULL, oldnode = NULL; + dom_object *intern; + char *value = NULL; + int value_len; + zend_error_handling error_handling; + + zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC); + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|s", &id, dom_text_class_entry, &value, &value_len) == FAILURE) { + zend_restore_error_handling(&error_handling TSRMLS_CC); + return; + } + + zend_restore_error_handling(&error_handling TSRMLS_CC); + nodep = xmlNewText((xmlChar *) value); + + if (!nodep) { + php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC); + RETURN_FALSE; + } + + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + if (intern != NULL) { + oldnode = dom_object_get_node(intern); + if (oldnode != NULL) { + php_libxml_node_free_resource(oldnode TSRMLS_CC); + } + php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC); + } +} +/* }}} end DOMText::__construct */ + +/* {{{ wholeText string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Text3-wholeText +Since: DOM Level 3 +*/ +int dom_text_whole_text_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlNodePtr node; + xmlChar *wholetext = NULL; + + node = dom_object_get_node(obj); + + if (node == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + /* Find starting text node */ + while (node->prev && ((node->prev->type == XML_TEXT_NODE) || (node->prev->type == XML_CDATA_SECTION_NODE))) { + node = node->prev; + } + + /* concatenate all adjacent text and cdata nodes */ + while (node && ((node->type == XML_TEXT_NODE) || (node->type == XML_CDATA_SECTION_NODE))) { + wholetext = xmlStrcat(wholetext, node->content); + node = node->next; + } + + ALLOC_ZVAL(*retval); + if (wholetext != NULL) { + ZVAL_STRING(*retval, wholetext, 1); + xmlFree(wholetext); + } else { + ZVAL_EMPTY_STRING(*retval); + } + + return SUCCESS; +} + +/* }}} */ + +/* {{{ proto DOMText dom_text_split_text(int offset); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-38853C1D +Since: +*/ +PHP_FUNCTION(dom_text_split_text) +{ + zval *id; + xmlChar *cur; + xmlChar *first; + xmlChar *second; + xmlNodePtr node; + xmlNodePtr nnode; + long offset; + int ret; + int length; + dom_object *intern; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &id, dom_text_class_entry, &offset) == FAILURE) { + return; + } + DOM_GET_OBJ(node, id, xmlNodePtr, intern); + + if (node->type != XML_TEXT_NODE && node->type != XML_CDATA_SECTION_NODE) { + RETURN_FALSE; + } + + cur = xmlNodeGetContent(node); + if (cur == NULL) { + RETURN_FALSE; + } + length = xmlUTF8Strlen(cur); + + if (offset > length || offset < 0) { + xmlFree(cur); + RETURN_FALSE; + } + + first = xmlUTF8Strndup(cur, offset); + second = xmlUTF8Strsub(cur, offset, length - offset); + + xmlFree(cur); + + xmlNodeSetContent(node, first); + nnode = xmlNewDocText(node->doc, second); + + xmlFree(first); + xmlFree(second); + + if (nnode == NULL) { + RETURN_FALSE; + } + + if (node->parent != NULL) { + nnode->type = XML_ELEMENT_NODE; + xmlAddNextSibling(node, nnode); + nnode->type = XML_TEXT_NODE; + } + + return_value = php_dom_create_object(nnode, &ret, return_value, intern TSRMLS_CC); +} +/* }}} end dom_text_split_text */ + +/* {{{ proto boolean dom_text_is_whitespace_in_element_content(); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Text3-isWhitespaceInElementContent +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_text_is_whitespace_in_element_content) +{ + zval *id; + xmlNodePtr node; + dom_object *intern; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_text_class_entry) == FAILURE) { + return; + } + DOM_GET_OBJ(node, id, xmlNodePtr, intern); + + if (xmlIsBlankNode(node)) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} end dom_text_is_whitespace_in_element_content */ + +/* {{{ proto DOMText dom_text_replace_whole_text(string content); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Text3-replaceWholeText +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_text_replace_whole_text) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_text_replace_whole_text */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/typeinfo.c b/ext/dom/typeinfo.c new file mode 100644 index 0000000..bc0e608 --- /dev/null +++ b/ext/dom/typeinfo.c @@ -0,0 +1,83 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class domtypeinfo +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#TypeInfo +* Since: DOM Level 3 +*/ + +const zend_function_entry php_dom_typeinfo_class_functions[] = { + PHP_FE_END +}; + +/* {{{ attribute protos, not implemented yet */ + +/* {{{ type_name string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#TypeInfo-typeName +Since: +*/ +int dom_typeinfo_type_name_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_NULL(*retval); + return SUCCESS; +} + +/* }}} */ + +/* {{{ type_namespace string +readonly=yes +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#TypeInfo-typeNamespace +Since: +*/ +int dom_typeinfo_type_namespace_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_NULL(*retval); + return SUCCESS; +} + +/* }}} */ + +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/userdatahandler.c b/ext/dom/userdatahandler.c new file mode 100644 index 0000000..d368a29 --- /dev/null +++ b/ext/dom/userdatahandler.c @@ -0,0 +1,66 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class domuserdatahandler +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#UserDataHandler +* Since: DOM Level 3 +*/ + +const zend_function_entry php_dom_userdatahandler_class_functions[] = { + PHP_FALIAS(handle, dom_userdatahandler_handle, NULL) + PHP_FE_END +}; + +/* {{{ attribute protos, not implemented yet */ + +/* {{{ proto dom_void dom_userdatahandler_handle(short operation, string key, domobject data, node src, node dst); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-handleUserDataEvent +Since: +*/ +PHP_FUNCTION(dom_userdatahandler_handle) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_userdatahandler_handle */ + +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/xml_common.h b/ext/dom/xml_common.h new file mode 100644 index 0000000..87a41c5 --- /dev/null +++ b/ext/dom/xml_common.h @@ -0,0 +1,106 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef PHP_XML_COMMON_H +#define PHP_XML_COMMON_H + +#include "ext/libxml/php_libxml.h" + +typedef libxml_doc_props *dom_doc_propsptr; + +typedef struct _dom_object { + zend_object std; + void *ptr; + php_libxml_ref_obj *document; + HashTable *prop_handler; + zend_object_handle handle; +} dom_object; + +#ifdef PHP_WIN32 +# ifdef PHPAPI +# undef PHPAPI +# endif +# ifdef DOM_EXPORTS +# define PHPAPI __declspec(dllexport) +# else +# define PHPAPI __declspec(dllimport) +# endif /* DOM_EXPORTS */ +#elif defined(__GNUC__) && __GNUC__ >= 4 +# ifdef PHPAPI +# undef PHPAPI +# endif +# define PHPAPI __attribute__ ((visibility("default"))) +#endif /* PHP_WIN32 */ + +#define PHP_DOM_EXPORT PHPAPI + +PHP_DOM_EXPORT extern zend_class_entry *dom_node_class_entry; +PHP_DOM_EXPORT dom_object *php_dom_object_get_data(xmlNodePtr obj); +PHP_DOM_EXPORT zval *php_dom_create_object(xmlNodePtr obj, int *found, zval* return_value, dom_object *domobj TSRMLS_DC); +PHP_DOM_EXPORT xmlNodePtr dom_object_get_node(dom_object *obj); + +#define DOM_XMLNS_NAMESPACE \ + (const xmlChar *) "http://www.w3.org/2000/xmlns/" + +#define NODE_GET_OBJ(__ptr, __id, __prtype, __intern) { \ + __intern = (php_libxml_node_object *)zend_object_store_get_object(__id TSRMLS_CC); \ + if (__intern->node == NULL || !(__ptr = (__prtype)__intern->node->node)) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", __intern->std.ce->name);\ + RETURN_NULL();\ + } \ +} + +#define DOC_GET_OBJ(__ptr, __id, __prtype, __intern) { \ + __intern = (php_libxml_node_object *)zend_object_store_get_object(__id TSRMLS_CC); \ + if (__intern->document != NULL) { \ + if (!(__ptr = (__prtype)__intern->document->ptr)) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", __intern->std.ce->name);\ + RETURN_NULL();\ + } \ + } \ +} + +#define DOM_RET_OBJ(obj, ret, domobject) \ + if (!php_dom_create_object(obj, ret, return_value, domobject TSRMLS_CC)) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); \ + RETURN_FALSE; \ + } + +#define DOM_GET_THIS(zval) \ + if (NULL == (zval = getThis())) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Underlying object missing"); \ + RETURN_FALSE; \ + } + +#define DOM_GET_THIS_OBJ(__ptr, __id, __prtype, __intern) \ + DOM_GET_THIS(__id); \ + DOM_GET_OBJ(__ptr, __id, __prtype, __intern); + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/dom/xpath.c b/ext/dom/xpath.c new file mode 100644 index 0000000..cf556a3 --- /dev/null +++ b/ext/dom/xpath.c @@ -0,0 +1,602 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + +#define PHP_DOM_XPATH_QUERY 0 +#define PHP_DOM_XPATH_EVALUATE 1 + +/* +* class DOMXPath +*/ + +#if defined(LIBXML_XPATH_ENABLED) + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_xpath_construct, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, doc, DOMDocument, 0) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_xpath_register_ns, 0, 0, 2) + ZEND_ARG_INFO(0, prefix) + ZEND_ARG_INFO(0, uri) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_xpath_query, 0, 0, 1) + ZEND_ARG_INFO(0, expr) + ZEND_ARG_OBJ_INFO(0, context, DOMNode, 1) + ZEND_ARG_INFO(0, registerNodeNS) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_xpath_evaluate, 0, 0, 1) + ZEND_ARG_INFO(0, expr) + ZEND_ARG_OBJ_INFO(0, context, DOMNode, 1) + ZEND_ARG_INFO(0, registerNodeNS) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_xpath_register_php_functions, 0, 0, 0) +ZEND_END_ARG_INFO(); +/* }}} */ + +const zend_function_entry php_dom_xpath_class_functions[] = { + PHP_ME(domxpath, __construct, arginfo_dom_xpath_construct, ZEND_ACC_PUBLIC) + PHP_FALIAS(registerNamespace, dom_xpath_register_ns, arginfo_dom_xpath_register_ns) + PHP_FALIAS(query, dom_xpath_query, arginfo_dom_xpath_query) + PHP_FALIAS(evaluate, dom_xpath_evaluate, arginfo_dom_xpath_evaluate) + PHP_FALIAS(registerPhpFunctions, dom_xpath_register_php_functions, arginfo_dom_xpath_register_php_functions) + PHP_FE_END +}; + + +static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */ +{ + zval **args; + zval *retval; + int result, i, ret; + int error = 0; + zend_fcall_info fci; + zval handler; + xmlXPathObjectPtr obj; + char *str; + char *callable = NULL; + dom_xpath_object *intern; + + TSRMLS_FETCH(); + + if (! zend_is_executing(TSRMLS_C)) { + xmlGenericError(xmlGenericErrorContext, + "xmlExtFunctionTest: Function called from outside of PHP\n"); + error = 1; + } else { + intern = (dom_xpath_object *) ctxt->context->userData; + if (intern == NULL) { + xmlGenericError(xmlGenericErrorContext, + "xmlExtFunctionTest: failed to get the internal object\n"); + error = 1; + } + else if (intern->registerPhpFunctions == 0) { + xmlGenericError(xmlGenericErrorContext, + "xmlExtFunctionTest: PHP Object did not register PHP functions\n"); + error = 1; + } + } + + if (error == 1) { + for (i = nargs - 1; i >= 0; i--) { + obj = valuePop(ctxt); + xmlXPathFreeObject(obj); + } + return; + } + + fci.param_count = nargs - 1; + if (fci.param_count > 0) { + fci.params = safe_emalloc(fci.param_count, sizeof(zval**), 0); + args = safe_emalloc(fci.param_count, sizeof(zval *), 0); + } + /* Reverse order to pop values off ctxt stack */ + for (i = nargs - 2; i >= 0; i--) { + obj = valuePop(ctxt); + MAKE_STD_ZVAL(args[i]); + switch (obj->type) { + case XPATH_STRING: + ZVAL_STRING(args[i], (char *)obj->stringval, 1); + break; + case XPATH_BOOLEAN: + ZVAL_BOOL(args[i], obj->boolval); + break; + case XPATH_NUMBER: + ZVAL_DOUBLE(args[i], obj->floatval); + break; + case XPATH_NODESET: + if (type == 1) { + str = (char *)xmlXPathCastToString(obj); + ZVAL_STRING(args[i], str, 1); + xmlFree(str); + } else if (type == 2) { + int j; + array_init(args[i]); + if (obj->nodesetval && obj->nodesetval->nodeNr > 0) { + for (j = 0; j < obj->nodesetval->nodeNr; j++) { + xmlNodePtr node = obj->nodesetval->nodeTab[j]; + zval *child; + MAKE_STD_ZVAL(child); + /* not sure, if we need this... it's copied from xpath.c */ + if (node->type == XML_NAMESPACE_DECL) { + xmlNsPtr curns; + xmlNodePtr nsparent; + + nsparent = node->_private; + curns = xmlNewNs(NULL, node->name, NULL); + if (node->children) { + curns->prefix = xmlStrdup((xmlChar *) node->children); + } + if (node->children) { + node = xmlNewDocNode(node->doc, NULL, (xmlChar *) node->children, node->name); + } else { + node = xmlNewDocNode(node->doc, NULL, (xmlChar *) "xmlns", node->name); + } + node->type = XML_NAMESPACE_DECL; + node->parent = nsparent; + node->ns = curns; + } + child = php_dom_create_object(node, &ret, child, (dom_object *)intern TSRMLS_CC); + add_next_index_zval(args[i], child); + } + } + } + break; + default: + ZVAL_STRING(args[i], (char *)xmlXPathCastToString(obj), 1); + } + xmlXPathFreeObject(obj); + fci.params[i] = &args[i]; + } + + fci.size = sizeof(fci); + fci.function_table = EG(function_table); + + obj = valuePop(ctxt); + if (obj->stringval == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Handler name must be a string"); + xmlXPathFreeObject(obj); + if (fci.param_count > 0) { + for (i = 0; i < nargs - 1; i++) { + zval_ptr_dtor(&args[i]); + } + efree(args); + efree(fci.params); + } + return; + } + INIT_PZVAL(&handler); + ZVAL_STRING(&handler, obj->stringval, 1); + xmlXPathFreeObject(obj); + + fci.function_name = &handler; + fci.symbol_table = NULL; + fci.object_ptr = NULL; + fci.retval_ptr_ptr = &retval; + fci.no_separation = 0; + + if (!zend_make_callable(&handler, &callable TSRMLS_CC)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", callable); + + } else if ( intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable, strlen(callable) + 1) == 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not allowed to call handler '%s()'.", callable); + /* Push an empty string, so that we at least have an xslt result... */ + valuePush(ctxt, xmlXPathNewString((xmlChar *)"")); + } else { + result = zend_call_function(&fci, NULL TSRMLS_CC); + if (result == FAILURE) { + if (Z_TYPE(handler) == IS_STRING) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", Z_STRVAL_P(&handler)); + } + /* retval is == NULL, when an exception occurred, don't report anything, because PHP itself will handle that */ + } else if (retval == NULL) { + } else { + if (retval->type == IS_OBJECT && instanceof_function( Z_OBJCE_P(retval), dom_node_class_entry TSRMLS_CC)) { + xmlNode *nodep; + dom_object *obj; + if (intern->node_list == NULL) { + ALLOC_HASHTABLE(intern->node_list); + zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0); + } + zval_add_ref(&retval); + zend_hash_next_index_insert(intern->node_list, &retval, sizeof(zval *), NULL); + obj = (dom_object *)zend_object_store_get_object(retval TSRMLS_CC); + nodep = dom_object_get_node(obj); + valuePush(ctxt, xmlXPathNewNodeSet(nodep)); + } else if (retval->type == IS_BOOL) { + valuePush(ctxt, xmlXPathNewBoolean(retval->value.lval)); + } else if (retval->type == IS_OBJECT) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "A PHP Object cannot be converted to a XPath-string"); + valuePush(ctxt, xmlXPathNewString((xmlChar *)"")); + } else { + convert_to_string_ex(&retval); + valuePush(ctxt, xmlXPathNewString( Z_STRVAL_P(retval))); + } + zval_ptr_dtor(&retval); + } + } + efree(callable); + zval_dtor(&handler); + if (fci.param_count > 0) { + for (i = 0; i < nargs - 1; i++) { + zval_ptr_dtor(&args[i]); + } + efree(args); + efree(fci.params); + } +} +/* }}} */ + +static void dom_xpath_ext_function_string_php(xmlXPathParserContextPtr ctxt, int nargs) /* {{{ */ +{ + dom_xpath_ext_function_php(ctxt, nargs, 1); +} +/* }}} */ + +static void dom_xpath_ext_function_object_php(xmlXPathParserContextPtr ctxt, int nargs) /* {{{ */ +{ + dom_xpath_ext_function_php(ctxt, nargs, 2); +} +/* }}} */ + +/* {{{ proto void DOMXPath::__construct(DOMDocument doc) U */ +PHP_METHOD(domxpath, __construct) +{ + zval *id, *doc; + xmlDocPtr docp = NULL; + dom_object *docobj; + dom_xpath_object *intern; + xmlXPathContextPtr ctx, oldctx; + zend_error_handling error_handling; + + zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC); + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_xpath_class_entry, &doc, dom_document_class_entry) == FAILURE) { + zend_restore_error_handling(&error_handling TSRMLS_CC); + return; + } + + zend_restore_error_handling(&error_handling TSRMLS_CC); + DOM_GET_OBJ(docp, doc, xmlDocPtr, docobj); + + ctx = xmlXPathNewContext(docp); + if (ctx == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC); + RETURN_FALSE; + } + + intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC); + if (intern != NULL) { + oldctx = (xmlXPathContextPtr)intern->ptr; + if (oldctx != NULL) { + php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC); + xmlXPathFreeContext(oldctx); + } + + xmlXPathRegisterFuncNS (ctx, (const xmlChar *) "functionString", + (const xmlChar *) "http://php.net/xpath", + dom_xpath_ext_function_string_php); + xmlXPathRegisterFuncNS (ctx, (const xmlChar *) "function", + (const xmlChar *) "http://php.net/xpath", + dom_xpath_ext_function_object_php); + + intern->ptr = ctx; + ctx->userData = (void *)intern; + intern->document = docobj->document; + php_libxml_increment_doc_ref((php_libxml_node_object *)intern, docp TSRMLS_CC); + } +} +/* }}} end DOMXPath::__construct */ + +/* {{{ document DOMDocument*/ +int dom_xpath_document_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + xmlDoc *docp = NULL; + xmlXPathContextPtr ctx; + int ret; + zval *tmp; + + ctx = (xmlXPathContextPtr) obj->ptr; + + if (ctx) { + docp = (xmlDocPtr) ctx->doc; + } + + ALLOC_ZVAL(*retval); + tmp = *retval; + + if (NULL == (*retval = php_dom_create_object((xmlNodePtr) docp, &ret, *retval, obj TSRMLS_CC))) { + FREE_ZVAL(tmp); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); + return FAILURE; + } + if (tmp != *retval) { + FREE_ZVAL(tmp); + } + return SUCCESS; +} +/* }}} */ + +/* {{{ proto boolean dom_xpath_register_ns(string prefix, string uri); */ +PHP_FUNCTION(dom_xpath_register_ns) +{ + zval *id; + xmlXPathContextPtr ctxp; + int prefix_len, ns_uri_len; + dom_xpath_object *intern; + unsigned char *prefix, *ns_uri; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_xpath_class_entry, &prefix, &prefix_len, &ns_uri, &ns_uri_len) == FAILURE) { + return; + } + + intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC); + + ctxp = (xmlXPathContextPtr) intern->ptr; + if (ctxp == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid XPath Context"); + RETURN_FALSE; + } + + if (xmlXPathRegisterNs(ctxp, prefix, ns_uri) != 0) { + RETURN_FALSE + } + RETURN_TRUE; +} +/* }}} */ + +static void dom_xpath_iter(zval *baseobj, dom_object *intern) /* {{{ */ +{ + dom_nnodemap_object *mapptr; + + mapptr = (dom_nnodemap_object *)intern->ptr; + mapptr->baseobjptr = baseobj; + mapptr->nodetype = DOM_NODESET; + +} +/* }}} */ + +static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ +{ + zval *id, *retval, *context = NULL; + xmlXPathContextPtr ctxp; + xmlNodePtr nodep = NULL; + xmlXPathObjectPtr xpathobjp; + int expr_len, ret, nsnbr = 0, xpath_type; + dom_xpath_object *intern; + dom_object *nodeobj; + char *expr; + xmlDoc *docp = NULL; + xmlNsPtr *ns = NULL; + zend_bool register_node_ns = 1; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|O!b", &id, dom_xpath_class_entry, &expr, &expr_len, &context, dom_node_class_entry, ®ister_node_ns) == FAILURE) { + return; + } + + intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC); + + ctxp = (xmlXPathContextPtr) intern->ptr; + if (ctxp == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid XPath Context"); + RETURN_FALSE; + } + + docp = (xmlDocPtr) ctxp->doc; + if (docp == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid XPath Document Pointer"); + RETURN_FALSE; + } + + if (context != NULL) { + DOM_GET_OBJ(nodep, context, xmlNodePtr, nodeobj); + } + + if (!nodep) { + nodep = xmlDocGetRootElement(docp); + } + + if (nodep && docp != nodep->doc) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Node From Wrong Document"); + RETURN_FALSE; + } + + ctxp->node = nodep; + + if (register_node_ns) { + /* Register namespaces in the node */ + ns = xmlGetNsList(docp, nodep); + + if (ns != NULL) { + while (ns[nsnbr] != NULL) + nsnbr++; + } + } + + + ctxp->namespaces = ns; + ctxp->nsNr = nsnbr; + + xpathobjp = xmlXPathEvalExpression(expr, ctxp); + ctxp->node = NULL; + + if (ns != NULL) { + xmlFree(ns); + ctxp->namespaces = NULL; + ctxp->nsNr = 0; + } + + if (! xpathobjp) { + RETURN_FALSE; + } + + if (type == PHP_DOM_XPATH_QUERY) { + xpath_type = XPATH_NODESET; + } else { + xpath_type = xpathobjp->type; + } + + switch (xpath_type) { + + case XPATH_NODESET: + { + int i; + xmlNodeSetPtr nodesetp; + + MAKE_STD_ZVAL(retval); + array_init(retval); + + if (xpathobjp->type == XPATH_NODESET && NULL != (nodesetp = xpathobjp->nodesetval)) { + + for (i = 0; i < nodesetp->nodeNr; i++) { + xmlNodePtr node = nodesetp->nodeTab[i]; + zval *child; + + MAKE_STD_ZVAL(child); + + if (node->type == XML_NAMESPACE_DECL) { + xmlNsPtr curns; + xmlNodePtr nsparent; + + nsparent = node->_private; + curns = xmlNewNs(NULL, node->name, NULL); + if (node->children) { + curns->prefix = xmlStrdup((char *) node->children); + } + if (node->children) { + node = xmlNewDocNode(docp, NULL, (char *) node->children, node->name); + } else { + node = xmlNewDocNode(docp, NULL, "xmlns", node->name); + } + node->type = XML_NAMESPACE_DECL; + node->parent = nsparent; + node->ns = curns; + } + child = php_dom_create_object(node, &ret, child, (dom_object *)intern TSRMLS_CC); + add_next_index_zval(retval, child); + } + } + php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC); + nodeobj = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC); + dom_xpath_iter(retval, nodeobj); + break; + } + + case XPATH_BOOLEAN: + RETVAL_BOOL(xpathobjp->boolval); + break; + + case XPATH_NUMBER: + RETVAL_DOUBLE(xpathobjp->floatval) + break; + + case XPATH_STRING: + RETVAL_STRING(xpathobjp->stringval, 1); + break; + + default: + RETVAL_NULL(); + break; + } + + xmlXPathFreeObject(xpathobjp); +} +/* }}} */ + +/* {{{ proto DOMNodeList dom_xpath_query(string expr [,DOMNode context [, boolean registerNodeNS]]); */ +PHP_FUNCTION(dom_xpath_query) +{ + php_xpath_eval(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_DOM_XPATH_QUERY); +} +/* }}} end dom_xpath_query */ + +/* {{{ proto mixed dom_xpath_evaluate(string expr [,DOMNode context [, boolean registerNodeNS]]); */ +PHP_FUNCTION(dom_xpath_evaluate) +{ + php_xpath_eval(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_DOM_XPATH_EVALUATE); +} +/* }}} end dom_xpath_evaluate */ + +/* {{{ proto void dom_xpath_register_php_functions() */ +PHP_FUNCTION(dom_xpath_register_php_functions) +{ + zval *id; + dom_xpath_object *intern; + zval *array_value, **entry, *new_string; + int name_len = 0; + char *name; + + DOM_GET_THIS(id); + + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "a", &array_value) == SUCCESS) { + intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC); + zend_hash_internal_pointer_reset(Z_ARRVAL_P(array_value)); + + while (zend_hash_get_current_data(Z_ARRVAL_P(array_value), (void **)&entry) == SUCCESS) { + SEPARATE_ZVAL(entry); + convert_to_string_ex(entry); + + MAKE_STD_ZVAL(new_string); + ZVAL_LONG(new_string,1); + + zend_hash_update(intern->registered_phpfunctions, Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) + 1, &new_string, sizeof(zval*), NULL); + zend_hash_move_forward(Z_ARRVAL_P(array_value)); + } + intern->registerPhpFunctions = 2; + RETURN_TRUE; + + } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == SUCCESS) { + intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC); + + MAKE_STD_ZVAL(new_string); + ZVAL_LONG(new_string,1); + zend_hash_update(intern->registered_phpfunctions, name, name_len + 1, &new_string, sizeof(zval*), NULL); + intern->registerPhpFunctions = 2; + + } else { + intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC); + intern->registerPhpFunctions = 1; + } + +} +/* }}} end dom_xpath_register_php_functions */ + +#endif /* LIBXML_XPATH_ENABLED */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ |