summaryrefslogtreecommitdiff
path: root/ext/dom/document.c
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2013-03-14 05:42:27 +0000
committer <>2013-04-03 16:25:08 +0000
commitc4dd7a1a684490673e25aaf4fabec5df138854c4 (patch)
tree4d57c44caae4480efff02b90b9be86f44bf25409 /ext/dom/document.c
downloadphp2-master.tar.gz
Imported from /home/lorry/working-area/delta_php2/php-5.4.13.tar.bz2.HEADphp-5.4.13master
Diffstat (limited to 'ext/dom/document.c')
-rw-r--r--ext/dom/document.c2422
1 files changed, 2422 insertions, 0 deletions
diff --git a/ext/dom/document.c b/ext/dom/document.c
new file mode 100644
index 0000000..d17c7cb
--- /dev/null
+++ b/ext/dom/document.c
@@ -0,0 +1,2422 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+#include <libxml/SAX.h>
+#ifdef LIBXML_SCHEMAS_ENABLED
+#include <libxml/relaxng.h>
+#include <libxml/xmlschemas.h>
+#endif
+
+typedef struct _idsIterator idsIterator;
+struct _idsIterator {
+ xmlChar *elementId;
+ xmlNode *element;
+};
+
+#define DOM_LOAD_STRING 0
+#define DOM_LOAD_FILE 1
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_element, 0, 0, 1)
+ ZEND_ARG_INFO(0, tagName)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_document_fragment, 0, 0, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_text_node, 0, 0, 1)
+ ZEND_ARG_INFO(0, data)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_comment, 0, 0, 1)
+ ZEND_ARG_INFO(0, data)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_cdatasection, 0, 0, 1)
+ ZEND_ARG_INFO(0, data)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_processing_instruction, 0, 0, 2)
+ ZEND_ARG_INFO(0, target)
+ ZEND_ARG_INFO(0, data)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_attribute, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_entity_reference, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_get_elements_by_tag_name, 0, 0, 1)
+ ZEND_ARG_INFO(0, tagName)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_import_node, 0, 0, 2)
+ ZEND_ARG_OBJ_INFO(0, importedNode, DOMNode, 0)
+ ZEND_ARG_INFO(0, deep)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_element_ns, 0, 0, 2)
+ ZEND_ARG_INFO(0, namespaceURI)
+ ZEND_ARG_INFO(0, qualifiedName)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_attribute_ns, 0, 0, 2)
+ ZEND_ARG_INFO(0, namespaceURI)
+ ZEND_ARG_INFO(0, qualifiedName)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_get_elements_by_tag_name_ns, 0, 0, 2)
+ ZEND_ARG_INFO(0, namespaceURI)
+ ZEND_ARG_INFO(0, localName)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_get_element_by_id, 0, 0, 1)
+ ZEND_ARG_INFO(0, elementId)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_adopt_node, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, source, DOMNode, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_normalize_document, 0, 0, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_rename_node, 0, 0, 3)
+ ZEND_ARG_OBJ_INFO(0, node, DOMNode, 0)
+ ZEND_ARG_INFO(0, namespaceURI)
+ ZEND_ARG_INFO(0, qualifiedName)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_load, 0, 0, 1)
+ ZEND_ARG_INFO(0, source)
+ ZEND_ARG_INFO(0, options)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_save, 0, 0, 1)
+ ZEND_ARG_INFO(0, file)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_loadxml, 0, 0, 1)
+ ZEND_ARG_INFO(0, source)
+ ZEND_ARG_INFO(0, options)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_savexml, 0, 0, 0)
+ ZEND_ARG_OBJ_INFO(0, node, DOMNode, 1)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_construct, 0, 0, 0)
+ ZEND_ARG_INFO(0, version)
+ ZEND_ARG_INFO(0, encoding)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_validate, 0, 0, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_xinclude, 0, 0, 0)
+ ZEND_ARG_INFO(0, options)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_loadhtml, 0, 0, 1)
+ ZEND_ARG_INFO(0, source)
+ ZEND_ARG_INFO(0, options)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_loadhtmlfile, 0, 0, 1)
+ ZEND_ARG_INFO(0, source)
+ ZEND_ARG_INFO(0, options)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_savehtml, 0, 0, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_savehtmlfile, 0, 0, 1)
+ ZEND_ARG_INFO(0, file)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_schema_validate_file, 0, 0, 1)
+ ZEND_ARG_INFO(0, filename)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_schema_validate_xml, 0, 0, 1)
+ ZEND_ARG_INFO(0, source)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_relaxNG_validate_file, 0, 0, 1)
+ ZEND_ARG_INFO(0, filename)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_relaxNG_validate_xml, 0, 0, 1)
+ ZEND_ARG_INFO(0, source)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_registernodeclass, 0, 0, 2)
+ ZEND_ARG_INFO(0, baseClass)
+ ZEND_ARG_INFO(0, extendedClass)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class DOMDocument extends DOMNode
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-i-Document
+* Since:
+*/
+
+const zend_function_entry php_dom_document_class_functions[] = { /* {{{ */
+ PHP_FALIAS(createElement, dom_document_create_element, arginfo_dom_document_create_element)
+ PHP_FALIAS(createDocumentFragment, dom_document_create_document_fragment, arginfo_dom_document_create_document_fragment)
+ PHP_FALIAS(createTextNode, dom_document_create_text_node, arginfo_dom_document_create_text_node)
+ PHP_FALIAS(createComment, dom_document_create_comment, arginfo_dom_document_create_comment)
+ PHP_FALIAS(createCDATASection, dom_document_create_cdatasection, arginfo_dom_document_create_cdatasection)
+ PHP_FALIAS(createProcessingInstruction, dom_document_create_processing_instruction, arginfo_dom_document_create_processing_instruction)
+ PHP_FALIAS(createAttribute, dom_document_create_attribute, arginfo_dom_document_create_attribute)
+ PHP_FALIAS(createEntityReference, dom_document_create_entity_reference, arginfo_dom_document_create_entity_reference)
+ PHP_FALIAS(getElementsByTagName, dom_document_get_elements_by_tag_name, arginfo_dom_document_get_elements_by_tag_name)
+ PHP_FALIAS(importNode, dom_document_import_node, arginfo_dom_document_import_node)
+ PHP_FALIAS(createElementNS, dom_document_create_element_ns, arginfo_dom_document_create_element_ns)
+ PHP_FALIAS(createAttributeNS, dom_document_create_attribute_ns, arginfo_dom_document_create_attribute_ns)
+ PHP_FALIAS(getElementsByTagNameNS, dom_document_get_elements_by_tag_name_ns, arginfo_dom_document_get_elements_by_tag_name_ns)
+ PHP_FALIAS(getElementById, dom_document_get_element_by_id, arginfo_dom_document_get_element_by_id)
+ PHP_FALIAS(adoptNode, dom_document_adopt_node, arginfo_dom_document_adopt_node)
+ PHP_FALIAS(normalizeDocument, dom_document_normalize_document, arginfo_dom_document_normalize_document)
+ PHP_FALIAS(renameNode, dom_document_rename_node, arginfo_dom_document_rename_node)
+ PHP_ME(domdocument, load, arginfo_dom_document_load, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
+ PHP_FALIAS(save, dom_document_save, arginfo_dom_document_save)
+ PHP_ME(domdocument, loadXML, arginfo_dom_document_loadxml, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
+ PHP_FALIAS(saveXML, dom_document_savexml, arginfo_dom_document_savexml)
+ PHP_ME(domdocument, __construct, arginfo_dom_document_construct, ZEND_ACC_PUBLIC)
+ PHP_FALIAS(validate, dom_document_validate, arginfo_dom_document_validate)
+ PHP_FALIAS(xinclude, dom_document_xinclude, arginfo_dom_document_xinclude)
+#if defined(LIBXML_HTML_ENABLED)
+ PHP_ME(domdocument, loadHTML, arginfo_dom_document_loadhtml, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
+ PHP_ME(domdocument, loadHTMLFile, arginfo_dom_document_loadhtmlfile, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
+ PHP_FALIAS(saveHTML, dom_document_save_html, arginfo_dom_document_savehtml)
+ PHP_FALIAS(saveHTMLFile, dom_document_save_html_file, arginfo_dom_document_savehtmlfile)
+#endif /* defined(LIBXML_HTML_ENABLED) */
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ PHP_FALIAS(schemaValidate, dom_document_schema_validate_file, arginfo_dom_document_schema_validate_file)
+ PHP_FALIAS(schemaValidateSource, dom_document_schema_validate_xml, arginfo_dom_document_schema_validate_xml)
+ PHP_FALIAS(relaxNGValidate, dom_document_relaxNG_validate_file, arginfo_dom_document_relaxNG_validate_file)
+ PHP_FALIAS(relaxNGValidateSource, dom_document_relaxNG_validate_xml, arginfo_dom_document_relaxNG_validate_xml)
+#endif
+ PHP_ME(domdocument, registerNodeClass, arginfo_dom_document_registernodeclass, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+/* }}} */
+
+/* {{{ docType DOMDocumentType
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-B63ED1A31
+Since:
+*/
+int dom_document_doctype_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlDoc *docp;
+ xmlDtdPtr dtdptr;
+ int ret;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ dtdptr = xmlGetIntSubset(docp);
+ if (!dtdptr) {
+ ZVAL_NULL(*retval);
+ return SUCCESS;
+ }
+
+ if (NULL == (*retval = php_dom_create_object((xmlNodePtr) dtdptr, &ret, *retval, obj TSRMLS_CC))) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
+ return FAILURE;
+ }
+ return SUCCESS;
+
+}
+
+/* }}} */
+
+/* {{{ implementation DOMImplementation
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1B793EBA
+Since:
+*/
+int dom_document_implementation_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ php_dom_create_implementation(retval TSRMLS_CC);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ documentElement DOMElement
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-87CD092
+Since:
+*/
+int dom_document_document_element_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlDoc *docp;
+ xmlNode *root;
+ int ret;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ root = xmlDocGetRootElement(docp);
+ if (!root) {
+ ZVAL_NULL(*retval);
+ return SUCCESS;
+ }
+
+ if (NULL == (*retval = php_dom_create_object(root, &ret, *retval, obj TSRMLS_CC))) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ encoding string
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-encoding
+Since: DOM Level 3
+*/
+int dom_document_encoding_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlDoc *docp;
+ char *encoding;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ encoding = (char *) docp->encoding;
+ ALLOC_ZVAL(*retval);
+
+ if (encoding != NULL) {
+ ZVAL_STRING(*retval, encoding, 1);
+ } else {
+ ZVAL_NULL(*retval);
+ }
+
+ return SUCCESS;
+}
+
+int dom_document_encoding_write(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ zval value_copy;
+ xmlDoc *docp;
+ xmlCharEncodingHandlerPtr handler;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ 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);
+ }
+
+ handler = xmlFindCharEncodingHandler(Z_STRVAL_P(newval));
+
+ if (handler != NULL) {
+ xmlCharEncCloseFunc(handler);
+ if (docp->encoding != NULL) {
+ xmlFree((xmlChar *)docp->encoding);
+ }
+ docp->encoding = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval));
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Document Encoding");
+ }
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ standalone boolean
+readonly=no
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-standalone
+Since: DOM Level 3
+*/
+int dom_document_standalone_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlDoc *docp;
+ int standalone;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+ standalone = docp->standalone;
+ ZVAL_BOOL(*retval, standalone);
+
+ return SUCCESS;
+}
+
+int dom_document_standalone_write(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ zval value_copy;
+ xmlDoc *docp;
+ int standalone;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ if(Z_REFCOUNT_P(newval) > 1) {
+ value_copy = *newval;
+ zval_copy_ctor(&value_copy);
+ newval = &value_copy;
+ }
+ convert_to_long(newval);
+
+ standalone = Z_LVAL_P(newval);
+ if (standalone > 0) {
+ docp->standalone = 1;
+ }
+ else if (standalone < 0) {
+ docp->standalone = -1;
+ }
+ else {
+ docp->standalone = 0;
+ }
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ version string
+readonly=no
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-version
+Since: DOM Level 3
+*/
+int dom_document_version_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlDoc *docp;
+ char *version;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ version = (char *) docp->version;
+ ALLOC_ZVAL(*retval);
+
+ if (version != NULL) {
+ ZVAL_STRING(*retval, version, 1);
+ } else {
+ ZVAL_NULL(*retval);
+ }
+
+ return SUCCESS;
+}
+
+int dom_document_version_write(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ zval value_copy;
+ xmlDoc *docp;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ if (docp->version != NULL) {
+ 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);
+ }
+
+ docp->version = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval));
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ strictErrorChecking boolean
+readonly=no
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-strictErrorChecking
+Since: DOM Level 3
+*/
+int dom_document_strict_error_checking_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ dom_doc_propsptr doc_prop;
+
+ ALLOC_ZVAL(*retval);
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ ZVAL_BOOL(*retval, doc_prop->stricterror);
+ } else {
+ ZVAL_FALSE(*retval);
+ }
+ return SUCCESS;
+}
+
+int dom_document_strict_error_checking_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);
+
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ doc_prop->stricterror = Z_LVAL_P(newval);
+ }
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ formatOutput boolean
+readonly=no
+*/
+int dom_document_format_output_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ dom_doc_propsptr doc_prop;
+
+ ALLOC_ZVAL(*retval);
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ ZVAL_BOOL(*retval, doc_prop->formatoutput);
+ } else {
+ ZVAL_FALSE(*retval);
+ }
+ return SUCCESS;
+}
+
+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);
+
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ doc_prop->formatoutput = Z_LVAL_P(newval);
+ }
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ validateOnParse boolean
+readonly=no
+*/
+int dom_document_validate_on_parse_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ dom_doc_propsptr doc_prop;
+
+ ALLOC_ZVAL(*retval);
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ ZVAL_BOOL(*retval, doc_prop->validateonparse);
+ } else {
+ ZVAL_FALSE(*retval);
+ }
+ return SUCCESS;
+}
+
+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);
+
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ doc_prop->validateonparse = Z_LVAL_P(newval);
+ }
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ resolveExternals boolean
+readonly=no
+*/
+int dom_document_resolve_externals_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ dom_doc_propsptr doc_prop;
+
+ ALLOC_ZVAL(*retval);
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ ZVAL_BOOL(*retval, doc_prop->resolveexternals);
+ } else {
+ ZVAL_FALSE(*retval);
+ }
+ return SUCCESS;
+}
+
+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);
+
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ doc_prop->resolveexternals = Z_LVAL_P(newval);
+ }
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ preserveWhiteSpace boolean
+readonly=no
+*/
+int dom_document_preserve_whitespace_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ dom_doc_propsptr doc_prop;
+
+ ALLOC_ZVAL(*retval);
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ ZVAL_BOOL(*retval, doc_prop->preservewhitespace);
+ } else {
+ ZVAL_FALSE(*retval);
+ }
+ return SUCCESS;
+}
+
+int dom_document_preserve_whitespace_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);
+
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ doc_prop->preservewhitespace = Z_LVAL_P(newval);
+ }
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ recover boolean
+readonly=no
+*/
+int dom_document_recover_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ dom_doc_propsptr doc_prop;
+
+ ALLOC_ZVAL(*retval);
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ ZVAL_BOOL(*retval, doc_prop->recover);
+ } else {
+ ZVAL_FALSE(*retval);
+ }
+ return SUCCESS;
+}
+
+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);
+
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ doc_prop->recover = Z_LVAL_P(newval);
+ }
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ substituteEntities boolean
+readonly=no
+*/
+int dom_document_substitue_entities_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ dom_doc_propsptr doc_prop;
+
+ ALLOC_ZVAL(*retval);
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ ZVAL_BOOL(*retval, doc_prop->substituteentities);
+ } else {
+ ZVAL_FALSE(*retval);
+ }
+ return SUCCESS;
+}
+
+int dom_document_substitue_entities_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);
+
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ doc_prop->substituteentities = Z_LVAL_P(newval);
+ }
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ documentURI string
+readonly=no
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-documentURI
+Since: DOM Level 3
+*/
+int dom_document_document_uri_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlDoc *docp;
+ char *url;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+ url = (char *) docp->URL;
+ if (url != NULL) {
+ ZVAL_STRING(*retval, url, 1);
+ } else {
+ ZVAL_NULL(*retval);
+ }
+
+ return SUCCESS;
+}
+
+int dom_document_document_uri_write(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ zval value_copy;
+ xmlDoc *docp;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ if (docp->URL != NULL) {
+ 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);
+ }
+
+ docp->URL = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval));
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ config DOMConfiguration
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-config
+Since: DOM Level 3
+*/
+int dom_document_config_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_NULL(*retval);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ proto DOMElement dom_document_create_element(string tagName [, string value]);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-2141741547
+Since:
+*/
+PHP_FUNCTION(dom_document_create_element)
+{
+ zval *id;
+ xmlNode *node;
+ xmlDocPtr docp;
+ dom_object *intern;
+ int ret, name_len, value_len;
+ char *name, *value = NULL;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_document_class_entry, &name, &name_len, &value, &value_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ if (xmlValidateName((xmlChar *) name, 0) != 0) {
+ php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ node = xmlNewDocNode(docp, NULL, name, value);
+ if (!node) {
+ RETURN_FALSE;
+ }
+
+ DOM_RET_OBJ(node, &ret, intern);
+}
+/* }}} end dom_document_create_element */
+
+/* {{{ proto DOMDocumentFragment dom_document_create_document_fragment();
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-35CB04B5
+Since:
+*/
+PHP_FUNCTION(dom_document_create_document_fragment)
+{
+ zval *id;
+ xmlNode *node;
+ xmlDocPtr docp;
+ dom_object *intern;
+ int ret;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_document_class_entry) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ node = xmlNewDocFragment(docp);
+ if (!node) {
+ RETURN_FALSE;
+ }
+
+ DOM_RET_OBJ(node, &ret, intern);
+}
+/* }}} end dom_document_create_document_fragment */
+
+/* {{{ proto DOMText dom_document_create_text_node(string data);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1975348127
+Since:
+*/
+PHP_FUNCTION(dom_document_create_text_node)
+{
+ zval *id;
+ xmlNode *node;
+ xmlDocPtr docp;
+ int ret, value_len;
+ dom_object *intern;
+ char *value;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ node = xmlNewDocText(docp, (xmlChar *) value);
+ if (!node) {
+ RETURN_FALSE;
+ }
+
+ DOM_RET_OBJ(node, &ret, intern);
+}
+/* }}} end dom_document_create_text_node */
+
+/* {{{ proto DOMComment dom_document_create_comment(string data);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1334481328
+Since:
+*/
+PHP_FUNCTION(dom_document_create_comment)
+{
+ zval *id;
+ xmlNode *node;
+ xmlDocPtr docp;
+ int ret, value_len;
+ dom_object *intern;
+ char *value;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ node = xmlNewDocComment(docp, (xmlChar *) value);
+ if (!node) {
+ RETURN_FALSE;
+ }
+
+ DOM_RET_OBJ(node, &ret, intern);
+}
+/* }}} end dom_document_create_comment */
+
+/* {{{ proto DOMCdataSection dom_document_create_cdatasection(string data);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D26C0AF8
+Since:
+*/
+PHP_FUNCTION(dom_document_create_cdatasection)
+{
+ zval *id;
+ xmlNode *node;
+ xmlDocPtr docp;
+ int ret, value_len;
+ dom_object *intern;
+ char *value;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ node = xmlNewCDataBlock(docp, (xmlChar *) value, value_len);
+ if (!node) {
+ RETURN_FALSE;
+ }
+
+ DOM_RET_OBJ(node, &ret, intern);
+}
+/* }}} end dom_document_create_cdatasection */
+
+/* {{{ proto DOMProcessingInstruction dom_document_create_processing_instruction(string target, string data);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-135944439
+Since:
+*/
+PHP_FUNCTION(dom_document_create_processing_instruction)
+{
+ zval *id;
+ xmlNode *node;
+ xmlDocPtr docp;
+ int ret, value_len, name_len = 0;
+ dom_object *intern;
+ char *name, *value = NULL;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_document_class_entry, &name, &name_len, &value, &value_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ if (xmlValidateName((xmlChar *) name, 0) != 0) {
+ php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ node = xmlNewPI((xmlChar *) name, (xmlChar *) value);
+ if (!node) {
+ RETURN_FALSE;
+ }
+
+ node->doc = docp;
+
+ DOM_RET_OBJ(node, &ret, intern);
+}
+/* }}} end dom_document_create_processing_instruction */
+
+/* {{{ proto DOMAttr dom_document_create_attribute(string name);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1084891198
+Since:
+*/
+PHP_FUNCTION(dom_document_create_attribute)
+{
+ zval *id;
+ xmlAttrPtr node;
+ xmlDocPtr docp;
+ int ret, name_len;
+ dom_object *intern;
+ char *name;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ if (xmlValidateName((xmlChar *) name, 0) != 0) {
+ php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ node = xmlNewDocProp(docp, (xmlChar *) name, NULL);
+ if (!node) {
+ RETURN_FALSE;
+ }
+
+ DOM_RET_OBJ((xmlNodePtr) node, &ret, intern);
+
+}
+/* }}} end dom_document_create_attribute */
+
+/* {{{ proto DOMEntityReference dom_document_create_entity_reference(string name);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-392B75AE
+Since:
+*/
+PHP_FUNCTION(dom_document_create_entity_reference)
+{
+ zval *id;
+ xmlNode *node;
+ xmlDocPtr docp = NULL;
+ dom_object *intern;
+ int ret, name_len;
+ char *name;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ if (xmlValidateName((xmlChar *) name, 0) != 0) {
+ php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ node = xmlNewReference(docp, name);
+ if (!node) {
+ RETURN_FALSE;
+ }
+
+ DOM_RET_OBJ((xmlNodePtr) node, &ret, intern);
+}
+/* }}} end dom_document_create_entity_reference */
+
+/* {{{ proto DOMNodeList dom_document_get_elements_by_tag_name(string tagname);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C9094
+Since:
+*/
+PHP_FUNCTION(dom_document_get_elements_by_tag_name)
+{
+ zval *id;
+ xmlDocPtr docp;
+ int name_len;
+ dom_object *intern, *namednode;
+ char *name;
+ xmlChar *local;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
+ namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
+ local = xmlCharStrndup(name, name_len);
+ dom_namednode_iter(intern, 0, namednode, NULL, local, NULL TSRMLS_CC);
+}
+/* }}} end dom_document_get_elements_by_tag_name */
+
+/* {{{ proto DOMNode dom_document_import_node(DOMNode importedNode, boolean deep);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Core-Document-importNode
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_document_import_node)
+{
+ zval *id, *node;
+ xmlDocPtr docp;
+ xmlNodePtr nodep, retnodep;
+ dom_object *intern, *nodeobj;
+ int ret;
+ long recursive = 0;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO|l", &id, dom_document_class_entry, &node, dom_node_class_entry, &recursive) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ DOM_GET_OBJ(nodep, node, xmlNodePtr, nodeobj);
+
+ if (nodep->type == XML_HTML_DOCUMENT_NODE || nodep->type == XML_DOCUMENT_NODE
+ || nodep->type == XML_DOCUMENT_TYPE_NODE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot import: Node Type Not Supported");
+ RETURN_FALSE;
+ }
+
+ if (nodep->doc == docp) {
+ retnodep = nodep;
+ } else {
+ if ((recursive == 0) && (nodep->type == XML_ELEMENT_NODE)) {
+ recursive = 2;
+ }
+ retnodep = xmlDocCopyNode(nodep, docp, recursive);
+ if (!retnodep) {
+ RETURN_FALSE;
+ }
+
+ if ((retnodep->type == XML_ATTRIBUTE_NODE) && (nodep->ns != NULL)) {
+ xmlNsPtr nsptr = NULL;
+ xmlNodePtr root = xmlDocGetRootElement(docp);
+
+ nsptr = xmlSearchNsByHref (nodep->doc, root, nodep->ns->href);
+ if (nsptr == NULL) {
+ int errorcode;
+ nsptr = dom_get_ns(root, (char *) nodep->ns->href, &errorcode, (char *) nodep->ns->prefix);
+ }
+ xmlSetNs(retnodep, nsptr);
+ }
+ }
+
+ DOM_RET_OBJ((xmlNodePtr) retnodep, &ret, intern);
+}
+/* }}} end dom_document_import_node */
+
+/* {{{ proto DOMElement dom_document_create_element_ns(string namespaceURI, string qualifiedName [,string value]);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrElNS
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_document_create_element_ns)
+{
+ zval *id;
+ xmlDocPtr docp;
+ xmlNodePtr nodep = NULL;
+ xmlNsPtr nsptr = NULL;
+ int ret, uri_len = 0, name_len = 0, value_len = 0;
+ char *uri, *name, *value = NULL;
+ char *localname = NULL, *prefix = NULL;
+ int errorcode;
+ dom_object *intern;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s|s", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len, &value, &value_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
+
+ if (errorcode == 0) {
+ if (xmlValidateName((xmlChar *) localname, 0) == 0) {
+ nodep = xmlNewDocNode (docp, NULL, localname, value);
+ if (nodep != NULL && uri != NULL) {
+ nsptr = xmlSearchNsByHref (nodep->doc, nodep, uri);
+ if (nsptr == NULL) {
+ nsptr = dom_get_ns(nodep, uri, &errorcode, prefix);
+ }
+ xmlSetNs(nodep, nsptr);
+ }
+ } else {
+ errorcode = INVALID_CHARACTER_ERR;
+ }
+ }
+
+ xmlFree(localname);
+ if (prefix != NULL) {
+ xmlFree(prefix);
+ }
+
+ if (errorcode != 0) {
+ if (nodep != NULL) {
+ xmlFreeNode(nodep);
+ }
+ php_dom_throw_error(errorcode, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (nodep == NULL) {
+ RETURN_FALSE;
+ }
+
+
+ nodep->ns = nsptr;
+
+ DOM_RET_OBJ(nodep, &ret, intern);
+}
+/* }}} end dom_document_create_element_ns */
+
+/* {{{ proto DOMAttr dom_document_create_attribute_ns(string namespaceURI, string qualifiedName);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrAttrNS
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_document_create_attribute_ns)
+{
+ zval *id;
+ xmlDocPtr docp;
+ xmlNodePtr nodep = NULL, root;
+ xmlNsPtr nsptr;
+ int ret, uri_len = 0, name_len = 0;
+ char *uri, *name;
+ char *localname = NULL, *prefix = NULL;
+ dom_object *intern;
+ int errorcode;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ root = xmlDocGetRootElement(docp);
+ if (root != NULL) {
+ errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
+ if (errorcode == 0) {
+ if (xmlValidateName((xmlChar *) localname, 0) == 0) {
+ nodep = (xmlNodePtr) xmlNewDocProp(docp, localname, NULL);
+ if (nodep != NULL && uri_len > 0) {
+ nsptr = xmlSearchNsByHref (nodep->doc, root, uri);
+ if (nsptr == NULL) {
+ nsptr = dom_get_ns(root, uri, &errorcode, prefix);
+ }
+ xmlSetNs(nodep, nsptr);
+ }
+ } else {
+ errorcode = INVALID_CHARACTER_ERR;
+ }
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Missing Root Element");
+ RETURN_FALSE;
+ }
+
+ xmlFree(localname);
+ if (prefix != NULL) {
+ xmlFree(prefix);
+ }
+
+ if (errorcode != 0) {
+ if (nodep != NULL) {
+ xmlFreeProp((xmlAttrPtr) nodep);
+ }
+ php_dom_throw_error(errorcode, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (nodep == NULL) {
+ RETURN_FALSE;
+ }
+
+ DOM_RET_OBJ(nodep, &ret, intern);
+}
+/* }}} end dom_document_create_attribute_ns */
+
+/* {{{ proto DOMNodeList dom_document_get_elements_by_tag_name_ns(string namespaceURI, string localName);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBTNNS
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_document_get_elements_by_tag_name_ns)
+{
+ zval *id;
+ xmlDocPtr docp;
+ int uri_len, name_len;
+ dom_object *intern, *namednode;
+ char *uri, *name;
+ xmlChar *local, *nsuri;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
+ namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
+ local = xmlCharStrndup(name, name_len);
+ nsuri = xmlCharStrndup(uri, uri_len);
+ dom_namednode_iter(intern, 0, namednode, NULL, local, nsuri TSRMLS_CC);
+}
+/* }}} end dom_document_get_elements_by_tag_name_ns */
+
+/* {{{ proto DOMElement dom_document_get_element_by_id(string elementId);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBId
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_document_get_element_by_id)
+{
+ zval *id;
+ xmlDocPtr docp;
+ xmlAttrPtr attrp;
+ int ret, idname_len;
+ dom_object *intern;
+ char *idname;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &idname, &idname_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ attrp = xmlGetID(docp, (xmlChar *) idname);
+
+ if (attrp && attrp->parent) {
+ DOM_RET_OBJ((xmlNodePtr) attrp->parent, &ret, intern);
+ } else {
+ RETVAL_NULL();
+ }
+
+}
+/* }}} end dom_document_get_element_by_id */
+
+/* {{{ proto DOMNode dom_document_adopt_node(DOMNode source);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-adoptNode
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_document_adopt_node)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_document_adopt_node */
+
+/* {{{ proto void dom_document_normalize_document();
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-normalizeDocument
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_document_normalize_document)
+{
+ zval *id;
+ xmlDocPtr docp;
+ dom_object *intern;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_document_class_entry) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ dom_normalize((xmlNodePtr) docp TSRMLS_CC);
+}
+/* }}} end dom_document_normalize_document */
+
+/* {{{ proto DOMNode dom_document_rename_node(node n, string namespaceURI, string qualifiedName);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-renameNode
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_document_rename_node)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_document_rename_node */
+
+/* {{{ proto void DOMDocument::__construct([string version], [string encoding]); */
+PHP_METHOD(domdocument, __construct)
+{
+
+ zval *id;
+ xmlDoc *docp = NULL, *olddoc;
+ dom_object *intern;
+ char *encoding, *version = NULL;
+ int encoding_len = 0, version_len = 0, refcount;
+ zend_error_handling error_handling;
+
+ zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|ss", &id, dom_document_class_entry, &version, &version_len, &encoding, &encoding_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ return;
+ }
+
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ docp = xmlNewDoc(version);
+
+ if (!docp) {
+ php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (encoding_len > 0) {
+ docp->encoding = (const xmlChar*)xmlStrdup(encoding);
+ }
+
+ intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+ if (intern != NULL) {
+ olddoc = (xmlDocPtr) dom_object_get_node(intern);
+ if (olddoc != NULL) {
+ php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC);
+ refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
+ if (refcount != 0) {
+ olddoc->_private = NULL;
+ }
+ }
+ intern->document = NULL;
+ if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, docp TSRMLS_CC) == -1) {
+ RETURN_FALSE;
+ }
+ php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)docp, (void *)intern TSRMLS_CC);
+ }
+}
+/* }}} end DOMDocument::__construct */
+
+char *_dom_get_valid_file_path(char *source, char *resolved_path, int resolved_path_len TSRMLS_DC) /* {{{ */
+{
+ xmlURI *uri;
+ xmlChar *escsource;
+ char *file_dest;
+ int isFileUri = 0;
+
+ uri = xmlCreateURI();
+ escsource = xmlURIEscapeStr(source, ":");
+ xmlParseURIReference(uri, escsource);
+ xmlFree(escsource);
+
+ if (uri->scheme != NULL) {
+ /* absolute file uris - libxml only supports localhost or empty host */
+ if (strncasecmp(source, "file:///",8) == 0) {
+ isFileUri = 1;
+#ifdef PHP_WIN32
+ source += 8;
+#else
+ source += 7;
+#endif
+ } else if (strncasecmp(source, "file://localhost/",17) == 0) {
+ isFileUri = 1;
+#ifdef PHP_WIN32
+ source += 17;
+#else
+ source += 16;
+#endif
+ }
+ }
+
+ file_dest = source;
+
+ if ((uri->scheme == NULL || isFileUri)) {
+ /* XXX possible buffer overflow if VCWD_REALPATH does not know size of resolved_path */
+ if (!VCWD_REALPATH(source, resolved_path) && !expand_filepath(source, resolved_path TSRMLS_CC)) {
+ xmlFreeURI(uri);
+ return NULL;
+ }
+ file_dest = resolved_path;
+ }
+
+ xmlFreeURI(uri);
+
+ return file_dest;
+}
+/* }}} */
+
+static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, int source_len, int options TSRMLS_DC) /* {{{ */
+{
+ xmlDocPtr ret;
+ xmlParserCtxtPtr ctxt = NULL;
+ dom_doc_propsptr doc_props;
+ dom_object *intern;
+ php_libxml_ref_obj *document = NULL;
+ int validate, recover, resolve_externals, keep_blanks, substitute_ent;
+ int resolved_path_len;
+ int old_error_reporting = 0;
+ char *directory=NULL, resolved_path[MAXPATHLEN];
+
+ if (id != NULL) {
+ intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+ document = intern->document;
+ }
+
+ doc_props = dom_get_doc_props(document);
+ validate = doc_props->validateonparse;
+ resolve_externals = doc_props->resolveexternals;
+ keep_blanks = doc_props->preservewhitespace;
+ substitute_ent = doc_props->substituteentities;
+ recover = doc_props->recover;
+
+ if (document == NULL) {
+ efree(doc_props);
+ }
+
+ xmlInitParser();
+
+ if (mode == DOM_LOAD_FILE) {
+ char *file_dest = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC);
+ if (file_dest) {
+ ctxt = xmlCreateFileParserCtxt(file_dest);
+ }
+
+ } else {
+ ctxt = xmlCreateMemoryParserCtxt(source, source_len);
+ }
+
+ if (ctxt == NULL) {
+ return(NULL);
+ }
+
+ /* If loading from memory, we need to set the base directory for the document */
+ if (mode != DOM_LOAD_FILE) {
+#if HAVE_GETCWD
+ directory = VCWD_GETCWD(resolved_path, MAXPATHLEN);
+#elif HAVE_GETWD
+ directory = VCWD_GETWD(resolved_path);
+#endif
+ if (directory) {
+ if(ctxt->directory != NULL) {
+ xmlFree((char *) ctxt->directory);
+ }
+ resolved_path_len = strlen(resolved_path);
+ if (resolved_path[resolved_path_len - 1] != DEFAULT_SLASH) {
+ resolved_path[resolved_path_len] = DEFAULT_SLASH;
+ resolved_path[++resolved_path_len] = '\0';
+ }
+ ctxt->directory = (char *) xmlCanonicPath((const xmlChar *) resolved_path);
+ }
+ }
+
+ ctxt->vctxt.error = php_libxml_ctx_error;
+ ctxt->vctxt.warning = php_libxml_ctx_warning;
+
+ if (ctxt->sax != NULL) {
+ ctxt->sax->error = php_libxml_ctx_error;
+ ctxt->sax->warning = php_libxml_ctx_warning;
+ }
+
+ if (validate && ! (options & XML_PARSE_DTDVALID)) {
+ options |= XML_PARSE_DTDVALID;
+ }
+ if (resolve_externals && ! (options & XML_PARSE_DTDATTR)) {
+ options |= XML_PARSE_DTDATTR;
+ }
+ if (substitute_ent && ! (options & XML_PARSE_NOENT)) {
+ options |= XML_PARSE_NOENT;
+ }
+ if (keep_blanks == 0 && ! (options & XML_PARSE_NOBLANKS)) {
+ options |= XML_PARSE_NOBLANKS;
+ }
+
+ xmlCtxtUseOptions(ctxt, options);
+
+ ctxt->recovery = recover;
+ if (recover) {
+ old_error_reporting = EG(error_reporting);
+ EG(error_reporting) = old_error_reporting | E_WARNING;
+ }
+
+ xmlParseDocument(ctxt);
+
+ if (ctxt->wellFormed || recover) {
+ ret = ctxt->myDoc;
+ if (ctxt->recovery) {
+ EG(error_reporting) = old_error_reporting;
+ }
+ /* If loading from memory, set the base reference uri for the document */
+ if (ret && ret->URL == NULL && ctxt->directory != NULL) {
+ ret->URL = xmlStrdup(ctxt->directory);
+ }
+ } else {
+ ret = NULL;
+ xmlFreeDoc(ctxt->myDoc);
+ ctxt->myDoc = NULL;
+ }
+
+ xmlFreeParserCtxt(ctxt);
+
+ return(ret);
+}
+/* }}} */
+
+/* {{{ static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) */
+static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) {
+ zval *id;
+ xmlDoc *docp = NULL, *newdoc;
+ dom_doc_propsptr doc_prop;
+ dom_object *intern;
+ char *source;
+ int source_len, refcount, ret;
+ long options = 0;
+
+ id = getThis();
+ if (id != NULL && ! instanceof_function(Z_OBJCE_P(id), dom_document_class_entry TSRMLS_CC)) {
+ id = NULL;
+ }
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &source, &source_len, &options) == FAILURE) {
+ return;
+ }
+
+ if (!source_len) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string supplied as input");
+ RETURN_FALSE;
+ }
+
+ newdoc = dom_document_parser(id, mode, source, source_len, options TSRMLS_CC);
+
+ if (!newdoc)
+ RETURN_FALSE;
+
+ if (id != NULL) {
+ intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+ if (intern != NULL) {
+ docp = (xmlDocPtr) dom_object_get_node(intern);
+ doc_prop = NULL;
+ if (docp != NULL) {
+ php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC);
+ doc_prop = intern->document->doc_props;
+ intern->document->doc_props = NULL;
+ refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
+ if (refcount != 0) {
+ docp->_private = NULL;
+ }
+ }
+ intern->document = NULL;
+ if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, newdoc TSRMLS_CC) == -1) {
+ RETURN_FALSE;
+ }
+ intern->document->doc_props = doc_prop;
+ }
+
+ php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)newdoc, (void *)intern TSRMLS_CC);
+
+ RETURN_TRUE;
+ } else {
+ DOM_RET_OBJ((xmlNodePtr) newdoc, &ret, NULL);
+ }
+}
+/* }}} end dom_parser_document */
+
+/* {{{ proto DOMNode dom_document_load(string source [, int options]);
+URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-load
+Since: DOM Level 3
+*/
+PHP_METHOD(domdocument, load)
+{
+ dom_parse_document(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
+}
+/* }}} end dom_document_load */
+
+/* {{{ proto DOMNode dom_document_loadxml(string source [, int options]);
+URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-loadXML
+Since: DOM Level 3
+*/
+PHP_METHOD(domdocument, loadXML)
+{
+ dom_parse_document(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
+}
+/* }}} end dom_document_loadxml */
+
+/* {{{ proto int dom_document_save(string file);
+Convenience method to save to file
+*/
+PHP_FUNCTION(dom_document_save)
+{
+ zval *id;
+ xmlDoc *docp;
+ int file_len = 0, bytes, format, saveempty = 0;
+ dom_object *intern;
+ dom_doc_propsptr doc_props;
+ char *file;
+ long options = 0;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|l", &id, dom_document_class_entry, &file, &file_len, &options) == FAILURE) {
+ return;
+ }
+
+ if (file_len == 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Filename");
+ RETURN_FALSE;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ /* encoding handled by property on doc */
+
+ doc_props = dom_get_doc_props(intern->document);
+ format = doc_props->formatoutput;
+ if (options & LIBXML_SAVE_NOEMPTYTAG) {
+ saveempty = xmlSaveNoEmptyTags;
+ xmlSaveNoEmptyTags = 1;
+ }
+ bytes = xmlSaveFormatFileEnc(file, docp, NULL, format);
+ if (options & LIBXML_SAVE_NOEMPTYTAG) {
+ xmlSaveNoEmptyTags = saveempty;
+ }
+ if (bytes == -1) {
+ RETURN_FALSE;
+ }
+ RETURN_LONG(bytes);
+}
+/* }}} end dom_document_save */
+
+/* {{{ proto string dom_document_savexml([node n]);
+URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-saveXML
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_document_savexml)
+{
+ zval *id, *nodep = NULL;
+ xmlDoc *docp;
+ xmlNode *node;
+ xmlBufferPtr buf;
+ xmlChar *mem;
+ dom_object *intern, *nodeobj;
+ dom_doc_propsptr doc_props;
+ int size, format, saveempty = 0;
+ long options = 0;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|O!l", &id, dom_document_class_entry, &nodep, dom_node_class_entry, &options) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ doc_props = dom_get_doc_props(intern->document);
+ format = doc_props->formatoutput;
+
+ if (nodep != NULL) {
+ /* Dump contents of Node */
+ DOM_GET_OBJ(node, nodep, xmlNodePtr, nodeobj);
+ if (node->doc != docp) {
+ php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ buf = xmlBufferCreate();
+ if (!buf) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch buffer");
+ RETURN_FALSE;
+ }
+ if (options & LIBXML_SAVE_NOEMPTYTAG) {
+ saveempty = xmlSaveNoEmptyTags;
+ xmlSaveNoEmptyTags = 1;
+ }
+ xmlNodeDump(buf, docp, node, 0, format);
+ if (options & LIBXML_SAVE_NOEMPTYTAG) {
+ xmlSaveNoEmptyTags = saveempty;
+ }
+ mem = (xmlChar*) xmlBufferContent(buf);
+ if (!mem) {
+ xmlBufferFree(buf);
+ RETURN_FALSE;
+ }
+ RETVAL_STRING(mem, 1);
+ xmlBufferFree(buf);
+ } else {
+ if (options & LIBXML_SAVE_NOEMPTYTAG) {
+ saveempty = xmlSaveNoEmptyTags;
+ xmlSaveNoEmptyTags = 1;
+ }
+ /* Encoding is handled from the encoding property set on the document */
+ xmlDocDumpFormatMemory(docp, &mem, &size, format);
+ if (options & LIBXML_SAVE_NOEMPTYTAG) {
+ xmlSaveNoEmptyTags = saveempty;
+ }
+ if (!size) {
+ RETURN_FALSE;
+ }
+ RETVAL_STRINGL(mem, size, 1);
+ xmlFree(mem);
+ }
+}
+/* }}} end dom_document_savexml */
+
+static xmlNodePtr php_dom_free_xinclude_node(xmlNodePtr cur TSRMLS_DC) /* {{{ */
+{
+ xmlNodePtr xincnode;
+
+ xincnode = cur;
+ cur = cur->next;
+ xmlUnlinkNode(xincnode);
+ php_libxml_node_free_resource(xincnode TSRMLS_CC);
+
+ return cur;
+}
+/* }}} */
+
+static void php_dom_remove_xinclude_nodes(xmlNodePtr cur TSRMLS_DC) /* {{{ */
+{
+ while(cur) {
+ if (cur->type == XML_XINCLUDE_START) {
+ cur = php_dom_free_xinclude_node(cur TSRMLS_CC);
+
+ /* XML_XINCLUDE_END node will be a sibling of XML_XINCLUDE_START */
+ while(cur && cur->type != XML_XINCLUDE_END) {
+ /* remove xinclude processing nodes from recursive xincludes */
+ if (cur->type == XML_ELEMENT_NODE) {
+ php_dom_remove_xinclude_nodes(cur->children TSRMLS_CC);
+ }
+ cur = cur->next;
+ }
+
+ if (cur && cur->type == XML_XINCLUDE_END) {
+ cur = php_dom_free_xinclude_node(cur TSRMLS_CC);
+ }
+ } else {
+ if (cur->type == XML_ELEMENT_NODE) {
+ php_dom_remove_xinclude_nodes(cur->children TSRMLS_CC);
+ }
+ cur = cur->next;
+ }
+ }
+}
+/* }}} */
+
+/* {{{ proto int dom_document_xinclude([int options])
+ Substitutues xincludes in a DomDocument */
+PHP_FUNCTION(dom_document_xinclude)
+{
+ zval *id;
+ xmlDoc *docp;
+ xmlNodePtr root;
+ long flags = 0;
+ int err;
+ dom_object *intern;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &id, dom_document_class_entry, &flags) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ err = xmlXIncludeProcessFlags(docp, flags);
+
+ /* XML_XINCLUDE_START and XML_XINCLUDE_END nodes need to be removed as these
+ are added via xmlXIncludeProcess to mark beginning and ending of xincluded document
+ but are not wanted in resulting document - must be done even if err as it could fail after
+ having processed some xincludes */
+ root = (xmlNodePtr) docp->children;
+ while(root && root->type != XML_ELEMENT_NODE && root->type != XML_XINCLUDE_START) {
+ root = root->next;
+ }
+ if (root) {
+ php_dom_remove_xinclude_nodes(root TSRMLS_CC);
+ }
+
+ if (err) {
+ RETVAL_LONG(err);
+ } else {
+ RETVAL_FALSE;
+ }
+
+}
+/* }}} */
+
+/* {{{ proto boolean dom_document_validate();
+Since: DOM extended
+*/
+PHP_FUNCTION(dom_document_validate)
+{
+ zval *id;
+ xmlDoc *docp;
+ dom_object *intern;
+ xmlValidCtxt *cvp;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_document_class_entry) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ cvp = xmlNewValidCtxt();
+
+ cvp->userData = NULL;
+ cvp->error = (xmlValidityErrorFunc) php_libxml_error_handler;
+ cvp->warning = (xmlValidityErrorFunc) php_libxml_error_handler;
+
+ if (xmlValidateDocument(cvp, docp)) {
+ RETVAL_TRUE;
+ } else {
+ RETVAL_FALSE;
+ }
+
+ xmlFreeValidCtxt(cvp);
+
+}
+/* }}} */
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+static void _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
+{
+ zval *id;
+ xmlDoc *docp;
+ dom_object *intern;
+ char *source = NULL, *valid_file = NULL;
+ int source_len = 0;
+ xmlSchemaParserCtxtPtr parser;
+ xmlSchemaPtr sptr;
+ xmlSchemaValidCtxtPtr vptr;
+ int is_valid;
+ char resolved_path[MAXPATHLEN + 1];
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Op", &id, dom_document_class_entry, &source, &source_len) == FAILURE) {
+ return;
+ }
+
+ if (source_len == 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema source");
+ RETURN_FALSE;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ switch (type) {
+ case DOM_LOAD_FILE:
+ valid_file = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC);
+ if (!valid_file) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema file source");
+ RETURN_FALSE;
+ }
+ parser = xmlSchemaNewParserCtxt(valid_file);
+ break;
+ case DOM_LOAD_STRING:
+ parser = xmlSchemaNewMemParserCtxt(source, source_len);
+ /* If loading from memory, we need to set the base directory for the document
+ but it is not apparent how to do that for schema's */
+ break;
+ default:
+ return;
+ }
+
+ xmlSchemaSetParserErrors(parser,
+ (xmlSchemaValidityErrorFunc) php_libxml_error_handler,
+ (xmlSchemaValidityWarningFunc) php_libxml_error_handler,
+ parser);
+ sptr = xmlSchemaParse(parser);
+ xmlSchemaFreeParserCtxt(parser);
+ if (!sptr) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema");
+ RETURN_FALSE;
+ }
+
+ docp = (xmlDocPtr) dom_object_get_node(intern);
+
+ vptr = xmlSchemaNewValidCtxt(sptr);
+ if (!vptr) {
+ xmlSchemaFree(sptr);
+ php_error(E_ERROR, "Invalid Schema Validation Context");
+ RETURN_FALSE;
+ }
+
+ xmlSchemaSetValidErrors(vptr, php_libxml_error_handler, php_libxml_error_handler, vptr);
+ is_valid = xmlSchemaValidateDoc(vptr, docp);
+ xmlSchemaFree(sptr);
+ xmlSchemaFreeValidCtxt(vptr);
+
+ if (is_valid == 0) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto boolean dom_document_schema_validate_file(string filename); */
+PHP_FUNCTION(dom_document_schema_validate_file)
+{
+ _dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
+}
+/* }}} end dom_document_schema_validate_file */
+
+/* {{{ proto boolean dom_document_schema_validate(string source); */
+PHP_FUNCTION(dom_document_schema_validate_xml)
+{
+ _dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
+}
+/* }}} end dom_document_schema_validate */
+
+static void _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
+{
+ zval *id;
+ xmlDoc *docp;
+ dom_object *intern;
+ char *source = NULL, *valid_file = NULL;
+ int source_len = 0;
+ xmlRelaxNGParserCtxtPtr parser;
+ xmlRelaxNGPtr sptr;
+ xmlRelaxNGValidCtxtPtr vptr;
+ int is_valid;
+ char resolved_path[MAXPATHLEN + 1];
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Op", &id, dom_document_class_entry, &source, &source_len) == FAILURE) {
+ return;
+ }
+
+ if (source_len == 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema source");
+ RETURN_FALSE;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ switch (type) {
+ case DOM_LOAD_FILE:
+ valid_file = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC);
+ if (!valid_file) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid RelaxNG file source");
+ RETURN_FALSE;
+ }
+ parser = xmlRelaxNGNewParserCtxt(valid_file);
+ break;
+ case DOM_LOAD_STRING:
+ parser = xmlRelaxNGNewMemParserCtxt(source, source_len);
+ /* If loading from memory, we need to set the base directory for the document
+ but it is not apparent how to do that for schema's */
+ break;
+ default:
+ return;
+ }
+
+ xmlRelaxNGSetParserErrors(parser,
+ (xmlRelaxNGValidityErrorFunc) php_libxml_error_handler,
+ (xmlRelaxNGValidityWarningFunc) php_libxml_error_handler,
+ parser);
+ sptr = xmlRelaxNGParse(parser);
+ xmlRelaxNGFreeParserCtxt(parser);
+ if (!sptr) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid RelaxNG");
+ RETURN_FALSE;
+ }
+
+ docp = (xmlDocPtr) dom_object_get_node(intern);
+
+ vptr = xmlRelaxNGNewValidCtxt(sptr);
+ if (!vptr) {
+ xmlRelaxNGFree(sptr);
+ php_error(E_ERROR, "Invalid RelaxNG Validation Context");
+ RETURN_FALSE;
+ }
+
+ xmlRelaxNGSetValidErrors(vptr, php_libxml_error_handler, php_libxml_error_handler, vptr);
+ is_valid = xmlRelaxNGValidateDoc(vptr, docp);
+ xmlRelaxNGFree(sptr);
+ xmlRelaxNGFreeValidCtxt(vptr);
+
+ if (is_valid == 0) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto boolean dom_document_relaxNG_validate_file(string filename); */
+PHP_FUNCTION(dom_document_relaxNG_validate_file)
+{
+ _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
+}
+/* }}} end dom_document_relaxNG_validate_file */
+
+/* {{{ proto boolean dom_document_relaxNG_validate_xml(string source); */
+PHP_FUNCTION(dom_document_relaxNG_validate_xml)
+{
+ _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
+}
+/* }}} end dom_document_relaxNG_validate_xml */
+
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+
+static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */
+{
+ zval *id;
+ xmlDoc *docp = NULL, *newdoc;
+ dom_object *intern;
+ dom_doc_propsptr doc_prop;
+ char *source;
+ int source_len, refcount, ret;
+ long options = 0;
+ htmlParserCtxtPtr ctxt;
+
+ id = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &source, &source_len, &options) == FAILURE) {
+ return;
+ }
+
+ if (!source_len) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string supplied as input");
+ RETURN_FALSE;
+ }
+
+ if (mode == DOM_LOAD_FILE) {
+ ctxt = htmlCreateFileParserCtxt(source, NULL);
+ } else {
+ source_len = xmlStrlen(source);
+ ctxt = htmlCreateMemoryParserCtxt(source, source_len);
+ }
+
+ if (!ctxt) {
+ RETURN_FALSE;
+ }
+
+ if (options) {
+ htmlCtxtUseOptions(ctxt, options);
+ }
+
+ ctxt->vctxt.error = php_libxml_ctx_error;
+ ctxt->vctxt.warning = php_libxml_ctx_warning;
+ if (ctxt->sax != NULL) {
+ ctxt->sax->error = php_libxml_ctx_error;
+ ctxt->sax->warning = php_libxml_ctx_warning;
+ }
+ htmlParseDocument(ctxt);
+ newdoc = ctxt->myDoc;
+ htmlFreeParserCtxt(ctxt);
+
+ if (!newdoc)
+ RETURN_FALSE;
+
+ if (id != NULL && instanceof_function(Z_OBJCE_P(id), dom_document_class_entry TSRMLS_CC)) {
+ intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+ if (intern != NULL) {
+ docp = (xmlDocPtr) dom_object_get_node(intern);
+ doc_prop = NULL;
+ if (docp != NULL) {
+ php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC);
+ doc_prop = intern->document->doc_props;
+ intern->document->doc_props = NULL;
+ refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
+ if (refcount != 0) {
+ docp->_private = NULL;
+ }
+ }
+ intern->document = NULL;
+ if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, newdoc TSRMLS_CC) == -1) {
+ RETURN_FALSE;
+ }
+ intern->document->doc_props = doc_prop;
+ }
+
+ php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)newdoc, (void *)intern TSRMLS_CC);
+
+ RETURN_TRUE;
+ } else {
+ DOM_RET_OBJ((xmlNodePtr) newdoc, &ret, NULL);
+ }
+}
+/* }}} */
+
+/* {{{ proto DOMNode dom_document_load_html_file(string source);
+Since: DOM extended
+*/
+PHP_METHOD(domdocument, loadHTMLFile)
+{
+ dom_load_html(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
+}
+/* }}} end dom_document_load_html_file */
+
+/* {{{ proto DOMNode dom_document_load_html(string source);
+Since: DOM extended
+*/
+PHP_METHOD(domdocument, loadHTML)
+{
+ dom_load_html(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
+}
+/* }}} end dom_document_load_html */
+
+/* {{{ proto int dom_document_save_html_file(string file);
+Convenience method to save to file as html
+*/
+PHP_FUNCTION(dom_document_save_html_file)
+{
+ zval *id;
+ xmlDoc *docp;
+ int file_len, bytes, format;
+ dom_object *intern;
+ dom_doc_propsptr doc_props;
+ char *file;
+ const char *encoding;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &file, &file_len) == FAILURE) {
+ return;
+ }
+
+ if (file_len == 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Filename");
+ RETURN_FALSE;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+
+ encoding = (const char *) htmlGetMetaEncoding(docp);
+
+ doc_props = dom_get_doc_props(intern->document);
+ format = doc_props->formatoutput;
+ bytes = htmlSaveFileFormat(file, docp, encoding, format);
+
+ if (bytes == -1) {
+ RETURN_FALSE;
+ }
+ RETURN_LONG(bytes);
+}
+/* }}} end dom_document_save_html_file */
+
+/* {{{ proto string dom_document_save_html();
+Convenience method to output as html
+*/
+PHP_FUNCTION(dom_document_save_html)
+{
+ zval *id, *nodep = NULL;
+ xmlDoc *docp;
+ xmlNode *node;
+ xmlBufferPtr buf;
+ dom_object *intern, *nodeobj;
+ xmlChar *mem = NULL;
+ int size, format;
+ dom_doc_propsptr doc_props;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "O|O!", &id, dom_document_class_entry, &nodep, dom_node_class_entry)
+ == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ doc_props = dom_get_doc_props(intern->document);
+ format = doc_props->formatoutput;
+
+ if (nodep != NULL) {
+ /* Dump contents of Node */
+ DOM_GET_OBJ(node, nodep, xmlNodePtr, nodeobj);
+ if (node->doc != docp) {
+ php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ buf = xmlBufferCreate();
+ if (!buf) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch buffer");
+ RETURN_FALSE;
+ }
+
+ size = htmlNodeDump(buf, docp, node);
+ if (size >= 0) {
+ mem = (xmlChar*) xmlBufferContent(buf);
+ if (!mem) {
+ RETVAL_FALSE;
+ } else {
+ RETVAL_STRINGL((const char*) mem, size, 1);
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error dumping HTML node");
+ RETVAL_FALSE;
+ }
+ xmlBufferFree(buf);
+ } else {
+#if LIBXML_VERSION >= 20623
+ htmlDocDumpMemoryFormat(docp, &mem, &size, format);
+#else
+ htmlDocDumpMemory(docp, &mem, &size);
+#endif
+ if (!size) {
+ RETVAL_FALSE;
+ } else {
+ RETVAL_STRINGL((const char*) mem, size, 1);
+ }
+ if (mem)
+ xmlFree(mem);
+ }
+
+}
+/* }}} end dom_document_save_html */
+
+#endif /* defined(LIBXML_HTML_ENABLED) */
+
+/* {{{ proto boolean DOMDocument::registerNodeClass(string baseclass, string extendedclass);
+ Register extended class used to create base node type */
+PHP_METHOD(domdocument, registerNodeClass)
+{
+ zval *id;
+ xmlDoc *docp;
+ char *baseclass = NULL, *extendedclass = NULL;
+ int baseclass_len = 0, extendedclass_len = 0;
+ zend_class_entry *basece = NULL, *ce = NULL;
+ dom_object *intern;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss!", &id, dom_document_class_entry, &baseclass, &baseclass_len, &extendedclass, &extendedclass_len) == FAILURE) {
+ return;
+ }
+
+ if (baseclass_len) {
+ zend_class_entry **pce;
+ if (zend_lookup_class(baseclass, baseclass_len, &pce TSRMLS_CC) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s does not exist", baseclass);
+ return;
+ }
+ basece = *pce;
+ }
+
+ if (basece == NULL || ! instanceof_function(basece, dom_node_class_entry TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s is not derived from DOMNode.", baseclass);
+ return;
+ }
+
+ if (extendedclass_len) {
+ zend_class_entry **pce;
+ if (zend_lookup_class(extendedclass, extendedclass_len, &pce TSRMLS_CC) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s does not exist", extendedclass);
+ }
+ ce = *pce;
+ }
+
+ if (ce == NULL || instanceof_function(ce, basece TSRMLS_CC)) {
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ if (dom_set_doc_classmap(intern->document, basece, ce TSRMLS_CC) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s could not be registered.", extendedclass);
+ }
+ RETURN_TRUE;
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s is not derived from %s.", extendedclass, baseclass);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+#endif /* HAVE_LIBXML && HAVE_DOM */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */