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