documentfragment.c 4.5 KB

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