Annotation of embedaddon/php/ext/dom/element.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
                      5:    | Copyright (c) 1997-2012 The PHP Group                                |
                      6:    +----------------------------------------------------------------------+
                      7:    | This source file is subject to version 3.01 of the PHP license,      |
                      8:    | that is bundled with this package in the file LICENSE, and is        |
                      9:    | available through the world-wide-web at the following url:           |
                     10:    | http://www.php.net/license/3_01.txt                                  |
                     11:    | If you did not receive a copy of the PHP license and are unable to   |
                     12:    | obtain it through the world-wide-web, please send a note to          |
                     13:    | license@php.net so we can mail you a copy immediately.               |
                     14:    +----------------------------------------------------------------------+
                     15:    | Authors: Christian Stocker <chregu@php.net>                          |
                     16:    |          Rob Richards <rrichards@php.net>                            |
                     17:    +----------------------------------------------------------------------+
                     18: */
                     19: 
                     20: /* $Id: element.c 321634 2012-01-01 13:15:04Z felipe $ */
                     21: 
                     22: #ifdef HAVE_CONFIG_H
                     23: #include "config.h"
                     24: #endif
                     25: 
                     26: #include "php.h"
                     27: #if HAVE_LIBXML && HAVE_DOM
                     28: #include "php_dom.h"
                     29: 
                     30: /* {{{ arginfo */
                     31: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_attribute, 0, 0, 1)
                     32:        ZEND_ARG_INFO(0, name)
                     33: ZEND_END_ARG_INFO();
                     34: 
                     35: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_attribute, 0, 0, 2)
                     36:        ZEND_ARG_INFO(0, name)
                     37:        ZEND_ARG_INFO(0, value)
                     38: ZEND_END_ARG_INFO();
                     39: 
                     40: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_remove_attribute, 0, 0, 1)
                     41:        ZEND_ARG_INFO(0, name)
                     42: ZEND_END_ARG_INFO();
                     43: 
                     44: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_attribute_node, 0, 0, 1)
                     45:        ZEND_ARG_INFO(0, name)
                     46: ZEND_END_ARG_INFO();
                     47: 
                     48: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_attribute_node, 0, 0, 1)
                     49:        ZEND_ARG_OBJ_INFO(0, newAttr, DOMAttr, 0)
                     50: ZEND_END_ARG_INFO();
                     51: 
                     52: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_remove_attribute_node, 0, 0, 1)
                     53:        ZEND_ARG_OBJ_INFO(0, oldAttr, DOMAttr, 0)
                     54: ZEND_END_ARG_INFO();
                     55: 
                     56: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_elements_by_tag_name, 0, 0, 1)
                     57:        ZEND_ARG_INFO(0, name)
                     58: ZEND_END_ARG_INFO();
                     59: 
                     60: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_attribute_ns, 0, 0, 2)
                     61:        ZEND_ARG_INFO(0, namespaceURI)
                     62:        ZEND_ARG_INFO(0, localName)
                     63: ZEND_END_ARG_INFO();
                     64: 
                     65: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_attribute_ns, 0, 0, 3)
                     66:        ZEND_ARG_INFO(0, namespaceURI)
                     67:        ZEND_ARG_INFO(0, qualifiedName)
                     68:        ZEND_ARG_INFO(0, value)
                     69: ZEND_END_ARG_INFO();
                     70: 
                     71: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_remove_attribute_ns, 0, 0, 2)
                     72:        ZEND_ARG_INFO(0, namespaceURI)
                     73:        ZEND_ARG_INFO(0, localName)
                     74: ZEND_END_ARG_INFO();
                     75: 
                     76: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_attribute_node_ns, 0, 0, 2)
                     77:        ZEND_ARG_INFO(0, namespaceURI)
                     78:        ZEND_ARG_INFO(0, localName)
                     79: ZEND_END_ARG_INFO();
                     80: 
                     81: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_attribute_node_ns, 0, 0, 1)
                     82:        ZEND_ARG_OBJ_INFO(0, newAttr, DOMAttr, 0)
                     83: ZEND_END_ARG_INFO();
                     84: 
                     85: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_elements_by_tag_name_ns, 0, 0, 2)
                     86:        ZEND_ARG_INFO(0, namespaceURI)
                     87:        ZEND_ARG_INFO(0, localName)
                     88: ZEND_END_ARG_INFO();
                     89: 
                     90: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_has_attribute, 0, 0, 1)
                     91:        ZEND_ARG_INFO(0, name)
                     92: ZEND_END_ARG_INFO();
                     93: 
                     94: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_has_attribute_ns, 0, 0, 2)
                     95:        ZEND_ARG_INFO(0, namespaceURI)
                     96:        ZEND_ARG_INFO(0, localName)
                     97: ZEND_END_ARG_INFO();
                     98: 
                     99: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_id_attribute, 0, 0, 2)
                    100:        ZEND_ARG_INFO(0, name)
                    101:        ZEND_ARG_INFO(0, isId)
                    102: ZEND_END_ARG_INFO();
                    103: 
                    104: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_id_attribute_ns, 0, 0, 3)
                    105:        ZEND_ARG_INFO(0, namespaceURI)
                    106:        ZEND_ARG_INFO(0, localName)
                    107:        ZEND_ARG_INFO(0, isId)
                    108: ZEND_END_ARG_INFO();
                    109: 
                    110: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_id_attribute_node, 0, 0, 2)
                    111:        ZEND_ARG_OBJ_INFO(0, attr, DOMAttr, 0)
                    112:        ZEND_ARG_INFO(0, isId)
                    113: ZEND_END_ARG_INFO();
                    114: 
                    115: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_construct, 0, 0, 1)
                    116:        ZEND_ARG_INFO(0, name)
                    117:        ZEND_ARG_INFO(0, value)
                    118:        ZEND_ARG_INFO(0, uri)
                    119: ZEND_END_ARG_INFO();
                    120: /* }}} */
                    121: 
                    122: /*
                    123: * class DOMElement extends DOMNode 
                    124: *
                    125: * URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-745549614
                    126: * Since: 
                    127: */
                    128: 
                    129: const zend_function_entry php_dom_element_class_functions[] = { /* {{{ */
                    130:        PHP_FALIAS(getAttribute, dom_element_get_attribute, arginfo_dom_element_get_attribute)
                    131:        PHP_FALIAS(setAttribute, dom_element_set_attribute, arginfo_dom_element_set_attribute)
                    132:        PHP_FALIAS(removeAttribute, dom_element_remove_attribute, arginfo_dom_element_remove_attribute)
                    133:        PHP_FALIAS(getAttributeNode, dom_element_get_attribute_node, arginfo_dom_element_get_attribute_node)
                    134:        PHP_FALIAS(setAttributeNode, dom_element_set_attribute_node, arginfo_dom_element_set_attribute_node)
                    135:        PHP_FALIAS(removeAttributeNode, dom_element_remove_attribute_node, arginfo_dom_element_remove_attribute_node)
                    136:        PHP_FALIAS(getElementsByTagName, dom_element_get_elements_by_tag_name, arginfo_dom_element_get_elements_by_tag_name)
                    137:        PHP_FALIAS(getAttributeNS, dom_element_get_attribute_ns, arginfo_dom_element_get_attribute_ns)
                    138:        PHP_FALIAS(setAttributeNS, dom_element_set_attribute_ns, arginfo_dom_element_set_attribute_ns)
                    139:        PHP_FALIAS(removeAttributeNS, dom_element_remove_attribute_ns, arginfo_dom_element_remove_attribute_ns)
                    140:        PHP_FALIAS(getAttributeNodeNS, dom_element_get_attribute_node_ns, arginfo_dom_element_get_attribute_node_ns)
                    141:        PHP_FALIAS(setAttributeNodeNS, dom_element_set_attribute_node_ns, arginfo_dom_element_set_attribute_node_ns)
                    142:        PHP_FALIAS(getElementsByTagNameNS, dom_element_get_elements_by_tag_name_ns, arginfo_dom_element_get_elements_by_tag_name_ns)
                    143:        PHP_FALIAS(hasAttribute, dom_element_has_attribute, arginfo_dom_element_has_attribute)
                    144:        PHP_FALIAS(hasAttributeNS, dom_element_has_attribute_ns, arginfo_dom_element_has_attribute_ns)
                    145:        PHP_FALIAS(setIdAttribute, dom_element_set_id_attribute, arginfo_dom_element_set_id_attribute)
                    146:        PHP_FALIAS(setIdAttributeNS, dom_element_set_id_attribute_ns, arginfo_dom_element_set_id_attribute_ns)
                    147:        PHP_FALIAS(setIdAttributeNode, dom_element_set_id_attribute_node, arginfo_dom_element_set_id_attribute_node)
                    148:        PHP_ME(domelement, __construct, arginfo_dom_element_construct, ZEND_ACC_PUBLIC)
                    149:        PHP_FE_END
                    150: };
                    151: /* }}} */
                    152: 
                    153: /* {{{ proto void DOMElement::__construct(string name, [string value], [string uri]); */
                    154: PHP_METHOD(domelement, __construct)
                    155: {
                    156: 
                    157:        zval *id;
                    158:        xmlNodePtr nodep = NULL, oldnode = NULL;
                    159:        dom_object *intern;
                    160:        char *name, *value = NULL, *uri = NULL;
                    161:        char *localname = NULL, *prefix = NULL;
                    162:        int errorcode = 0, uri_len = 0;
                    163:        int name_len, value_len = 0, name_valid;
                    164:        xmlNsPtr nsptr = NULL;
                    165:        zend_error_handling error_handling;
                    166: 
                    167:        zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
                    168:        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) {
                    169:                zend_restore_error_handling(&error_handling TSRMLS_CC);
                    170:                return;
                    171:        }
                    172:        zend_restore_error_handling(&error_handling TSRMLS_CC);
                    173: 
                    174:        name_valid = xmlValidateName((xmlChar *) name, 0);
                    175:        if (name_valid != 0) {
                    176:                php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC);
                    177:                RETURN_FALSE;
                    178:        }
                    179: 
                    180:        /* Namespace logic is seperate and only when uri passed in to insure no BC breakage */
                    181:        if (uri_len > 0) {
                    182:                errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
                    183:                if (errorcode == 0) {
                    184:                        nodep = xmlNewNode (NULL, (xmlChar *)localname);
                    185:                        if (nodep != NULL && uri != NULL) {
                    186:                                nsptr = dom_get_ns(nodep, uri, &errorcode, prefix);
                    187:                                xmlSetNs(nodep, nsptr);
                    188:                        }
                    189:                }
                    190:                xmlFree(localname);
                    191:                if (prefix != NULL) {
                    192:                        xmlFree(prefix);
                    193:                }
                    194:                if (errorcode != 0) {
                    195:                        if (nodep != NULL) {
                    196:                                xmlFreeNode(nodep);
                    197:                        }
                    198:                        php_dom_throw_error(errorcode, 1 TSRMLS_CC);
                    199:                        RETURN_FALSE;
                    200:                }
                    201:        } else {
                    202:            /* If you don't pass a namespace uri, then you can't set a prefix */
                    203:            localname = xmlSplitQName2((xmlChar *)name, (xmlChar **) &prefix);
                    204:            if (prefix != NULL) {
                    205:                        xmlFree(localname);
                    206:                        xmlFree(prefix);
                    207:                php_dom_throw_error(NAMESPACE_ERR, 1 TSRMLS_CC);
                    208:                RETURN_FALSE;
                    209:            }
                    210:                nodep = xmlNewNode(NULL, (xmlChar *) name);
                    211:        }
                    212: 
                    213:        if (!nodep) {
                    214:                php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
                    215:                RETURN_FALSE;
                    216:        }
                    217: 
                    218:        if (value_len > 0) {
                    219:                xmlNodeSetContentLen(nodep, (xmlChar *) value, value_len);
                    220:        }
                    221: 
                    222:        intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
                    223:        if (intern != NULL) {
                    224:                oldnode = dom_object_get_node(intern);
                    225:                if (oldnode != NULL) {
                    226:                        php_libxml_node_free_resource(oldnode  TSRMLS_CC);
                    227:                }
                    228:                php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC);
                    229:        }
                    230: }
                    231: /* }}} end DOMElement::__construct */
                    232: 
                    233: /* {{{ tagName string  
                    234: readonly=yes 
                    235: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-104682815
                    236: Since: 
                    237: */
                    238: int dom_element_tag_name_read(dom_object *obj, zval **retval TSRMLS_DC)
                    239: {
                    240:        xmlNodePtr nodep;
                    241:        xmlNsPtr ns;
                    242:        xmlChar *qname;
                    243: 
                    244:        nodep = dom_object_get_node(obj);
                    245: 
                    246:        if (nodep == NULL) {
                    247:                php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
                    248:                return FAILURE;
                    249:        }
                    250: 
                    251:        ALLOC_ZVAL(*retval);
                    252:        ns = nodep->ns;
                    253:        if (ns != NULL && ns->prefix) {
                    254:                qname = xmlStrdup(ns->prefix);
                    255:                qname = xmlStrcat(qname, (xmlChar *)":");
                    256:                qname = xmlStrcat(qname, nodep->name);
                    257:                ZVAL_STRING(*retval, (char *)qname, 1);
                    258:                xmlFree(qname);
                    259:        } else {
                    260:                ZVAL_STRING(*retval, (char *) nodep->name, 1);
                    261:        }
                    262: 
                    263:        return SUCCESS;
                    264: }
                    265: 
                    266: /* }}} */
                    267: 
                    268: /* {{{ schemaTypeInfo  typeinfo        
                    269: readonly=yes 
                    270: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Element-schemaTypeInfo
                    271: Since: DOM Level 3
                    272: */
                    273: int dom_element_schema_type_info_read(dom_object *obj, zval **retval TSRMLS_DC)
                    274: {
                    275:        ALLOC_ZVAL(*retval);
                    276:        ZVAL_NULL(*retval);
                    277:        return SUCCESS;
                    278: }
                    279: 
                    280: /* }}} */
                    281: 
                    282: static xmlNodePtr dom_get_dom1_attribute(xmlNodePtr elem, xmlChar *name) /* {{{ */
                    283: {
                    284:     int len;
                    285:     const xmlChar *nqname;
                    286: 
                    287:        nqname = xmlSplitQName3(name, &len);
                    288:        if (nqname != NULL) {
                    289:                xmlNsPtr ns;
                    290:                xmlChar *prefix = xmlStrndup(name, len);
                    291:                if (prefix && xmlStrEqual(prefix, (xmlChar *)"xmlns")) {
                    292:                        ns = elem->nsDef;
                    293:                        while (ns) {
                    294:                                if (xmlStrEqual(ns->prefix, nqname)) {
                    295:                                        break;
                    296:                                }
                    297:                                ns = ns->next;
                    298:                        }
                    299:                        xmlFree(prefix);
                    300:                        return (xmlNodePtr)ns;
                    301:                }
                    302:                ns = xmlSearchNs(elem->doc, elem, prefix);
                    303:                if (prefix != NULL) {
                    304:                        xmlFree(prefix);
                    305:                }
                    306:                if (ns != NULL) {
                    307:                        return (xmlNodePtr)xmlHasNsProp(elem, nqname, ns->href);
                    308:                }
                    309:        } else {
                    310:                if (xmlStrEqual(name, (xmlChar *)"xmlns")) {
                    311:                        xmlNsPtr nsPtr = elem->nsDef;
                    312:                        while (nsPtr) {
                    313:                                if (nsPtr->prefix == NULL) {
                    314:                                        return (xmlNodePtr)nsPtr;
                    315:                                }
                    316:                                nsPtr = nsPtr->next;
                    317:                        }
                    318:                        return NULL;
                    319:                }
                    320:        }
                    321:        return (xmlNodePtr)xmlHasNsProp(elem, name, NULL);
                    322: }
                    323: /* }}} */
                    324: 
                    325: /* {{{ proto string dom_element_get_attribute(string name);
                    326: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-666EE0F9
                    327: Since:
                    328: */
                    329: PHP_FUNCTION(dom_element_get_attribute)
                    330: {
                    331:        zval *id;
                    332:        xmlNode *nodep;
                    333:        char *name;
                    334:        xmlChar *value = NULL;
                    335:        dom_object *intern;
                    336:        xmlNodePtr attr;
                    337:        int name_len;
                    338: 
                    339:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) {
                    340:                return;
                    341:        }
                    342: 
                    343:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                    344: 
                    345:        attr = dom_get_dom1_attribute(nodep, (xmlChar *)name);
                    346:        if (attr) {
                    347:                switch (attr->type) {
                    348:                        case XML_ATTRIBUTE_NODE:
                    349:                                value = xmlNodeListGetString(attr->doc, attr->children, 1);
                    350:                                break;
                    351:                        case XML_NAMESPACE_DECL:
                    352:                                value = xmlStrdup(((xmlNsPtr)attr)->href);
                    353:                                break;
                    354:                        default:
                    355:                                value = xmlStrdup(((xmlAttributePtr)attr)->defaultValue);
                    356:                }
                    357:        }
                    358:        
                    359:        if (value == NULL) {
                    360:                RETURN_EMPTY_STRING();
                    361:        } else {
                    362:                RETVAL_STRING((char *)value, 1);
                    363:                xmlFree(value);
                    364:        }
                    365: }
                    366: /* }}} end dom_element_get_attribute */
                    367: 
                    368: /* {{{ proto void dom_element_set_attribute(string name, string value);
                    369: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68F082
                    370: Since: 
                    371: */
                    372: PHP_FUNCTION(dom_element_set_attribute)
                    373: {
                    374:        zval *id, *rv = NULL;
                    375:        xmlNode *nodep;
                    376:        xmlNodePtr attr = NULL;
                    377:        int ret, name_len, value_len, name_valid;
                    378:        dom_object *intern;
                    379:        char *name, *value;
                    380: 
                    381:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_element_class_entry, &name, &name_len, &value, &value_len) == FAILURE) {
                    382:                return;
                    383:        }
                    384: 
                    385:        if (name_len == 0) {
                    386:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute Name is required");
                    387:                RETURN_FALSE;
                    388:        }
                    389: 
                    390:        name_valid = xmlValidateName((xmlChar *) name, 0);
                    391:        if (name_valid != 0) {
                    392:                php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC);
                    393:                RETURN_FALSE;
                    394:        }
                    395: 
                    396:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                    397: 
                    398:        if (dom_node_is_read_only(nodep) == SUCCESS) {
                    399:                php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
                    400:                RETURN_FALSE;
                    401:        }
                    402: 
                    403:        attr = dom_get_dom1_attribute(nodep, (xmlChar *)name);
                    404:        if (attr != NULL) {
                    405:                switch (attr->type) {
                    406:                        case XML_ATTRIBUTE_NODE:
                    407:                                node_list_unlink(attr->children TSRMLS_CC);
                    408:                                break;
                    409:                        case XML_NAMESPACE_DECL:
                    410:                                RETURN_FALSE;
                    411:                        default:
                    412:                                break;
                    413:                }
                    414: 
                    415:        }
                    416: 
                    417:        if (xmlStrEqual((xmlChar *)name, (xmlChar *)"xmlns")) {
                    418:                if (xmlNewNs(nodep, (xmlChar *)value, NULL)) {
                    419:                        RETURN_TRUE;
                    420:                }
                    421:        } else {
                    422:                attr = (xmlNodePtr)xmlSetProp(nodep, (xmlChar *) name, (xmlChar *)value);
                    423:        }
                    424:        if (!attr) {
                    425:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such attribute '%s'", name);
                    426:                RETURN_FALSE;
                    427:        }
                    428: 
                    429:        DOM_RET_OBJ(rv, attr, &ret, intern);
                    430: 
                    431: }
                    432: /* }}} end dom_element_set_attribute */
                    433: 
                    434: /* {{{ proto void dom_element_remove_attribute(string name);
                    435: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6D6AC0F9
                    436: Since:
                    437: */
                    438: PHP_FUNCTION(dom_element_remove_attribute)
                    439: {
                    440:        zval *id;
                    441:        xmlNodePtr nodep, attrp;
                    442:        dom_object *intern;
                    443:        int name_len;
                    444:        char *name;
                    445: 
                    446:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) {
                    447:                return;
                    448:        }
                    449: 
                    450:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                    451: 
                    452:        if (dom_node_is_read_only(nodep) == SUCCESS) {
                    453:                php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
                    454:                RETURN_FALSE;
                    455:        }
                    456: 
                    457:        attrp = dom_get_dom1_attribute(nodep, (xmlChar *)name);
                    458:        if (attrp == NULL) {
                    459:                RETURN_FALSE;
                    460:        }
                    461: 
                    462:        switch (attrp->type) {
                    463:                case XML_ATTRIBUTE_NODE:
                    464:                        if (php_dom_object_get_data(attrp) == NULL) {
                    465:                        node_list_unlink(attrp->children TSRMLS_CC);
                    466:                                xmlUnlinkNode(attrp);
                    467:                                xmlFreeProp((xmlAttrPtr)attrp);
                    468:                } else {
                    469:                                xmlUnlinkNode(attrp);
                    470:                }
                    471:                        break;
                    472:                case XML_NAMESPACE_DECL:
                    473:                        RETURN_FALSE;
                    474:                default:
                    475:                        break;
                    476:        }
                    477: 
                    478:        RETURN_TRUE;
                    479: }
                    480: /* }}} end dom_element_remove_attribute */
                    481: 
                    482: /* {{{ proto DOMAttr dom_element_get_attribute_node(string name);
                    483: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-217A91B8
                    484: Since: 
                    485: */
                    486: PHP_FUNCTION(dom_element_get_attribute_node)
                    487: {
                    488:        zval *id, *rv = NULL;
                    489:        xmlNodePtr nodep, attrp;
                    490:        int name_len, ret;
                    491:        dom_object *intern;
                    492:        char *name;
                    493: 
                    494:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) {
                    495:                return;
                    496:        }
                    497: 
                    498:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                    499: 
                    500:        attrp = dom_get_dom1_attribute(nodep, (xmlChar *)name);
                    501:        if (attrp == NULL) {
                    502:                RETURN_FALSE;
                    503:        }
                    504: 
                    505:        if (attrp->type == XML_NAMESPACE_DECL) {
                    506:                xmlNsPtr curns;
                    507:                xmlNodePtr nsparent;
                    508: 
                    509:                nsparent = attrp->_private;
                    510:                curns = xmlNewNs(NULL, attrp->name, NULL);
                    511:                if (attrp->children) {
                    512:                        curns->prefix = xmlStrdup((xmlChar *) attrp->children);
                    513:                }
                    514:                if (attrp->children) {
                    515:                        attrp = xmlNewDocNode(nodep->doc, NULL, (xmlChar *) attrp->children, attrp->name);
                    516:                } else {
                    517:                        attrp = xmlNewDocNode(nodep->doc, NULL, (xmlChar *)"xmlns", attrp->name);
                    518:                }
                    519:                attrp->type = XML_NAMESPACE_DECL;
                    520:                attrp->parent = nsparent;
                    521:                attrp->ns = curns;
                    522:        }
                    523: 
                    524:        DOM_RET_OBJ(rv, (xmlNodePtr) attrp, &ret, intern);
                    525: }
                    526: /* }}} end dom_element_get_attribute_node */
                    527: 
                    528: /* {{{ proto DOMAttr dom_element_set_attribute_node(DOMAttr newAttr);
                    529: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-887236154
                    530: Since: 
                    531: */
                    532: PHP_FUNCTION(dom_element_set_attribute_node)
                    533: {
                    534:        zval *id, *node, *rv = NULL;
                    535:        xmlNode *nodep;
                    536:        xmlAttr *attrp, *existattrp = NULL;
                    537:        dom_object *intern, *attrobj, *oldobj;
                    538:        int ret;
                    539: 
                    540:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_element_class_entry, &node, dom_attr_class_entry) == FAILURE) {
                    541:                return;
                    542:        }
                    543: 
                    544:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                    545: 
                    546:        if (dom_node_is_read_only(nodep) == SUCCESS) {
                    547:                php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
                    548:                RETURN_FALSE;
                    549:        }
                    550: 
                    551:        DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj);
                    552: 
                    553:        if (attrp->type != XML_ATTRIBUTE_NODE) {
                    554:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute node is required");
                    555:                RETURN_FALSE;
                    556:        }
                    557: 
                    558:        if (!(attrp->doc == NULL || attrp->doc == nodep->doc)) {
                    559:                php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
                    560:                RETURN_FALSE;
                    561:        }
                    562: 
                    563:        existattrp = xmlHasProp(nodep, attrp->name);
                    564:        if (existattrp != NULL && existattrp->type != XML_ATTRIBUTE_DECL) {
                    565:                if ((oldobj = php_dom_object_get_data((xmlNodePtr) existattrp)) != NULL && 
                    566:                        ((php_libxml_node_ptr *)oldobj->ptr)->node == (xmlNodePtr) attrp)
                    567:                {
                    568:                        RETURN_NULL();
                    569:                }
                    570:                xmlUnlinkNode((xmlNodePtr) existattrp);
                    571:        }
                    572: 
                    573:        if (attrp->parent != NULL) {
                    574:                xmlUnlinkNode((xmlNodePtr) attrp);
                    575:        }
                    576: 
                    577:        if (attrp->doc == NULL && nodep->doc != NULL) {
                    578:                attrobj->document = intern->document;
                    579:                php_libxml_increment_doc_ref((php_libxml_node_object *)attrobj, NULL TSRMLS_CC);
                    580:        }
                    581: 
                    582:        xmlAddChild(nodep, (xmlNodePtr) attrp);
                    583: 
                    584:        /* Returns old property if removed otherwise NULL */
                    585:        if (existattrp != NULL) {
                    586:                DOM_RET_OBJ(rv, (xmlNodePtr) existattrp, &ret, intern);
                    587:        } else {
                    588:                RETVAL_NULL();
                    589:        }
                    590: 
                    591: }
                    592: /* }}} end dom_element_set_attribute_node */
                    593: 
                    594: /* {{{ proto DOMAttr dom_element_remove_attribute_node(DOMAttr oldAttr);
                    595: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D589198
                    596: Since: 
                    597: */
                    598: PHP_FUNCTION(dom_element_remove_attribute_node)
                    599: {
                    600:        zval *id, *node, *rv = NULL;
                    601:        xmlNode *nodep;
                    602:        xmlAttr *attrp;
                    603:        dom_object *intern, *attrobj;
                    604:        int ret;
                    605: 
                    606:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_element_class_entry, &node, dom_attr_class_entry) == FAILURE) {
                    607:                return;
                    608:        }
                    609: 
                    610:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                    611: 
                    612:        if (dom_node_is_read_only(nodep) == SUCCESS) {
                    613:                php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
                    614:                RETURN_FALSE;
                    615:        }
                    616: 
                    617:        DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj);
                    618: 
                    619:        if (attrp->type != XML_ATTRIBUTE_NODE || attrp->parent != nodep) {
                    620:                php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
                    621:                RETURN_FALSE;
                    622:        }
                    623: 
                    624:        xmlUnlinkNode((xmlNodePtr) attrp);
                    625: 
                    626:        DOM_RET_OBJ(rv, (xmlNodePtr) attrp, &ret, intern);
                    627: 
                    628: }
                    629: /* }}} end dom_element_remove_attribute_node */
                    630: 
                    631: /* {{{ proto DOMNodeList dom_element_get_elements_by_tag_name(string name);
                    632: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1938918D
                    633: Since: 
                    634: */
                    635: PHP_FUNCTION(dom_element_get_elements_by_tag_name)
                    636: {
                    637:        zval *id;
                    638:        xmlNodePtr elemp;
                    639:        int name_len;
                    640:        dom_object *intern, *namednode;
                    641:        char *name;
                    642:        xmlChar *local;
                    643: 
                    644:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) {
                    645:                return;
                    646:        }
                    647: 
                    648:        DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
                    649: 
                    650:        php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
                    651:        namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
                    652:        local = xmlCharStrndup(name, name_len);
                    653:        dom_namednode_iter(intern, 0, namednode, NULL, local, NULL TSRMLS_CC);
                    654: }
                    655: /* }}} end dom_element_get_elements_by_tag_name */
                    656: 
                    657: /* {{{ proto string dom_element_get_attribute_ns(string namespaceURI, string localName);
                    658: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElGetAttrNS
                    659: Since: DOM Level 2
                    660: */
                    661: PHP_FUNCTION(dom_element_get_attribute_ns)
                    662: {
                    663:        zval *id;
                    664:        xmlNodePtr elemp;
                    665:        xmlNsPtr nsptr;
                    666:        dom_object *intern;
                    667:        int uri_len = 0, name_len = 0;
                    668:        char *uri, *name;
                    669:        xmlChar *strattr;
                    670: 
                    671:        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) {
                    672:                return;
                    673:        }
                    674: 
                    675:        DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
                    676: 
                    677:        strattr = xmlGetNsProp(elemp, (xmlChar *) name, (xmlChar *) uri);
                    678: 
                    679:        if (strattr != NULL) {
                    680:                RETVAL_STRING((char *)strattr, 1);
                    681:                xmlFree(strattr);
                    682:        } else {
                    683:                if (xmlStrEqual((xmlChar *) uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) {
                    684:                        nsptr = dom_get_nsdecl(elemp, (xmlChar *)name);
                    685:                        if (nsptr != NULL) {
                    686:                                RETVAL_STRING((char *) nsptr->href, 1);
                    687:                        } else {
                    688:                                RETVAL_EMPTY_STRING();
                    689:                        }
                    690:                } else {
                    691:                        RETVAL_EMPTY_STRING();
                    692:                }
                    693:        }
                    694: 
                    695: }
                    696: /* }}} end dom_element_get_attribute_ns */
                    697: 
                    698: static xmlNsPtr _dom_new_reconNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) /* {{{ */
                    699: {
                    700:     xmlNsPtr def;
                    701:     xmlChar prefix[50];
                    702:     int counter = 1;
                    703: 
                    704:        if ((tree == NULL) || (ns == NULL) || (ns->type != XML_NAMESPACE_DECL)) {
                    705:                return NULL;
                    706:        }
                    707: 
                    708:        /* Code taken from libxml2 (2.6.20) xmlNewReconciliedNs
                    709:         *
                    710:         * Find a close prefix which is not already in use.
                    711:         * Let's strip namespace prefixes longer than 20 chars !
                    712:         */
                    713:        if (ns->prefix == NULL)
                    714:                snprintf((char *) prefix, sizeof(prefix), "default");
                    715:        else
                    716:                snprintf((char *) prefix, sizeof(prefix), "%.20s", (char *)ns->prefix);
                    717: 
                    718:        def = xmlSearchNs(doc, tree, prefix);
                    719:        while (def != NULL) {
                    720:                if (counter > 1000) return(NULL);
                    721:                if (ns->prefix == NULL)
                    722:                        snprintf((char *) prefix, sizeof(prefix), "default%d", counter++);
                    723:                else
                    724:                        snprintf((char *) prefix, sizeof(prefix), "%.20s%d", 
                    725:                        (char *)ns->prefix, counter++);
                    726:                def = xmlSearchNs(doc, tree, prefix);
                    727:        }
                    728: 
                    729:        /*
                    730:         * OK, now we are ready to create a new one.
                    731:         */
                    732:        def = xmlNewNs(tree, ns->href, prefix);
                    733:        return(def);
                    734: }
                    735: /* }}} */
                    736: 
                    737: /* {{{ proto void dom_element_set_attribute_ns(string namespaceURI, string qualifiedName, string value);
                    738: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAttrNS
                    739: Since: DOM Level 2
                    740: */
                    741: PHP_FUNCTION(dom_element_set_attribute_ns)
                    742: {
                    743:        zval *id;
                    744:        xmlNodePtr elemp, nodep = NULL;
                    745:        xmlNsPtr nsptr;
                    746:        xmlAttr *attr;
                    747:        int uri_len = 0, name_len = 0, value_len = 0;
                    748:        char *uri, *name, *value;
                    749:        char *localname = NULL, *prefix = NULL;
                    750:        dom_object *intern;
                    751:        int errorcode = 0, stricterror, is_xmlns = 0, name_valid;
                    752: 
                    753:        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) {
                    754:                return;
                    755:        }
                    756: 
                    757:        if (name_len == 0) {
                    758:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute Name is required");
                    759:                RETURN_FALSE;
                    760:        }
                    761: 
                    762:        DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
                    763: 
                    764:        stricterror = dom_get_strict_error(intern->document);
                    765: 
                    766:        if (dom_node_is_read_only(elemp) == SUCCESS) {
                    767:                php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
                    768:                RETURN_NULL();
                    769:        }
                    770: 
                    771:        errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
                    772: 
                    773:        if (errorcode == 0) {
                    774:                if (uri_len > 0) {
                    775:                        nodep = (xmlNodePtr) xmlHasNsProp(elemp, (xmlChar *) localname, (xmlChar *) uri);
                    776:                        if (nodep != NULL && nodep->type != XML_ATTRIBUTE_DECL) {
                    777:                                node_list_unlink(nodep->children TSRMLS_CC);
                    778:                        }
                    779: 
                    780:                        if ((xmlStrEqual((xmlChar *) prefix, (xmlChar *)"xmlns") || 
                    781:                                (prefix == NULL && xmlStrEqual((xmlChar *) localname, (xmlChar *)"xmlns"))) && 
                    782:                                xmlStrEqual((xmlChar *) uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) {
                    783:                                is_xmlns = 1;
                    784:                                if (prefix == NULL) {
                    785:                                        nsptr = dom_get_nsdecl(elemp, NULL);
                    786:                                } else {
                    787:                                        nsptr = dom_get_nsdecl(elemp, (xmlChar *)localname);
                    788:                                }
                    789:                        } else {
                    790:                                nsptr = xmlSearchNsByHref(elemp->doc, elemp, (xmlChar *)uri);
                    791:                                if (nsptr && nsptr->prefix == NULL) {
                    792:                                        xmlNsPtr tmpnsptr;
                    793: 
                    794:                                        tmpnsptr = nsptr->next;
                    795:                                        while (tmpnsptr) {
                    796:                                                if ((tmpnsptr->prefix != NULL) && (tmpnsptr->href != NULL) && 
                    797:                                                        (xmlStrEqual(tmpnsptr->href, (xmlChar *) uri))) {
                    798:                                                        nsptr = tmpnsptr;
                    799:                                                        break;
                    800:                                                }
                    801:                                                tmpnsptr = tmpnsptr->next;
                    802:                                        }
                    803:                                        if (tmpnsptr == NULL) {
                    804:                                                nsptr = _dom_new_reconNs(elemp->doc, elemp, nsptr);
                    805:                                        }
                    806:                                }
                    807:                        }
                    808: 
                    809:                        if (nsptr == NULL) {
                    810:                                if (prefix == NULL) {
                    811:                                        if (is_xmlns == 1) {
                    812:                                                xmlNewNs(elemp, (xmlChar *)value, NULL);
                    813:                                                xmlReconciliateNs(elemp->doc, elemp);
                    814:                                        } else {
                    815:                                                errorcode = NAMESPACE_ERR;
                    816:                                        }
                    817:                                } else {
                    818:                                        if (is_xmlns == 1) {
                    819:                                                xmlNewNs(elemp, (xmlChar *)value, (xmlChar *)localname);
                    820:                                        } else {
                    821:                                                nsptr = dom_get_ns(elemp, uri, &errorcode, prefix);
                    822:                                        }
                    823:                                        xmlReconciliateNs(elemp->doc, elemp);
                    824:                                }
                    825:                        } else {
                    826:                                if (is_xmlns == 1) {
                    827:                                        if (nsptr->href) {
                    828:                                                xmlFree((xmlChar *) nsptr->href);
                    829:                                        }
                    830:                                        nsptr->href = xmlStrdup((xmlChar *)value);
                    831:                                }
                    832:                        }
                    833: 
                    834:                        if (errorcode == 0 && is_xmlns == 0) {
                    835:                                attr = xmlSetNsProp(elemp, nsptr, (xmlChar *)localname, (xmlChar *)value);
                    836:                        }
                    837:                } else {
                    838:                        name_valid = xmlValidateName((xmlChar *) localname, 0);
                    839:                        if (name_valid != 0) {
                    840:                                errorcode = INVALID_CHARACTER_ERR;
                    841:                                stricterror = 1;
                    842:                        } else {
                    843:                                attr = xmlHasProp(elemp, (xmlChar *)localname);
                    844:                                if (attr != NULL && attr->type != XML_ATTRIBUTE_DECL) {
                    845:                                        node_list_unlink(attr->children TSRMLS_CC);
                    846:                                }
                    847:                                attr = xmlSetProp(elemp, (xmlChar *)localname, (xmlChar *)value);
                    848:                        }
                    849:                }
                    850:        }
                    851: 
                    852:        xmlFree(localname);
                    853:        if (prefix != NULL) {
                    854:                xmlFree(prefix);
                    855:        }
                    856: 
                    857:        if (errorcode != 0) {
                    858:                php_dom_throw_error(errorcode, stricterror TSRMLS_CC);
                    859:        }
                    860: 
                    861:        RETURN_NULL();
                    862: }
                    863: /* }}} end dom_element_set_attribute_ns */
                    864: 
                    865: /* {{{ proto void dom_element_remove_attribute_ns(string namespaceURI, string localName);
                    866: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElRemAtNS
                    867: Since: DOM Level 2
                    868: */
                    869: PHP_FUNCTION(dom_element_remove_attribute_ns)
                    870: {
                    871:        zval *id;
                    872:        xmlNode *nodep;
                    873:        xmlAttr *attrp;
                    874:        xmlNsPtr nsptr;
                    875:        dom_object *intern;
                    876:        int name_len, uri_len;
                    877:        char *name, *uri;
                    878: 
                    879:        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) {
                    880:                return;
                    881:        }
                    882: 
                    883:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                    884: 
                    885:        if (dom_node_is_read_only(nodep) == SUCCESS) {
                    886:                php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
                    887:                RETURN_NULL();
                    888:        }
                    889: 
                    890:        attrp = xmlHasNsProp(nodep, (xmlChar *)name, (xmlChar *)uri);
                    891: 
                    892:        nsptr = dom_get_nsdecl(nodep, (xmlChar *)name);
                    893:        if (nsptr != NULL) {
                    894:                if (xmlStrEqual((xmlChar *)uri, nsptr->href)) {
                    895:                        if (nsptr->href != NULL) {
                    896:                                xmlFree((char *) nsptr->href);
                    897:                                nsptr->href = NULL;
                    898:                        }
                    899:                        if (nsptr->prefix != NULL) {
                    900:                                xmlFree((char *) nsptr->prefix);
                    901:                                nsptr->prefix = NULL;
                    902:                        }
                    903:                } else {
                    904:                        RETURN_NULL();
                    905:                }
                    906:        }
                    907: 
                    908:        if (attrp && attrp->type != XML_ATTRIBUTE_DECL) {
                    909:                if (php_dom_object_get_data((xmlNodePtr) attrp) == NULL) {
                    910:                        node_list_unlink(attrp->children TSRMLS_CC);
                    911:                        xmlUnlinkNode((xmlNodePtr) attrp);
                    912:                        xmlFreeProp(attrp);
                    913:                } else {
                    914:                        xmlUnlinkNode((xmlNodePtr) attrp);
                    915:                }
                    916:        }
                    917: 
                    918:        RETURN_NULL();
                    919: }
                    920: /* }}} end dom_element_remove_attribute_ns */
                    921: 
                    922: /* {{{ proto DOMAttr dom_element_get_attribute_node_ns(string namespaceURI, string localName);
                    923: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElGetAtNodeNS
                    924: Since: DOM Level 2
                    925: */
                    926: PHP_FUNCTION(dom_element_get_attribute_node_ns)
                    927: {
                    928:        zval *id, *rv = NULL;
                    929:        xmlNodePtr elemp;
                    930:        xmlAttrPtr attrp;
                    931:        dom_object *intern;
                    932:        int uri_len, name_len, ret;
                    933:        char *uri, *name;
                    934: 
                    935:        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) {
                    936:                return;
                    937:        }
                    938: 
                    939:        DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
                    940: 
                    941:        attrp = xmlHasNsProp(elemp, (xmlChar *)name, (xmlChar *)uri);
                    942: 
                    943:        if (attrp == NULL) {
                    944:                RETURN_NULL();
                    945:        }
                    946: 
                    947:        DOM_RET_OBJ(rv, (xmlNodePtr) attrp, &ret, intern);
                    948: 
                    949: }
                    950: /* }}} end dom_element_get_attribute_node_ns */
                    951: 
                    952: /* {{{ proto DOMAttr dom_element_set_attribute_node_ns(DOMAttr newAttr);
                    953: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAtNodeNS
                    954: Since: DOM Level 2
                    955: */
                    956: PHP_FUNCTION(dom_element_set_attribute_node_ns)
                    957: {
                    958:        zval *id, *node, *rv = NULL;
                    959:        xmlNode *nodep;
                    960:        xmlNs *nsp;
                    961:        xmlAttr *attrp, *existattrp = NULL;
                    962:        dom_object *intern, *attrobj, *oldobj;
                    963:        int ret;
                    964: 
                    965:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_element_class_entry, &node, dom_attr_class_entry) == FAILURE) {
                    966:                return;
                    967:        }
                    968: 
                    969:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                    970: 
                    971:        if (dom_node_is_read_only(nodep) == SUCCESS) {
                    972:                php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
                    973:                RETURN_FALSE;
                    974:        }
                    975: 
                    976:        DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj);
                    977: 
                    978:        if (attrp->type != XML_ATTRIBUTE_NODE) {
                    979:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute node is required");
                    980:                RETURN_FALSE;
                    981:        }
                    982: 
                    983:        if (!(attrp->doc == NULL || attrp->doc == nodep->doc)) {
                    984:                php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
                    985:                RETURN_FALSE;
                    986:        }
                    987: 
                    988:     nsp = attrp->ns;
                    989:     if (nsp != NULL) {
                    990:         existattrp = xmlHasNsProp(nodep, nsp->href, attrp->name);
                    991:     } else {
                    992:         existattrp = xmlHasProp(nodep, attrp->name);
                    993:     }
                    994: 
                    995:        if (existattrp != NULL && existattrp->type != XML_ATTRIBUTE_DECL) {
                    996:                if ((oldobj = php_dom_object_get_data((xmlNodePtr) existattrp)) != NULL && 
                    997:                        ((php_libxml_node_ptr *)oldobj->ptr)->node == (xmlNodePtr) attrp)
                    998:                {
                    999:                        RETURN_NULL();
                   1000:                }
                   1001:                xmlUnlinkNode((xmlNodePtr) existattrp);
                   1002:        }
                   1003: 
                   1004:        if (attrp->parent != NULL) {
                   1005:                xmlUnlinkNode((xmlNodePtr) attrp);
                   1006:        }
                   1007: 
                   1008:        if (attrp->doc == NULL && nodep->doc != NULL) {
                   1009:                attrobj->document = intern->document;
                   1010:                php_libxml_increment_doc_ref((php_libxml_node_object *)attrobj, NULL TSRMLS_CC);
                   1011:        }
                   1012: 
                   1013:        xmlAddChild(nodep, (xmlNodePtr) attrp);
                   1014: 
                   1015:        /* Returns old property if removed otherwise NULL */
                   1016:        if (existattrp != NULL) {
                   1017:                DOM_RET_OBJ(rv, (xmlNodePtr) existattrp, &ret, intern);
                   1018:        } else {
                   1019:                RETVAL_NULL();
                   1020:        }
                   1021: 
                   1022: }
                   1023: /* }}} end dom_element_set_attribute_node_ns */
                   1024: 
                   1025: /* {{{ proto DOMNodeList dom_element_get_elements_by_tag_name_ns(string namespaceURI, string localName);
                   1026: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C90942
                   1027: Since: DOM Level 2
                   1028: */
                   1029: PHP_FUNCTION(dom_element_get_elements_by_tag_name_ns)
                   1030: {
                   1031:        zval *id;
                   1032:        xmlNodePtr elemp;
                   1033:        int uri_len, name_len;
                   1034:        dom_object *intern, *namednode;
                   1035:        char *uri, *name;
                   1036:        xmlChar *local, *nsuri;
                   1037: 
                   1038:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
                   1039:                return;
                   1040:        }
                   1041: 
                   1042:        DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
                   1043: 
                   1044:        php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
                   1045:        namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
                   1046:        local = xmlCharStrndup(name, name_len);
                   1047:        nsuri = xmlCharStrndup(uri, uri_len);
                   1048:        dom_namednode_iter(intern, 0, namednode, NULL, local, nsuri TSRMLS_CC);
                   1049: 
                   1050: }
                   1051: /* }}} end dom_element_get_elements_by_tag_name_ns */
                   1052: 
                   1053: /* {{{ proto boolean dom_element_has_attribute(string name);
                   1054: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElHasAttr
                   1055: Since: DOM Level 2
                   1056: */
                   1057: PHP_FUNCTION(dom_element_has_attribute)
                   1058: {
                   1059:        zval *id;
                   1060:        xmlNode *nodep;
                   1061:        dom_object *intern;
                   1062:        char *name;
                   1063:        int name_len;
                   1064:        xmlNodePtr attr;
                   1065: 
                   1066:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) {
                   1067:                return;
                   1068:        }
                   1069: 
                   1070:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                   1071: 
                   1072:        attr = dom_get_dom1_attribute(nodep, (xmlChar *)name);
                   1073:        if (attr == NULL) {
                   1074:                RETURN_FALSE;
                   1075:        } else {
                   1076:                RETURN_TRUE;
                   1077:        }
                   1078: }
                   1079: /* }}} end dom_element_has_attribute */
                   1080: 
                   1081: /* {{{ proto boolean dom_element_has_attribute_ns(string namespaceURI, string localName);
                   1082: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElHasAttrNS
                   1083: Since: DOM Level 2
                   1084: */
                   1085: PHP_FUNCTION(dom_element_has_attribute_ns)
                   1086: {
                   1087:        zval *id;
                   1088:        xmlNodePtr elemp;
                   1089:        xmlNs *nsp;
                   1090:        dom_object *intern;
                   1091:        int uri_len, name_len;
                   1092:        char *uri, *name;
                   1093:        xmlChar *value;
                   1094: 
                   1095:        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) {
                   1096:                return;
                   1097:        }
                   1098: 
                   1099:        DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
                   1100: 
                   1101:        value = xmlGetNsProp(elemp, (xmlChar *)name, (xmlChar *)uri);
                   1102: 
                   1103:        if (value != NULL) {
                   1104:                xmlFree(value);
                   1105:                RETURN_TRUE;
                   1106:        } else {
                   1107:                if (xmlStrEqual((xmlChar *)uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) {
                   1108:                        nsp = dom_get_nsdecl(elemp, (xmlChar *)name);
                   1109:                        if (nsp != NULL) {
                   1110:                                RETURN_TRUE;
                   1111:                        }
                   1112:                }
                   1113:        }
                   1114: 
                   1115:        RETURN_FALSE;
                   1116: }
                   1117: /* }}} end dom_element_has_attribute_ns */
                   1118: 
                   1119: static void php_set_attribute_id(xmlAttrPtr attrp, zend_bool is_id) /* {{{ */
                   1120: {
                   1121:        if (is_id == 1 && attrp->atype != XML_ATTRIBUTE_ID) {
                   1122:                xmlChar *id_val;
                   1123: 
                   1124:                id_val = xmlNodeListGetString(attrp->doc, attrp->children, 1);
                   1125:                if (id_val != NULL) {
                   1126:                        xmlAddID(NULL, attrp->doc, id_val, attrp);
                   1127:                        xmlFree(id_val);
                   1128:                }
                   1129:        } else {
                   1130:                if (attrp->atype == XML_ATTRIBUTE_ID) {
                   1131:                        xmlRemoveID(attrp->doc, attrp);
                   1132:                        attrp->atype = 0;
                   1133:                }
                   1134:        }
                   1135: }
                   1136: /* }}} */
                   1137: 
                   1138: /* {{{ proto void dom_element_set_id_attribute(string name, boolean isId);
                   1139: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttr
                   1140: Since: DOM Level 3
                   1141: */
                   1142: PHP_FUNCTION(dom_element_set_id_attribute)
                   1143: {
                   1144:        zval *id;
                   1145:        xmlNode *nodep;
                   1146:        xmlAttrPtr attrp;
                   1147:        dom_object *intern;
                   1148:        char *name;
                   1149:        int name_len;
                   1150:        zend_bool is_id;
                   1151: 
                   1152:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osb", &id, dom_element_class_entry, &name, &name_len, &is_id) == FAILURE) {
                   1153:                return;
                   1154:        }
                   1155: 
                   1156:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                   1157: 
                   1158:        if (dom_node_is_read_only(nodep) == SUCCESS) {
                   1159:                php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
                   1160:                RETURN_NULL();
                   1161:        }
                   1162: 
                   1163:        attrp = xmlHasNsProp(nodep, (xmlChar *)name, NULL);
                   1164:        if (attrp == NULL || attrp->type == XML_ATTRIBUTE_DECL) {
                   1165:                php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
                   1166:        } else {
                   1167:                php_set_attribute_id(attrp, is_id);
                   1168:        }
                   1169: 
                   1170:        RETURN_NULL();
                   1171: }
                   1172: /* }}} end dom_element_set_id_attribute */
                   1173: 
                   1174: /* {{{ proto void dom_element_set_id_attribute_ns(string namespaceURI, string localName, boolean isId);
                   1175: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttrNS
                   1176: Since: DOM Level 3
                   1177: */
                   1178: PHP_FUNCTION(dom_element_set_id_attribute_ns)
                   1179: {
                   1180:        zval *id;
                   1181:        xmlNodePtr elemp;
                   1182:        xmlAttrPtr attrp;
                   1183:        dom_object *intern;
                   1184:        int uri_len, name_len;
                   1185:        char *uri, *name;
                   1186:        zend_bool is_id;
                   1187: 
                   1188:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ossb", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len, &is_id) == FAILURE) {
                   1189:                return;
                   1190:        }
                   1191: 
                   1192:        DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
                   1193: 
                   1194:        if (dom_node_is_read_only(elemp) == SUCCESS) {
                   1195:                php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
                   1196:                RETURN_NULL();
                   1197:        }
                   1198: 
                   1199:        attrp = xmlHasNsProp(elemp, (xmlChar *)name, (xmlChar *)uri);
                   1200:        if (attrp == NULL || attrp->type == XML_ATTRIBUTE_DECL) {
                   1201:                php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
                   1202:        } else {
                   1203:                php_set_attribute_id(attrp, is_id);
                   1204:        }
                   1205: 
                   1206:        RETURN_NULL();
                   1207: }
                   1208: /* }}} end dom_element_set_id_attribute_ns */
                   1209: 
                   1210: /* {{{ proto void dom_element_set_id_attribute_node(attr idAttr, boolean isId);
                   1211: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttrNode
                   1212: Since: DOM Level 3
                   1213: */
                   1214: PHP_FUNCTION(dom_element_set_id_attribute_node)
                   1215: {
                   1216:        zval *id, *node;
                   1217:        xmlNode *nodep;
                   1218:        xmlAttrPtr attrp;
                   1219:        dom_object *intern, *attrobj;
                   1220:        zend_bool is_id;
                   1221: 
                   1222:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OOb", &id, dom_element_class_entry, &node, dom_attr_class_entry, &is_id) == FAILURE) {
                   1223:                return;
                   1224:        }
                   1225: 
                   1226:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                   1227: 
                   1228:        if (dom_node_is_read_only(nodep) == SUCCESS) {
                   1229:                php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
                   1230:                RETURN_NULL();
                   1231:        }
                   1232: 
                   1233:        DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj);
                   1234: 
                   1235:        if (attrp->parent != nodep) {
                   1236:                php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
                   1237:        } else {
                   1238:                php_set_attribute_id(attrp, is_id);
                   1239:        }
                   1240: 
                   1241:        RETURN_NULL();
                   1242: }
                   1243: /* }}} end dom_element_set_id_attribute_node */
                   1244: 
                   1245: #endif
                   1246: 
                   1247: /*
                   1248:  * Local variables:
                   1249:  * tab-width: 4
                   1250:  * c-basic-offset: 4
                   1251:  * End:
                   1252:  * vim600: noet sw=4 ts=4 fdm=marker
                   1253:  * vim<600: noet sw=4 ts=4
                   1254:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>