documentfragment.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2016 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. /* $Id$ */
  20. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23. #include "php.h"
  24. #if HAVE_LIBXML && HAVE_DOM
  25. #include "php_dom.h"
  26. /* {{{ arginfo */
  27. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_documentfragement_construct, 0, 0, 0)
  28. ZEND_END_ARG_INFO();
  29. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_documentfragement_appendXML, 0, 0, 1)
  30. ZEND_ARG_INFO(0, data)
  31. ZEND_END_ARG_INFO();
  32. /* }}} */
  33. /*
  34. * class DOMDocumentFragment extends DOMNode
  35. *
  36. * URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-B63ED1A3
  37. * Since:
  38. */
  39. const zend_function_entry php_dom_documentfragment_class_functions[] = {
  40. PHP_ME(domdocumentfragment, __construct, arginfo_dom_documentfragement_construct, ZEND_ACC_PUBLIC)
  41. PHP_ME(domdocumentfragment, appendXML, arginfo_dom_documentfragement_appendXML, ZEND_ACC_PUBLIC)
  42. PHP_FE_END
  43. };
  44. /* {{{ proto void DOMDocumentFragment::__construct(); */
  45. PHP_METHOD(domdocumentfragment, __construct)
  46. {
  47. zval *id;
  48. xmlNodePtr nodep = NULL, oldnode = NULL;
  49. dom_object *intern;
  50. zend_error_handling error_handling;
  51. zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
  52. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_documentfragment_class_entry) == FAILURE) {
  53. zend_restore_error_handling(&error_handling TSRMLS_CC);
  54. return;
  55. }
  56. zend_restore_error_handling(&error_handling TSRMLS_CC);
  57. nodep = xmlNewDocFragment(NULL);
  58. if (!nodep) {
  59. php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
  60. RETURN_FALSE;
  61. }
  62. intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
  63. if (intern != NULL) {
  64. oldnode = dom_object_get_node(intern);
  65. if (oldnode != NULL) {
  66. php_libxml_node_free_resource(oldnode TSRMLS_CC);
  67. }
  68. /* php_dom_set_object(intern, nodep TSRMLS_CC); */
  69. php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC);
  70. }
  71. }
  72. /* }}} end DOMDocumentFragment::__construct */
  73. /* php_dom_xmlSetTreeDoc is a custom implementation of xmlSetTreeDoc
  74. needed for hack in appendXML due to libxml bug - no need to share this function */
  75. static void php_dom_xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr doc) /* {{{ */
  76. {
  77. xmlAttrPtr prop;
  78. xmlNodePtr cur;
  79. if (tree) {
  80. if(tree->type == XML_ELEMENT_NODE) {
  81. prop = tree->properties;
  82. while (prop != NULL) {
  83. prop->doc = doc;
  84. if (prop->children) {
  85. cur = prop->children;
  86. while (cur != NULL) {
  87. php_dom_xmlSetTreeDoc(cur, doc);
  88. cur = cur->next;
  89. }
  90. }
  91. prop = prop->next;
  92. }
  93. }
  94. if (tree->children != NULL) {
  95. cur = tree->children;
  96. while (cur != NULL) {
  97. php_dom_xmlSetTreeDoc(cur, doc);
  98. cur = cur->next;
  99. }
  100. }
  101. tree->doc = doc;
  102. }
  103. }
  104. /* }}} */
  105. /* {{{ proto void DOMDocumentFragment::appendXML(string data); */
  106. PHP_METHOD(domdocumentfragment, appendXML) {
  107. zval *id;
  108. xmlNode *nodep;
  109. dom_object *intern;
  110. char *data = NULL;
  111. int data_len = 0;
  112. int err;
  113. xmlNodePtr lst;
  114. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_documentfragment_class_entry, &data, &data_len) == FAILURE) {
  115. return;
  116. }
  117. DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
  118. if (dom_node_is_read_only(nodep) == SUCCESS) {
  119. php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  120. RETURN_FALSE;
  121. }
  122. if (data) {
  123. err = xmlParseBalancedChunkMemory(nodep->doc, NULL, NULL, 0, data, &lst);
  124. if (err != 0) {
  125. RETURN_FALSE;
  126. }
  127. /* Following needed due to bug in libxml2 <= 2.6.14
  128. ifdef after next libxml release as bug is fixed in their cvs */
  129. php_dom_xmlSetTreeDoc(lst, nodep->doc);
  130. /* End stupid hack */
  131. xmlAddChildList(nodep,lst);
  132. }
  133. RETURN_TRUE;
  134. }
  135. /* }}} */
  136. #endif
  137. /*
  138. * Local variables:
  139. * tab-width: 4
  140. * c-basic-offset: 4
  141. * End:
  142. * vim600: noet sw=4 ts=4 fdm=marker
  143. * vim<600: noet sw=4 ts=4
  144. */