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