diff options
author | Mark A. Hershberger <mah@debian.(none)> | 2009-03-25 00:34:21 -0400 |
---|---|---|
committer | Mark A. Hershberger <mah@debian.(none)> | 2009-03-25 00:34:21 -0400 |
commit | 0e920280a2e04b110827bb766b9f29e3d581c4ee (patch) | |
tree | 8f2125f3d00fe3089e3b94adb06f04479ee15f2a /ext/dom | |
download | php-0e920280a2e04b110827bb766b9f29e3d581c4ee.tar.gz |
Imported Upstream version 5.0.4upstream/5.0.4
Diffstat (limited to 'ext/dom')
73 files changed, 13152 insertions, 0 deletions
diff --git a/ext/dom/CREDITS b/ext/dom/CREDITS new file mode 100644 index 000000000..b78e376d6 --- /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 000000000..52afb1821 --- /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 000000000..530c99f24 --- /dev/null +++ b/ext/dom/attr.c @@ -0,0 +1,283 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: attr.c,v 1.15.2.1 2004/11/18 19:55:00 rrichards Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#if HAVE_LIBXML && HAVE_DOM + +#include "php_dom.h" + + +/* +* class DOMAttr extends DOMNode +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-637646024 +* Since: +*/ + +zend_function_entry php_dom_attr_class_functions[] = { + PHP_FALIAS(isId, dom_attr_is_id, NULL) + PHP_ME(domattr, __construct, NULL, ZEND_ACC_PUBLIC) + {NULL, NULL, NULL} +}; + +/* {{{ 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; + + php_set_error_handling(EH_THROW, dom_domexception_class_entry 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) { + php_std_error_handling(); + return; + } + + php_std_error_handling(); + 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 = (xmlNodePtr)intern->ptr; + 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(newval->refcount > 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; + } + + nodeparent = nodep->parent; + if (!nodeparent) { + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + if (NULL == (*retval = php_dom_create_object(nodeparent, &ret, NULL, *retval, obj TSRMLS_CC))) { + php_error(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; + xmlNodePtr nodep; + + 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); + + nodep = attrp->parent; + + if (xmlIsID(attrp->doc, nodep, attrp)) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} end dom_attr_is_id */ + +#endif diff --git a/ext/dom/cdatasection.c b/ext/dom/cdatasection.c new file mode 100644 index 000000000..0429e7638 --- /dev/null +++ b/ext/dom/cdatasection.c @@ -0,0 +1,78 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: cdatasection.c,v 1.10 2004/05/31 12:50:28 rrichards Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class DOMCdataSection extends DOMText +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-667469212 +* Since: +*/ + +zend_function_entry php_dom_cdatasection_class_functions[] = { + PHP_ME(domcdatasection, __construct, NULL, ZEND_ACC_PUBLIC) + {NULL, NULL, NULL} +}; + +/* {{{ 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; + + php_set_error_handling(EH_THROW, dom_domexception_class_entry TSRMLS_CC); + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_cdatasection_class_entry, &value, &value_len) == FAILURE) { + php_std_error_handling(); + return; + } + + php_std_error_handling(); + 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 = (xmlNodePtr)intern->ptr; + 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 diff --git a/ext/dom/characterdata.c b/ext/dom/characterdata.c new file mode 100644 index 000000000..8ebec1c06 --- /dev/null +++ b/ext/dom/characterdata.c @@ -0,0 +1,384 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: characterdata.c,v 1.13.2.1 2004/11/18 19:55:00 rrichards Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class DOMCharacterData extends DOMNode +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-FF21A306 +* Since: +*/ + +zend_function_entry php_dom_characterdata_class_functions[] = { + PHP_FALIAS(substringData, dom_characterdata_substring_data, NULL) + PHP_FALIAS(appendData, dom_characterdata_append_data, NULL) + PHP_FALIAS(insertData, dom_characterdata_insert_data, NULL) + PHP_FALIAS(deleteData, dom_characterdata_delete_data, NULL) + PHP_FALIAS(replaceData, dom_characterdata_replace_data, NULL) + {NULL, NULL, NULL} +}; + +/* {{{ 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(newval->refcount > 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); + + xmlTextConcat(nodep, arg, arg_len); + + 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 diff --git a/ext/dom/comment.c b/ext/dom/comment.c new file mode 100644 index 000000000..c3ba1cb97 --- /dev/null +++ b/ext/dom/comment.c @@ -0,0 +1,77 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: comment.c,v 1.10 2004/05/31 12:50:28 rrichards Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class DOMComment extends DOMCharacterData +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-1728279322 +* Since: +*/ + +zend_function_entry php_dom_comment_class_functions[] = { + PHP_ME(domcomment, __construct, NULL, 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; + + php_set_error_handling(EH_THROW, dom_domexception_class_entry TSRMLS_CC); + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|s", &id, dom_comment_class_entry, &value, &value_len) == FAILURE) { + php_std_error_handling(); + return; + } + + php_std_error_handling(); + 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 = (xmlNodePtr)intern->ptr; + 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 diff --git a/ext/dom/config.m4 b/ext/dom/config.m4 new file mode 100644 index 000000000..81adf5596 --- /dev/null +++ b/ext/dom/config.m4 @@ -0,0 +1,32 @@ +dnl +dnl $Id: config.m4,v 1.15 2003/12/07 15:37:30 sniper Exp $ +dnl + +PHP_ARG_ENABLE(dom, whether to enable DOM support, +[ --disable-dom Disable new 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" && test "$PHP_LIBXML" != "no"; then + + 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) + ], [ + 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 000000000..182467b47 --- /dev/null +++ b/ext/dom/config.w32 @@ -0,0 +1,22 @@ +// $Id: config.w32,v 1.3 2003/12/22 13:16:39 wez Exp $ +// vim:ft=javascript + +ARG_WITH("dom", "DOM support", "yes"); + +if (PHP_DOM == "yes" && PHP_LIBXML == "yes") { + 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 "); + } + ADD_EXTENSION_DEP('dom', 'libxml'); +} + + diff --git a/ext/dom/document.c b/ext/dom/document.c new file mode 100644 index 000000000..aa81e16ce --- /dev/null +++ b/ext/dom/document.c @@ -0,0 +1,2109 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: document.c,v 1.55.2.3 2004/11/18 19:55:00 rrichards Exp $ */ + +#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 + +/* +* class DOMDocument extends DOMNode +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-i-Document +* Since: +*/ + +zend_function_entry php_dom_document_class_functions[] = { + PHP_FALIAS(createElement, dom_document_create_element, NULL) + PHP_FALIAS(createDocumentFragment, dom_document_create_document_fragment, NULL) + PHP_FALIAS(createTextNode, dom_document_create_text_node, NULL) + PHP_FALIAS(createComment, dom_document_create_comment, NULL) + PHP_FALIAS(createCDATASection, dom_document_create_cdatasection, NULL) + PHP_FALIAS(createProcessingInstruction, dom_document_create_processing_instruction, NULL) + PHP_FALIAS(createAttribute, dom_document_create_attribute, NULL) + PHP_FALIAS(createEntityReference, dom_document_create_entity_reference, NULL) + PHP_FALIAS(getElementsByTagName, dom_document_get_elements_by_tag_name, NULL) + PHP_FALIAS(importNode, dom_document_import_node, NULL) + PHP_FALIAS(createElementNS, dom_document_create_element_ns, NULL) + PHP_FALIAS(createAttributeNS, dom_document_create_attribute_ns, NULL) + PHP_FALIAS(getElementsByTagNameNS, dom_document_get_elements_by_tag_name_ns, NULL) + PHP_FALIAS(getElementById, dom_document_get_element_by_id, NULL) + PHP_FALIAS(adoptNode, dom_document_adopt_node, NULL) + PHP_FALIAS(normalizeDocument, dom_document_normalize_document, NULL) + PHP_FALIAS(renameNode, dom_document_rename_node, NULL) + PHP_ME(domdocument, load, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC) + PHP_FALIAS(save, dom_document_save, NULL) + PHP_ME(domdocument, loadXML, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC) + PHP_FALIAS(saveXML, dom_document_savexml, NULL) + PHP_ME(domdocument, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_FALIAS(validate, dom_document_validate, NULL) + PHP_FALIAS(xinclude, dom_document_xinclude, NULL) +#if defined(LIBXML_HTML_ENABLED) + PHP_ME(domdocument, loadHTML, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC) + PHP_ME(domdocument, loadHTMLFile, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC) + PHP_FALIAS(saveHTML, dom_document_save_html, NULL) + PHP_FALIAS(saveHTMLFile, dom_document_save_html_file, NULL) +#endif /* defined(LIBXML_HTML_ENABLED) */ +#if defined(LIBXML_SCHEMAS_ENABLED) + PHP_FALIAS(schemaValidate, dom_document_schema_validate_file, NULL) + PHP_FALIAS(schemaValidateSource, dom_document_schema_validate_xml, NULL) + PHP_FALIAS(relaxNGValidate, dom_document_relaxNG_validate_file, NULL) + PHP_FALIAS(relaxNGValidateSource, dom_document_relaxNG_validate_xml, NULL) +#endif + {NULL, NULL, NULL} +}; + +/* {{{ 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; + } + + dtdptr = xmlGetIntSubset(docp); + if (!dtdptr) { + return FAILURE; + } + + ALLOC_ZVAL(*retval); + if (NULL == (*retval = php_dom_create_object((xmlNodePtr) dtdptr, &ret, NULL, *retval, obj TSRMLS_CC))) { + php_error(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; + } + + root = xmlDocGetRootElement(docp); + if (!root) { + return FAILURE; + } + + ALLOC_ZVAL(*retval); + if (NULL == (*retval = php_dom_create_object(root, &ret, NULL, *retval, obj TSRMLS_CC))) { + php_error(E_WARNING, "Cannot create required DOM object"); + return FAILURE; + } + return SUCCESS; +} + +/* }}} */ + + +/* {{{ actualEncoding string +readonly=no +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-actualEncoding +Since: DOM Level 3 +*/ +/* READ ONLY FOR NOW USING ENCODING PROPERTY +int dom_document_actual_encoding_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + ALLOC_ZVAL(*retval); + ZVAL_NULL(*retval); + return SUCCESS; +} + +int dom_document_actual_encoding_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + 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(newval->refcount > 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(newval->refcount > 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(newval->refcount > 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_props *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_props *doc_prop; + + if(newval->refcount > 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_props *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_props *doc_prop; + + if(newval->refcount > 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_props *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_props *doc_prop; + + if(newval->refcount > 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_props *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_props *doc_prop; + + if(newval->refcount > 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_props *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_props *doc_prop; + + if(newval->refcount > 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; +} +/* }}} */ + + +/* {{{ substituteEntities boolean +readonly=no +*/ +int dom_document_substitue_entities_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + dom_doc_props *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_props *doc_prop; + + if(newval->refcount > 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(newval->refcount > 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, *rv = NULL; + 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(rv, 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, *rv = NULL; + 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(rv, 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, *rv = NULL; + 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(rv, 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, *rv = NULL; + 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(rv, 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, *rv = NULL; + 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(rv, 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, *rv = NULL; + 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(rv, 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, *rv = NULL; + 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(rv, (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, *rv = NULL; + 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(rv, (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 *rv = NULL; + 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 { + retnodep = xmlDocCopyNode(nodep, docp, recursive); + if (!retnodep) { + RETURN_FALSE; + } + } + + DOM_RET_OBJ(rv, (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, *rv = NULL; + 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(rv, 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, *rv = NULL; + 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(rv, 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, *rv = NULL; + 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(rv, (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; + + php_set_error_handling(EH_THROW, dom_domexception_class_entry 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) { + php_std_error_handling(); + return; + } + + php_std_error_handling(); + 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; + php_libxml_increment_doc_ref((php_libxml_node_object *)intern, docp TSRMLS_CC); + 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); + } + file_dest = resolved_path; + } + + xmlFreeURI(uri); + + return file_dest; +} + + +/* {{{ */ +static xmlDocPtr dom_document_parser(zval *id, int mode, char *source TSRMLS_DC) { + xmlDocPtr ret; + xmlParserCtxtPtr ctxt = NULL; + dom_doc_props *doc_props; + dom_object *intern; + php_libxml_ref_obj *document = NULL; + int validate, resolve_externals, keep_blanks, substitute_ent; + int resolved_path_len; + 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; + + if (document == NULL) { + efree(doc_props); + } + + xmlInitParser(); + + keep_blanks = xmlKeepBlanksDefault(keep_blanks); + + 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 = xmlCreateDocParserCtxt(source); + } + + xmlKeepBlanksDefault(keep_blanks); + /* xmlIndentTreeOutput default is changed in xmlKeepBlanksDefault + reset back to 1 which is default value */ + + xmlIndentTreeOutput = 1; + + 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->recovery = 0; + ctxt->validate = validate; + ctxt->loadsubset = (resolve_externals * XML_COMPLETE_ATTRS); + ctxt->replaceEntities = substitute_ent; + + 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; + } + + xmlParseDocument(ctxt); + + if (ctxt->wellFormed) { + ret = ctxt->myDoc; + /* If loading from memory, set the base reference uri for the document */ + if (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, *rv = NULL; + xmlDoc *docp = NULL, *newdoc; + dom_doc_props *doc_prop; + dom_object *intern; + char *source; + int source_len, refcount, ret; + + 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", &source, &source_len) == 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 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; + php_libxml_increment_doc_ref((php_libxml_node_object *)intern, newdoc TSRMLS_CC); + 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(rv, (xmlNodePtr) newdoc, &ret, NULL); + } +} +/* }}} end dom_parser_document */ + +/* {{{ proto DOMNode dom_document_load(string source); +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); +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; + dom_object *intern; + dom_doc_props *doc_props; + char *file; + + 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(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; + bytes = xmlSaveFormatFileEnc(file, docp, NULL, format); + + 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_props *doc_props; + int size, format; + + 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(E_WARNING, "Could not fetch buffer"); + RETURN_FALSE; + } + + xmlNodeDump(buf, docp, node, 0, format); + mem = (xmlChar*) xmlBufferContent(buf); + if (!mem) { + xmlBufferFree(buf); + RETURN_FALSE; + } + RETVAL_STRING(mem, 1); + xmlBufferFree(buf); + } else { + /* Encoding is handled from the encoding property set on the document */ + xmlDocDumpFormatMemory(docp, &mem, &size, format); + 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) { + 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() + Substitutues xincludes in a DomDocument */ +PHP_FUNCTION(dom_document_xinclude) +{ + zval *id; + xmlDoc *docp; + xmlNodePtr root; + int err; + 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); + + err = xmlXIncludeProcess (docp); + + /* 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); + + if (docp->intSubset == NULL) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "No DTD given in XML-Document"); + } + + 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(), "Os", &id, dom_document_class_entry, &source, &source_len) == FAILURE) { + return; + } + + if (source_len == 0) { + php_error(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(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(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(), "Os", &id, dom_document_class_entry, &source, &source_len) == FAILURE) { + return; + } + + if (source_len == 0) { + php_error(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(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(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, *rv = NULL; + xmlDoc *docp = NULL, *newdoc; + dom_object *intern; + dom_doc_props *doc_prop; + char *source; + int source_len, refcount, ret; + htmlParserCtxtPtr ctxt; + + id = getThis(); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &source, &source_len) == 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; + } + + 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; + php_libxml_increment_doc_ref((php_libxml_node_object *)intern, newdoc TSRMLS_CC); + 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(rv, (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_props *doc_props; + char *file; + + 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(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; + bytes = htmlSaveFileFormat(file, docp, NULL, 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; + xmlDoc *docp; + dom_object *intern; + xmlChar *mem; + int size; + + 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); + + htmlDocDumpMemory(docp, &mem, &size); + if (!size) { + if (mem) + xmlFree(mem); + RETURN_FALSE; + } + RETVAL_STRINGL(mem, size, 1); + xmlFree(mem); +} +/* }}} end dom_document_save_html */ + +#endif /* defined(LIBXML_HTML_ENABLED) */ + +#endif /* HAVE_LIBXML && HAVE_DOM */ diff --git a/ext/dom/documentfragment.c b/ext/dom/documentfragment.c new file mode 100644 index 000000000..b7ce96890 --- /dev/null +++ b/ext/dom/documentfragment.c @@ -0,0 +1,76 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: documentfragment.c,v 1.11 2004/05/31 12:50:28 rrichards Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class DOMDocumentFragment extends DOMNode +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-B63ED1A3 +* Since: +*/ + +zend_function_entry php_dom_documentfragment_class_functions[] = { + PHP_ME(domdocumentfragment, __construct, NULL, ZEND_ACC_PUBLIC) + {NULL, NULL, NULL} +}; + +/* {{{ proto void DOMDocumentFragment::__construct(); */ +PHP_METHOD(domdocumentfragment, __construct) +{ + + zval *id; + xmlNodePtr nodep = NULL, oldnode = NULL; + dom_object *intern; + + php_set_error_handling(EH_THROW, dom_domexception_class_entry TSRMLS_CC); + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_documentfragment_class_entry) == FAILURE) { + php_std_error_handling(); + return; + } + + php_std_error_handling(); + 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 = (xmlNodePtr)intern->ptr; + 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 */ +#endif diff --git a/ext/dom/documenttype.c b/ext/dom/documenttype.c new file mode 100644 index 000000000..8363cb950 --- /dev/null +++ b/ext/dom/documenttype.c @@ -0,0 +1,234 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: documenttype.c,v 1.12.2.2 2004/11/18 19:55:00 rrichards Exp $ */ + +#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: +*/ + +zend_function_entry php_dom_documenttype_class_functions[] = { + {NULL, NULL, NULL} +}; + +/* {{{ 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; + xmlChar *strintsubset; + + 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); + strintsubset = xmlStrndup(buff->buffer->content, buff->buffer->use); + (void)xmlOutputBufferClose(buff); + ZVAL_STRING(*retval, (char *) strintsubset, 1); + return SUCCESS; + } + } + + ZVAL_EMPTY_STRING(*retval); + + return SUCCESS; + +} + +/* }}} */ + +#endif diff --git a/ext/dom/dom.dsp b/ext/dom/dom.dsp new file mode 100644 index 000000000..f2ae5b1a7 --- /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 000000000..e3b60742a --- /dev/null +++ b/ext/dom/dom_ce.h @@ -0,0 +1,57 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: dom_ce.h,v 1.6 2004/01/08 17:32:03 sniper Exp $ */ +#ifndef DOM_CE_H +#define DOM_CE_H + +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; + +#endif /* DOM_CE_H */ diff --git a/ext/dom/dom_fe.h b/ext/dom/dom_fe.h new file mode 100644 index 000000000..8ee8204cc --- /dev/null +++ b/ext/dom/dom_fe.h @@ -0,0 +1,263 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: dom_fe.h,v 1.11 2004/05/16 10:30:16 rrichards Exp $ */ +#ifndef DOM_FE_H +#define DOM_FE_H + +extern zend_function_entry php_dom_domexception_class_functions[]; +extern zend_function_entry php_dom_domstringlist_class_functions[]; +extern zend_function_entry php_dom_namelist_class_functions[]; +extern zend_function_entry php_dom_domimplementationlist_class_functions[]; +extern zend_function_entry php_dom_domimplementationsource_class_functions[]; +extern zend_function_entry php_dom_domimplementation_class_functions[]; +extern zend_function_entry php_dom_documentfragment_class_functions[]; +extern zend_function_entry php_dom_document_class_functions[]; +extern zend_function_entry php_dom_node_class_functions[]; +extern zend_function_entry php_dom_nodelist_class_functions[]; +extern zend_function_entry php_dom_namednodemap_class_functions[]; +extern zend_function_entry php_dom_characterdata_class_functions[]; +extern zend_function_entry php_dom_attr_class_functions[]; +extern zend_function_entry php_dom_element_class_functions[]; +extern zend_function_entry php_dom_text_class_functions[]; +extern zend_function_entry php_dom_comment_class_functions[]; +extern zend_function_entry php_dom_typeinfo_class_functions[]; +extern zend_function_entry php_dom_userdatahandler_class_functions[]; +extern zend_function_entry php_dom_domerror_class_functions[]; +extern zend_function_entry php_dom_domerrorhandler_class_functions[]; +extern zend_function_entry php_dom_domlocator_class_functions[]; +extern zend_function_entry php_dom_domconfiguration_class_functions[]; +extern zend_function_entry php_dom_cdatasection_class_functions[]; +extern zend_function_entry php_dom_documenttype_class_functions[]; +extern zend_function_entry php_dom_notation_class_functions[]; +extern zend_function_entry php_dom_entity_class_functions[]; +extern zend_function_entry php_dom_entityreference_class_functions[]; +extern zend_function_entry php_dom_processinginstruction_class_functions[]; +extern zend_function_entry php_dom_string_extend_class_functions[]; +extern 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); + +/* 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); + +#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); + +/* 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); +#endif + +#endif /* DOM_FE_H */ diff --git a/ext/dom/dom_iterators.c b/ext/dom/dom_iterators.c new file mode 100644 index 000000000..596f7dfd3 --- /dev/null +++ b/ext/dom/dom_iterators.c @@ -0,0 +1,312 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: dom_iterators.c,v 1.8 2004/03/08 21:15:39 helly Exp $ */ + +#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 - 1; + 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; + } + + 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=1; + HashTable *nodeht; + pval **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->ht == NULL) { + 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; + curattr->refcount++; + } + } 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 { + basenode = basenode->children; + } + 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); + } + } + } + + zval_ptr_dtor((zval**)&curobj); + if (curnode) { + MAKE_STD_ZVAL(curattr); + curattr = php_dom_create_object(curnode, &ret, NULL, 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 TSRMLS_DC) +{ + dom_object *intern; + dom_nnodemap_object *objmap; + xmlNodePtr nodep, curnode=NULL; + zval *curattr = NULL; + int ret, curindex = 0; + HashTable *nodeht; + pval **entry; + + php_dom_iterator *iterator = emalloc(sizeof(php_dom_iterator)); + + object->refcount++; + 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->ht == NULL) { + 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; + curattr->refcount++; + } + } else { + nodep = (xmlNode *)dom_object_get_node(objmap->baseobj); + 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 { + curnode = php_dom_libxml_hash_iter(objmap->ht, 0); + } + } + + if (curnode) { + MAKE_STD_ZVAL(curattr); + curattr = php_dom_create_object(curnode, &ret, NULL, curattr, objmap->baseobj TSRMLS_CC); + } + + iterator->curobj = curattr; + + return (zend_object_iterator*)iterator; +} + +#endif diff --git a/ext/dom/dom_properties.h b/ext/dom/dom_properties.h new file mode 100644 index 000000000..8af5a8b0e --- /dev/null +++ b/ext/dom/dom_properties.h @@ -0,0 +1,160 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: dom_properties.h,v 1.5 2004/01/08 17:32:03 sniper Exp $ */ +#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_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 */ diff --git a/ext/dom/domconfiguration.c b/ext/dom/domconfiguration.c new file mode 100644 index 000000000..1c80aa804 --- /dev/null +++ b/ext/dom/domconfiguration.c @@ -0,0 +1,79 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: domconfiguration.c,v 1.4 2004/01/08 08:15:16 andi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class domdomconfiguration +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration +* Since: DOM Level 3 +*/ + +zend_function_entry php_dom_domconfiguration_class_functions[] = { + PHP_FALIAS(setParameter, dom_domconfiguration_set_parameter, NULL) + PHP_FALIAS(getParameter, dom_domconfiguration_get_parameter, NULL) + PHP_FALIAS(canSetParameter, dom_domconfiguration_can_set_parameter, NULL) + {NULL, NULL, NULL} +}; + +/* {{{ 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 diff --git a/ext/dom/domerror.c b/ext/dom/domerror.c new file mode 100644 index 000000000..c4fd80b61 --- /dev/null +++ b/ext/dom/domerror.c @@ -0,0 +1,138 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: domerror.c,v 1.4.2.1 2004/11/18 19:55:00 rrichards Exp $ */ + +#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 +*/ + +zend_function_entry php_dom_domerror_class_functions[] = { + {NULL, NULL, NULL} +}; + +/* {{{ 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 diff --git a/ext/dom/domerrorhandler.c b/ext/dom/domerrorhandler.c new file mode 100644 index 000000000..f2a84013f --- /dev/null +++ b/ext/dom/domerrorhandler.c @@ -0,0 +1,55 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: domerrorhandler.c,v 1.4 2004/01/08 08:15:16 andi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* 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 +*/ + +zend_function_entry php_dom_domerrorhandler_class_functions[] = { + PHP_FALIAS(handleError, dom_domerrorhandler_handle_error, NULL) + {NULL, NULL, NULL} +}; + +/* {{{ 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 diff --git a/ext/dom/domexception.c b/ext/dom/domexception.c new file mode 100644 index 000000000..7e5b8c6bf --- /dev/null +++ b/ext/dom/domexception.c @@ -0,0 +1,111 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: domexception.c,v 1.9 2004/05/31 12:50:28 rrichards Exp $ */ + +#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; + +zend_function_entry php_dom_domexception_class_functions[] = { + {NULL, NULL, NULL} +}; + +/* {{{ 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"; + } + + if (strict_error == 1) { + zend_throw_exception(dom_domexception_class_entry, error_message, error_code TSRMLS_CC); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", error_message); + } +} +/* }}} end php_dom_throw_error */ + +#endif /* HAVE_LIBXML && HAVE_DOM */ diff --git a/ext/dom/domimplementation.c b/ext/dom/domimplementation.c new file mode 100644 index 000000000..7c01b77af --- /dev/null +++ b/ext/dom/domimplementation.c @@ -0,0 +1,233 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: domimplementation.c,v 1.13 2004/05/31 12:50:28 rrichards Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + +/* +* class DOMImplementation +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-102161490 +* Since: +*/ + +zend_function_entry php_dom_domimplementation_class_functions[] = { + PHP_ME(domimplementation, getFeature, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC) + PHP_ME(domimplementation, hasFeature, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC) + PHP_ME(domimplementation, createDocumentType, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC) + PHP_ME(domimplementation, createDocument, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC) + {NULL, NULL, NULL} +}; + +/* {{{ 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) +{ + zval *rv = NULL; + xmlDtd *doctype; + int ret, name_len = 0, publicid_len = 0, systemid_len = 0; + char *name, *publicid, *systemid; + 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->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); + */ + + xmlFreeURI(uri); + + doctype = xmlCreateIntSubset(NULL, localname, pch1, pch2); + xmlFree(localname); + + DOM_RET_OBJ(rv, (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, *rv = NULL; + xmlDoc *docp; + xmlNode *nodep; + xmlDtdPtr doctype = NULL; + xmlNsPtr nsptr = NULL; + int ret, uri_len = 0, name_len = 0, errorcode = 0; + char *uri, *name; + 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(E_WARNING, "Unexpected Error"); + RETURN_FALSE; + } + + nodep->nsDef = nsptr; + + xmlDocSetRootElement(docp, nodep); + xmlFree(localname); + } + + DOM_RET_OBJ(rv, (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 diff --git a/ext/dom/domimplementationlist.c b/ext/dom/domimplementationlist.c new file mode 100644 index 000000000..6463216c3 --- /dev/null +++ b/ext/dom/domimplementationlist.c @@ -0,0 +1,71 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: domimplementationlist.c,v 1.4.2.1 2004/11/18 19:55:00 rrichards Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class domimplementationlist +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementationList +* Since: DOM Level 3 +*/ + +zend_function_entry php_dom_domimplementationlist_class_functions[] = { + PHP_FALIAS(item, dom_domimplementationlist_item, NULL) + {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 diff --git a/ext/dom/domimplementationsource.c b/ext/dom/domimplementationsource.c new file mode 100644 index 000000000..1db0e41bd --- /dev/null +++ b/ext/dom/domimplementationsource.c @@ -0,0 +1,67 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: domimplementationsource.c,v 1.4 2004/01/08 08:15:16 andi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class domimplementationsource +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementationSource +* Since: DOM Level 3 +*/ + +zend_function_entry php_dom_domimplementationsource_class_functions[] = { + PHP_FALIAS(getDomimplementation, dom_domimplementationsource_get_domimplementation, NULL) + PHP_FALIAS(getDomimplementations, dom_domimplementationsource_get_domimplementations, NULL) + {NULL, NULL, NULL} +}; + +/* {{{ 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 diff --git a/ext/dom/domlocator.c b/ext/dom/domlocator.c new file mode 100644 index 000000000..b6779d4e1 --- /dev/null +++ b/ext/dom/domlocator.c @@ -0,0 +1,123 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: domlocator.c,v 1.4.2.1 2004/11/18 19:55:00 rrichards Exp $ */ + +#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 +*/ + +zend_function_entry php_dom_domlocator_class_functions[] = { + {NULL, NULL, NULL} +}; + +/* {{{ 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 diff --git a/ext/dom/domstringlist.c b/ext/dom/domstringlist.c new file mode 100644 index 000000000..158e8a34a --- /dev/null +++ b/ext/dom/domstringlist.c @@ -0,0 +1,71 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: domstringlist.c,v 1.4.2.1 2004/11/18 19:55:00 rrichards Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class domstringlist +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMStringList +* Since: DOM Level 3 +*/ + +zend_function_entry php_dom_domstringlist_class_functions[] = { + PHP_FALIAS(item, dom_domstringlist_item, NULL) + {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#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 diff --git a/ext/dom/element.c b/ext/dom/element.c new file mode 100644 index 000000000..afd8a11ab --- /dev/null +++ b/ext/dom/element.c @@ -0,0 +1,885 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: element.c,v 1.30.2.2 2004/11/18 19:55:00 rrichards Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class DOMElement extends DOMNode +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-745549614 +* Since: +*/ + +zend_function_entry php_dom_element_class_functions[] = { + PHP_FALIAS(getAttribute, dom_element_get_attribute, NULL) + PHP_FALIAS(setAttribute, dom_element_set_attribute, NULL) + PHP_FALIAS(removeAttribute, dom_element_remove_attribute, NULL) + PHP_FALIAS(getAttributeNode, dom_element_get_attribute_node, NULL) + PHP_FALIAS(setAttributeNode, dom_element_set_attribute_node, NULL) + PHP_FALIAS(removeAttributeNode, dom_element_remove_attribute_node, NULL) + PHP_FALIAS(getElementsByTagName, dom_element_get_elements_by_tag_name, NULL) + PHP_FALIAS(getAttributeNS, dom_element_get_attribute_ns, NULL) + PHP_FALIAS(setAttributeNS, dom_element_set_attribute_ns, NULL) + PHP_FALIAS(removeAttributeNS, dom_element_remove_attribute_ns, NULL) + PHP_FALIAS(getAttributeNodeNS, dom_element_get_attribute_node_ns, NULL) + PHP_FALIAS(setAttributeNodeNS, dom_element_set_attribute_node_ns, NULL) + PHP_FALIAS(getElementsByTagNameNS, dom_element_get_elements_by_tag_name_ns, NULL) + PHP_FALIAS(hasAttribute, dom_element_has_attribute, NULL) + PHP_FALIAS(hasAttributeNS, dom_element_has_attribute_ns, NULL) + PHP_FALIAS(setIdAttribute, dom_element_set_id_attribute, NULL) + PHP_FALIAS(setIdAttributeNS, dom_element_set_id_attribute_ns, NULL) + PHP_FALIAS(setIdAttributeNode, dom_element_set_id_attribute_node, NULL) + PHP_ME(domelement, __construct, NULL, ZEND_ACC_PUBLIC) + {NULL, NULL, NULL} +}; + +/* {{{ 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; + + php_set_error_handling(EH_THROW, dom_domexception_class_entry 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) { + php_std_error_handling(); + return; + } + + php_std_error_handling(); + 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, 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) { + xmlFree(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(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, value, value_len); + } + + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + if (intern != NULL) { + oldnode = (xmlNodePtr)intern->ptr; + 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, ":"); + qname = xmlStrcat(qname, nodep->name); + ZVAL_STRING(*retval, 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; +} + +/* }}} */ + + + +/* {{{ 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, *value; + dom_object *intern; + 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); + + value = xmlGetProp(nodep, name); + if (value == NULL) { + RETURN_EMPTY_STRING(); + } else { + RETVAL_STRING(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, *rv = NULL; + xmlNode *nodep; + xmlAttr *attr; + int ret, name_len, value_len; + 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; + } + + 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 = xmlHasProp(nodep,name); + if (attr != NULL) { + node_list_unlink(attr->children TSRMLS_CC); + } + attr = xmlSetProp(nodep, name, value); + if (!attr) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such attribute '%s'", name); + RETURN_FALSE; + } + + DOM_RET_OBJ(rv, (xmlNodePtr) 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; + xmlNode *nodep; + xmlAttr *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 = xmlHasProp(nodep,name); + if (attrp == NULL) { + RETURN_FALSE; + } + + /* TODO: DTD defined attributes are handled special */ + 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_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, *rv = NULL; + xmlNode *nodep; + xmlAttr *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 = xmlHasProp(nodep,name); + if (attrp == NULL) { + RETURN_FALSE; + } + + DOM_RET_OBJ(rv, (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, *rv = NULL; + 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; + } + + existattrp = xmlHasProp(nodep, attrp->name); + if (existattrp != NULL) { + 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->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(rv, (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, *rv = NULL; + 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(rv, (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, *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, name, uri); + + if (strattr != NULL) { + RETVAL_STRING(strattr, 1); + xmlFree(strattr); + } else { + if (xmlStrEqual(uri, DOM_XMLNS_NAMESPACE)) { + nsptr = dom_get_nsdecl(elemp, name); + if (nsptr != NULL) { + RETVAL_STRING((char *) nsptr->href, 1); + } else { + RETVAL_EMPTY_STRING(); + } + } else { + RETVAL_EMPTY_STRING(); + } + } + +} +/* }}} end dom_element_get_attribute_ns */ + + +/* {{{ 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; + + 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, localname, uri); + if (nodep != NULL) { + node_list_unlink(nodep->children TSRMLS_CC); + } + + if (xmlStrEqual(prefix,"xmlns") && xmlStrEqual(uri, DOM_XMLNS_NAMESPACE)) { + is_xmlns = 1; + nsptr = dom_get_nsdecl(elemp, localname); + } else { + nsptr = xmlSearchNsByHref(elemp->doc, elemp, uri); + while (nsptr && nsptr->prefix == NULL) { + nsptr = nsptr->next; + } + } + + if (nsptr == NULL) { + if (prefix == NULL) { + errorcode = NAMESPACE_ERR; + } else { + if (is_xmlns == 1) { + xmlNewNs(elemp, value, localname); + } else { + nsptr = dom_get_ns(elemp, uri, &errorcode, prefix); + } + } + } else { + if (is_xmlns == 1) { + if (nsptr->href) { + xmlFree((xmlChar *) nsptr->href); + } + nsptr->href = xmlStrdup(value); + } + } + + if (errorcode == 0 && is_xmlns == 0) { + attr = xmlSetNsProp(elemp, nsptr, localname, value); + } + } else { + attr = xmlHasProp(elemp, localname); + if (attr != NULL) { + node_list_unlink(attr->children TSRMLS_CC); + } + attr = xmlSetProp(elemp, localname, 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, name, uri); + + nsptr = dom_get_nsdecl(nodep, name); + if (nsptr != NULL) { + if (xmlStrEqual(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) { + 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, *rv = NULL; + 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(), "Oss", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) { + return; + } + + DOM_GET_OBJ(elemp, id, xmlNodePtr, intern); + + attrp = xmlHasNsProp(elemp, name, uri); + + if (attrp == NULL) { + RETURN_NULL(); + } + + DOM_RET_OBJ(rv, (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, *rv = NULL; + 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; + } + + nsp = attrp->ns; + if (nsp != NULL) { + existattrp = xmlHasNsProp(nodep, nsp->href, attrp->name); + } else { + existattrp = xmlHasProp(nodep, attrp->name); + } + + if (existattrp != NULL) { + 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->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(rv, (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, *value; + 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); + + value = xmlGetProp(nodep, name); + if (value == NULL) { + RETURN_FALSE; + } else { + xmlFree(value); + 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, *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, name, uri); + + if (value != NULL) { + xmlFree(value); + RETURN_TRUE; + } else { + if (xmlStrEqual(uri, DOM_XMLNS_NAMESPACE)) { + nsp = dom_get_nsdecl(elemp, name); + if (nsp != NULL) { + RETURN_TRUE; + } + } + } + + RETURN_FALSE; +} +/* }}} end dom_element_has_attribute_ns */ + + +/* {{{ 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) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} 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) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} 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) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_element_set_id_attribute_node */ + +#endif diff --git a/ext/dom/entity.c b/ext/dom/entity.c new file mode 100644 index 000000000..bc625a2c0 --- /dev/null +++ b/ext/dom/entity.c @@ -0,0 +1,196 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: entity.c,v 1.7.2.1 2004/11/18 19:55:00 rrichards Exp $ */ + +#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: +*/ + +zend_function_entry php_dom_entity_class_functions[] = { + {NULL, NULL, NULL} +}; + +/* {{{ 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 diff --git a/ext/dom/entityreference.c b/ext/dom/entityreference.c new file mode 100644 index 000000000..1d19470d1 --- /dev/null +++ b/ext/dom/entityreference.c @@ -0,0 +1,85 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: entityreference.c,v 1.11 2004/05/31 12:50:28 rrichards Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class DOMEntityReference extends DOMNode +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-11C98490 +* Since: +*/ + +zend_function_entry php_dom_entityreference_class_functions[] = { + PHP_ME(domentityreference, __construct, NULL, ZEND_ACC_PUBLIC) + {NULL, NULL, NULL} +}; + +/* {{{ 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; + + php_set_error_handling(EH_THROW, dom_domexception_class_entry TSRMLS_CC); + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_entityreference_class_entry, &name, &name_len) == FAILURE) { + php_std_error_handling(); + return; + } + + php_std_error_handling(); + + 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 = (xmlNodePtr)intern->ptr; + 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 diff --git a/ext/dom/examples/dom1.inc b/ext/dom/examples/dom1.inc new file mode 100644 index 000000000..792d6f2db --- /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 000000000..8ea367458 --- /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 000000000..58d4e6504 --- /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 000000000..4016eb581 --- /dev/null +++ b/ext/dom/examples/note.dtd @@ -0,0 +1,6 @@ +<?xml version="1.0" ?> +<!ELEMENT note (to,from,heading,body)> +<!ELEMENT to (#PCDATA)> +<!ELEMENT from (#PCDATA)> +<!ELEMENT heading (#PCDATA)> +<!ELEMENT body (#PCDATA)>
\ No newline at end of file diff --git a/ext/dom/examples/note.php b/ext/dom/examples/note.php new file mode 100644 index 000000000..a8695f366 --- /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 000000000..49614a1b5 --- /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 000000000..d265fd988 --- /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 000000000..f4357e04e --- /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 000000000..6b0cac122 --- /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 000000000..4adae7b15 --- /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 000000000..73e1eb616 --- /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 000000000..5205fd201 --- /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 000000000..dc8a09e30 --- /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 000000000..8b16b7c03 --- /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 000000000..0754e3fb2 --- /dev/null +++ b/ext/dom/namednodemap.c @@ -0,0 +1,288 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: namednodemap.c,v 1.12.2.1 2004/11/18 19:55:00 rrichards Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class DOMNamedNodeMap +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1780488922 +* Since: +*/ + +zend_function_entry php_dom_namednodemap_class_functions[] = { + PHP_FALIAS(getNamedItem, dom_namednodemap_get_named_item, NULL) + PHP_FALIAS(setNamedItem, dom_namednodemap_set_named_item, NULL) + PHP_FALIAS(removeNamedItem, dom_namednodemap_remove_named_item, NULL) + PHP_FALIAS(item, dom_namednodemap_item, NULL) + PHP_FALIAS(getNamedItemNS, dom_namednodemap_get_named_item_ns, NULL) + PHP_FALIAS(setNamedItemNS, dom_namednodemap_set_named_item_ns, NULL) + PHP_FALIAS(removeNamedItemNS, dom_namednodemap_remove_named_item_ns, NULL) + {NULL, NULL, NULL} +}; + +/* {{{ 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->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, *rv = NULL; + 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->ht) { + if (objmap->nodetype == XML_ENTITY_NODE) { + itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named); + } else { + notep = (xmlNotation *)xmlHashLookup(objmap->ht, named); + 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(rv, 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, *rv = NULL; + int index, 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->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(rv, 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, *rv = NULL; + 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->ht) { + if (objmap->nodetype == XML_ENTITY_NODE) { + itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named); + } else { + notep = (xmlNotation *)xmlHashLookup(objmap->ht, named); + 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(rv, 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 diff --git a/ext/dom/namelist.c b/ext/dom/namelist.c new file mode 100644 index 000000000..5698401ed --- /dev/null +++ b/ext/dom/namelist.c @@ -0,0 +1,81 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: namelist.c,v 1.5.2.1 2004/11/18 19:55:00 rrichards Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class DOMNameList +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#NameList +* Since: DOM Level 3 +*/ + +zend_function_entry php_dom_namelist_class_functions[] = { + PHP_FALIAS(getName, dom_namelist_get_name, NULL) + PHP_FALIAS(getNamespaceURI, dom_namelist_get_namespace_uri, NULL) + {NULL, NULL, NULL} +}; + +/* {{{ 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 diff --git a/ext/dom/node.c b/ext/dom/node.c new file mode 100644 index 000000000..b87d181ba --- /dev/null +++ b/ext/dom/node.c @@ -0,0 +1,1736 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: node.c,v 1.29.2.3 2005/02/18 11:47:50 rrichards Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + +/* +* class DOMNode +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1950641247 +* Since: +*/ + +zend_function_entry php_dom_node_class_functions[] = { + PHP_FALIAS(insertBefore, dom_node_insert_before, NULL) + PHP_FALIAS(replaceChild, dom_node_replace_child, NULL) + PHP_FALIAS(removeChild, dom_node_remove_child, NULL) + PHP_FALIAS(appendChild, dom_node_append_child, NULL) + PHP_FALIAS(hasChildNodes, dom_node_has_child_nodes, NULL) + PHP_FALIAS(cloneNode, dom_node_clone_node, NULL) + PHP_FALIAS(normalize, dom_node_normalize, NULL) + PHP_FALIAS(isSupported, dom_node_is_supported, NULL) + PHP_FALIAS(hasAttributes, dom_node_has_attributes, NULL) + PHP_FALIAS(compareDocumentPosition, dom_node_compare_document_position, NULL) + PHP_FALIAS(isSameNode, dom_node_is_same_node, NULL) + PHP_FALIAS(lookupPrefix, dom_node_lookup_prefix, NULL) + PHP_FALIAS(isDefaultNamespace, dom_node_is_default_namespace, NULL) + PHP_FALIAS(lookupNamespaceUri, dom_node_lookup_namespace_uri, NULL) + PHP_FALIAS(isEqualNode, dom_node_is_equal_node, NULL) + PHP_FALIAS(getFeature, dom_node_get_feature, NULL) + PHP_FALIAS(setUserData, dom_node_set_user_data, NULL) + PHP_FALIAS(getUserData, dom_node_get_user_data, NULL) + {NULL, NULL, NULL} +}; + +static void dom_reconcile_ns(xmlDocPtr doc, xmlNodePtr nodep) { + xmlNsPtr nsptr; + + if (nodep->type == XML_ELEMENT_NODE) { + /* Following if block primarily used for inserting nodes created via createElementNS */ + if (nodep->nsDef != NULL && nodep->nsDef->href != NULL) { + if((nsptr = xmlSearchNsByHref(doc, nodep->parent, nodep->nsDef->href)) && + (nodep->nsDef->prefix == NULL || xmlStrEqual(nsptr->prefix, nodep->nsDef->prefix))) { + dom_set_old_ns(doc, nodep->nsDef); + nodep->nsDef = NULL; + } + } + 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"); + return FAILURE; + } + + 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(newval->refcount > 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; + } + + nodeparent = nodep->parent; + if (!nodeparent) { + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + if (NULL == (*retval = php_dom_create_object(nodeparent, &ret, NULL, *retval, obj TSRMLS_CC))) { + php_error(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; + } + + if (!first) { + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + if (NULL == (*retval = php_dom_create_object(first, &ret, NULL, *retval, obj TSRMLS_CC))) { + php_error(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; + } + + if (!last) { + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + if (NULL == (*retval = php_dom_create_object(last, &ret, NULL, *retval, obj TSRMLS_CC))) { + php_error(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; + } + + prevsib = nodep->prev; + if (!prevsib) { + return FAILURE; + } + + ALLOC_ZVAL(*retval); + + if (NULL == (*retval = php_dom_create_object(prevsib, &ret, NULL, *retval, obj TSRMLS_CC))) { + php_error(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, NULL, *retval, obj TSRMLS_CC))) { + php_error(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, NULL, *retval, obj TSRMLS_CC))) { + php_error(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(newval->refcount > 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); + } else { + ZVAL_EMPTY_STRING(*retval); + } + xmlFree(str); + + return SUCCESS; +} + +int dom_node_text_content_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + return SUCCESS; +} + +/* }}} */ + + + + +/* {{{ 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, *rv = 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) { + if (lastattr != (xmlAttrPtr) child) { + xmlUnlinkNode((xmlNodePtr) lastattr); + php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC); + } else { + DOM_RET_OBJ(rv, child, &ret, intern); + return; + } + } + } else if (child->type == XML_DOCUMENT_FRAG_NODE) { + xmlNodePtr fragment; + + fragment = child; + new_child = child->children; + child = new_child; + while (child->next != NULL) { + child->parent = parentp; + if (child->doc != parentp->doc) { + xmlSetTreeDoc(child, parentp->doc); + } + child = child->next; + } + child->parent = parentp; + if (child->doc != parentp->doc) { + xmlSetTreeDoc(child, parentp->doc); + } + + if (refp->prev != NULL) { + refp->prev->next = new_child; + } else { + parentp->children = new_child; + } + new_child->prev = refp->prev; + refp->prev = child; + child->next = refp; + fragment->children = NULL; + } + + if (new_child == NULL) { + new_child = xmlAddPrevSibling(refp, child); + } + } else { + if (child->parent == parentp){ + 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) { + if (lastattr != (xmlAttrPtr) child) { + xmlUnlinkNode((xmlNodePtr) lastattr); + php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC); + } else { + DOM_RET_OBJ(rv, child, &ret, intern); + return; + } + } + } else if (child->type == XML_DOCUMENT_FRAG_NODE) { + xmlNodePtr fragment; + + fragment = child; + + new_child = child->children; + if (parentp->children == NULL) { + parentp->children = new_child; + } else { + child = parentp->last; + child->next = new_child; + new_child->prev = child; + } + child = new_child; + while (child->next != NULL) { + child->parent = parentp; + if (child->doc != parentp->doc) { + xmlSetTreeDoc(child, parentp->doc); + } + child = child->next; + } + child->parent = parentp; + if (child->doc != parentp->doc) { + xmlSetTreeDoc(child, parentp->doc); + } + parentp->last = child; + fragment->children = NULL; + } + 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(rv, 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 wether the new child is already a child */ + while (children) { + if (children == oldchild) { + foundoldchild = 1; + break; + } + children = children->next; + } + + if (foundoldchild) { + xmlNodePtr node; + zval *rv = NULL; + + if (newchild->type == XML_DOCUMENT_FRAG_NODE) { + xmlNodePtr fragment, prevsib, nextsib; + fragment = newchild; + prevsib = oldchild->prev; + nextsib = oldchild->next; + + newchild = fragment->children; + + xmlUnlinkNode(oldchild); + + if (prevsib == NULL && nextsib == NULL) { + nodep->children = newchild; + nodep->last = fragment->last; + } else { + if (newchild) { + prevsib->next = newchild; + newchild->prev = prevsib; + + fragment->last->next = nextsib; + if (nextsib) { + nextsib->prev = fragment->last; + } else { + nodep->last = fragment->last; + } + } + } + node = newchild; + while (node != NULL) { + node->parent = nodep; + if (node->doc != nodep->doc) { + xmlSetTreeDoc(node, nodep->doc); + if (node->_private != NULL) { + newchildobj = node->_private; + newchildobj->document = intern->document; + php_libxml_increment_doc_ref((php_libxml_node_object *)newchildobj, NULL TSRMLS_CC); + } + } + if (node == fragment->last) { + break; + } + node = node->next; + } + + fragment->children = NULL; + fragment->last = NULL; + } 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); + } + node = xmlReplaceNode(oldchild, newchild); + dom_reconcile_ns(nodep->doc, newchild); + } + DOM_RET_OBJ(rv, 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) { + zval *rv = NULL; + xmlUnlinkNode(child); + DOM_RET_OBJ(rv, 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, *rv = NULL; + 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) { + if (lastattr != (xmlAttrPtr) child) { + xmlUnlinkNode((xmlNodePtr) lastattr); + php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC); + } + } + } else if (child->type == XML_DOCUMENT_FRAG_NODE) { + xmlNodePtr fragment; + + fragment = child; + new_child = child->children; + if (nodep->children == NULL) { + nodep->children = new_child; + } else { + child = nodep->last; + child->next = new_child; + new_child->prev = child; + } + child = new_child; + while (child->next != NULL) { + child->parent = nodep; + if (child->doc != nodep->doc) { + xmlSetTreeDoc(child, nodep->doc); + } + child = child->next; + } + child->parent = nodep; + if (child->doc != nodep->doc) { + xmlSetTreeDoc(child, nodep->doc); + } + nodep->last = child; + fragment->children = NULL; + } + + if (new_child == NULL) { + new_child = xmlAddChild(nodep, child); + if (new_child == NULL) { + php_error(E_WARNING, "Couldn't append node"); + RETURN_FALSE; + } + } + + dom_reconcile_ns(nodep->doc, new_child); + + DOM_RET_OBJ(rv, 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 *rv = NULL; + 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(rv, 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 (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; + + 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 (prefix_len > 0) { + 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 DomUserData dom_node_set_user_data(string key, DomUserData 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 DomUserData 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 */ +#endif diff --git a/ext/dom/nodelist.c b/ext/dom/nodelist.c new file mode 100644 index 000000000..457774a3b --- /dev/null +++ b/ext/dom/nodelist.c @@ -0,0 +1,168 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: nodelist.c,v 1.14.2.1 2004/11/18 19:55:00 rrichards Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class DOMNodeList +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-536297177 +* Since: +*/ + +zend_function_entry php_dom_nodelist_class_functions[] = { + PHP_FALIAS(item, dom_nodelist_item, NULL) + {NULL, NULL, NULL} +}; + +/* {{{ 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, *rv = NULL; + int index, ret; + dom_object *intern; + xmlNodePtr itemnode = NULL; + + dom_nnodemap_object *objmap; + xmlNodePtr nodep, curnode; + int count = 0; + HashTable *nodeht; + pval **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 { + 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(rv, itemnode, &ret, objmap->baseobj); + return; + } + } + + RETVAL_NULL(); +} +/* }}} end dom_nodelist_item */ +#endif diff --git a/ext/dom/notation.c b/ext/dom/notation.c new file mode 100644 index 000000000..ae2c57302 --- /dev/null +++ b/ext/dom/notation.c @@ -0,0 +1,102 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: notation.c,v 1.7.2.1 2004/11/18 19:55:00 rrichards Exp $ */ + +#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: +*/ + +zend_function_entry php_dom_notation_class_functions[] = { + {NULL, NULL, NULL} +}; + +/* {{{ 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) +{ + xmlNotationPtr nodep; + + nodep = (xmlNotationPtr) 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->PublicID) { + ZVAL_STRING(*retval, (char *) (nodep->PublicID), 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) +{ + xmlNotationPtr nodep; + + nodep = (xmlNotationPtr) 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->PublicID), 1); + } else { + ZVAL_EMPTY_STRING(*retval); + } + + return SUCCESS; +} + +/* }}} */ + +#endif diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c new file mode 100644 index 000000000..3187a04bd --- /dev/null +++ b/ext/dom/php_dom.c @@ -0,0 +1,1416 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: php_dom.c,v 1.60.2.6 2005/02/09 11:47:12 rrichards Exp $ */ + +#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 "ext/standard/info.h" +#define PHP_XPATH 1 +#define PHP_XPTR 2 + +zend_object_handlers dom_object_handlers; +zend_object_handlers dom_ze1_object_handlers; + +static HashTable classes; + +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_props *doc_props; + + if (document && document->doc_props) { + return document->doc_props; + } else { + doc_props = emalloc(sizeof(dom_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; + if (document) { + document->doc_props = doc_props; + } + return doc_props; + } +} +/* }}} */ + +/* {{{ dom_get_strict_error() */ +int dom_get_strict_error(php_libxml_ref_obj *document) { + int stricterror; + dom_doc_props *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) */ +xmlNodePtr dom_object_get_node(dom_object *obj) +{ + if (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) */ +dom_object *php_dom_object_get_data(xmlNodePtr obj) +{ + if (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 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 TSRMLS_CC); + } + + if (member == &tmp_member) { + zval_dtor(member); + } + return retval; +} + +/* {{{ dom_read_property */ +zval *dom_read_property(zval *object, zval *member, int type 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); + } + if (ret == SUCCESS) { + ret = hnd->read_func(obj, &retval TSRMLS_CC); + if (ret == SUCCESS) { + /* ensure we're creating a temporary variable */ + retval->refcount = 0; + } else { + retval = EG(uninitialized_zval_ptr); + } + } else { + std_hnd = zend_get_std_object_handlers(); + retval = std_hnd->read_property(object, member, type TSRMLS_CC); + } + + if (member == &tmp_member) { + zval_dtor(member); + } + return retval; +} +/* }}} */ + +/* {{{ dom_write_property */ +void dom_write_property(zval *object, zval *member, zval *value 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 TSRMLS_CC); + } + + if (member == &tmp_member) { + zval_dtor(member); + } +} +/* }}} */ + + +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) +{ +#ifdef HAVE_SIMPLEXML + zval *rv = NULL; + 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(rv, (xmlNodePtr) nodep, &ret, (dom_object *)nodeobj); + } else { + php_error(E_WARNING, "Invalid Nodetype to import"); + RETURN_NULL(); + } +#else + php_error(E_WARNING, "SimpleXML support is not enabled"); + return; +#endif +} +/* }}} */ + +zend_object_value dom_objects_store_clone_obj(zval *zobject TSRMLS_DC) +{ + zend_object_value retval; + void *new_object; + dom_object *intern; + 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); + + return retval; +} + +zend_object_value dom_objects_ze1_clone_obj(zval *zobject TSRMLS_DC) +{ + php_error(E_ERROR, "Cannot clone object of class %s due to 'zend.ze1_compatibility_mode'", Z_OBJCE_P(zobject)->name); + /* Return zobject->value.obj just to satisfy compiler */ + return zobject->value.obj; +} + +static zend_function_entry dom_functions[] = { + PHP_FE(dom_import_simplexml, NULL) + {NULL, NULL, NULL} +}; + +static zend_object_handlers* dom_get_obj_handlers(TSRMLS_D) { + if (EG(ze1_compatibility_mode)) { + return &dom_ze1_object_handlers; + } else { + return &dom_object_handlers; + } +} + +zend_module_entry dom_module_entry = { + STANDARD_MODULE_HEADER, + "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; + + memcpy(&dom_ze1_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + dom_ze1_object_handlers.read_property = dom_read_property; + dom_ze1_object_handlers.write_property = dom_write_property; + dom_object_handlers.get_property_ptr_ptr = dom_get_property_ptr_ptr; + dom_ze1_object_handlers.clone_obj = dom_objects_ze1_clone_obj; + + 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(), 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); +/* actualEncoding currently set as read only alias to encoding + dom_register_prop_handler(&dom_document_prop_handlers, "actualEncoding", dom_document_actual_encoding_read, dom_document_actual_encoding_write 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, "standalone", 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, "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, "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_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_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", NULL, 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); + /* Notation nodes are special */ + dom_register_prop_handler(&dom_notation_prop_handlers, "nodeName", dom_node_node_name_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_notation_prop_handlers, "nodeValue", dom_node_node_value_read, dom_node_node_value_write TSRMLS_CC); + dom_register_prop_handler(&dom_notation_prop_handlers, "attributes", dom_node_attributes_read, NULL TSRMLS_CC); + 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 { + 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: + 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_object *intern = (dom_object *)object; + + zend_hash_destroy(intern->std.properties); + FREE_HASHTABLE(intern->std.properties); + + if (intern->ptr != NULL) { + xmlXPathFreeContext((xmlXPathContextPtr) intern->ptr); + php_libxml_decrement_doc_ref((php_libxml_node_object *) intern TSRMLS_CC); + intern->ptr = NULL; + } + + 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_hash_destroy(intern->std.properties); + FREE_HASHTABLE(intern->std.properties); + + 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; + baseobj->is_ref = 1; + 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 TSRMLS_DC) +{ + zend_class_entry *base_class; + zval *tmp; + dom_object *intern; + + intern = emalloc(sizeof(dom_object)); + intern->std.ce = class_type; + intern->std.in_get = 0; + intern->std.in_set = 0; + 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); + + ALLOC_HASHTABLE(intern->std.properties); + zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + + 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 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); + } + + } + } + + *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 TSRMLS_CC); + + retval.handle = zend_objects_store_put(intern, NULL, (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_object *intern; + + intern = dom_objects_set_class(class_type TSRMLS_CC); + + retval.handle = zend_objects_store_put(intern, NULL, (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_hash_destroy(intern->std.properties); + FREE_HASHTABLE(intern->std.properties); + + 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 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 */ +zval *php_dom_create_object(xmlNodePtr obj, int *found, zval *wrapper_in, 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; + return_value->is_ref = 1; + 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\n", Z_TYPE_P(obj)); + ZVAL_NULL(wrapper); + return wrapper; + } + + 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, local) || xmlStrEqual("*", local)) { + if (ns == NULL || (nodep->ns != NULL && (xmlStrEqual(nodep->ns->href, ns) || xmlStrEqual("*", 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 = xmlSplitQName2(qname, (xmlChar **) prefix); + if (*localname == NULL) { + *localname = xmlStrdup(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, XML_XML_NAMESPACE)) || + (prefix && !strcmp (prefix, "xmlns") && strcmp(uri, DOM_XMLNS_NAMESPACE)) || + (prefix && !strcmp(uri, DOM_XMLNS_NAMESPACE) && strcmp (prefix, "xmlns")))) { + nsptr = xmlNewNs(nodep, uri, 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, "")) { + 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 000000000..c78a7c3c3 --- /dev/null +++ b/ext/dom/php_dom.h @@ -0,0 +1,143 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: php_dom.h,v 1.24.2.1 2004/08/30 15:09:07 rrichards Exp $ */ + +#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> +#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_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 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 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(E_WARNING, "Couldn't fetch %s", __intern->std.ce->name);\ + RETURN_NULL();\ + } \ +} + +#define DOM_NO_ARGS() \ + if (ZEND_NUM_ARGS() != 0) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expects exactly 0 parameters, %d given", ZEND_NUM_ARGS()); \ + 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 */ diff --git a/ext/dom/processinginstruction.c b/ext/dom/processinginstruction.c new file mode 100644 index 000000000..e7975d48b --- /dev/null +++ b/ext/dom/processinginstruction.c @@ -0,0 +1,173 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: processinginstruction.c,v 1.15.2.1 2004/11/18 19:55:00 rrichards Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class DOMProcessingInstruction extends DOMNode +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-1004215813 +* Since: +*/ + +zend_function_entry php_dom_processinginstruction_class_functions[] = { + PHP_ME(domprocessinginstruction, __construct, NULL, ZEND_ACC_PUBLIC) + {NULL, NULL, NULL} +}; + +/* {{{ 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; + + php_set_error_handling(EH_THROW, dom_domexception_class_entry 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) { + php_std_error_handling(); + return; + } + + php_std_error_handling(); + + 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 = (xmlNodePtr)intern->ptr; + 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(newval->refcount > 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 diff --git a/ext/dom/string_extend.c b/ext/dom/string_extend.c new file mode 100644 index 000000000..e79ebbec6 --- /dev/null +++ b/ext/dom/string_extend.c @@ -0,0 +1,67 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: string_extend.c,v 1.4 2004/01/08 08:15:17 andi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class domstringextend +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#i18n-methods-StringExtend +* Since: +*/ + +zend_function_entry php_dom_string_extend_class_functions[] = { + PHP_FALIAS(findOffset16, dom_string_extend_find_offset16, NULL) + PHP_FALIAS(findOffset32, dom_string_extend_find_offset32, NULL) + {NULL, NULL, NULL} +}; + +/* {{{ 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 diff --git a/ext/dom/tests/book.xml b/ext/dom/tests/book.xml new file mode 100644 index 000000000..95de0da86 --- /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 000000000..2c97807a5 --- /dev/null +++ b/ext/dom/tests/book.xml.gz diff --git a/ext/dom/tests/bug28721.phpt b/ext/dom/tests/bug28721.phpt new file mode 100644 index 000000000..e8e7d867d --- /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 000000000..26dd283c5 --- /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/dom001.phpt b/ext/dom/tests/dom001.phpt new file mode 100644 index 000000000..a0c78fbb0 --- /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 000000000..3343a1774 --- /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 000000000..e8c1db2ce --- /dev/null +++ b/ext/dom/tests/dom003.phpt @@ -0,0 +1,44 @@ +--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) { + var_dump($e); +} +print "--- Don't catch exception with try/catch\n"; +$rootNode->appendChild($rootNode); + + +?> +--EXPECTF-- +--- Catch exception with try/catch +object(DOMException)#%d (6) { + ["message:protected"]=> + string(23) "Hierarchy Request Error" + ["string:private"]=> + string(0) "" + ["file:protected"]=> + string(%d) "%s/ext/dom/tests/dom003.php" + ["line:protected"]=> + int(8) + ["trace:private"]=> + array(0) { + } + ["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 {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 000000000..82b7915f6 --- /dev/null +++ b/ext/dom/tests/dom004.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test 4: Streams Test +--SKIPIF-- +<?php +require_once('skipif.inc'); +array_search('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 000000000..c0f4bb714 --- /dev/null +++ b/ext/dom/tests/dom005.phpt @@ -0,0 +1,36 @@ +--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("DOCTYPE HTML","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><p> +This is a not well-formed<br/> +html files with undeclared entities  +</p></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><p> +This is a not well-formed<br> +html files with undeclared entities +</p></body> +</html> diff --git a/ext/dom/tests/dom006.phpt b/ext/dom/tests/dom006.phpt new file mode 100644 index 000000000..b8e8ed172 --- /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/dom_create_element.phpt b/ext/dom/tests/dom_create_element.phpt new file mode 100644 index 000000000..3f307099b --- /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 000000000..81744aa26 --- /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_test.inc b/ext/dom/tests/dom_test.inc new file mode 100644 index 000000000..86b426f8f --- /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 000000000..92df048bc --- /dev/null +++ b/ext/dom/tests/dom_xinclude.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test: Xinclude and Streams +--SKIPIF-- +<?php +require_once('skipif.inc'); +array_search('compress.zlib', stream_get_wrappers()) or die('skip compress.zlib wrapper is not available'); +?> +--FILE-- +<?php +$dom = new domdocument; +$dom->load(dirname(__FILE__)."/xinclude.xml"); +$dom->xinclude(); +print $dom->saveXML()."\n"; +foreach ($dom->documentElement->childNodes as $node) { + print $node->nodeName."\n"; +} + +--EXPECT-- +<?xml version="1.0"?> +<foo xmlns:xi="http://www.w3.org/2001/XInclude"> + <book xml:base="compress.zlib://ext/dom/tests/book.xml"> + <title>The Grapes of Wrath</title> + <author>John Steinbeck</author> + </book><book xml:base="compress.zlib://ext/dom/tests/book.xml"> + <title>The Pearl</title> + <author>John Steinbeck</author> + </book> + </foo> + +#text +book +book +#text diff --git a/ext/dom/tests/skipif.inc b/ext/dom/tests/skipif.inc new file mode 100644 index 000000000..08fd695d9 --- /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 000000000..fe6d0d3db --- /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 000000000..27efa91ae --- /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 000000000..1fb4aeaf0 --- /dev/null +++ b/ext/dom/text.c @@ -0,0 +1,202 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: text.c,v 1.20.2.1 2004/11/18 19:55:00 rrichards Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" +#include "dom_ce.h" + +/* +* class DOMText extends DOMCharacterData +* +* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-1312295772 +* Since: +*/ + +zend_function_entry php_dom_text_class_functions[] = { + PHP_FALIAS(splitText, dom_text_split_text, NULL) + PHP_FALIAS(isWhitespaceInElementContent, dom_text_is_whitespace_in_element_content, NULL) + PHP_FALIAS(replaceWholeText, dom_text_replace_whole_text, NULL) + PHP_ME(domtext, __construct, NULL, ZEND_ACC_PUBLIC) + {NULL, NULL, NULL} +}; + +/* {{{ 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; + + php_set_error_handling(EH_THROW, dom_domexception_class_entry TSRMLS_CC); + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|s", &id, dom_text_class_entry, &value, &value_len) == FAILURE) { + php_std_error_handling(); + return; + } + + php_std_error_handling(); + 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 = (xmlNodePtr)intern->ptr; + 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; + + node = dom_object_get_node(obj); + + if (node == NULL) { + php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC); + return FAILURE; + } + + ALLOC_ZVAL(*retval); + wholetext = xmlNodeListGetString(node->doc, node, 1); + ZVAL_STRING(*retval, wholetext, 1); + + xmlFree(wholetext); + + 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) { + RETURN_FALSE; + } + + cur = xmlNodeGetContent(node); + if (cur == NULL) { + RETURN_FALSE; + } + length = xmlStrlen(cur); + + if (offset > length || offset < 0) { + xmlFree(cur); + RETURN_FALSE; + } + + first = xmlStrndup(cur, offset); + second = xmlStrdup(cur + offset); + + xmlFree(cur); + + xmlNodeSetContentLen(node, first, offset); + nnode = xmlNewDocText(node->doc, second); + + xmlFree(first); + xmlFree(second); + + 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, NULL, 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 diff --git a/ext/dom/typeinfo.c b/ext/dom/typeinfo.c new file mode 100644 index 000000000..b9d6b5d1b --- /dev/null +++ b/ext/dom/typeinfo.c @@ -0,0 +1,74 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: typeinfo.c,v 1.4.2.1 2004/11/18 19:55:00 rrichards Exp $ */ + +#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 +*/ + +zend_function_entry php_dom_typeinfo_class_functions[] = { + {NULL, NULL, NULL} +}; + +/* {{{ 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 diff --git a/ext/dom/userdatahandler.c b/ext/dom/userdatahandler.c new file mode 100644 index 000000000..be5172d68 --- /dev/null +++ b/ext/dom/userdatahandler.c @@ -0,0 +1,55 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: userdatahandler.c,v 1.4.2.1 2004/11/18 19:55:00 rrichards Exp $ */ + +#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 +*/ + +zend_function_entry php_dom_userdatahandler_class_functions[] = { + PHP_FALIAS(handle, dom_userdatahandler_handle, NULL) + {NULL, NULL, NULL} +}; + +/* {{{ 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 diff --git a/ext/dom/xml_common.h b/ext/dom/xml_common.h new file mode 100644 index 000000000..7c9292b83 --- /dev/null +++ b/ext/dom/xml_common.h @@ -0,0 +1,101 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: xml_common.h,v 1.19 2004/01/08 17:32:03 sniper Exp $ */ + +#ifndef PHP_XML_COMMON_H +#define PHP_XML_COMMON_H + +#include "ext/libxml/php_libxml.h" + +typedef struct _dom_doc_props { + int formatoutput; + int validateonparse; + int resolveexternals; + int preservewhitespace; + int substituteentities; + int stricterror; +} dom_doc_props; + +typedef dom_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 */ +#endif /* PHP_WIN32 */ + +#define PHP_DOM_EXPORT(__type) PHPAPI __type + +PHP_DOM_EXPORT(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 *in, 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(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(E_WARNING, "Couldn't fetch %s", __intern->std.ce->name);\ + RETURN_NULL();\ + } \ + } \ +} + +#define DOM_RET_OBJ(zval, obj, ret, domobject) \ + if (NULL == (zval = php_dom_create_object(obj, ret, zval, return_value, domobject TSRMLS_CC))) { \ + php_error(E_WARNING, "Cannot create required DOM object"); \ + RETURN_FALSE; \ + } + +#define DOM_GET_THIS(zval) \ + if (NULL == (zval = getThis())) { \ + php_error(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 diff --git a/ext/dom/xpath.c b/ext/dom/xpath.c new file mode 100644 index 000000000..ed45d3688 --- /dev/null +++ b/ext/dom/xpath.c @@ -0,0 +1,262 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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: xpath.c,v 1.22.2.1 2004/11/18 19:55:00 rrichards Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#if HAVE_LIBXML && HAVE_DOM +#include "php_dom.h" + + +/* +* class DOMXPath +*/ + +#if defined(LIBXML_XPATH_ENABLED) + +zend_function_entry php_dom_xpath_class_functions[] = { + PHP_ME(domxpath, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_FALIAS(registerNamespace, dom_xpath_register_ns, NULL) + PHP_FALIAS(query, dom_xpath_query, NULL) + {NULL, NULL, NULL} +}; + +/* {{{ proto void DOMXPath::__construct(DOMDocument doc); */ +PHP_METHOD(domxpath, __construct) +{ + zval *id, *doc; + xmlDocPtr docp = NULL; + dom_object *docobj, *intern; + xmlXPathContextPtr ctx, oldctx; + + php_set_error_handling(EH_THROW, dom_domexception_class_entry 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) { + php_std_error_handling(); + return; + } + + php_std_error_handling(); + 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_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); + } + intern->ptr = ctx; + 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; + + ctx = (xmlXPathContextPtr) obj->ptr; + + if (ctx) { + docp = (xmlDocPtr) ctx->doc; + } + + ALLOC_ZVAL(*retval); + if (NULL == (*retval = php_dom_create_object((xmlNodePtr) docp, &ret, NULL, *retval, obj TSRMLS_CC))) { + php_error(E_WARNING, "Cannot create required DOM object"); + return FAILURE; + } + 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_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_object *)zend_object_store_get_object(id TSRMLS_CC); + + ctxp = (xmlXPathContextPtr) intern->ptr; + if (ctxp == NULL) { + php_error(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; + +} + +/* {{{ proto DOMNodeList dom_xpath_query(string expr [,DOMNode context]); */ +PHP_FUNCTION(dom_xpath_query) +{ + zval *id, *retval, *context = NULL; + xmlXPathContextPtr ctxp; + xmlNodePtr nodep = NULL; + xmlXPathObjectPtr xpathobjp; + int expr_len, ret, nsnbr = 0; + dom_object *intern, *nodeobj; + char *expr; + xmlDoc *docp = NULL; + xmlNsPtr *ns; + + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|O", &id, dom_xpath_class_entry, &expr, &expr_len, &context, dom_node_class_entry) == FAILURE) { + return; + } + + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + + ctxp = (xmlXPathContextPtr) intern->ptr; + if (ctxp == NULL) { + php_error(E_WARNING, "Invalid XPath Context"); + RETURN_FALSE; + } + + docp = (xmlDocPtr) ctxp->doc; + if (docp == NULL) { + php_error(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(E_WARNING, "Node From Wrong Document"); + RETURN_FALSE; + } + + ctxp->node = nodep; + + /* 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; + } + + + MAKE_STD_ZVAL(retval); + array_init(retval); + + if (xpathobjp->type == XPATH_NODESET) { + int i; + xmlNodeSetPtr nodesetp; + + if (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, NULL, child, intern TSRMLS_CC); + add_next_index_zval(retval, child); + } + } + } + + php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC); + intern = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC); + dom_xpath_iter(retval, intern); + + xmlXPathFreeObject(xpathobjp); +} +/* }}} end dom_xpath_query */ + +#endif /* LIBXML_XPATH_ENABLED */ + +/* }}} */ +#endif |