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