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