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