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