1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2014 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 */
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]); */
PHP_METHOD(domelement,__construct)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 separate 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 */
dom_element_tag_name_read(dom_object * obj,zval ** retval TSRMLS_DC)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 */
dom_element_schema_type_info_read(dom_object * obj,zval ** retval TSRMLS_DC)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
dom_get_dom1_attribute(xmlNodePtr elem,xmlChar * name)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 */
PHP_FUNCTION(dom_element_get_attribute)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 */
PHP_FUNCTION(dom_element_set_attribute)372 PHP_FUNCTION(dom_element_set_attribute)
373 {
374 zval *id;
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(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 */
PHP_FUNCTION(dom_element_remove_attribute)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 */
PHP_FUNCTION(dom_element_get_attribute_node)486 PHP_FUNCTION(dom_element_get_attribute_node)
487 {
488 zval *id;
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((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 */
PHP_FUNCTION(dom_element_set_attribute_node)532 PHP_FUNCTION(dom_element_set_attribute_node)
533 {
534 zval *id, *node;
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((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 */
PHP_FUNCTION(dom_element_remove_attribute_node)598 PHP_FUNCTION(dom_element_remove_attribute_node)
599 {
600 zval *id, *node;
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((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 */
PHP_FUNCTION(dom_element_get_elements_by_tag_name)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 */
PHP_FUNCTION(dom_element_get_attribute_ns)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
_dom_new_reconNs(xmlDocPtr doc,xmlNodePtr tree,xmlNsPtr ns)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 */
PHP_FUNCTION(dom_element_set_attribute_ns)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 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 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 */
PHP_FUNCTION(dom_element_remove_attribute_ns)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 */
PHP_FUNCTION(dom_element_get_attribute_node_ns)926 PHP_FUNCTION(dom_element_get_attribute_node_ns)
927 {
928 zval *id;
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((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 */
PHP_FUNCTION(dom_element_set_attribute_node_ns)956 PHP_FUNCTION(dom_element_set_attribute_node_ns)
957 {
958 zval *id, *node;
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((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 */
PHP_FUNCTION(dom_element_get_elements_by_tag_name_ns)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 */
PHP_FUNCTION(dom_element_has_attribute)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 */
PHP_FUNCTION(dom_element_has_attribute_ns)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
php_set_attribute_id(xmlAttrPtr attrp,zend_bool is_id)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 */
PHP_FUNCTION(dom_element_set_id_attribute)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 */
PHP_FUNCTION(dom_element_set_id_attribute_ns)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 */
PHP_FUNCTION(dom_element_set_id_attribute_node)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 */
1255