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