]> granicus.if.org Git - php/commitdiff
Make DOMNode::textContent writeable
authorTjerk Meesters <datibbaw@php.net>
Mon, 1 Sep 2014 22:34:18 +0000 (06:34 +0800)
committerTjerk Meesters <datibbaw@php.net>
Mon, 1 Sep 2014 22:34:18 +0000 (06:34 +0800)
ext/dom/attr.c
ext/dom/characterdata.c
ext/dom/document.c
ext/dom/node.c
ext/dom/php_dom.h
ext/dom/tests/node_textcontent.phpt [new file with mode: 0644]

index ebbc41f6f5fa359599450d357f8e3a62fbffdce4..2976add461b12e7e9a80c35fdf2a6d73a884b5d0 100644 (file)
@@ -183,14 +183,7 @@ int dom_attr_value_write(dom_object *obj, zval *newval TSRMLS_DC)
                node_list_unlink(attrp->children TSRMLS_CC);
        }
 
-       if (newval->type != IS_STRING) {
-               if(Z_REFCOUNT_P(newval) > 1) {
-                       value_copy = *newval;
-                       zval_copy_ctor(&value_copy);
-                       newval = &value_copy;
-               }
-               convert_to_string(newval);
-       }
+       convert_to_string_copy(newval, value_copy);
 
        xmlNodeSetContentLen((xmlNodePtr) attrp, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1);
 
index 92eb2801593577515d46a92b0b79577e7470168f..606886fed387eff4dc6a682f8dde8a7f30477c25 100644 (file)
@@ -112,14 +112,7 @@ int dom_characterdata_data_write(dom_object *obj, zval *newval TSRMLS_DC)
                return FAILURE;
        }
 
-       if (newval->type != IS_STRING) {
-               if(Z_REFCOUNT_P(newval) > 1) {
-                       value_copy = *newval;
-                       zval_copy_ctor(&value_copy);
-                       newval = &value_copy;
-               }
-               convert_to_string(newval);
-       }
+       convert_to_string_copy(newval, value_copy);
 
        xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1);
 
index 095f96dc0978fd39b848f37823b10dd082de9854..3d8a1571d1e98332670735d09602f700c654a1f6 100644 (file)
@@ -361,14 +361,7 @@ int dom_document_encoding_write(dom_object *obj, zval *newval TSRMLS_DC)
                return FAILURE;
        }
 
-       if (newval->type != IS_STRING) {
-               if(Z_REFCOUNT_P(newval) > 1) {
-                       value_copy = *newval;
-                       zval_copy_ctor(&value_copy);
-                       newval = &value_copy;
-               }
-               convert_to_string(newval);
-       }
+       convert_to_string_copy(newval, value_copy);
 
        handler = xmlFindCharEncodingHandler(Z_STRVAL_P(newval));
 
@@ -428,12 +421,7 @@ int dom_document_standalone_write(dom_object *obj, zval *newval TSRMLS_DC)
                return FAILURE;
        }
 
-       if(Z_REFCOUNT_P(newval) > 1) {
-               value_copy = *newval;
-               zval_copy_ctor(&value_copy);
-               newval = &value_copy;
-       }
-       convert_to_long(newval);
+       convert_to_long_copy(newval, value_copy);
 
        standalone = Z_LVAL_P(newval);
     if (standalone > 0) {
@@ -500,14 +488,7 @@ int dom_document_version_write(dom_object *obj, zval *newval TSRMLS_DC)
                xmlFree((xmlChar *) docp->version );
        }
 
-       if (newval->type != IS_STRING) {
-               if(Z_REFCOUNT_P(newval) > 1) {
-                       value_copy = *newval;
-                       zval_copy_ctor(&value_copy);
-                       newval = &value_copy;
-               }
-               convert_to_string(newval);
-       }
+       convert_to_string_copy(newval, value_copy);
 
        docp->version = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval));
 
@@ -544,12 +525,7 @@ int dom_document_strict_error_checking_write(dom_object *obj, zval *newval TSRML
        zval value_copy;
        dom_doc_propsptr doc_prop;
 
-       if(Z_REFCOUNT_P(newval) > 1) {
-               value_copy = *newval;
-               zval_copy_ctor(&value_copy);
-               newval = &value_copy;
-       }
-       convert_to_boolean(newval);
+       convert_to_boolean_copy(newval, value_copy);
 
        if (obj->document) {
                doc_prop = dom_get_doc_props(obj->document);
@@ -587,12 +563,7 @@ int dom_document_format_output_write(dom_object *obj, zval *newval TSRMLS_DC)
        zval value_copy;
        dom_doc_propsptr doc_prop;
 
-       if(Z_REFCOUNT_P(newval) > 1) {
-               value_copy = *newval;
-               zval_copy_ctor(&value_copy);
-               newval = &value_copy;
-       }
-       convert_to_boolean(newval);
+       convert_to_boolean_copy(newval, value_copy);
 
        if (obj->document) {
                doc_prop = dom_get_doc_props(obj->document);
@@ -629,12 +600,7 @@ int dom_document_validate_on_parse_write(dom_object *obj, zval *newval TSRMLS_DC
        zval value_copy;
        dom_doc_propsptr doc_prop;
 
-       if(Z_REFCOUNT_P(newval) > 1) {
-               value_copy = *newval;
-               zval_copy_ctor(&value_copy);
-               newval = &value_copy;
-       }
-       convert_to_boolean(newval);
+       convert_to_boolean_copy(newval, value_copy);
 
        if (obj->document) {
                doc_prop = dom_get_doc_props(obj->document);
@@ -671,12 +637,7 @@ int dom_document_resolve_externals_write(dom_object *obj, zval *newval TSRMLS_DC
        zval value_copy;
        dom_doc_propsptr doc_prop;
 
-       if(Z_REFCOUNT_P(newval) > 1) {
-               value_copy = *newval;
-               zval_copy_ctor(&value_copy);
-               newval = &value_copy;
-       }
-       convert_to_boolean(newval);
+       convert_to_boolean_copy(newval, value_copy);
 
        if (obj->document) {
                doc_prop = dom_get_doc_props(obj->document);
@@ -713,12 +674,7 @@ int dom_document_preserve_whitespace_write(dom_object *obj, zval *newval TSRMLS_
        zval value_copy;
        dom_doc_propsptr doc_prop;
 
-       if(Z_REFCOUNT_P(newval) > 1) {
-               value_copy = *newval;
-               zval_copy_ctor(&value_copy);
-               newval = &value_copy;
-       }
-       convert_to_boolean(newval);
+       convert_to_boolean_copy(newval, value_copy);
 
        if (obj->document) {
                doc_prop = dom_get_doc_props(obj->document);
@@ -755,12 +711,7 @@ int dom_document_recover_write(dom_object *obj, zval *newval TSRMLS_DC)
        zval value_copy;
        dom_doc_propsptr doc_prop;
 
-       if(Z_REFCOUNT_P(newval) > 1) {
-               value_copy = *newval;
-               zval_copy_ctor(&value_copy);
-               newval = &value_copy;
-       }
-       convert_to_boolean(newval);
+       convert_to_boolean_copy(newval, value_copy);
 
        if (obj->document) {
                doc_prop = dom_get_doc_props(obj->document);
@@ -797,12 +748,7 @@ int dom_document_substitue_entities_write(dom_object *obj, zval *newval TSRMLS_D
        zval value_copy;
        dom_doc_propsptr doc_prop;
 
-       if(Z_REFCOUNT_P(newval) > 1) {
-               value_copy = *newval;
-               zval_copy_ctor(&value_copy);
-               newval = &value_copy;
-       }
-       convert_to_boolean(newval);
+       convert_to_boolean_copy(newval, value_copy);
 
        if (obj->document) {
                doc_prop = dom_get_doc_props(obj->document);
@@ -861,14 +807,7 @@ int dom_document_document_uri_write(dom_object *obj, zval *newval TSRMLS_DC)
                xmlFree((xmlChar *) docp->URL);
        }
 
-       if (newval->type != IS_STRING) {
-               if(Z_REFCOUNT_P(newval) > 1) {
-                       value_copy = *newval;
-                       zval_copy_ctor(&value_copy);
-                       newval = &value_copy;
-               }
-               convert_to_string(newval);
-       }
+       convert_to_string_copy(newval, value_copy);
 
        docp->URL = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval));
 
index ae74ea04cffc8b7c19e187b6baf69db9f4ba46eb..2c484adae9b47af98513713fb6de768cb76a6541 100644 (file)
@@ -352,14 +352,7 @@ int dom_node_node_value_write(dom_object *obj, zval *newval TSRMLS_DC)
                case XML_COMMENT_NODE:
                case XML_CDATA_SECTION_NODE:
                case XML_PI_NODE:
-                       if (newval->type != IS_STRING) {
-                               if(Z_REFCOUNT_P(newval) > 1) {
-                                       value_copy = *newval;
-                                       zval_copy_ctor(&value_copy);
-                                       newval = &value_copy;
-                               }
-                               convert_to_string(newval);
-                       }
+                       convert_to_string_copy(newval, value_copy);
                        xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1);
                        if (newval == &value_copy) {
                                zval_dtor(newval);
@@ -794,14 +787,7 @@ int dom_node_prefix_write(dom_object *obj, zval *newval TSRMLS_DC)
                                        nsnode = xmlDocGetRootElement(nodep->doc);
                                }
                        }
-                       if (newval->type != IS_STRING) {
-                               if(Z_REFCOUNT_P(newval) > 1) {
-                                       value_copy = *newval;
-                                       zval_copy_ctor(&value_copy);
-                                       newval = &value_copy;
-                               }
-                               convert_to_string(newval);
-                       }
+                       convert_to_string_copy(newval, value_copy);
                        prefix = Z_STRVAL_P(newval);
                        if (nsnode && nodep->ns != NULL && !xmlStrEqual(nodep->ns->prefix, (xmlChar *)prefix)) {
                                strURI = (char *) nodep->ns->href;
@@ -942,6 +928,23 @@ int dom_node_text_content_read(dom_object *obj, zval **retval TSRMLS_DC)
 
 int dom_node_text_content_write(dom_object *obj, zval *newval TSRMLS_DC)
 {
+       xmlNode *nodep = dom_object_get_node(obj);
+       zval value_copy;
+       xmlChar *enc_str;
+
+       if (nodep == NULL) {
+               php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+               return FAILURE;
+       }
+
+       convert_to_string_copy(newval, value_copy);
+       enc_str = xmlEncodeEntitiesReentrant(nodep->doc, Z_STRVAL_P(newval));
+       xmlNodeSetContent(nodep, enc_str);
+       xmlFree(enc_str);
+       if (newval == &value_copy) {
+               zval_dtor(newval);
+       }
+
        return SUCCESS;
 }
 
index f2bccf7b87186abc73e906071d8cd8bd75d0ed1c..f5f0bc6a728e80df57ec4fbe5d9d7a403858cc01 100644 (file)
@@ -146,6 +146,20 @@ entry = zend_register_internal_class_ex(&ce, parent_ce, NULL TSRMLS_CC);
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not yet implemented"); \
        return;
 
+#define convert_to_copy_master(orig, copy, lower_type, upper_type) \
+       if (Z_TYPE_P(orig) != IS_##upper_type) { \
+               if (Z_REFCOUNT_P(orig) > 1) {        \
+                       copy = *orig;                    \
+                       zval_copy_ctor(&copy);           \
+                       orig = &copy;                    \
+               }                                    \
+               convert_to_##lower_type(orig);       \
+       }
+
+#define convert_to_string_copy(orig, copy)  convert_to_copy_master(orig, copy, string, STRING);
+#define convert_to_long_copy(orig, copy)    convert_to_copy_master(orig, copy, long, LONG);
+#define convert_to_boolean_copy(orig, copy) convert_to_copy_master(orig, copy, boolean, BOOL);
+
 #define DOM_NODELIST 0
 #define DOM_NAMEDNODEMAP 1
 
diff --git a/ext/dom/tests/node_textcontent.phpt b/ext/dom/tests/node_textcontent.phpt
new file mode 100644 (file)
index 0000000..a731a26
--- /dev/null
@@ -0,0 +1,29 @@
+--TEST--
+Testing reading and writing to DOMNode::textContent
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$html = <<<HTML
+<div id="test"><span>hi there</span></div>
+HTML;
+
+$text = '<p>hello world &trade;</p>';
+
+$dom = new DOMDocument('1.0', 'UTF-8');
+$dom->loadHTML($html);
+
+$node = $dom->getElementById('test');
+var_dump($node->textContent);
+$node->textContent = $text;
+var_dump($node->textContent == $text);
+
+var_dump($dom->saveHTML($node));
+
+?>
+--EXPECT--
+string(8) "hi there"
+bool(true)
+string(63) "<div id="test">&lt;p&gt;hello world &amp;trade;&lt;/p&gt;</div>"
+