diff options
Diffstat (limited to 'ext/dom/node.c')
-rw-r--r-- | ext/dom/node.c | 1274 |
1 files changed, 1274 insertions, 0 deletions
diff --git a/ext/dom/node.c b/ext/dom/node.c new file mode 100644 index 0000000000..8b9ab306cf --- /dev/null +++ b/ext/dom/node.c @@ -0,0 +1,1274 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 4 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2003 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.02 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available at through the world-wide-web at | + | http://www.php.net/license/2_02.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Christian Stocker <chregu@php.net> | + | Rob Richards <rrichards@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#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} +}; + +/* {{{ proto 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; + char *str = NULL; + + nodep = obj->ptr; + + switch (nodep->type) { + case XML_ATTRIBUTE_NODE: + case XML_ELEMENT_NODE: + 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; + case XML_NAMESPACE_DECL: + if (nodep->ns != NULL) { + str = (char *) nodep->ns->prefix; + } + 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); + } + + return SUCCESS; + +} + +/* }}} */ + + + +/* {{{ proto 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 = obj->ptr; +/* TODO: Element node is invalid for this property - +currently here as a convience method while developing */ + 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; + default: + str = NULL; + break; + } + + ALLOC_ZVAL(*retval); + + if(str != NULL) { + ZVAL_STRING(*retval, str, 1); + xmlFree(str); + } else { + ZVAL_EMPTY_STRING(*retval); + } + + + return SUCCESS; + +} + +int dom_node_node_value_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + xmlNode *nodep; + + nodep = obj->ptr; + + switch (nodep->type) { + 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: + xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1); + break; + default: + break; + } + + return SUCCESS; +} + +/* }}} */ + + + +/* {{{ proto nodeType unsigned short +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 = obj->ptr; + + ALLOC_ZVAL(*retval); + ZVAL_LONG(*retval, nodep->type); + return SUCCESS; +} + +/* }}} */ + + + +/* {{{ proto parentNode node +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) +{ + zval *wrapper; + xmlNode *nodep, *nodeparent; + int ret; + + nodep = obj->ptr; + + nodeparent = nodep->parent; + if (!nodeparent) { + return FAILURE; + } + + wrapper = dom_object_get_data(nodeparent); + if (wrapper == NULL) { + ALLOC_ZVAL(*retval); + } + if (NULL == (*retval = php_dom_create_object(nodeparent, &ret, wrapper, *retval TSRMLS_CC))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); + return FAILURE; + } + return SUCCESS; +} + +/* }}} */ + + + +/* {{{ proto childNodes nodelist +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) +{ + xmlNodePtr nodep, last; + int ret; + nodep = obj->ptr; + + if ((nodep->type == XML_DOCUMENT_NODE) || (nodep->type == XML_HTML_DOCUMENT_NODE)) { + last = ((xmlDoc *) nodep)->children; + } else { + last = nodep->children; + } + MAKE_STD_ZVAL(*retval); + array_init(*retval); + + if (last) { + while (last) { + zval *child = NULL; + zval *wrapper; + wrapper = dom_object_get_data(last); + if (wrapper == NULL) { + MAKE_STD_ZVAL(child); + } + child = php_dom_create_object(last, &ret, wrapper, child TSRMLS_CC); + add_next_index_zval(*retval, child); + last = last->next; + } + } + return SUCCESS; +} + +/* }}} */ + + + +/* {{{ proto firstChild node +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) +{ + zval *wrapper; + xmlNode *nodep, *first; + int ret; + + nodep = obj->ptr; + + + first = nodep->children; + if (!first) { + return FAILURE; + } + + wrapper = dom_object_get_data(first); + if (wrapper == NULL) { + ALLOC_ZVAL(*retval); + } + if (NULL == (*retval = php_dom_create_object(first, &ret, wrapper, *retval TSRMLS_CC))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); + return FAILURE; + } + return SUCCESS; +} + +/* }}} */ + + + +/* {{{ proto lastChild node +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) +{ + zval *wrapper; + xmlNode *nodep, *last; + int ret; + + nodep = obj->ptr; + + last = nodep->last; + if (!last) { + return FAILURE; + } + + wrapper = dom_object_get_data(last); + if (wrapper == NULL) { + ALLOC_ZVAL(*retval); + } + if (NULL == (*retval = php_dom_create_object(last, &ret, wrapper, *retval TSRMLS_CC))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); + return FAILURE; + } + return SUCCESS; +} + +/* }}} */ + + + +/* {{{ proto previousSibling node +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) +{ + zval *wrapper; + xmlNode *nodep, *prevsib; + int ret; + + nodep = obj->ptr; + + prevsib = nodep->prev; + if (!prevsib) { + return FAILURE; + } + + wrapper = dom_object_get_data(prevsib); + if (wrapper == NULL) { + ALLOC_ZVAL(*retval); + } + if (NULL == (*retval = php_dom_create_object(prevsib, &ret, wrapper, *retval TSRMLS_CC))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); + return FAILURE; + } + return SUCCESS; +} + +/* }}} */ + + + +/* {{{ proto nextSibling node +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) +{ + zval *wrapper; + xmlNode *nodep, *nextsib; + int ret; + + nodep = obj->ptr; + + nextsib = nodep->next; + if (!nextsib) { + return FAILURE; + } + + wrapper = dom_object_get_data(nextsib); + if (wrapper == NULL) { + ALLOC_ZVAL(*retval); + } + if (NULL == (*retval = php_dom_create_object(nextsib, &ret, wrapper, *retval TSRMLS_CC))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); + return FAILURE; + } + return SUCCESS; +} + +/* }}} */ + + + +/* {{{ proto attributes namednodemap +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) +{ + xmlNodePtr nodep; + xmlAttr *attr; + + int ret; + nodep = obj->ptr; + + ALLOC_ZVAL(*retval); + + if (nodep->type == XML_ELEMENT_NODE) { + attr = nodep->properties; + array_init(*retval); + + while (attr) { + zval *curattr = NULL; + zval *wrapper; + wrapper = dom_object_get_data((xmlNodePtr) attr); + if (wrapper == NULL) { + MAKE_STD_ZVAL(curattr); + } + curattr = php_dom_create_object((xmlNodePtr) attr, &ret, wrapper, curattr TSRMLS_CC); + add_assoc_zval(*retval, (char *) attr->name, curattr); + attr = attr->next; + } + } else { + ZVAL_NULL(*retval); + } + + return SUCCESS; +} + +/* }}} */ + + + +/* {{{ proto ownerDocument dom_document +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) +{ + zval *wrapper; + xmlNode *nodep; + xmlDocPtr docp; + int ret; + + nodep = obj->ptr; + + 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; + } + + wrapper = dom_object_get_data((xmlNodePtr) docp); + if (wrapper == NULL) { + ALLOC_ZVAL(*retval); + } + if (NULL == (*retval = php_dom_create_object((xmlNodePtr) docp, &ret, wrapper, *retval TSRMLS_CC))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); + return FAILURE; + } + return SUCCESS; +} + +/* }}} */ + + + +/* {{{ proto 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 = obj->ptr; + + switch (nodep->type) { + case XML_ELEMENT_NODE: + case XML_ATTRIBUTE_NODE: + 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_EMPTY_STRING(*retval); + } + + return SUCCESS; +} + +/* }}} */ + + + +/* {{{ proto 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 = obj->ptr; + + switch (nodep->type) { + case XML_ELEMENT_NODE: + case XML_ATTRIBUTE_NODE: + ns = nodep->ns; + if (ns != NULL) { + if (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) +{ + xmlNode *nodep; + xmlDocPtr doc; + xmlNsPtr ns, curns = NULL; + char *strURI; + char *prefix; + + nodep = obj->ptr; + + switch (nodep->type) { + case XML_ELEMENT_NODE: + case XML_ATTRIBUTE_NODE: + ns = nodep->ns; + strURI = NULL; + if (nodep->ns != NULL) { + strURI = (char *) nodep->ns->href; + } + prefix = Z_STRVAL_P(newval); + 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"))) { + + /* TODO: throw error - find out how to without a return_value + php_dom_throw_error(NAMESPACE_ERR, &return_value TSRMLS_CC); */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Namespace"); + return FAILURE; + } + ns = xmlNewNs(NULL, nodep->ns->href, (xmlChar *)prefix); + if (nodep->doc != NULL) { + doc = nodep->doc; + if (doc->oldNs == NULL) { + doc->oldNs = (xmlNsPtr) xmlMalloc(sizeof(xmlNs)); + 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"); + } + + curns = doc->oldNs; + while (curns->next != NULL) { + curns = curns->next; + } + curns->next = ns; + } + + nodep->ns = curns; + break; + default: + break; + } + + return SUCCESS; +} + +/* }}} */ + + + +/* {{{ proto 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 = obj->ptr; + + ALLOC_ZVAL(*retval); + + if (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE) { + ZVAL_STRING(*retval, (char *) (nodep->name), 1); + } else { + ZVAL_NULL(*retval); + } + + return SUCCESS; +} + +/* }}} */ + + + +/* {{{ proto 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) +{ + /* TODO: Implement this feature */ + ALLOC_ZVAL(*retval); + ZVAL_NULL(*retval); + return SUCCESS; +} + +/* }}} */ + + + +/* {{{ proto 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 = obj->ptr; + + 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(node newChild, node 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, *rv = NULL; + xmlNodePtr child, new_child, parentp, refp; + int ret; + + DOM_GET_THIS_OBJ(parentp, id, xmlNodePtr); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oo!", &node, &ref) == FAILURE) { + return; + } + + DOM_GET_OBJ(child, node, xmlNodePtr); + + new_child = NULL; + + if (dom_hierarchy(parentp, child) == FAILURE) { + php_dom_throw_error(HIERARCHY_REQUEST_ERR, &return_value TSRMLS_CC); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Hierarchy Request Error"); + } + + if (child->doc != parentp->doc && child->doc != NULL) { + php_dom_throw_error(WRONG_DOCUMENT_ERR, &return_value TSRMLS_CC); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't add newnode as it was created from a different document"); + RETURN_FALSE; + } + + if (ref != NULL) { + DOM_GET_OBJ(refp, ref, xmlNodePtr); + if (refp->parent != parentp) { + php_dom_throw_error(NOT_FOUND_ERR, &return_value TSRMLS_CC); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't add newnode as refnode is not child of node"); + RETURN_FALSE; + } + + if (child->parent != NULL) { + xmlUnlinkNode(child); + } + + if (child->type == XML_TEXT_NODE) { + if (refp->type == XML_TEXT_NODE) { + xmlChar *tmp; + + tmp = xmlStrdup(child->content); + tmp = xmlStrcat(tmp, refp->content); + xmlNodeSetContent(refp, tmp); + xmlFree(tmp); + node_free_resource(child TSRMLS_CC); + DOM_RET_OBJ(rv, refp, &ret); + return; + } + if ((refp->prev != NULL) && (refp->prev->type == XML_TEXT_NODE) + && (refp->name == refp->prev->name)) { + xmlNodeAddContent(refp->prev, child->content); + node_free_resource(child TSRMLS_CC); + DOM_RET_OBJ(rv, refp->prev, &ret); + return; + } + } 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); + node_free_resource((xmlNodePtr) lastattr TSRMLS_CC); + xmlFreeProp(lastattr); + } else { + DOM_RET_OBJ(rv, child, &ret); + return; + } + } + + } + new_child = xmlAddPrevSibling(refp, child); + } else { + if (child->parent == parentp){ + xmlUnlinkNode(child); + } + if (child->type == XML_TEXT_NODE) { + if ((parentp->type == XML_TEXT_NODE) && + (parentp->content != NULL) && + (parentp != child)) { + xmlNodeAddContent(parentp, child->content); + node_free_resource(child TSRMLS_CC); + DOM_RET_OBJ(rv, parentp, &ret); + return; + } + if ((parentp->last != NULL) && (parentp->last->type == XML_TEXT_NODE) && + (parentp->last->name == child->name) && + (parentp->last != child)) { + xmlNodeAddContent(parentp->last, child->content); + node_free_resource(child TSRMLS_CC); + DOM_RET_OBJ(rv, parentp->last, &ret); + return; + } + } 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); + node_free_resource((xmlNodePtr) lastattr TSRMLS_CC); + xmlFreeProp(lastattr); + } else { + DOM_RET_OBJ(rv, child, &ret); + return; + } + } + } else if (child->type == XML_DOCUMENT_FRAG_NODE) { + new_child = xmlAddChildList(parentp, child->children); + if (new_child != NULL) { + child->children = NULL; + } + dom_add_to_list(child, (xmlDocPtr) child->doc TSRMLS_CC); + DOM_RET_OBJ(rv, new_child, &ret); + return; + } + 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_del_from_list(child, (xmlDocPtr) child->doc TSRMLS_CC); + + DOM_RET_OBJ(rv, new_child, &ret); + +} +/* }}} end dom_node_insert_before */ + + +/* {{{ proto domnode dom_node_replace_child(node newChild, node 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; + int foundoldchild = 0; + int ret; + + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oo", &newnode, &oldnode) == FAILURE) { + return; + } + + DOM_GET_OBJ(newchild, newnode, xmlNodePtr); + DOM_GET_OBJ(oldchild, oldnode, xmlNodePtr); + + children = nodep->children; + if (!children) { + RETURN_FALSE; + } + + if (newchild->doc != nodep->doc && newchild->doc != NULL) { + php_dom_throw_error(WRONG_DOCUMENT_ERR, &return_value TSRMLS_CC); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't add newnode as it was created from a different document"); + RETURN_FALSE; + } + + if (dom_hierarchy(nodep, newchild) == FAILURE) { + php_dom_throw_error(HIERARCHY_REQUEST_ERR, &return_value TSRMLS_CC); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Hierarchy Request Error"); + } + + /* 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) { + zval *rv = NULL; + if (oldchild != newchild) { + xmlNodePtr node; + if (newchild->parent == NULL && newchild->doc != NULL) { + dom_del_from_list(newchild, (xmlDocPtr) newchild->doc TSRMLS_CC); + } + if((node = xmlReplaceNode(oldchild, newchild)) != NULL) { + dom_add_to_list(node, (xmlDocPtr) node->doc TSRMLS_CC); + } + } + DOM_RET_OBJ(rv, oldchild, &ret); + return; + } else { + php_dom_throw_error(NOT_FOUND_ERR, &return_value TSRMLS_CC); + RETURN_FALSE; + } + +} +/* }}} end dom_node_replace_child */ + + +/* {{{ proto domnode dom_node_remove_child(node 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; + int ret; + + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &node) == FAILURE) { + return; + } + + DOM_GET_OBJ(child, node, xmlNodePtr); + + children = nodep->children; + if (!children) { + php_dom_throw_error(NOT_FOUND_ERR, &return_value TSRMLS_CC); + RETURN_FALSE; + } + + while (children) { + if (children == child) { + zval *rv = NULL; + xmlUnlinkNode(child); + dom_add_to_list(child, (xmlDocPtr) child->doc TSRMLS_CC); + DOM_RET_OBJ(rv, child, &ret); + return; + } + children = children->next; + } + + php_dom_throw_error(NOT_FOUND_ERR, &return_value TSRMLS_CC); + RETURN_FALSE +} +/* }}} end dom_node_remove_child */ + + +/* {{{ proto domnode dom_node_append_child(node 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; + int ret; + + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &node) == FAILURE) { + return; + } + + DOM_GET_OBJ(child, node, xmlNodePtr); + + if (dom_hierarchy(nodep, child) == FAILURE) { + php_dom_throw_error(HIERARCHY_REQUEST_ERR, &return_value TSRMLS_CC); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Hierarchy Request Error"); + } + + if (!(child->doc == NULL || child->doc == nodep->doc)) { + php_dom_throw_error(WRONG_DOCUMENT_ERR, &return_value TSRMLS_CC); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't append node, which is in a different document than the parent node"); + RETURN_FALSE; + } + + if (child->parent != NULL){ + xmlUnlinkNode(child); + } + + if (child->type == XML_TEXT_NODE) { + if ((nodep->type == XML_TEXT_NODE) && + (nodep->content != NULL)) { + xmlNodeAddContent(nodep, child->content); + node_free_resource(child TSRMLS_CC); + DOM_RET_OBJ(rv, nodep, &ret); + return; + } + if ((nodep->last != NULL) && (nodep->last->type == XML_TEXT_NODE) && + (nodep->last->name == child->name)) { + xmlNodeAddContent(nodep->last, child->content); + node_free_resource(child TSRMLS_CC); + DOM_RET_OBJ(rv, nodep->last, &ret); + return; + } + } 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); + node_free_resource((xmlNodePtr) lastattr TSRMLS_CC); + xmlFreeProp(lastattr); + } + } + } else if (child->type == XML_DOCUMENT_FRAG_NODE) { + new_child = xmlAddChildList(nodep, child->children); + if (new_child != NULL) { + child->children = NULL; + } + dom_add_to_list(child, (xmlDocPtr) child->doc TSRMLS_CC); + DOM_RET_OBJ(rv, new_child, &ret); + return; + } + + new_child = xmlAddChild(nodep, child); + + if (new_child == NULL) { + dom_add_to_list(child, (xmlDocPtr) child->doc TSRMLS_CC); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't append node"); + RETURN_FALSE; + } + + dom_del_from_list(child, (xmlDocPtr) child->doc TSRMLS_CC); + + DOM_RET_OBJ(rv, new_child, &ret); +} +/* }}} 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_GET_THIS_OBJ(nodep, id, xmlNodePtr); + + DOM_NO_ARGS(); + + 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; + long recursive = 0; + + DOM_GET_THIS_OBJ(n, id, xmlNodePtr); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &recursive) == FAILURE) { + return; + } + + node = xmlCopyNode(n, recursive); + if (!node) { + RETURN_FALSE; + } + dom_add_to_list(node, (xmlDocPtr) node->doc TSRMLS_CC); + + DOM_RET_OBJ(rv, node, &ret); +} +/* }}} end dom_node_clone_node */ + + + +/* {{{ proto dom_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_GET_THIS_OBJ(nodep, id, xmlNodePtr); + + DOM_NO_ARGS(); + + 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#Level-2-Core-Node-supports +Since: DOM Level 2 +*/ +PHP_FUNCTION(dom_node_is_supported) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} 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_GET_THIS_OBJ(nodep, id, xmlNodePtr); + + DOM_NO_ARGS(); + + if (nodep->type != XML_ELEMENT_NODE) + RETURN_FALSE; + + if (nodep->properties) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} end dom_node_has_attributes */ + + +/* {{{ proto unsigned short dom_node_compare_document_position(node 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(node 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_GET_THIS_OBJ(nodep, id, xmlNodePtr); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &node) == FAILURE) { + return; + } + + DOM_GET_OBJ(nodeotherp, node, xmlNodePtr); + + if (nodep == nodeotherp) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} end dom_node_is_same_node */ + + +/* {{{ proto domstring 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) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_node_lookup_prefix */ + + +/* {{{ proto boolean dom_node_is_default_namespace(string namespaceURI); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isDefaultNamespace +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_node_is_default_namespace) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_node_is_default_namespace */ + + +/* {{{ proto domstring dom_node_lookup_namespace_uri(string prefix); +URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-lookupNamespaceURI +Since: DOM Level 3 +*/ +PHP_FUNCTION(dom_node_lookup_namespace_uri) +{ + DOM_NOT_IMPLEMENTED(); +} +/* }}} end dom_node_lookup_namespace_uri */ + + +/* {{{ proto boolean dom_node_is_equal_node(node 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 */ |