1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 The PHP Group |
6 : +----------------------------------------------------------------------+
7 : | This source file is subject to version 3.01 of the PHP license, |
8 : | that is bundled with this package in the file LICENSE, and is |
9 : | available through the world-wide-web at the following url: |
10 : | http://www.php.net/license/3_01.txt |
11 : | If you did not receive a copy of the PHP license and are unable to |
12 : | obtain it through the world-wide-web, please send a note to |
13 : | license@php.net so we can mail you a copy immediately. |
14 : +----------------------------------------------------------------------+
15 : | Authors: Christian Stocker <chregu@php.net> |
16 : | Rob Richards <rrichards@php.net> |
17 : +----------------------------------------------------------------------+
18 : */
19 :
20 : /* $Id: node.c 288658 2009-09-24 15:10:21Z rrichards $ */
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 : static
32 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_insert_before, 0, 0, 1)
33 : ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0)
34 : ZEND_ARG_OBJ_INFO(0, refChild, DOMNode, 1)
35 : ZEND_END_ARG_INFO();
36 :
37 : static
38 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_replace_child, 0, 0, 2)
39 : ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0)
40 : ZEND_ARG_OBJ_INFO(0, oldChild, DOMNode, 0)
41 : ZEND_END_ARG_INFO();
42 :
43 : static
44 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_remove_child, 0, 0, 1)
45 : ZEND_ARG_OBJ_INFO(0, oldChild, DOMNode, 0)
46 : ZEND_END_ARG_INFO();
47 :
48 : static
49 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_append_child, 0, 0, 1)
50 : ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0)
51 : ZEND_END_ARG_INFO();
52 :
53 : static
54 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_has_child_nodes, 0, 0, 0)
55 : ZEND_END_ARG_INFO();
56 :
57 : static
58 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_clone_node, 0, 0, 1)
59 : ZEND_ARG_INFO(0, deep)
60 : ZEND_END_ARG_INFO();
61 :
62 : static
63 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_normalize, 0, 0, 0)
64 : ZEND_END_ARG_INFO();
65 :
66 : static
67 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_supported, 0, 0, 2)
68 : ZEND_ARG_INFO(0, feature)
69 : ZEND_ARG_INFO(0, version)
70 : ZEND_END_ARG_INFO();
71 :
72 : static
73 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_has_attributes, 0, 0, 0)
74 : ZEND_END_ARG_INFO();
75 :
76 : static
77 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_compare_document_position, 0, 0, 1)
78 : ZEND_ARG_OBJ_INFO(0, other, DOMNode, 0)
79 : ZEND_END_ARG_INFO();
80 :
81 : static
82 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_same_node, 0, 0, 1)
83 : ZEND_ARG_OBJ_INFO(0, other, DOMNode, 0)
84 : ZEND_END_ARG_INFO();
85 :
86 : static
87 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_lookup_prefix, 0, 0, 1)
88 : ZEND_ARG_INFO(0, namespaceURI)
89 : ZEND_END_ARG_INFO();
90 :
91 : static
92 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_default_namespace, 0, 0, 1)
93 : ZEND_ARG_INFO(0, namespaceURI)
94 : ZEND_END_ARG_INFO();
95 :
96 : static
97 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_lookup_namespace_uri, 0, 0, 1)
98 : ZEND_ARG_INFO(0, prefix)
99 : ZEND_END_ARG_INFO();
100 :
101 : static
102 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_equal_node, 0, 0, 1)
103 : ZEND_ARG_OBJ_INFO(0, arg, DOMNode, 0)
104 : ZEND_END_ARG_INFO();
105 :
106 : static
107 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_get_feature, 0, 0, 2)
108 : ZEND_ARG_INFO(0, feature)
109 : ZEND_ARG_INFO(0, version)
110 : ZEND_END_ARG_INFO();
111 :
112 : static
113 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_set_user_data, 0, 0, 3)
114 : ZEND_ARG_INFO(0, key)
115 : ZEND_ARG_INFO(0, data)
116 : ZEND_ARG_INFO(0, handler)
117 : ZEND_END_ARG_INFO();
118 :
119 : static
120 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_get_user_data, 0, 0, 1)
121 : ZEND_ARG_INFO(0, key)
122 : ZEND_END_ARG_INFO();
123 :
124 : static
125 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_getNodePath, 0, 0, 0)
126 : ZEND_END_ARG_INFO();
127 :
128 : static
129 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_C14N, 0, 0, 0)
130 : ZEND_ARG_INFO(0, exclusive)
131 : ZEND_ARG_INFO(0, with_comments)
132 : ZEND_ARG_ARRAY_INFO(0, xpath, 1)
133 : ZEND_ARG_ARRAY_INFO(0, ns_prefixes, 1)
134 : ZEND_END_ARG_INFO();
135 :
136 : static
137 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_C14NFile, 0, 0, 1)
138 : ZEND_ARG_INFO(0, uri)
139 : ZEND_ARG_INFO(0, exclusive)
140 : ZEND_ARG_INFO(0, with_comments)
141 : ZEND_ARG_ARRAY_INFO(0, xpath, 1)
142 : ZEND_ARG_ARRAY_INFO(0, ns_prefixes, 1)
143 : ZEND_END_ARG_INFO();
144 : /* }}} */
145 :
146 : /*
147 : * class DOMNode
148 : *
149 : * URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1950641247
150 : * Since:
151 : */
152 :
153 : zend_function_entry php_dom_node_class_functions[] = {
154 : PHP_FALIAS(insertBefore, dom_node_insert_before, arginfo_dom_node_insert_before)
155 : PHP_FALIAS(replaceChild, dom_node_replace_child, arginfo_dom_node_replace_child)
156 : PHP_FALIAS(removeChild, dom_node_remove_child, arginfo_dom_node_remove_child)
157 : PHP_FALIAS(appendChild, dom_node_append_child, arginfo_dom_node_append_child)
158 : PHP_FALIAS(hasChildNodes, dom_node_has_child_nodes, arginfo_dom_node_has_child_nodes)
159 : PHP_FALIAS(cloneNode, dom_node_clone_node, arginfo_dom_node_clone_node)
160 : PHP_FALIAS(normalize, dom_node_normalize, arginfo_dom_node_normalize)
161 : PHP_FALIAS(isSupported, dom_node_is_supported, arginfo_dom_node_is_supported)
162 : PHP_FALIAS(hasAttributes, dom_node_has_attributes, arginfo_dom_node_has_attributes)
163 : PHP_FALIAS(compareDocumentPosition, dom_node_compare_document_position, arginfo_dom_node_compare_document_position)
164 : PHP_FALIAS(isSameNode, dom_node_is_same_node, arginfo_dom_node_is_same_node)
165 : PHP_FALIAS(lookupPrefix, dom_node_lookup_prefix, arginfo_dom_node_lookup_prefix)
166 : PHP_FALIAS(isDefaultNamespace, dom_node_is_default_namespace, arginfo_dom_node_is_default_namespace)
167 : PHP_FALIAS(lookupNamespaceUri, dom_node_lookup_namespace_uri, arginfo_dom_node_lookup_namespace_uri)
168 : PHP_FALIAS(isEqualNode, dom_node_is_equal_node, arginfo_dom_node_is_equal_node)
169 : PHP_FALIAS(getFeature, dom_node_get_feature, arginfo_dom_node_get_feature)
170 : PHP_FALIAS(setUserData, dom_node_set_user_data, arginfo_dom_node_set_user_data)
171 : PHP_FALIAS(getUserData, dom_node_get_user_data, arginfo_dom_node_get_user_data)
172 : PHP_ME(domnode, getNodePath, arginfo_dom_node_getNodePath, ZEND_ACC_PUBLIC)
173 : PHP_ME(domnode, C14N, arginfo_dom_node_C14N, ZEND_ACC_PUBLIC)
174 : PHP_ME(domnode, C14NFile, arginfo_dom_node_C14NFile, ZEND_ACC_PUBLIC)
175 : {NULL, NULL, NULL}
176 : };
177 :
178 150 : static void dom_reconcile_ns(xmlDocPtr doc, xmlNodePtr nodep) {
179 : xmlNsPtr nsptr;
180 :
181 150 : if (nodep->type == XML_ELEMENT_NODE) {
182 : /* Following if block primarily used for inserting nodes created via createElementNS */
183 99 : if (nodep->nsDef != NULL && nodep->nsDef->href != NULL) {
184 4 : if((nsptr = xmlSearchNsByHref(doc, nodep->parent, nodep->nsDef->href)) &&
185 : (nodep->nsDef->prefix == NULL || xmlStrEqual(nsptr->prefix, nodep->nsDef->prefix))) {
186 0 : dom_set_old_ns(doc, nodep->nsDef);
187 0 : nodep->nsDef = NULL;
188 : }
189 : }
190 99 : xmlReconciliateNs(doc, nodep);
191 : }
192 150 : }
193 :
194 : /* {{{ nodeName string
195 : readonly=yes
196 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68D095
197 : Since:
198 : */
199 : int dom_node_node_name_read(dom_object *obj, zval **retval TSRMLS_DC)
200 258 : {
201 : xmlNode *nodep;
202 : xmlNsPtr ns;
203 258 : char *str = NULL;
204 258 : xmlChar *qname = NULL;
205 :
206 258 : nodep = dom_object_get_node(obj);
207 :
208 258 : if (nodep == NULL) {
209 0 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
210 0 : return FAILURE;
211 : }
212 :
213 258 : switch (nodep->type) {
214 : case XML_ATTRIBUTE_NODE:
215 : case XML_ELEMENT_NODE:
216 143 : ns = nodep->ns;
217 152 : if (ns != NULL && ns->prefix) {
218 9 : qname = xmlStrdup(ns->prefix);
219 9 : qname = xmlStrcat(qname, ":");
220 9 : qname = xmlStrcat(qname, nodep->name);
221 9 : str = qname;
222 : } else {
223 134 : str = (char *) nodep->name;
224 : }
225 143 : break;
226 : case XML_NAMESPACE_DECL:
227 0 : ns = nodep->ns;
228 0 : if (ns != NULL && ns->prefix) {
229 0 : qname = xmlStrdup("xmlns");
230 0 : qname = xmlStrcat(qname, ":");
231 0 : qname = xmlStrcat(qname, nodep->name);
232 0 : str = qname;
233 : } else {
234 0 : str = (char *) nodep->name;
235 : }
236 0 : break;
237 : case XML_DOCUMENT_TYPE_NODE:
238 : case XML_DTD_NODE:
239 : case XML_PI_NODE:
240 : case XML_ENTITY_DECL:
241 : case XML_ENTITY_REF_NODE:
242 : case XML_NOTATION_NODE:
243 11 : str = (char *) nodep->name;
244 11 : break;
245 : case XML_CDATA_SECTION_NODE:
246 0 : str = "#cdata-section";
247 0 : break;
248 : case XML_COMMENT_NODE:
249 0 : str = "#comment";
250 0 : break;
251 : case XML_HTML_DOCUMENT_NODE:
252 : case XML_DOCUMENT_NODE:
253 0 : str = "#document";
254 0 : break;
255 : case XML_DOCUMENT_FRAG_NODE:
256 5 : str = "#document-fragment";
257 5 : break;
258 : case XML_TEXT_NODE:
259 99 : str = "#text";
260 99 : break;
261 : default:
262 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Node Type");
263 : }
264 :
265 258 : ALLOC_ZVAL(*retval);
266 :
267 258 : if(str != NULL) {
268 258 : ZVAL_STRING(*retval, str, 1);
269 : } else {
270 0 : ZVAL_EMPTY_STRING(*retval);
271 : }
272 :
273 258 : if (qname != NULL) {
274 9 : xmlFree(qname);
275 : }
276 :
277 258 : return SUCCESS;
278 :
279 : }
280 :
281 : /* }}} */
282 :
283 :
284 :
285 : /* {{{ nodeValue string
286 : readonly=no
287 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68D080
288 : Since:
289 : */
290 : int dom_node_node_value_read(dom_object *obj, zval **retval TSRMLS_DC)
291 216 : {
292 : xmlNode *nodep;
293 216 : char *str = NULL;
294 :
295 216 : nodep = dom_object_get_node(obj);
296 :
297 216 : if (nodep == NULL) {
298 0 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
299 0 : return FAILURE;
300 : }
301 :
302 : /* Access to Element node is implemented as a convience method */
303 216 : switch (nodep->type) {
304 : case XML_ATTRIBUTE_NODE:
305 : case XML_TEXT_NODE:
306 : case XML_ELEMENT_NODE:
307 : case XML_COMMENT_NODE:
308 : case XML_CDATA_SECTION_NODE:
309 : case XML_PI_NODE:
310 211 : str = xmlNodeGetContent(nodep);
311 211 : break;
312 : case XML_NAMESPACE_DECL:
313 0 : str = xmlNodeGetContent(nodep->children);
314 0 : break;
315 : default:
316 5 : str = NULL;
317 : break;
318 : }
319 :
320 216 : ALLOC_ZVAL(*retval);
321 :
322 216 : if(str != NULL) {
323 211 : ZVAL_STRING(*retval, str, 1);
324 211 : xmlFree(str);
325 : } else {
326 5 : ZVAL_NULL(*retval);
327 : }
328 :
329 :
330 216 : return SUCCESS;
331 :
332 : }
333 :
334 : int dom_node_node_value_write(dom_object *obj, zval *newval TSRMLS_DC)
335 2 : {
336 : xmlNode *nodep;
337 : zval value_copy;
338 :
339 2 : nodep = dom_object_get_node(obj);
340 :
341 2 : if (nodep == NULL) {
342 0 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
343 0 : return FAILURE;
344 : }
345 :
346 : /* Access to Element node is implemented as a convience method */
347 2 : switch (nodep->type) {
348 : case XML_ELEMENT_NODE:
349 : case XML_ATTRIBUTE_NODE:
350 2 : if (nodep->children) {
351 1 : node_list_unlink(nodep->children TSRMLS_CC);
352 : }
353 : case XML_TEXT_NODE:
354 : case XML_COMMENT_NODE:
355 : case XML_CDATA_SECTION_NODE:
356 : case XML_PI_NODE:
357 2 : if (newval->type != IS_STRING) {
358 0 : if(newval->refcount > 1) {
359 0 : value_copy = *newval;
360 0 : zval_copy_ctor(&value_copy);
361 0 : newval = &value_copy;
362 : }
363 0 : convert_to_string(newval);
364 : }
365 2 : xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1);
366 2 : if (newval == &value_copy) {
367 0 : zval_dtor(newval);
368 : }
369 : break;
370 : default:
371 : break;
372 : }
373 :
374 2 : return SUCCESS;
375 : }
376 :
377 : /* }}} */
378 :
379 :
380 :
381 : /* {{{ nodeType int
382 : readonly=yes
383 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-111237558
384 : Since:
385 : */
386 : int dom_node_node_type_read(dom_object *obj, zval **retval TSRMLS_DC)
387 69 : {
388 : xmlNode *nodep;
389 :
390 69 : nodep = dom_object_get_node(obj);
391 :
392 69 : if (nodep == NULL) {
393 0 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
394 0 : return FAILURE;
395 : }
396 :
397 69 : ALLOC_ZVAL(*retval);
398 :
399 : /* Specs dictate that they are both type XML_DOCUMENT_TYPE_NODE */
400 69 : if (nodep->type == XML_DTD_NODE) {
401 0 : ZVAL_LONG(*retval, XML_DOCUMENT_TYPE_NODE);
402 : } else {
403 69 : ZVAL_LONG(*retval, nodep->type);
404 : }
405 :
406 69 : return SUCCESS;
407 : }
408 :
409 : /* }}} */
410 :
411 :
412 :
413 : /* {{{ parentNode DomNode
414 : readonly=yes
415 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1060184317
416 : Since:
417 : */
418 : int dom_node_parent_node_read(dom_object *obj, zval **retval TSRMLS_DC)
419 128 : {
420 : xmlNode *nodep, *nodeparent;
421 : int ret;
422 :
423 128 : nodep = dom_object_get_node(obj);
424 :
425 128 : if (nodep == NULL) {
426 0 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
427 0 : return FAILURE;
428 : }
429 :
430 128 : ALLOC_ZVAL(*retval);
431 :
432 128 : nodeparent = nodep->parent;
433 128 : if (!nodeparent) {
434 11 : ZVAL_NULL(*retval);
435 11 : return SUCCESS;
436 : }
437 :
438 117 : if (NULL == (*retval = php_dom_create_object(nodeparent, &ret, NULL, *retval, obj TSRMLS_CC))) {
439 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
440 0 : return FAILURE;
441 : }
442 117 : return SUCCESS;
443 : }
444 :
445 : /* }}} */
446 :
447 :
448 :
449 : /* {{{ childNodes DomNodeList
450 : readonly=yes
451 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1451460987
452 : Since:
453 : */
454 : int dom_node_child_nodes_read(dom_object *obj, zval **retval TSRMLS_DC)
455 100 : {
456 : xmlNode *nodep;
457 : dom_object *intern;
458 :
459 100 : nodep = dom_object_get_node(obj);
460 :
461 100 : if (nodep == NULL) {
462 0 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
463 0 : return FAILURE;
464 : }
465 :
466 100 : ALLOC_ZVAL(*retval);
467 :
468 100 : if (dom_node_children_valid(nodep) == FAILURE) {
469 0 : ZVAL_NULL(*retval);
470 : } else {
471 100 : php_dom_create_interator(*retval, DOM_NODELIST TSRMLS_CC);
472 100 : intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC);
473 100 : dom_namednode_iter(obj, XML_ELEMENT_NODE, intern, NULL, NULL, NULL TSRMLS_CC);
474 : }
475 :
476 100 : return SUCCESS;
477 : }
478 :
479 : /* }}} */
480 :
481 :
482 :
483 : /* {{{ firstChild DomNode
484 : readonly=yes
485 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-169727388
486 : Since:
487 : */
488 : int dom_node_first_child_read(dom_object *obj, zval **retval TSRMLS_DC)
489 41 : {
490 41 : xmlNode *nodep, *first = NULL;
491 : int ret;
492 :
493 41 : nodep = dom_object_get_node(obj);
494 :
495 41 : if (nodep == NULL) {
496 0 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
497 0 : return FAILURE;
498 : }
499 :
500 41 : if (dom_node_children_valid(nodep) == SUCCESS) {
501 41 : first = nodep->children;
502 : }
503 :
504 41 : ALLOC_ZVAL(*retval);
505 :
506 41 : if (!first) {
507 1 : ZVAL_NULL(*retval);
508 1 : return SUCCESS;
509 : }
510 :
511 40 : if (NULL == (*retval = php_dom_create_object(first, &ret, NULL, *retval, obj TSRMLS_CC))) {
512 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
513 0 : return FAILURE;
514 : }
515 40 : return SUCCESS;
516 : }
517 :
518 : /* }}} */
519 :
520 :
521 :
522 : /* {{{ lastChild DomNode
523 : readonly=yes
524 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-61AD09FB
525 : Since:
526 : */
527 : int dom_node_last_child_read(dom_object *obj, zval **retval TSRMLS_DC)
528 3 : {
529 3 : xmlNode *nodep, *last = NULL;
530 : int ret;
531 :
532 3 : nodep = dom_object_get_node(obj);
533 :
534 3 : if (nodep == NULL) {
535 0 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
536 0 : return FAILURE;
537 : }
538 :
539 3 : if (dom_node_children_valid(nodep) == SUCCESS) {
540 3 : last = nodep->last;
541 : }
542 :
543 3 : ALLOC_ZVAL(*retval);
544 :
545 3 : if (!last) {
546 0 : ZVAL_NULL(*retval);
547 0 : return SUCCESS;
548 : }
549 :
550 3 : if (NULL == (*retval = php_dom_create_object(last, &ret, NULL, *retval, obj TSRMLS_CC))) {
551 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
552 0 : return FAILURE;
553 : }
554 3 : return SUCCESS;
555 : }
556 :
557 : /* }}} */
558 :
559 :
560 :
561 : /* {{{ previousSibling DomNode
562 : readonly=yes
563 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-640FB3C8
564 : Since:
565 : */
566 : int dom_node_previous_sibling_read(dom_object *obj, zval **retval TSRMLS_DC)
567 105 : {
568 : xmlNode *nodep, *prevsib;
569 : int ret;
570 :
571 105 : nodep = dom_object_get_node(obj);
572 :
573 105 : if (nodep == NULL) {
574 0 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
575 0 : return FAILURE;
576 : }
577 :
578 105 : ALLOC_ZVAL(*retval);
579 :
580 105 : prevsib = nodep->prev;
581 105 : if (!prevsib) {
582 35 : ZVAL_NULL(*retval);
583 35 : return SUCCESS;
584 : }
585 :
586 70 : if (NULL == (*retval = php_dom_create_object(prevsib, &ret, NULL, *retval, obj TSRMLS_CC))) {
587 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
588 0 : return FAILURE;
589 : }
590 70 : return SUCCESS;
591 : }
592 :
593 : /* }}} */
594 :
595 :
596 :
597 : /* {{{ nextSibling DomNode
598 : readonly=yes
599 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6AC54C2F
600 : Since:
601 : */
602 : int dom_node_next_sibling_read(dom_object *obj, zval **retval TSRMLS_DC)
603 109 : {
604 : xmlNode *nodep, *nextsib;
605 : int ret;
606 :
607 109 : nodep = dom_object_get_node(obj);
608 :
609 109 : if (nodep == NULL) {
610 0 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
611 0 : return FAILURE;
612 : }
613 :
614 109 : nextsib = nodep->next;
615 109 : if (!nextsib) {
616 33 : return FAILURE;
617 : }
618 :
619 76 : ALLOC_ZVAL(*retval);
620 :
621 76 : if (NULL == (*retval = php_dom_create_object(nextsib, &ret, NULL, *retval, obj TSRMLS_CC))) {
622 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
623 0 : return FAILURE;
624 : }
625 76 : return SUCCESS;
626 : }
627 :
628 : /* }}} */
629 :
630 :
631 :
632 : /* {{{ attributes DomNamedNodeMap
633 : readonly=yes
634 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-84CF096
635 : Since:
636 : */
637 : int dom_node_attributes_read(dom_object *obj, zval **retval TSRMLS_DC)
638 2 : {
639 : xmlNode *nodep;
640 : dom_object *intern;
641 :
642 2 : nodep = dom_object_get_node(obj);
643 :
644 2 : if (nodep == NULL) {
645 0 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
646 0 : return FAILURE;
647 : }
648 :
649 2 : ALLOC_ZVAL(*retval);
650 :
651 2 : if (nodep->type == XML_ELEMENT_NODE) {
652 2 : php_dom_create_interator(*retval, DOM_NAMEDNODEMAP TSRMLS_CC);
653 2 : intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC);
654 2 : dom_namednode_iter(obj, XML_ATTRIBUTE_NODE, intern, NULL, NULL, NULL TSRMLS_CC);
655 : } else {
656 0 : ZVAL_NULL(*retval);
657 : }
658 :
659 2 : return SUCCESS;
660 : }
661 :
662 : /* }}} */
663 :
664 :
665 :
666 : /* {{{ ownerDocument DomDocument
667 : readonly=yes
668 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-node-ownerDoc
669 : Since:
670 : */
671 : int dom_node_owner_document_read(dom_object *obj, zval **retval TSRMLS_DC)
672 1 : {
673 : xmlNode *nodep;
674 : xmlDocPtr docp;
675 : int ret;
676 :
677 1 : nodep = dom_object_get_node(obj);
678 :
679 1 : if (nodep == NULL) {
680 0 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
681 0 : return FAILURE;
682 : }
683 :
684 1 : if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
685 0 : ALLOC_ZVAL(*retval);
686 0 : ZVAL_NULL(*retval);
687 0 : return SUCCESS;
688 : }
689 :
690 1 : docp = nodep->doc;
691 1 : if (!docp) {
692 0 : return FAILURE;
693 : }
694 :
695 1 : ALLOC_ZVAL(*retval);
696 :
697 1 : if (NULL == (*retval = php_dom_create_object((xmlNodePtr) docp, &ret, NULL, *retval, obj TSRMLS_CC))) {
698 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
699 0 : return FAILURE;
700 : }
701 1 : return SUCCESS;
702 : }
703 :
704 : /* }}} */
705 :
706 :
707 :
708 : /* {{{ namespaceUri string
709 : readonly=yes
710 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSname
711 : Since: DOM Level 2
712 : */
713 : int dom_node_namespace_uri_read(dom_object *obj, zval **retval TSRMLS_DC)
714 0 : {
715 : xmlNode *nodep;
716 0 : char *str = NULL;
717 :
718 0 : nodep = dom_object_get_node(obj);
719 :
720 0 : if (nodep == NULL) {
721 0 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
722 0 : return FAILURE;
723 : }
724 :
725 0 : switch (nodep->type) {
726 : case XML_ELEMENT_NODE:
727 : case XML_ATTRIBUTE_NODE:
728 : case XML_NAMESPACE_DECL:
729 0 : if (nodep->ns != NULL) {
730 0 : str = (char *) nodep->ns->href;
731 : }
732 0 : break;
733 : default:
734 0 : str = NULL;
735 : break;
736 : }
737 :
738 0 : ALLOC_ZVAL(*retval);
739 :
740 0 : if(str != NULL) {
741 0 : ZVAL_STRING(*retval, str, 1);
742 : } else {
743 0 : ZVAL_NULL(*retval);
744 : }
745 :
746 0 : return SUCCESS;
747 : }
748 :
749 : /* }}} */
750 :
751 :
752 :
753 : /* {{{ prefix string
754 : readonly=no
755 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSPrefix
756 : Since: DOM Level 2
757 : */
758 : int dom_node_prefix_read(dom_object *obj, zval **retval TSRMLS_DC)
759 0 : {
760 : xmlNode *nodep;
761 : xmlNsPtr ns;
762 0 : char *str = NULL;
763 :
764 0 : nodep = dom_object_get_node(obj);
765 :
766 0 : if (nodep == NULL) {
767 0 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
768 0 : return FAILURE;
769 : }
770 :
771 0 : switch (nodep->type) {
772 : case XML_ELEMENT_NODE:
773 : case XML_ATTRIBUTE_NODE:
774 : case XML_NAMESPACE_DECL:
775 0 : ns = nodep->ns;
776 0 : if (ns != NULL && ns->prefix) {
777 0 : str = (char *) ns->prefix;
778 : }
779 0 : break;
780 : default:
781 0 : str = NULL;
782 : break;
783 : }
784 :
785 0 : ALLOC_ZVAL(*retval);
786 :
787 0 : if (str == NULL) {
788 0 : ZVAL_EMPTY_STRING(*retval);
789 : } else {
790 0 : ZVAL_STRING(*retval, str, 1);
791 : }
792 0 : return SUCCESS;
793 :
794 : }
795 :
796 : int dom_node_prefix_write(dom_object *obj, zval *newval TSRMLS_DC)
797 0 : {
798 : zval value_copy;
799 0 : xmlNode *nodep, *nsnode = NULL;
800 0 : xmlNsPtr ns = NULL, curns;
801 : char *strURI;
802 : char *prefix;
803 :
804 0 : nodep = dom_object_get_node(obj);
805 :
806 0 : if (nodep == NULL) {
807 0 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
808 0 : return FAILURE;
809 : }
810 :
811 0 : switch (nodep->type) {
812 : case XML_ELEMENT_NODE:
813 0 : nsnode = nodep;
814 : case XML_ATTRIBUTE_NODE:
815 0 : if (nsnode == NULL) {
816 0 : nsnode = nodep->parent;
817 0 : if (nsnode == NULL) {
818 0 : nsnode = xmlDocGetRootElement(nodep->doc);
819 : }
820 : }
821 0 : if (newval->type != IS_STRING) {
822 0 : if(newval->refcount > 1) {
823 0 : value_copy = *newval;
824 0 : zval_copy_ctor(&value_copy);
825 0 : newval = &value_copy;
826 : }
827 0 : convert_to_string(newval);
828 : }
829 0 : prefix = Z_STRVAL_P(newval);
830 0 : if (nsnode && nodep->ns != NULL && !xmlStrEqual(nodep->ns->prefix, (xmlChar *)prefix)) {
831 0 : strURI = (char *) nodep->ns->href;
832 0 : if (strURI == NULL ||
833 : (!strcmp (prefix, "xml") && strcmp(strURI, XML_XML_NAMESPACE)) ||
834 : (nodep->type == XML_ATTRIBUTE_NODE && !strcmp (prefix, "xmlns") &&
835 : strcmp (strURI, DOM_XMLNS_NAMESPACE)) ||
836 : (nodep->type == XML_ATTRIBUTE_NODE && !strcmp (nodep->name, "xmlns"))) {
837 0 : ns = NULL;
838 : } else {
839 0 : curns = nsnode->nsDef;
840 0 : while (curns != NULL) {
841 0 : if (xmlStrEqual((xmlChar *)prefix, curns->prefix) && xmlStrEqual(nodep->ns->href, curns->href)) {
842 0 : ns = curns;
843 0 : break;
844 : }
845 0 : curns = curns->next;
846 : }
847 0 : if (ns == NULL) {
848 0 : ns = xmlNewNs(nsnode, nodep->ns->href, (xmlChar *)prefix);
849 : }
850 : }
851 :
852 0 : if (ns == NULL) {
853 0 : if (newval == &value_copy) {
854 0 : zval_dtor(newval);
855 : }
856 0 : php_dom_throw_error(NAMESPACE_ERR, dom_get_strict_error(obj->document) TSRMLS_CC);
857 0 : return FAILURE;
858 : }
859 :
860 0 : xmlSetNs(nodep, ns);
861 : }
862 0 : if (newval == &value_copy) {
863 0 : zval_dtor(newval);
864 : }
865 : break;
866 : default:
867 : break;
868 : }
869 :
870 0 : return SUCCESS;
871 : }
872 :
873 : /* }}} */
874 :
875 :
876 :
877 : /* {{{ localName string
878 : readonly=yes
879 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSLocalN
880 : Since: DOM Level 2
881 : */
882 : int dom_node_local_name_read(dom_object *obj, zval **retval TSRMLS_DC)
883 2 : {
884 : xmlNode *nodep;
885 :
886 2 : nodep = dom_object_get_node(obj);
887 :
888 2 : if (nodep == NULL) {
889 0 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
890 0 : return FAILURE;
891 : }
892 :
893 2 : ALLOC_ZVAL(*retval);
894 :
895 4 : if (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE || nodep->type == XML_NAMESPACE_DECL) {
896 2 : ZVAL_STRING(*retval, (char *) (nodep->name), 1);
897 : } else {
898 0 : ZVAL_NULL(*retval);
899 : }
900 :
901 2 : return SUCCESS;
902 : }
903 :
904 : /* }}} */
905 :
906 :
907 :
908 : /* {{{ baseURI string
909 : readonly=yes
910 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-baseURI
911 : Since: DOM Level 3
912 : */
913 : int dom_node_base_uri_read(dom_object *obj, zval **retval TSRMLS_DC)
914 0 : {
915 : xmlNode *nodep;
916 : xmlChar *baseuri;
917 :
918 0 : nodep = dom_object_get_node(obj);
919 :
920 0 : if (nodep == NULL) {
921 0 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
922 0 : return FAILURE;
923 : }
924 :
925 0 : ALLOC_ZVAL(*retval);
926 :
927 0 : baseuri = xmlNodeGetBase(nodep->doc, nodep);
928 0 : if (baseuri) {
929 0 : ZVAL_STRING(*retval, (char *) (baseuri), 1);
930 0 : xmlFree(baseuri);
931 : } else {
932 0 : ZVAL_NULL(*retval);
933 : }
934 :
935 0 : return SUCCESS;
936 : }
937 :
938 : /* }}} */
939 :
940 :
941 :
942 : /* {{{ textContent string
943 : readonly=no
944 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-textContent
945 : Since: DOM Level 3
946 : */
947 : int dom_node_text_content_read(dom_object *obj, zval **retval TSRMLS_DC)
948 20 : {
949 : xmlNode *nodep;
950 20 : char *str = NULL;
951 :
952 20 : nodep = dom_object_get_node(obj);
953 :
954 20 : if (nodep == NULL) {
955 0 : php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
956 0 : return FAILURE;
957 : }
958 :
959 20 : str = xmlNodeGetContent(nodep);
960 :
961 20 : ALLOC_ZVAL(*retval);
962 :
963 20 : if(str != NULL) {
964 20 : ZVAL_STRING(*retval, str, 1);
965 20 : xmlFree(str);
966 : } else {
967 0 : ZVAL_EMPTY_STRING(*retval);
968 : }
969 :
970 20 : return SUCCESS;
971 : }
972 :
973 : int dom_node_text_content_write(dom_object *obj, zval *newval TSRMLS_DC)
974 0 : {
975 0 : return SUCCESS;
976 : }
977 :
978 : /* }}} */
979 :
980 :
981 : static xmlNodePtr _php_dom_insert_fragment(xmlNodePtr nodep, xmlNodePtr prevsib,
982 : xmlNodePtr nextsib, xmlNodePtr fragment,
983 : dom_object *intern, dom_object *childobj TSRMLS_DC)
984 17 : {
985 : xmlNodePtr newchild, node;
986 :
987 17 : newchild = fragment->children;
988 :
989 17 : if (newchild) {
990 16 : if (prevsib == NULL) {
991 6 : nodep->children = newchild;
992 : } else {
993 10 : prevsib->next = newchild;
994 : }
995 16 : newchild->prev = prevsib;
996 16 : if (nextsib == NULL) {
997 10 : nodep->last = fragment->last;
998 : } else {
999 6 : fragment->last->next = nextsib;
1000 6 : nextsib->prev = fragment->last;
1001 : }
1002 :
1003 16 : node = newchild;
1004 35 : while (node != NULL) {
1005 19 : node->parent = nodep;
1006 19 : if (node->doc != nodep->doc) {
1007 0 : xmlSetTreeDoc(node, nodep->doc);
1008 0 : if (node->_private != NULL) {
1009 0 : childobj = node->_private;
1010 0 : childobj->document = intern->document;
1011 0 : php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
1012 : }
1013 : }
1014 19 : if (node == fragment->last) {
1015 16 : break;
1016 : }
1017 3 : node = node->next;
1018 : }
1019 :
1020 16 : fragment->children = NULL;
1021 16 : fragment->last = NULL;
1022 : }
1023 :
1024 17 : return newchild;
1025 : }
1026 :
1027 : /* {{{ proto domnode dom_node_insert_before(DomNode newChild, DomNode refChild);
1028 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-952280727
1029 : Since:
1030 : */
1031 : PHP_FUNCTION(dom_node_insert_before)
1032 9 : {
1033 9 : zval *id, *node, *ref = NULL, *rv = NULL;
1034 : xmlNodePtr child, new_child, parentp, refp;
1035 : dom_object *intern, *childobj, *refpobj;
1036 : int ret, stricterror;
1037 :
1038 9 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO|O!", &id, dom_node_class_entry, &node, dom_node_class_entry, &ref, dom_node_class_entry) == FAILURE) {
1039 0 : return;
1040 : }
1041 :
1042 9 : DOM_GET_OBJ(parentp, id, xmlNodePtr, intern);
1043 :
1044 9 : if (dom_node_children_valid(parentp) == FAILURE) {
1045 0 : RETURN_FALSE;
1046 : }
1047 :
1048 9 : DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
1049 :
1050 9 : new_child = NULL;
1051 :
1052 9 : stricterror = dom_get_strict_error(intern->document);
1053 :
1054 9 : if (dom_node_is_read_only(parentp) == SUCCESS ||
1055 : (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
1056 0 : php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
1057 0 : RETURN_FALSE;
1058 : }
1059 :
1060 9 : if (dom_hierarchy(parentp, child) == FAILURE) {
1061 0 : php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC);
1062 0 : RETURN_FALSE;
1063 : }
1064 :
1065 9 : if (child->doc != parentp->doc && child->doc != NULL) {
1066 0 : php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC);
1067 0 : RETURN_FALSE;
1068 : }
1069 :
1070 9 : if (child->type == XML_DOCUMENT_FRAG_NODE && child->children == NULL) {
1071 1 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Fragment is empty");
1072 1 : RETURN_FALSE;
1073 : }
1074 :
1075 8 : if (child->doc == NULL && parentp->doc != NULL) {
1076 0 : childobj->document = intern->document;
1077 0 : php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
1078 : }
1079 :
1080 8 : if (ref != NULL) {
1081 5 : DOM_GET_OBJ(refp, ref, xmlNodePtr, refpobj);
1082 5 : if (refp->parent != parentp) {
1083 0 : php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC);
1084 0 : RETURN_FALSE;
1085 : }
1086 :
1087 5 : if (child->parent != NULL) {
1088 1 : xmlUnlinkNode(child);
1089 : }
1090 :
1091 7 : if (child->type == XML_TEXT_NODE && (refp->type == XML_TEXT_NODE ||
1092 : (refp->prev != NULL && refp->prev->type == XML_TEXT_NODE))) {
1093 2 : if (child->doc == NULL) {
1094 0 : xmlSetTreeDoc(child, parentp->doc);
1095 : }
1096 2 : new_child = child;
1097 2 : new_child->parent = refp->parent;
1098 2 : new_child->next = refp;
1099 2 : new_child->prev = refp->prev;
1100 2 : refp->prev = new_child;
1101 2 : if (new_child->prev != NULL) {
1102 1 : new_child->prev->next = new_child;
1103 : }
1104 2 : if (new_child->parent != NULL) {
1105 2 : if (new_child->parent->children == refp) {
1106 1 : new_child->parent->children = new_child;
1107 : }
1108 : }
1109 :
1110 3 : } else if (child->type == XML_ATTRIBUTE_NODE) {
1111 : xmlAttrPtr lastattr;
1112 :
1113 0 : if (child->ns == NULL)
1114 0 : lastattr = xmlHasProp(refp->parent, child->name);
1115 : else
1116 0 : lastattr = xmlHasNsProp(refp->parent, child->name, child->ns->href);
1117 0 : if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
1118 0 : if (lastattr != (xmlAttrPtr) child) {
1119 0 : xmlUnlinkNode((xmlNodePtr) lastattr);
1120 0 : php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
1121 : } else {
1122 0 : DOM_RET_OBJ(rv, child, &ret, intern);
1123 0 : return;
1124 : }
1125 : }
1126 3 : } else if (child->type == XML_DOCUMENT_FRAG_NODE) {
1127 3 : new_child = _php_dom_insert_fragment(parentp, refp->prev, refp, child, intern, childobj TSRMLS_CC);
1128 : }
1129 :
1130 5 : if (new_child == NULL) {
1131 0 : new_child = xmlAddPrevSibling(refp, child);
1132 : }
1133 : } else {
1134 3 : if (child->parent != NULL){
1135 1 : xmlUnlinkNode(child);
1136 : }
1137 4 : if (child->type == XML_TEXT_NODE && parentp->last != NULL && parentp->last->type == XML_TEXT_NODE) {
1138 1 : child->parent = parentp;
1139 1 : if (child->doc == NULL) {
1140 0 : xmlSetTreeDoc(child, parentp->doc);
1141 : }
1142 1 : new_child = child;
1143 1 : if (parentp->children == NULL) {
1144 0 : parentp->children = child;
1145 0 : parentp->last = child;
1146 : } else {
1147 1 : child = parentp->last;
1148 1 : child->next = new_child;
1149 1 : new_child->prev = child;
1150 1 : parentp->last = new_child;
1151 : }
1152 2 : } else if (child->type == XML_ATTRIBUTE_NODE) {
1153 : xmlAttrPtr lastattr;
1154 :
1155 0 : if (child->ns == NULL)
1156 0 : lastattr = xmlHasProp(parentp, child->name);
1157 : else
1158 0 : lastattr = xmlHasNsProp(parentp, child->name, child->ns->href);
1159 0 : if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
1160 0 : if (lastattr != (xmlAttrPtr) child) {
1161 0 : xmlUnlinkNode((xmlNodePtr) lastattr);
1162 0 : php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
1163 : } else {
1164 0 : DOM_RET_OBJ(rv, child, &ret, intern);
1165 0 : return;
1166 : }
1167 : }
1168 2 : } else if (child->type == XML_DOCUMENT_FRAG_NODE) {
1169 2 : new_child = _php_dom_insert_fragment(parentp, parentp->last, NULL, child, intern, childobj TSRMLS_CC);
1170 : }
1171 3 : if (new_child == NULL) {
1172 0 : new_child = xmlAddChild(parentp, child);
1173 : }
1174 : }
1175 :
1176 8 : if (NULL == new_child) {
1177 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't add newnode as the previous sibling of refnode");
1178 0 : RETURN_FALSE;
1179 : }
1180 :
1181 8 : dom_reconcile_ns(parentp->doc, new_child);
1182 :
1183 8 : DOM_RET_OBJ(rv, new_child, &ret, intern);
1184 :
1185 : }
1186 : /* }}} end dom_node_insert_before */
1187 :
1188 :
1189 : /* {{{ proto DomNode dom_node_replace_child(DomNode newChild, DomNode oldChild);
1190 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-785887307
1191 : Since:
1192 : */
1193 : PHP_FUNCTION(dom_node_replace_child)
1194 9 : {
1195 : zval *id, *newnode, *oldnode;
1196 : xmlNodePtr children, newchild, oldchild, nodep;
1197 : dom_object *intern, *newchildobj, *oldchildobj;
1198 9 : int foundoldchild = 0, stricterror;
1199 :
1200 : int ret;
1201 :
1202 9 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OOO", &id, dom_node_class_entry, &newnode, dom_node_class_entry, &oldnode, dom_node_class_entry) == FAILURE) {
1203 0 : return;
1204 : }
1205 :
1206 9 : DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
1207 :
1208 9 : if (dom_node_children_valid(nodep) == FAILURE) {
1209 0 : RETURN_FALSE;
1210 : }
1211 :
1212 9 : DOM_GET_OBJ(newchild, newnode, xmlNodePtr, newchildobj);
1213 9 : DOM_GET_OBJ(oldchild, oldnode, xmlNodePtr, oldchildobj);
1214 :
1215 9 : children = nodep->children;
1216 9 : if (!children) {
1217 0 : RETURN_FALSE;
1218 : }
1219 :
1220 9 : stricterror = dom_get_strict_error(intern->document);
1221 :
1222 9 : if (dom_node_is_read_only(nodep) == SUCCESS ||
1223 : (newchild->parent != NULL && dom_node_is_read_only(newchild->parent) == SUCCESS)) {
1224 0 : php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
1225 0 : RETURN_FALSE;
1226 : }
1227 :
1228 9 : if (newchild->doc != nodep->doc && newchild->doc != NULL) {
1229 0 : php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC);
1230 0 : RETURN_FALSE;
1231 : }
1232 :
1233 9 : if (dom_hierarchy(nodep, newchild) == FAILURE) {
1234 0 : php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC);
1235 0 : RETURN_FALSE;
1236 : }
1237 :
1238 : /* check for the old child and whether the new child is already a child */
1239 27 : while (children) {
1240 18 : if (children == oldchild) {
1241 9 : foundoldchild = 1;
1242 9 : break;
1243 : }
1244 9 : children = children->next;
1245 : }
1246 :
1247 9 : if (foundoldchild) {
1248 : xmlNodePtr node;
1249 9 : zval *rv = NULL;
1250 :
1251 9 : if (newchild->type == XML_DOCUMENT_FRAG_NODE) {
1252 : xmlNodePtr prevsib, nextsib;
1253 6 : prevsib = oldchild->prev;
1254 6 : nextsib = oldchild->next;
1255 :
1256 6 : xmlUnlinkNode(oldchild);
1257 :
1258 6 : newchild = _php_dom_insert_fragment(nodep, prevsib, nextsib, newchild, intern, newchildobj TSRMLS_CC);
1259 6 : if (newchild) {
1260 5 : dom_reconcile_ns(nodep->doc, newchild);
1261 : }
1262 3 : } else if (oldchild != newchild) {
1263 3 : if (newchild->doc == NULL && nodep->doc != NULL) {
1264 0 : xmlSetTreeDoc(newchild, nodep->doc);
1265 0 : newchildobj->document = intern->document;
1266 0 : php_libxml_increment_doc_ref((php_libxml_node_object *)newchildobj, NULL TSRMLS_CC);
1267 : }
1268 3 : node = xmlReplaceNode(oldchild, newchild);
1269 3 : dom_reconcile_ns(nodep->doc, newchild);
1270 : }
1271 9 : DOM_RET_OBJ(rv, oldchild, &ret, intern);
1272 9 : return;
1273 : } else {
1274 0 : php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
1275 0 : RETURN_FALSE;
1276 : }
1277 : }
1278 : /* }}} end dom_node_replace_child */
1279 :
1280 :
1281 : /* {{{ proto DomNode dom_node_remove_child(DomNode oldChild);
1282 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1734834066
1283 : Since:
1284 : */
1285 : PHP_FUNCTION(dom_node_remove_child)
1286 16 : {
1287 : zval *id, *node;
1288 : xmlNodePtr children, child, nodep;
1289 : dom_object *intern, *childobj;
1290 : int ret, stricterror;
1291 :
1292 16 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) {
1293 0 : return;
1294 : }
1295 :
1296 16 : DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
1297 :
1298 16 : if (dom_node_children_valid(nodep) == FAILURE) {
1299 0 : RETURN_FALSE;
1300 : }
1301 :
1302 16 : DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
1303 :
1304 16 : stricterror = dom_get_strict_error(intern->document);
1305 :
1306 16 : if (dom_node_is_read_only(nodep) == SUCCESS ||
1307 : (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
1308 0 : php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
1309 0 : RETURN_FALSE;
1310 : }
1311 :
1312 16 : children = nodep->children;
1313 16 : if (!children) {
1314 0 : php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC);
1315 0 : RETURN_FALSE;
1316 : }
1317 :
1318 48 : while (children) {
1319 32 : if (children == child) {
1320 16 : zval *rv = NULL;
1321 16 : xmlUnlinkNode(child);
1322 16 : DOM_RET_OBJ(rv, child, &ret, intern);
1323 16 : return;
1324 : }
1325 16 : children = children->next;
1326 : }
1327 :
1328 0 : php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC);
1329 0 : RETURN_FALSE
1330 : }
1331 : /* }}} end dom_node_remove_child */
1332 :
1333 :
1334 : /* {{{ proto DomNode dom_node_append_child(DomNode newChild);
1335 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-184E7107
1336 : Since:
1337 : */
1338 : PHP_FUNCTION(dom_node_append_child)
1339 137 : {
1340 137 : zval *id, *node, *rv = NULL;
1341 137 : xmlNodePtr child, nodep, new_child = NULL;
1342 : dom_object *intern, *childobj;
1343 : int ret, stricterror;
1344 :
1345 137 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) {
1346 0 : return;
1347 : }
1348 :
1349 137 : DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
1350 :
1351 137 : if (dom_node_children_valid(nodep) == FAILURE) {
1352 0 : RETURN_FALSE;
1353 : }
1354 :
1355 137 : DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
1356 :
1357 137 : stricterror = dom_get_strict_error(intern->document);
1358 :
1359 137 : if (dom_node_is_read_only(nodep) == SUCCESS ||
1360 : (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
1361 0 : php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
1362 0 : RETURN_FALSE;
1363 : }
1364 :
1365 137 : if (dom_hierarchy(nodep, child) == FAILURE) {
1366 2 : php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC);
1367 2 : RETURN_FALSE;
1368 : }
1369 :
1370 135 : if (!(child->doc == NULL || child->doc == nodep->doc)) {
1371 0 : php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC);
1372 0 : RETURN_FALSE;
1373 : }
1374 :
1375 135 : if (child->type == XML_DOCUMENT_FRAG_NODE && child->children == NULL) {
1376 1 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Fragment is empty");
1377 1 : RETURN_FALSE;
1378 : }
1379 :
1380 134 : if (child->doc == NULL && nodep->doc != NULL) {
1381 22 : childobj->document = intern->document;
1382 22 : php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
1383 : }
1384 :
1385 134 : if (child->parent != NULL){
1386 1 : xmlUnlinkNode(child);
1387 : }
1388 :
1389 139 : if (child->type == XML_TEXT_NODE && nodep->last != NULL && nodep->last->type == XML_TEXT_NODE) {
1390 5 : child->parent = nodep;
1391 5 : if (child->doc == NULL) {
1392 0 : xmlSetTreeDoc(child, nodep->doc);
1393 : }
1394 5 : new_child = child;
1395 5 : if (nodep->children == NULL) {
1396 0 : nodep->children = child;
1397 0 : nodep->last = child;
1398 : } else {
1399 5 : child = nodep->last;
1400 5 : child->next = new_child;
1401 5 : new_child->prev = child;
1402 5 : nodep->last = new_child;
1403 : }
1404 129 : } else if (child->type == XML_ATTRIBUTE_NODE) {
1405 : xmlAttrPtr lastattr;
1406 :
1407 1 : if (child->ns == NULL)
1408 1 : lastattr = xmlHasProp(nodep, child->name);
1409 : else
1410 0 : lastattr = xmlHasNsProp(nodep, child->name, child->ns->href);
1411 1 : if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
1412 0 : if (lastattr != (xmlAttrPtr) child) {
1413 0 : xmlUnlinkNode((xmlNodePtr) lastattr);
1414 0 : php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
1415 : }
1416 : }
1417 128 : } else if (child->type == XML_DOCUMENT_FRAG_NODE) {
1418 6 : new_child = _php_dom_insert_fragment(nodep, nodep->last, NULL, child, intern, childobj TSRMLS_CC);
1419 : }
1420 :
1421 134 : if (new_child == NULL) {
1422 123 : new_child = xmlAddChild(nodep, child);
1423 123 : if (new_child == NULL) {
1424 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't append node");
1425 0 : RETURN_FALSE;
1426 : }
1427 : }
1428 :
1429 134 : dom_reconcile_ns(nodep->doc, new_child);
1430 :
1431 134 : DOM_RET_OBJ(rv, new_child, &ret, intern);
1432 : }
1433 : /* }}} end dom_node_append_child */
1434 :
1435 :
1436 : /* {{{ proto boolean dom_node_has_child_nodes();
1437 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-810594187
1438 : Since:
1439 : */
1440 : PHP_FUNCTION(dom_node_has_child_nodes)
1441 80 : {
1442 : zval *id;
1443 : xmlNode *nodep;
1444 : dom_object *intern;
1445 :
1446 80 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) {
1447 0 : return;
1448 : }
1449 :
1450 80 : DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
1451 :
1452 80 : if (dom_node_children_valid(nodep) == FAILURE) {
1453 42 : RETURN_FALSE;
1454 : }
1455 :
1456 38 : if (nodep->children) {
1457 31 : RETURN_TRUE;
1458 : } else {
1459 7 : RETURN_FALSE;
1460 : }
1461 : }
1462 : /* }}} end dom_node_has_child_nodes */
1463 :
1464 :
1465 : /* {{{ proto DomNode dom_node_clone_node(boolean deep);
1466 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3A0ED0A4
1467 : Since:
1468 : */
1469 : PHP_FUNCTION(dom_node_clone_node)
1470 5 : {
1471 5 : zval *rv = NULL;
1472 : zval *id;
1473 : xmlNode *n, *node;
1474 : int ret;
1475 : dom_object *intern;
1476 5 : long recursive = 0;
1477 :
1478 5 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &id, dom_node_class_entry, &recursive) == FAILURE) {
1479 0 : return;
1480 : }
1481 :
1482 5 : DOM_GET_OBJ(n, id, xmlNodePtr, intern);
1483 :
1484 5 : node = xmlDocCopyNode(n, n->doc, recursive);
1485 :
1486 5 : if (!node) {
1487 0 : RETURN_FALSE;
1488 : }
1489 :
1490 : /* When deep is false Element nodes still require the attributes
1491 : Following taken from libxml as xmlDocCopyNode doesnt do this */
1492 5 : if (n->type == XML_ELEMENT_NODE && recursive == 0) {
1493 3 : if (n->nsDef != NULL) {
1494 0 : node->nsDef = xmlCopyNamespaceList(n->nsDef);
1495 : }
1496 3 : if (n->ns != NULL) {
1497 : xmlNsPtr ns;
1498 0 : ns = xmlSearchNs(n->doc, node, n->ns->prefix);
1499 0 : if (ns == NULL) {
1500 0 : ns = xmlSearchNs(n->doc, n, n->ns->prefix);
1501 0 : if (ns != NULL) {
1502 0 : xmlNodePtr root = node;
1503 :
1504 0 : while (root->parent != NULL) {
1505 0 : root = root->parent;
1506 : }
1507 0 : node->ns = xmlNewNs(root, ns->href, ns->prefix);
1508 : }
1509 : } else {
1510 0 : node->ns = ns;
1511 : }
1512 : }
1513 3 : if (n->properties != NULL) {
1514 3 : node->properties = xmlCopyPropList(node, n->properties);
1515 : }
1516 : }
1517 :
1518 : /* If document cloned we want a new document proxy */
1519 5 : if (node->doc != n->doc) {
1520 0 : intern = NULL;
1521 : }
1522 :
1523 5 : DOM_RET_OBJ(rv, node, &ret, intern);
1524 : }
1525 : /* }}} end dom_node_clone_node */
1526 :
1527 :
1528 :
1529 : /* {{{ proto void dom_node_normalize();
1530 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-normalize
1531 : Since:
1532 : */
1533 : PHP_FUNCTION(dom_node_normalize)
1534 2 : {
1535 : zval *id;
1536 : xmlNode *nodep;
1537 : dom_object *intern;
1538 :
1539 2 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) {
1540 0 : return;
1541 : }
1542 :
1543 2 : DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
1544 :
1545 2 : dom_normalize(nodep TSRMLS_CC);
1546 :
1547 : }
1548 : /* }}} end dom_node_normalize */
1549 :
1550 :
1551 : /* {{{ proto boolean dom_node_is_supported(string feature, string version);
1552 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Level-2-Core-Node-supports
1553 : Since: DOM Level 2
1554 : */
1555 : PHP_FUNCTION(dom_node_is_supported)
1556 0 : {
1557 : zval *id;
1558 : int feature_len, version_len;
1559 : char *feature, *version;
1560 :
1561 0 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_node_class_entry, &feature, &feature_len, &version, &version_len) == FAILURE) {
1562 0 : return;
1563 : }
1564 :
1565 0 : if (dom_has_feature(feature, version)) {
1566 0 : RETURN_TRUE;
1567 : } else {
1568 0 : RETURN_FALSE;
1569 : }
1570 : }
1571 : /* }}} end dom_node_is_supported */
1572 :
1573 :
1574 : /* {{{ proto boolean dom_node_has_attributes();
1575 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeHasAttrs
1576 : Since: DOM Level 2
1577 : */
1578 : PHP_FUNCTION(dom_node_has_attributes)
1579 2 : {
1580 : zval *id;
1581 : xmlNode *nodep;
1582 : dom_object *intern;
1583 :
1584 2 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) {
1585 0 : return;
1586 : }
1587 :
1588 2 : DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
1589 :
1590 2 : if (nodep->type != XML_ELEMENT_NODE)
1591 0 : RETURN_FALSE;
1592 :
1593 2 : if (nodep->properties) {
1594 1 : RETURN_TRUE;
1595 : } else {
1596 1 : RETURN_FALSE;
1597 : }
1598 : }
1599 : /* }}} end dom_node_has_attributes */
1600 :
1601 : /* {{{ proto short dom_node_compare_document_position(DomNode other);
1602 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-compareDocumentPosition
1603 : Since: DOM Level 3
1604 : */
1605 : PHP_FUNCTION(dom_node_compare_document_position)
1606 0 : {
1607 0 : DOM_NOT_IMPLEMENTED();
1608 : }
1609 : /* }}} end dom_node_compare_document_position */
1610 :
1611 :
1612 : /* {{{ proto boolean dom_node_is_same_node(DomNode other);
1613 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isSameNode
1614 : Since: DOM Level 3
1615 : */
1616 : PHP_FUNCTION(dom_node_is_same_node)
1617 2 : {
1618 : zval *id, *node;
1619 : xmlNodePtr nodeotherp, nodep;
1620 : dom_object *intern, *nodeotherobj;
1621 :
1622 2 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) {
1623 0 : return;
1624 : }
1625 :
1626 2 : DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
1627 :
1628 2 : DOM_GET_OBJ(nodeotherp, node, xmlNodePtr, nodeotherobj);
1629 :
1630 2 : if (nodep == nodeotherp) {
1631 1 : RETURN_TRUE;
1632 : } else {
1633 1 : RETURN_FALSE;
1634 : }
1635 : }
1636 : /* }}} end dom_node_is_same_node */
1637 :
1638 :
1639 : /* {{{ proto string dom_node_lookup_prefix(string namespaceURI);
1640 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-lookupNamespacePrefix
1641 : Since: DOM Level 3
1642 : */
1643 : PHP_FUNCTION(dom_node_lookup_prefix)
1644 2 : {
1645 : zval *id;
1646 2 : xmlNodePtr nodep, lookupp = NULL;
1647 : dom_object *intern;
1648 : xmlNsPtr nsptr;
1649 2 : int uri_len = 0;
1650 : char *uri;
1651 :
1652 2 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_node_class_entry, &uri, &uri_len) == FAILURE) {
1653 0 : return;
1654 : }
1655 :
1656 2 : DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
1657 :
1658 2 : if (uri_len > 0) {
1659 2 : switch (nodep->type) {
1660 : case XML_ELEMENT_NODE:
1661 1 : lookupp = nodep;
1662 1 : break;
1663 : case XML_DOCUMENT_NODE:
1664 : case XML_HTML_DOCUMENT_NODE:
1665 1 : lookupp = xmlDocGetRootElement((xmlDocPtr) nodep);
1666 1 : break;
1667 : case XML_ENTITY_NODE :
1668 : case XML_NOTATION_NODE:
1669 : case XML_DOCUMENT_FRAG_NODE:
1670 : case XML_DOCUMENT_TYPE_NODE:
1671 : case XML_DTD_NODE:
1672 0 : RETURN_NULL();
1673 : break;
1674 : default:
1675 0 : lookupp = nodep->parent;
1676 : }
1677 :
1678 2 : if (lookupp != NULL && (nsptr = xmlSearchNsByHref(lookupp->doc, lookupp, uri))) {
1679 2 : if (nsptr->prefix != NULL) {
1680 2 : RETURN_STRING((char *) nsptr->prefix, 1);
1681 : }
1682 : }
1683 : }
1684 :
1685 0 : RETURN_NULL();
1686 : }
1687 : /* }}} end dom_node_lookup_prefix */
1688 :
1689 :
1690 : /* {{{ proto boolean dom_node_is_default_namespace(string namespaceURI);
1691 : URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-isDefaultNamespace
1692 : Since: DOM Level 3
1693 : */
1694 : PHP_FUNCTION(dom_node_is_default_namespace)
1695 2 : {
1696 : zval *id;
1697 : xmlNodePtr nodep;
1698 : dom_object *intern;
1699 : xmlNsPtr nsptr;
1700 2 : int uri_len = 0;
1701 : char *uri;
1702 :
1703 2 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_node_class_entry, &uri, &uri_len) == FAILURE) {
1704 0 : return;
1705 : }
1706 :
1707 2 : DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
1708 2 : if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
1709 1 : nodep = xmlDocGetRootElement((xmlDocPtr) nodep);
1710 : }
1711 :
1712 2 : if (nodep && uri_len > 0) {
1713 2 : nsptr = xmlSearchNs(nodep->doc, nodep, NULL);
1714 2 : if (nsptr && xmlStrEqual(nsptr->href, uri)) {
1715 2 : RETURN_TRUE;
1716 : }
1717 : }
1718 :
1719 0 : RETURN_FALSE;
1720 : }
1721 : /* }}} end dom_node_is_default_namespace */
1722 :
1723 :
1724 : /* {{{ proto string dom_node_lookup_namespace_uri(string prefix);
1725 : URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI
1726 : Since: DOM Level 3
1727 : */
1728 : PHP_FUNCTION(dom_node_lookup_namespace_uri)
1729 3 : {
1730 : zval *id;
1731 : xmlNodePtr nodep;
1732 : dom_object *intern;
1733 : xmlNsPtr nsptr;
1734 3 : int prefix_len = 0;
1735 3 : char *prefix=NULL;
1736 :
1737 3 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!", &id, dom_node_class_entry, &prefix, &prefix_len) == FAILURE) {
1738 0 : return;
1739 : }
1740 :
1741 3 : DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
1742 3 : if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
1743 1 : nodep = xmlDocGetRootElement((xmlDocPtr) nodep);
1744 1 : if (nodep == NULL) {
1745 0 : RETURN_NULL();
1746 : }
1747 : }
1748 :
1749 3 : nsptr = xmlSearchNs(nodep->doc, nodep, prefix);
1750 3 : if (nsptr && nsptr->href != NULL) {
1751 3 : RETURN_STRING((char *) nsptr->href, 1);
1752 : }
1753 :
1754 0 : RETURN_NULL();
1755 : }
1756 : /* }}} end dom_node_lookup_namespace_uri */
1757 :
1758 :
1759 : /* {{{ proto boolean dom_node_is_equal_node(DomNode arg);
1760 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isEqualNode
1761 : Since: DOM Level 3
1762 : */
1763 : PHP_FUNCTION(dom_node_is_equal_node)
1764 0 : {
1765 0 : DOM_NOT_IMPLEMENTED();
1766 : }
1767 : /* }}} end dom_node_is_equal_node */
1768 :
1769 :
1770 : /* {{{ proto DomNode dom_node_get_feature(string feature, string version);
1771 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getFeature
1772 : Since: DOM Level 3
1773 : */
1774 : PHP_FUNCTION(dom_node_get_feature)
1775 0 : {
1776 0 : DOM_NOT_IMPLEMENTED();
1777 : }
1778 : /* }}} end dom_node_get_feature */
1779 :
1780 :
1781 : /* {{{ proto mixed dom_node_set_user_data(string key, mixed data, userdatahandler handler);
1782 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-setUserData
1783 : Since: DOM Level 3
1784 : */
1785 : PHP_FUNCTION(dom_node_set_user_data)
1786 0 : {
1787 0 : DOM_NOT_IMPLEMENTED();
1788 : }
1789 : /* }}} end dom_node_set_user_data */
1790 :
1791 :
1792 : /* {{{ proto mixed dom_node_get_user_data(string key);
1793 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getUserData
1794 : Since: DOM Level 3
1795 : */
1796 : PHP_FUNCTION(dom_node_get_user_data)
1797 0 : {
1798 0 : DOM_NOT_IMPLEMENTED();
1799 : }
1800 : /* }}} end dom_node_get_user_data */
1801 :
1802 :
1803 : static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode)
1804 7 : {
1805 : zval *id;
1806 7 : zval *xpath_array=NULL, *ns_prefixes=NULL;
1807 : xmlNodePtr nodep;
1808 : xmlDocPtr docp;
1809 7 : xmlNodeSetPtr nodeset = NULL;
1810 : dom_object *intern;
1811 7 : zend_bool exclusive=0, with_comments=0;
1812 7 : xmlChar **inclusive_ns_prefixes = NULL;
1813 7 : char *file = NULL;
1814 7 : int ret = -1, file_len = 0;
1815 : xmlOutputBufferPtr buf;
1816 7 : xmlXPathContextPtr ctxp=NULL;
1817 7 : xmlXPathObjectPtr xpathobjp=NULL;
1818 :
1819 7 : if (mode == 0) {
1820 7 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
1821 : "O|bba!a!", &id, dom_node_class_entry, &exclusive, &with_comments,
1822 : &xpath_array, &ns_prefixes) == FAILURE) {
1823 0 : return;
1824 : }
1825 : } else {
1826 0 : if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
1827 : "Os|bba!a!", &id, dom_node_class_entry, &file, &file_len, &exclusive,
1828 : &with_comments, &xpath_array, &ns_prefixes) == FAILURE) {
1829 0 : return;
1830 : }
1831 : }
1832 :
1833 7 : DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
1834 :
1835 7 : docp = nodep->doc;
1836 :
1837 7 : if (! docp) {
1838 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Node must be associated with a document");
1839 0 : RETURN_FALSE;
1840 : }
1841 :
1842 7 : if (xpath_array == NULL) {
1843 5 : if (nodep->type != XML_DOCUMENT_NODE) {
1844 5 : ctxp = xmlXPathNewContext(docp);
1845 5 : ctxp->node = nodep;
1846 5 : xpathobjp = xmlXPathEvalExpression("(.//. | .//@* | .//namespace::*)", ctxp);
1847 5 : ctxp->node = NULL;
1848 10 : if (xpathobjp && xpathobjp->type == XPATH_NODESET) {
1849 5 : nodeset = xpathobjp->nodesetval;
1850 : } else {
1851 0 : if (xpathobjp) {
1852 0 : xmlXPathFreeObject(xpathobjp);
1853 : }
1854 0 : xmlXPathFreeContext(ctxp);
1855 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "XPath query did not return a nodeset.");
1856 0 : RETURN_FALSE;
1857 : }
1858 : }
1859 : } else {
1860 : /*xpath query from xpath_array */
1861 2 : HashTable *ht = Z_ARRVAL_P(xpath_array);
1862 : zval **tmp;
1863 : char *xquery;
1864 :
1865 2 : if (zend_hash_find(ht, "query", sizeof("query"), (void**)&tmp) == SUCCESS &&
1866 : Z_TYPE_PP(tmp) == IS_STRING) {
1867 2 : xquery = Z_STRVAL_PP(tmp);
1868 : } else {
1869 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "'query' missing from xpath array or is not a string");
1870 0 : RETURN_FALSE;
1871 : }
1872 :
1873 2 : ctxp = xmlXPathNewContext(docp);
1874 2 : ctxp->node = nodep;
1875 :
1876 3 : if (zend_hash_find(ht, "namespaces", sizeof("namespaces"), (void**)&tmp) == SUCCESS &&
1877 : Z_TYPE_PP(tmp) == IS_ARRAY) {
1878 : zval **tmpns;
1879 3 : while (zend_hash_get_current_data(Z_ARRVAL_PP(tmp), (void **)&tmpns) == SUCCESS) {
1880 1 : if (Z_TYPE_PP(tmpns) == IS_STRING) {
1881 : char *prefix;
1882 : ulong idx;
1883 : int prefix_key_len;
1884 :
1885 1 : if (zend_hash_get_current_key_ex(Z_ARRVAL_PP(tmp),
1886 : &prefix, &prefix_key_len, &idx, 0, NULL) == HASH_KEY_IS_STRING) {
1887 1 : xmlXPathRegisterNs(ctxp, prefix, Z_STRVAL_PP(tmpns));
1888 : }
1889 : }
1890 1 : zend_hash_move_forward(Z_ARRVAL_PP(tmp));
1891 : }
1892 : }
1893 :
1894 2 : xpathobjp = xmlXPathEvalExpression(xquery, ctxp);
1895 2 : ctxp->node = NULL;
1896 4 : if (xpathobjp && xpathobjp->type == XPATH_NODESET) {
1897 2 : nodeset = xpathobjp->nodesetval;
1898 : } else {
1899 0 : if (xpathobjp) {
1900 0 : xmlXPathFreeObject(xpathobjp);
1901 : }
1902 0 : xmlXPathFreeContext(ctxp);
1903 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "XPath query did not return a nodeset.");
1904 0 : RETURN_FALSE;
1905 : }
1906 : }
1907 :
1908 7 : if (ns_prefixes != NULL) {
1909 2 : if (exclusive) {
1910 : zval **tmpns;
1911 2 : int nscount = 0;
1912 :
1913 2 : inclusive_ns_prefixes = safe_emalloc(zend_hash_num_elements(Z_ARRVAL_P(ns_prefixes)) + 1,
1914 : sizeof(xmlChar *), 0);
1915 6 : while (zend_hash_get_current_data(Z_ARRVAL_P(ns_prefixes), (void **)&tmpns) == SUCCESS) {
1916 2 : if (Z_TYPE_PP(tmpns) == IS_STRING) {
1917 2 : inclusive_ns_prefixes[nscount++] = Z_STRVAL_PP(tmpns);
1918 : }
1919 2 : zend_hash_move_forward(Z_ARRVAL_P(ns_prefixes));
1920 : }
1921 2 : inclusive_ns_prefixes[nscount] = NULL;
1922 : } else {
1923 0 : php_error_docref(NULL TSRMLS_CC, E_NOTICE,
1924 : "Inclusive namespace prefixes only allowed in exlcusive mode.");
1925 : }
1926 : }
1927 :
1928 7 : if (mode == 1) {
1929 0 : buf = xmlOutputBufferCreateFilename(file, NULL, 0);
1930 : } else {
1931 7 : buf = xmlAllocOutputBuffer(NULL);
1932 : }
1933 :
1934 7 : if (buf != NULL) {
1935 7 : ret = xmlC14NDocSaveTo(docp, nodeset, exclusive, inclusive_ns_prefixes,
1936 : with_comments, buf);
1937 : }
1938 :
1939 7 : if (inclusive_ns_prefixes != NULL) {
1940 2 : efree(inclusive_ns_prefixes);
1941 : }
1942 7 : if (xpathobjp != NULL) {
1943 7 : xmlXPathFreeObject(xpathobjp);
1944 : }
1945 7 : if (ctxp != NULL) {
1946 7 : xmlXPathFreeContext(ctxp);
1947 : }
1948 :
1949 7 : if (buf == NULL || ret < 0) {
1950 0 : RETVAL_FALSE;
1951 : } else {
1952 7 : if (mode == 0) {
1953 7 : ret = buf->buffer->use;
1954 7 : if (ret > 0) {
1955 7 : RETVAL_STRINGL((char *) buf->buffer->content, ret, 1);
1956 : } else {
1957 0 : RETVAL_EMPTY_STRING();
1958 : }
1959 : }
1960 : }
1961 :
1962 7 : if (buf) {
1963 : int bytes;
1964 :
1965 7 : bytes = xmlOutputBufferClose(buf);
1966 7 : if (mode == 1 && (ret >= 0)) {
1967 0 : RETURN_LONG(bytes);
1968 : }
1969 : }
1970 : }
1971 :
1972 : /* {{{ proto string DOMNode::C14N([bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]])
1973 : Canonicalize nodes to a string */
1974 : PHP_METHOD(domnode, C14N)
1975 7 : {
1976 7 : dom_canonicalization(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
1977 7 : }
1978 :
1979 : /* {{{ proto int DOMNode::C14NFile(string uri [, bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]])
1980 : Canonicalize nodes to a file */
1981 : PHP_METHOD(domnode, C14NFile)
1982 0 : {
1983 0 : dom_canonicalization(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
1984 0 : }
1985 :
1986 : #endif
1987 :
1988 : /* {{{ proto int DOMNode::getNodePath()
1989 : Gets an xpath for a node */
1990 :
1991 : PHP_METHOD(domnode, getNodePath)
1992 0 : {
1993 : zval *id;
1994 : xmlNode *nodep;
1995 : dom_object *intern;
1996 : char *value;
1997 :
1998 :
1999 :
2000 0 : DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern);
2001 :
2002 0 : value = xmlGetNodePath(nodep);
2003 0 : if (value == NULL) {
2004 0 : RETURN_NULL();
2005 : } else {
2006 0 : RETVAL_STRING(value, 1);
2007 0 : xmlFree(value);
2008 : }
2009 :
2010 :
2011 : }
2012 :
|