]> granicus.if.org Git - php/commitdiff
add registerNodeClass() method
authorRob Richards <rrichards@php.net>
Wed, 23 Nov 2005 02:56:41 +0000 (02:56 +0000)
committerRob Richards <rrichards@php.net>
Wed, 23 Nov 2005 02:56:41 +0000 (02:56 +0000)
 - methods can now natively return user classes registered with document

ext/dom/document.c
ext/dom/dom_fe.h
ext/dom/php_dom.c
ext/dom/php_dom.h
ext/dom/xml_common.h

index d8765e16ca0f1774e8676b8603fd67257dbf91f0..601c75bd176edd4933d185c30515e022442a1f70 100644 (file)
@@ -85,6 +85,7 @@ zend_function_entry php_dom_document_class_functions[] = {
        PHP_FALIAS(relaxNGValidate, dom_document_relaxNG_validate_file, NULL)
        PHP_FALIAS(relaxNGValidateSource, dom_document_relaxNG_validate_xml, NULL)
 #endif
+       PHP_ME(domdocument, registerNodeClass, NULL, ZEND_ACC_PUBLIC)
        {NULL, NULL, NULL}
 };
 
@@ -384,7 +385,7 @@ Since: DOM Level 3
 */
 int dom_document_strict_error_checking_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-       dom_doc_props *doc_prop;
+       dom_doc_propsptr doc_prop;
 
        ALLOC_ZVAL(*retval);
        if (obj->document) {
@@ -399,7 +400,7 @@ int dom_document_strict_error_checking_read(dom_object *obj, zval **retval TSRML
 int dom_document_strict_error_checking_write(dom_object *obj, zval *newval TSRMLS_DC)
 {
        zval value_copy;
-       dom_doc_props *doc_prop;
+       dom_doc_propsptr doc_prop;
 
        if(newval->refcount > 1) {
                value_copy = *newval;
@@ -427,7 +428,7 @@ readonly=no
 */
 int dom_document_format_output_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-       dom_doc_props *doc_prop;
+       dom_doc_propsptr doc_prop;
 
        ALLOC_ZVAL(*retval);
        if (obj->document) {
@@ -442,7 +443,7 @@ int dom_document_format_output_read(dom_object *obj, zval **retval TSRMLS_DC)
 int dom_document_format_output_write(dom_object *obj, zval *newval TSRMLS_DC)
 {
        zval value_copy;
-       dom_doc_props *doc_prop;
+       dom_doc_propsptr doc_prop;
 
        if(newval->refcount > 1) {
                value_copy = *newval;
@@ -469,7 +470,7 @@ readonly=no
 */
 int    dom_document_validate_on_parse_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-       dom_doc_props *doc_prop;
+       dom_doc_propsptr doc_prop;
 
        ALLOC_ZVAL(*retval);
        if (obj->document) {
@@ -484,7 +485,7 @@ int dom_document_validate_on_parse_read(dom_object *obj, zval **retval TSRMLS_DC
 int dom_document_validate_on_parse_write(dom_object *obj, zval *newval TSRMLS_DC)
 {
        zval value_copy;
-       dom_doc_props *doc_prop;
+       dom_doc_propsptr doc_prop;
 
        if(newval->refcount > 1) {
                value_copy = *newval;
@@ -512,7 +513,7 @@ readonly=no
 */
 int dom_document_resolve_externals_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-       dom_doc_props *doc_prop;
+       dom_doc_propsptr doc_prop;
 
        ALLOC_ZVAL(*retval);
        if (obj->document) {
@@ -527,7 +528,7 @@ int dom_document_resolve_externals_read(dom_object *obj, zval **retval TSRMLS_DC
 int dom_document_resolve_externals_write(dom_object *obj, zval *newval TSRMLS_DC)
 {
        zval value_copy;
-       dom_doc_props *doc_prop;
+       dom_doc_propsptr doc_prop;
 
        if(newval->refcount > 1) {
                value_copy = *newval;
@@ -555,7 +556,7 @@ readonly=no
 */
 int dom_document_preserve_whitespace_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-       dom_doc_props *doc_prop;
+       dom_doc_propsptr doc_prop;
 
        ALLOC_ZVAL(*retval);
        if (obj->document) {
@@ -570,7 +571,7 @@ int dom_document_preserve_whitespace_read(dom_object *obj, zval **retval TSRMLS_
 int dom_document_preserve_whitespace_write(dom_object *obj, zval *newval TSRMLS_DC)
 {
        zval value_copy;
-       dom_doc_props *doc_prop;
+       dom_doc_propsptr doc_prop;
 
        if(newval->refcount > 1) {
                value_copy = *newval;
@@ -597,7 +598,7 @@ readonly=no
 */
 int dom_document_recover_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-       dom_doc_props *doc_prop;
+       dom_doc_propsptr doc_prop;
 
        ALLOC_ZVAL(*retval);
        if (obj->document) {
@@ -612,7 +613,7 @@ int dom_document_recover_read(dom_object *obj, zval **retval TSRMLS_DC)
 int dom_document_recover_write(dom_object *obj, zval *newval TSRMLS_DC)
 {
        zval value_copy;
-       dom_doc_props *doc_prop;
+       dom_doc_propsptr doc_prop;
 
        if(newval->refcount > 1) {
                value_copy = *newval;
@@ -640,7 +641,7 @@ readonly=no
 */
 int dom_document_substitue_entities_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-       dom_doc_props *doc_prop;
+       dom_doc_propsptr doc_prop;
 
        ALLOC_ZVAL(*retval);
        if (obj->document) {
@@ -655,7 +656,7 @@ int dom_document_substitue_entities_read(dom_object *obj, zval **retval TSRMLS_D
 int dom_document_substitue_entities_write(dom_object *obj, zval *newval TSRMLS_DC)
 {
        zval value_copy;
-       dom_doc_props *doc_prop;
+       dom_doc_propsptr doc_prop;
 
        if(newval->refcount > 1) {
                value_copy = *newval;
@@ -1410,7 +1411,7 @@ char *_dom_get_valid_file_path(char *source, char *resolved_path, int resolved_p
 static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, int options TSRMLS_DC) {
     xmlDocPtr ret;
     xmlParserCtxtPtr ctxt = NULL;
-       dom_doc_props *doc_props;
+       dom_doc_propsptr doc_props;
        dom_object *intern;
        php_libxml_ref_obj *document = NULL;
        int validate, recover, resolve_externals, keep_blanks, substitute_ent;
@@ -1436,10 +1437,6 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, int optio
 
        xmlInitParser();
 
-#if LIBXML_VERSION < 20600
-       keep_blanks = xmlKeepBlanksDefault(keep_blanks);
-#endif
-
        if (mode == DOM_LOAD_FILE) {
                char *file_dest = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN  TSRMLS_CC);
                if (file_dest) {
@@ -1450,14 +1447,6 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, int optio
                ctxt = xmlCreateDocParserCtxt(source);
        }
 
-#if LIBXML_VERSION < 20600
-       xmlKeepBlanksDefault(keep_blanks);
-       /* xmlIndentTreeOutput default is changed in xmlKeepBlanksDefault
-       reset back to 1 which is default value */
-
-       xmlIndentTreeOutput = 1;
-#endif
-
        if (ctxt == NULL) {
                return(NULL);
        }
@@ -1490,7 +1479,6 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, int optio
                ctxt->sax->warning = php_libxml_ctx_warning;
        }
 
-#if LIBXML_VERSION >= 20600
        if (validate && ! (options & XML_PARSE_DTDVALID)) {
                options |= XML_PARSE_DTDVALID;
        }
@@ -1505,11 +1493,6 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, int optio
        }
 
        xmlCtxtUseOptions(ctxt, options);
-#else
-       ctxt->validate = validate;
-    ctxt->loadsubset = (resolve_externals * XML_COMPLETE_ATTRS);
-       ctxt->replaceEntities = substitute_ent;
-#endif
 
        ctxt->recovery = recover;
        if (recover) {
@@ -1544,7 +1527,7 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, int optio
 static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) {
        zval *id, *rv = NULL;
        xmlDoc *docp = NULL, *newdoc;
-       dom_doc_props *doc_prop;
+       dom_doc_propsptr doc_prop;
        dom_object *intern;
        char *source;
        int source_len, refcount, ret;
@@ -1626,7 +1609,7 @@ PHP_FUNCTION(dom_document_save)
        xmlDoc *docp;
        int file_len = 0, bytes, format, saveempty;
        dom_object *intern;
-       dom_doc_props *doc_props;
+       dom_doc_propsptr doc_props;
        char *file;
        long options = 0;
 
@@ -1672,7 +1655,7 @@ PHP_FUNCTION(dom_document_savexml)
        xmlBufferPtr buf;
        xmlChar *mem;
        dom_object *intern, *nodeobj;
-       dom_doc_props *doc_props;
+       dom_doc_propsptr doc_props;
        int size, format, saveempty;
        long options = 0;
 
@@ -1781,11 +1764,7 @@ PHP_FUNCTION(dom_document_xinclude)
 
        DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
 
-#if LIBXML_VERSION >= 20607
        err = xmlXIncludeProcessFlags(docp, flags);
-#else
-       err = xmlXIncludeProcess (docp);
-#endif
 
        /* 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 
@@ -2034,7 +2013,7 @@ static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode)
        zval *id, *rv = NULL;
        xmlDoc *docp = NULL, *newdoc;
        dom_object *intern;
-       dom_doc_props *doc_prop;
+       dom_doc_propsptr doc_prop;
        char *source;
        int source_len, refcount, ret;
        htmlParserCtxtPtr ctxt;
@@ -2128,7 +2107,7 @@ PHP_FUNCTION(dom_document_save_html_file)
        xmlDoc *docp;
        int file_len, bytes, format;
        dom_object *intern;
-       dom_doc_props *doc_props;
+       dom_doc_propsptr doc_props;
        char *file;
 
        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, U_CLASS_ENTRY(dom_document_class_entry), &file, &file_len) == FAILURE) {
@@ -2185,4 +2164,58 @@ PHP_FUNCTION(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;
+       zend_uchar type1, type2;
+
+       if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss!", &id, U_CLASS_ENTRY(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, U_CLASS_ENTRY(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 */
index f20daff65b53be1d96a16804aec31f26c73568fd..f3c7772695f71fec0564a4e9404805b4237826d5 100644 (file)
@@ -130,6 +130,7 @@ PHP_METHOD(domdocument, loadXML);
 PHP_FUNCTION(dom_document_savexml);
 PHP_FUNCTION(dom_document_validate);
 PHP_FUNCTION(dom_document_xinclude);
+PHP_METHOD(domdocument, registerNodeClass);
 
 #if defined(LIBXML_HTML_ENABLED)
 PHP_METHOD(domdocument, loadHTML);
index 1c54e523f6254b2a1ebc08833968f6c8800c20b7..3e7a916025f4608befc412a33df0c0e65cdcd0ef 100644 (file)
@@ -127,12 +127,12 @@ int dom_node_children_valid(xmlNodePtr node) {
 /* {{{ dom_get_doc_props() */
 dom_doc_propsptr dom_get_doc_props(php_libxml_ref_obj *document)
 {
-       dom_doc_props *doc_props;
+       dom_doc_propsptr doc_props;
 
        if (document && document->doc_props) {
                return document->doc_props;
        } else {
-               doc_props = emalloc(sizeof(dom_doc_props));
+               doc_props = emalloc(sizeof(libxml_doc_props));
                doc_props->formatoutput = 0;
                doc_props->validateonparse = 0;
                doc_props->resolveexternals = 0;
@@ -140,18 +140,58 @@ dom_doc_propsptr dom_get_doc_props(php_libxml_ref_obj *document)
                doc_props->substituteentities = 0;
                doc_props->stricterror = 1;
                doc_props->recover = 0;
+               doc_props->classmap = NULL;
                if (document) {
                        document->doc_props = doc_props;
                }
                return doc_props;
        }
 }
+
+int dom_set_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece, zend_class_entry *ce TSRMLS_DC)
+{
+       dom_doc_propsptr doc_props;
+
+       if (document) {
+               doc_props = dom_get_doc_props(document);
+               if (doc_props->classmap == NULL) {
+                       if (ce == NULL) {
+                               return SUCCESS;
+                       }
+                       ALLOC_HASHTABLE(doc_props->classmap);
+                       zend_u_hash_init(doc_props->classmap, 0, NULL, NULL, 0, UG(unicode));
+               }
+               if (ce) {
+                       return zend_u_hash_add(doc_props->classmap, UG(unicode)?IS_UNICODE:IS_STRING, basece->name, basece->name_length + 1, &ce, sizeof(ce), NULL);
+               } else {
+                       return zend_u_hash_del(doc_props->classmap, UG(unicode)?IS_UNICODE:IS_STRING, basece->name, basece->name_length + 1);
+               }
+       }
+       return SUCCESS;
+}
+
+zend_class_entry *dom_get_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece TSRMLS_DC)
+{
+       dom_doc_propsptr doc_props;
+       zend_class_entry **ce = NULL;
+       
+       if (document) {
+               doc_props = dom_get_doc_props(document);
+               if (doc_props->classmap) {
+                       if (zend_u_hash_find(doc_props->classmap, UG(unicode)?IS_UNICODE:IS_STRING, basece->name, basece->name_length + 1,  (void**) &ce) == SUCCESS) {
+                               return *ce;
+                       }
+               }
+       }
+
+       return basece;
+}
 /* }}} */
 
 /* {{{ dom_get_strict_error() */
 int dom_get_strict_error(php_libxml_ref_obj *document) {
        int stricterror;
-       dom_doc_props *doc_props;
+       dom_doc_propsptr doc_props;
 
        doc_props = dom_get_doc_props(document);
        stricterror = doc_props->stricterror;
@@ -1240,6 +1280,9 @@ zval *php_dom_create_object(xmlNodePtr obj, int *found, zval *wrapper_in, zval *
                        return wrapper;
        }
 
+       if (domobj && domobj->document) {
+               ce = dom_get_doc_classmap(domobj->document, ce TSRMLS_CC);
+       }
        object_init_ex(wrapper, ce);
 
        intern = (dom_object *)zend_objects_get_address(wrapper TSRMLS_CC);
index 210d2cfe1b47c61bbfeb1fc46de156e39bfd187d..ef5834dc2878008528dbe12717bfe7d495c36d8d 100644 (file)
@@ -110,6 +110,7 @@ xmlNodePtr create_notation(const xmlChar *name, const xmlChar *ExternalID, const
 xmlNode *php_dom_libxml_hash_iter(xmlHashTable *ht, int index);
 xmlNode *php_dom_libxml_notation_iter(xmlHashTable *ht, int index);
 zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object TSRMLS_DC);
+int dom_set_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece, zend_class_entry *ce TSRMLS_DC);
 
 #define REGISTER_DOM_CLASS(ce, name, parent_ce, funcs, entry) \
 INIT_CLASS_ENTRY(ce, name, funcs); \
index dff448b6f3e218520ee386b637edffd89d0dee37..fe12c9c2b3d94dc09686c4261c235c4d7e95100b 100644 (file)
 
 #include "ext/libxml/php_libxml.h"
 
-typedef struct _dom_doc_props {
-       int formatoutput;
-       int validateonparse;
-       int resolveexternals;
-       int preservewhitespace;
-       int substituteentities;
-       int stricterror;
-       int recover;
-} dom_doc_props;
-
-typedef dom_doc_props *dom_doc_propsptr;
+typedef libxml_doc_props *dom_doc_propsptr;
 
 typedef struct _dom_object {
        zend_object  std;