From 3ab293525063e30c03fd77f20cdabb4547deccf1 Mon Sep 17 00:00:00 2001 From: John Coggeshall Date: Sun, 14 Dec 2003 06:02:33 +0000 Subject: [PATCH] Tons of changes for Tidy 2.0 -- output buffering, multiple documents, dual nature ($a->parse_file() and $a = tidy_parse_file()), etc. --- ext/tidy/TODO | 2 +- ext/tidy/package.xml | 5 +- ext/tidy/php_tidy.h | 243 +++-- ext/tidy/tidy.c | 2158 +++++++++++++++++++++++++++--------------- 4 files changed, 1518 insertions(+), 890 deletions(-) diff --git a/ext/tidy/TODO b/ext/tidy/TODO index 699c207dcb..8a13162cc0 100644 --- a/ext/tidy/TODO +++ b/ext/tidy/TODO @@ -1,3 +1,3 @@ TODO - - Implement get_nodes() method +Do the docs. diff --git a/ext/tidy/package.xml b/ext/tidy/package.xml index 266cc5d7c6..9117d87cb7 100644 --- a/ext/tidy/package.xml +++ b/ext/tidy/package.xml @@ -14,7 +14,7 @@ iliaa Ilia Alshanetsky ilia@php.net - lead + developer @@ -44,6 +44,7 @@ but also traverse the document tree using the Zend Engine 2 OO semantics. + @@ -59,6 +60,6 @@ but also traverse the document tree using the Zend Engine 2 OO semantics. - diff --git a/ext/tidy/php_tidy.h b/ext/tidy/php_tidy.h index e170d37086..929d8dca2c 100644 --- a/ext/tidy/php_tidy.h +++ b/ext/tidy/php_tidy.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 4 | + | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2003 The PHP Group | +----------------------------------------------------------------------+ @@ -12,8 +12,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Author: John Coggeshall | - | Ilia Alshanetsky | + | Author: John Coggeshall | +----------------------------------------------------------------------+ */ @@ -22,6 +21,10 @@ #ifndef PHP_TIDY_H #define PHP_TIDY_H +#include "tidyenum.h" +#include "tidy.h" +#include "buffio.h" + extern zend_module_entry tidy_module_entry; #define phpext_tidy_ptr &tidy_module_entry @@ -35,47 +38,31 @@ extern zend_module_entry tidy_module_entry; #include "TSRM.h" #endif -#include "tidyenum.h" -#include "tidy.h" -#include "buffio.h" - -#ifdef ZTS -#define TG(v) TSRMG(tidy_globals_id, zend_tidy_globals *, v) -#else -#define TG(v) (tidy_globals.v) -#endif - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - -#define TIDY_RV_FALSE(__t) __t->type = IS_BOOL; __t->value.lval = FALSE -#define TIDY_RV_TRUE(__t) __t->type = IS_BOOL; __t->value.lval = TRUE +#define PHP_TIDY_MODULE_VERSION "2.0-dev" #define REMOVE_NEWLINE(_z) _z->value.str.val[_z->value.str.len-1] = '\0'; _z->value.str.len--; -#define TIDY_TAG_CONST(tag) REGISTER_LONG_CONSTANT("TIDY_TAG_" #tag, TidyTag_##tag, CONST_CS | CONST_PERSISTENT) -#define TIDY_ATTR_CONST(attr) REGISTER_LONG_CONSTANT("TIDY_ATTR_" #attr, TidyAttr_##attr, CONST_CS | CONST_PERSISTENT) -#define TIDY_NODE_CONST(name, type) REGISTER_LONG_CONSTANT("TIDY_NODETYPE_" #name, TidyNode_##type, CONST_CS | CONST_PERSISTENT) - -#define PHP_ME_MAPPING(name, func_name, arg_types) \ - ZEND_NAMED_FE(name, ZEND_FN(func_name), arg_types) +#define TIDYDOC_FROM_OBJECT(tdoc, object) \ + { \ + PHPTidyObj *obj = (PHPTidyObj*) zend_object_store_get_object(object TSRMLS_CC); \ + tdoc = obj->ptdoc; \ + } -#define PHP_NODE_METHOD(name) PHP_FUNCTION(tnm_ ##name) -#define PHP_ATTR_METHOD(name) PHP_FUNCTION(tam_ ##name) -#define PHP_NODE_ME(name, param) PHP_ME_MAPPING(name, tnm_ ##name, param) -#define PHP_ATTR_ME(name, param) PHP_ME_MAPPING(name, tam_ ##name, param) +#define Z_OBJ_P(zval_p) zend_objects_get_address(zval_p TSRMLS_CC) +#define TIDY_METHOD_MAP(name, func_name, arg_types) \ + ZEND_NAMED_FE(name, ZEND_FN(func_name), arg_types) +#define TIDY_THROW(message) \ + PG(suppress_errors) = 0; \ + EG(exception) = zend_throw_exception(tidy_ce_exception, message, 0 TSRMLS_CC); -#define TIDY_REGISTER_OBJECT(_type, _object, _ptr) \ - { \ - tidy_object *obj; \ - obj = (tidy_object*)zend_object_store_get_object(_object TSRMLS_CC); \ - obj->type = is_ ## _type; \ - obj->u._type = _ptr; \ - } +#define TIDY_NODE_METHOD(name) PHP_FUNCTION(tnm_ ##name) +#define TIDY_NODE_ME(name, param) TIDY_METHOD_MAP(name, tnm_ ##name, param) +#define TIDY_DOC_METHOD(name) PHP_FUNCTION(tdm_ ##name) +#define TIDY_DOC_ME(name, param) TIDY_METHOD_MAP(name, tdm_ ##name, param) +#define TIDY_ATTR_METHOD(name) PHP_FUNCTION(tam_ ##name) +#define TIDY_ATTR_ME(name, param) TIDY_METHOD_MAP(name, tam_ ##name, param) #define REGISTER_TIDY_CLASS(name, parent) \ { \ @@ -88,62 +75,122 @@ extern zend_module_entry tidy_module_entry; tidy_object_handlers_ ## name.clone_obj = NULL; \ } -#define GET_THIS_CONTAINER() \ - PHPTidyObj *obj; \ - { \ - zval *object = getThis(); \ - obj = (PHPTidyObj *)zend_object_store_get_object(object TSRMLS_CC); \ - } +#define TIDY_TAG_CONST(tag) REGISTER_LONG_CONSTANT("TIDY_TAG_" #tag, TidyTag_##tag, CONST_CS | CONST_PERSISTENT) +#define TIDY_ATTR_CONST(attr) REGISTER_LONG_CONSTANT("TIDY_ATTR_" #attr, TidyAttr_##attr, CONST_CS | CONST_PERSISTENT) +#define TIDY_NODE_CONST(name, type) REGISTER_LONG_CONSTANT("TIDY_NODETYPE_" #name, TidyNode_##type, CONST_CS | CONST_PERSISTENT) -#define INSTANCIATE_NODE(_zval, _container, _node) \ - tidy_instanciate(tidy_ce_node, _zval TSRMLS_CC); \ - _container = (PHPTidyObj *) zend_object_store_get_object(_zval TSRMLS_CC); \ - _container->node = _node; \ - _container->attr = NULL; \ - _container->type = is_node; \ - tidy_add_default_properities(_container, is_node TSRMLS_CC); - -#define INSTANCIATE_ATTR(_zval, _container, _attr) \ - tidy_instanciate(tidy_ce_attr, _zval TSRMLS_CC); \ - _container = (PHPTidyObj *) zend_object_store_get_object(_zval TSRMLS_CC); \ - _container->node = NULL; \ - _container->attr = _attr; \ - _container->type = is_attr; \ - tidy_add_default_properities(_container, is_attr TSRMLS_CC); - -#define PHP_NODE_METHOD_IS_TYPE(_type, _const) \ -PHP_NODE_METHOD(is_ ##_type) \ -{ \ - GET_THIS_CONTAINER(); \ - if(tidyNodeGetType(obj->node) == _const) {\ - RETURN_TRUE; \ - } else { \ - RETURN_FALSE; \ - } \ +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +#define ADD_PROPERITY_STRING(_table, _key, _string) \ + { \ + zval *tmp; \ + MAKE_STD_ZVAL(tmp); \ + if(_string) { \ + ZVAL_STRING(tmp, (char *)_string, 1); \ + } else { \ + ZVAL_EMPTY_STRING(tmp); \ + } \ + zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \ + } + +#define ADD_PROPERITY_LONG(_table, _key, _long) \ + { \ + zval *tmp; \ + MAKE_STD_ZVAL(tmp); \ + ZVAL_LONG(tmp, _long); \ + zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \ + } + +#define ADD_PROPERITY_NULL(_table, _key) \ + { \ + zval *tmp; \ + MAKE_STD_ZVAL(tmp); \ + ZVAL_NULL(tmp); \ + zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \ + } + +#define TIDY_PARSED_CHECK(_obj) \ +if(!_obj->ptdoc->parsed) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "A document must be parsed before executing this function."); \ + RETURN_FALSE; \ +} + +#define TIDY_PARSED_REPAIR_CHECK(_obj) \ +TIDY_PARSED_CHECK(_obj); \ +if(!_obj->ptdoc->repaired) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must clean and repair the document before executing this function."); \ + RETURN_FALSE; \ } +#define TIDY_SAFE_MODE_CHECK(filename) \ +if ((PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(filename TSRMLS_CC)) { \ + RETURN_FALSE; \ +} \ + +#define TIDY_SET_DEFAULT_CONFIG(_doc) \ + if (TG(default_config) && TG(default_config)[0]) { \ + if (tidyLoadConfig(_doc, TG(default_config)) < 0) { \ + zend_error(E_ERROR, "Unable to load Tidy configuration file at '%s'.", TG(default_config)); \ + } \ + } + +typedef struct _PHPTidyDoc PHPTidyDoc; +typedef struct _PHPTidyObj PHPTidyObj; + typedef enum { is_node, - is_attr + is_attr, + is_doc, + is_exception } tidy_obj_type; +typedef enum { + is_root_node, + is_html_node, + is_head_node, + is_body_node +} tidy_base_nodetypes; + struct _PHPTidyDoc { - TidyDoc doc; TidyBuffer *errbuf; zend_bool parsed; + zend_bool repaired; + unsigned int ref_count; }; -typedef struct _PHPTidyDoc PHPTidyDoc; -typedef struct _PHPTidyObj PHPTidyObj; - struct _PHPTidyObj { zend_object std; TidyNode node; TidyAttr attr; tidy_obj_type type; + + PHPTidyDoc *ptdoc; }; +static char *php_tidy_file_to_mem(char *, zend_bool TSRMLS_DC); +static void tidy_object_dtor(void *, zend_object_handle TSRMLS_DC); +static zend_object_value tidy_object_new_node(zend_class_entry * TSRMLS_DC); +static zend_object_value tidy_object_new_attr(zend_class_entry * TSRMLS_DC); +static zend_object_value tidy_object_new_doc(zend_class_entry * TSRMLS_DC); +static zend_object_value tidy_object_new_exception(zend_class_entry * TSRMLS_DC); +static zend_class_entry *tidy_get_ce_node(zval * TSRMLS_DC); +static zend_class_entry *tidy_get_ce_attr(zval * TSRMLS_DC); +static zend_class_entry *tidy_get_ce_doc(zval * TSRMLS_DC); +static zval * tidy_instanciate(zend_class_entry *, zval * TSRMLS_DC); +static int tidy_doc_cast_handler(zval *, zval *, int, int TSRMLS_DC); +static int tidy_node_cast_handler(zval *, zval *, int, int TSRMLS_DC); +static void tidy_doc_update_properties(PHPTidyObj * TSRMLS_DC); +static void tidy_add_default_properities(PHPTidyObj *, tidy_obj_type TSRMLS_DC); +static void *php_tidy_get_opt_val(PHPTidyDoc *, TidyOption, TidyOptionType * TSRMLS_DC); +static void php_tidy_create_node(INTERNAL_FUNCTION_PARAMETERS, tidy_base_nodetypes); + +void _php_tidy_register_nodetypes(INIT_FUNC_ARGS); +void _php_tidy_register_tags(INIT_FUNC_ARGS); +void _php_tidy_register_attributes(INIT_FUNC_ARGS); PHP_MINIT_FUNCTION(tidy); PHP_MSHUTDOWN_FUNCTION(tidy); @@ -151,6 +198,9 @@ PHP_RINIT_FUNCTION(tidy); PHP_RSHUTDOWN_FUNCTION(tidy); PHP_MINFO_FUNCTION(tidy); +PHP_FUNCTION(tidy_reset_config); +PHP_FUNCTION(tidy_restore_config); +PHP_FUNCTION(tidy_snapshot_config); PHP_FUNCTION(tidy_setopt); PHP_FUNCTION(tidy_getopt); PHP_FUNCTION(tidy_parse_string); @@ -177,42 +227,28 @@ PHP_FUNCTION(tidy_load_config_enc); PHP_FUNCTION(tidy_set_encoding); PHP_FUNCTION(tidy_save_config); +PHP_FUNCTION(ob_tidyhandler); + PHP_FUNCTION(tidy_get_root); PHP_FUNCTION(tidy_get_html); PHP_FUNCTION(tidy_get_head); PHP_FUNCTION(tidy_get_body); -PHP_NODE_METHOD(__construct); -PHP_NODE_METHOD(attributes); -PHP_NODE_METHOD(children); - -PHP_NODE_METHOD(has_children); -PHP_NODE_METHOD(has_siblings); -PHP_NODE_METHOD(is_comment); -PHP_NODE_METHOD(is_html); -PHP_NODE_METHOD(is_xhtml); -PHP_NODE_METHOD(is_xml); -PHP_NODE_METHOD(is_text); -PHP_NODE_METHOD(is_jste); -PHP_NODE_METHOD(is_asp); -PHP_NODE_METHOD(is_php); - -PHP_NODE_METHOD(next); -PHP_NODE_METHOD(prev); -PHP_NODE_METHOD(get_attr); -PHP_NODE_METHOD(get_nodes); - -/* resource dtor */ -void dtor_TidyDoc(zend_rsrc_list_entry * TSRMLS_DC); - -/* constant register helpers */ -void _php_tidy_register_nodetypes(INIT_FUNC_ARGS); -void _php_tidy_register_tags(INIT_FUNC_ARGS); -void _php_tidy_register_attributes(INIT_FUNC_ARGS); +TIDY_ATTR_METHOD(__construct); + +TIDY_NODE_METHOD(__construct); +TIDY_NODE_METHOD(has_children); +TIDY_NODE_METHOD(has_siblings); +TIDY_NODE_METHOD(is_comment); +TIDY_NODE_METHOD(is_html); +TIDY_NODE_METHOD(is_xhtml); +TIDY_NODE_METHOD(is_xml); +TIDY_NODE_METHOD(is_text); +TIDY_NODE_METHOD(is_jste); +TIDY_NODE_METHOD(is_asp); +TIDY_NODE_METHOD(is_php); ZEND_BEGIN_MODULE_GLOBALS(tidy) - PHPTidyDoc *tdoc; - zend_bool used; char *default_config; ZEND_END_MODULE_GLOBALS(tidy) @@ -222,9 +258,6 @@ ZEND_END_MODULE_GLOBALS(tidy) #define TG(v) (tidy_globals.v) #endif - - - #endif diff --git a/ext/tidy/tidy.c b/ext/tidy/tidy.c index baaf38f1d0..d5b54776b5 100644 --- a/ext/tidy/tidy.c +++ b/ext/tidy/tidy.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 4 | + | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2003 The PHP Group | +----------------------------------------------------------------------+ @@ -13,7 +13,6 @@ | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: John Coggeshall | - | Ilia Alshanetsky | +----------------------------------------------------------------------+ */ @@ -30,19 +29,15 @@ #include "Zend/zend_API.h" #include "Zend/zend_hash.h" #include "safe_mode.h" +#include "zend_default_classes.h" +#include "zend_object_handlers.h" -ZEND_DECLARE_MODULE_GLOBALS(tidy); - -#define TIDY_PARSED_CHECK() \ -if(!TG(tdoc)->parsed) { \ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "A document must be parsed before executing this function."); \ - RETURN_FALSE; \ -} \ +ZEND_DECLARE_MODULE_GLOBALS(tidy) -#define TIDY_SAFE_MODE_CHECK(filename) \ -if ((PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(filename TSRMLS_CC)) { \ - RETURN_FALSE; \ -} \ +PHP_INI_BEGIN() +STD_PHP_INI_ENTRY("tidy.default_config", "", PHP_INI_SYSTEM, OnUpdateString, default_config, zend_tidy_globals, tidy_globals) +PHP_INI_ENTRY("tidy.clean_output", "0", PHP_INI_SYSTEM, NULL) +PHP_INI_END() function_entry tidy_functions[] = { PHP_FE(tidy_setopt, NULL) @@ -69,62 +64,62 @@ function_entry tidy_functions[] = { PHP_FE(tidy_load_config_enc, NULL) PHP_FE(tidy_set_encoding, NULL) PHP_FE(tidy_save_config, NULL) - -#ifdef ZEND_ENGINE_2 PHP_FE(tidy_get_root, NULL) PHP_FE(tidy_get_head, NULL) PHP_FE(tidy_get_html, NULL) PHP_FE(tidy_get_body, NULL) -#endif - + PHP_FE(tidy_reset_config, NULL) + PHP_FE(tidy_snapshot_config, NULL) + PHP_FE(tidy_restore_config, NULL) + PHP_FE(ob_tidyhandler, NULL) {NULL, NULL, NULL} }; -#ifdef ZEND_ENGINE_2 -#include "zend_default_classes.h" - -static void tidy_object_dtor(void *object, zend_object_handle handle TSRMLS_DC); -static void tidy_object_new(zend_class_entry *class_type, zend_object_handlers *handlers, zend_object_value *retval TSRMLS_DC); - -static zend_object_value tidy_object_new_node(zend_class_entry *class_type TSRMLS_DC); -static zend_object_value tidy_object_new_attr(zend_class_entry *class_type TSRMLS_DC); -static zend_object_value tidy_object_new_exception(zend_class_entry *class_type TSRMLS_DC); - -static zend_class_entry *tidy_get_ce_node(zval *object TSRMLS_DC); -static zend_class_entry *tidy_get_ce_attr(zval *object TSRMLS_DC); - -static zval * tidy_instanciate(zend_class_entry *pce, zval *object TSRMLS_DC); - -zend_class_entry *tidy_ce_node, *tidy_ce_attr, - *tidy_ce_exception; - -static zend_object_handlers tidy_object_handlers_node; -static zend_object_handlers tidy_object_handlers_attr; -static zend_object_handlers tidy_object_handlers_exception; +function_entry tidy_funcs_doc[] = { + TIDY_METHOD_MAP(setopt, tidy_setopt, NULL) + TIDY_METHOD_MAP(getopt, tidy_getopt, NULL) + TIDY_METHOD_MAP(parse_string, tidy_parse_string, NULL) + TIDY_METHOD_MAP(parse_file, tidy_parse_file, NULL) + TIDY_METHOD_MAP(clean_repair, tidy_clean_repair, NULL) + TIDY_METHOD_MAP(repair_string, tidy_repair_string, NULL) + TIDY_METHOD_MAP(repair_file, tidy_repair_file, NULL) + TIDY_METHOD_MAP(diagnose, tidy_diagnose, NULL) + TIDY_METHOD_MAP(get_release, tidy_get_release, NULL) + TIDY_METHOD_MAP(get_config, tidy_get_config, NULL) + TIDY_METHOD_MAP(get_status, tidy_get_status, NULL) + TIDY_METHOD_MAP(get_html_ver, tidy_get_html_ver, NULL) + TIDY_METHOD_MAP(is_xhtml, tidy_is_xhtml, NULL) + TIDY_METHOD_MAP(is_xml, tidy_is_xml, NULL) + TIDY_METHOD_MAP(load_config, tidy_load_config, NULL) + TIDY_METHOD_MAP(load_config_enc, tidy_load_config_enc, NULL) + TIDY_METHOD_MAP(set_encoding, tidy_set_encoding, NULL) + TIDY_METHOD_MAP(save_config, tidy_save_config, NULL) + TIDY_METHOD_MAP(root, tidy_get_root, NULL) + TIDY_METHOD_MAP(head, tidy_get_head, NULL) + TIDY_METHOD_MAP(html, tidy_get_html, NULL) + TIDY_METHOD_MAP(body, tidy_get_body, NULL) + TIDY_METHOD_MAP(reset_config, tidy_reset_config, NULL) + TIDY_METHOD_MAP(snapshot_config, tidy_snapshot_config, NULL) + TIDY_METHOD_MAP(restore_config, tidy_restore_config, NULL) + {NULL, NULL, NULL} +}; function_entry tidy_funcs_node[] = { - PHP_NODE_ME(__construct, NULL) - PHP_NODE_ME(attributes, NULL) - PHP_NODE_ME(children, NULL) - - PHP_NODE_ME(has_children, NULL) - PHP_NODE_ME(has_siblings, NULL) - PHP_NODE_ME(is_comment, NULL) - PHP_NODE_ME(is_html, NULL) - PHP_NODE_ME(is_text, NULL) - PHP_NODE_ME(is_jste, NULL) - PHP_NODE_ME(is_asp, NULL) - PHP_NODE_ME(is_php, NULL) - - PHP_NODE_ME(next, NULL) - PHP_NODE_ME(prev, NULL) - PHP_NODE_ME(get_attr, NULL) - /*PHP_NODE_ME(get_nodes, NULL) TODO */ + TIDY_NODE_ME(__construct, NULL) + TIDY_NODE_ME(has_children, NULL) + TIDY_NODE_ME(has_siblings, NULL) + TIDY_NODE_ME(is_comment, NULL) + TIDY_NODE_ME(is_html, NULL) + TIDY_NODE_ME(is_text, NULL) + TIDY_NODE_ME(is_jste, NULL) + TIDY_NODE_ME(is_asp, NULL) + TIDY_NODE_ME(is_php, NULL) {NULL, NULL, NULL} }; function_entry tidy_funcs_attr[] = { + TIDY_ATTR_ME(__construct, NULL) {NULL, NULL, NULL} }; @@ -132,7 +127,13 @@ function_entry tidy_funcs_exception[] = { {NULL, NULL, NULL} }; -#endif +zend_class_entry *tidy_ce_doc, *tidy_ce_node, + *tidy_ce_attr, *tidy_ce_exception; + +static zend_object_handlers tidy_object_handlers_doc; +static zend_object_handlers tidy_object_handlers_node; +static zend_object_handlers tidy_object_handlers_attr; +static zend_object_handlers tidy_object_handlers_exception; zend_module_entry tidy_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 @@ -142,100 +143,39 @@ zend_module_entry tidy_module_entry = { tidy_functions, PHP_MINIT(tidy), PHP_MSHUTDOWN(tidy), - PHP_RINIT(tidy), - NULL, + PHP_RINIT(tidy), + PHP_RSHUTDOWN(tidy), PHP_MINFO(tidy), #if ZEND_MODULE_API_NO >= 20010901 - "1.0", + PHP_TIDY_MODULE_VERSION, #endif STANDARD_MODULE_PROPERTIES }; + #ifdef COMPILE_DL_TIDY ZEND_GET_MODULE(tidy) #endif -/* {{{ PHP_INI - */ -PHP_INI_BEGIN() -STD_PHP_INI_ENTRY("tidy.default_config", "", PHP_INI_SYSTEM, OnUpdateString, default_config, zend_tidy_globals, tidy_globals) -PHP_INI_END() -/* }}} */ - -static void tidy_globals_ctor(zend_tidy_globals *g TSRMLS_DC) +/* Wrappers so tidy can use the PHP memory management */ +void *php_tidy_malloc(size_t len) { - g->used = 0; - g->tdoc = pemalloc(sizeof(PHPTidyDoc), 1); - g->tdoc->doc = tidyCreate(); - g->tdoc->parsed = 0; - g->tdoc->errbuf = pemalloc(sizeof(TidyBuffer), 1); - tidyBufInit(g->tdoc->errbuf); - - if(tidySetErrorBuffer(g->tdoc->doc, g->tdoc->errbuf) != 0) { - zend_error(E_ERROR, "Could not set Tidy error buffer"); - } - - tidyOptSetBool(g->tdoc->doc, TidyForceOutput, yes); - tidyOptSetBool(g->tdoc->doc, TidyMark, no); - - /* remember settings so that we can restore them */ - tidyOptSnapshot(g->tdoc->doc); + return emalloc(len); } -static void tidy_globals_dtor(zend_tidy_globals *g TSRMLS_DC) +void *php_tidy_realloc(void *buf, size_t len) { - tidyBufFree(g->tdoc->errbuf); - pefree(g->tdoc->errbuf, 1); - tidyRelease(g->tdoc->doc); - pefree(g->tdoc, 1); - g->used = 0; + return erealloc(buf, len); } -static void *php_tidy_get_opt_val(TidyOption opt, TidyOptionType *type TSRMLS_DC) +void php_tidy_free(void *buf) { - *type = tidyOptGetType(opt); - - switch (*type) { - case TidyString: { - char *val = (char *) tidyOptGetValue(TG(tdoc)->doc, tidyOptGetId(opt)); - if (val) { - return (void *) estrdup(val); - } else { - return (void *) estrdup(""); - } - } - break; - - case TidyInteger: - return (void *) tidyOptGetInt(TG(tdoc)->doc, tidyOptGetId(opt)); - break; - - case TidyBoolean: - return (void *) tidyOptGetBool(TG(tdoc)->doc, tidyOptGetId(opt)); - break; - } - - /* should not happen */ - return NULL; + efree(buf); } -static char *php_tidy_file_to_mem(char *filename, zend_bool use_include_path TSRMLS_DC) +void php_tidy_panic(ctmbstr msg) { - php_stream *stream; - int len; - char *data = NULL; - - if (!(stream = php_stream_open_wrapper(filename, "rb", (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL))) { - return NULL; - } - if ((len = php_stream_copy_to_mem(stream, &data, PHP_STREAM_COPY_ALL, 0)) > 0) { - /* noop */ - } else if (len == 0) { - data = estrdup(""); - } - php_stream_close(stream); - - return data; + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not allocate memory for tidy! (Reason: %s)", (char *)msg); } static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_file) @@ -243,11 +183,28 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_fil char *data=NULL, *cfg_file=NULL, *arg1; int cfg_file_len, arg1_len; zend_bool use_include_path = 0; + zval *object = getThis(); + PHPTidyObj *obj; + + if(object) { + + if(zend_parse_parameters(1 TSRMLS_CC, "s|sb", &arg1, &arg1_len, &cfg_file, &cfg_file_len, &use_include_path) == FAILURE) { + RETURN_FALSE; + } + + } else { + + if(zend_parse_parameters(1 TSRMLS_CC, "Os|sb", &object, tidy_ce_doc, + &arg1, &arg1_len, &cfg_file, &cfg_file_len, &use_include_path) == FAILURE) { + return; + } + + tidy_instanciate(tidy_ce_doc, return_value TSRMLS_CC); - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sb", &arg1, &arg1_len, &cfg_file, &cfg_file_len, &use_include_path) == FAILURE) { - RETURN_FALSE; } + obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC); + if (is_file) { if (!(data = php_tidy_file_to_mem(arg1, use_include_path TSRMLS_CC))) { RETURN_FALSE; @@ -258,23 +215,22 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_fil if (cfg_file && cfg_file[0]) { TIDY_SAFE_MODE_CHECK(cfg_file); - if(tidyLoadConfig(TG(tdoc)->doc, cfg_file) < 0) { + if(tidyLoadConfig(obj->ptdoc->doc, cfg_file) < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not load configuration file '%s'", cfg_file); RETVAL_FALSE; } - TG(used) = 1; } if (data) { - if(tidyParseString(TG(tdoc)->doc, data) < 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "[Tidy error] %s", TG(tdoc)->errbuf->bp); + if(tidyParseString(obj->ptdoc->doc, data) < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "[Tidy error] %s", obj->ptdoc->errbuf->bp); RETVAL_FALSE; } else { - TG(tdoc)->parsed = TRUE; - if (tidyCleanAndRepair(TG(tdoc)->doc) >= 0) { + obj->ptdoc->parsed = TRUE; + if (tidyCleanAndRepair(obj->ptdoc->doc) >= 0) { TidyBuffer output = {0}; - tidySaveBuffer (TG(tdoc)->doc, &output); + tidySaveBuffer (obj->ptdoc->doc, &output); RETVAL_STRING(output.bp, 1); tidyBufFree(&output); } else { @@ -288,179 +244,717 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_fil } } -PHP_MINIT_FUNCTION(tidy) +static char *php_tidy_file_to_mem(char *filename, zend_bool use_include_path TSRMLS_DC) { - REGISTER_INI_ENTRIES(); - -#ifdef ZEND_ENGINE_2 - REGISTER_TIDY_CLASS(node, NULL); - REGISTER_TIDY_CLASS(attr, NULL); - REGISTER_TIDY_CLASS(exception, zend_exception_get_default()); - - tidy_object_handlers_node.get_class_entry = tidy_get_ce_node; - tidy_object_handlers_attr.get_class_entry = tidy_get_ce_attr; -#endif - - _php_tidy_register_tags(INIT_FUNC_ARGS_PASSTHRU); - _php_tidy_register_attributes(INIT_FUNC_ARGS_PASSTHRU); - _php_tidy_register_nodetypes(INIT_FUNC_ARGS_PASSTHRU); + php_stream *stream; + int len; + char *data = NULL; - ZEND_INIT_MODULE_GLOBALS(tidy, tidy_globals_ctor, tidy_globals_dtor); + if (!(stream = php_stream_open_wrapper(filename, "rb", (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL))) { + return NULL; + } + if ((len = php_stream_copy_to_mem(stream, &data, PHP_STREAM_COPY_ALL, 0)) > 0) { + /* noop */ + } else if (len == 0) { + data = estrdup(""); + } + php_stream_close(stream); - return SUCCESS; + return data; } -PHP_MSHUTDOWN_FUNCTION(tidy) +static void tidy_object_dtor(void *object, zend_object_handle handle TSRMLS_DC) { -#ifndef ZTS - tidy_globals_dtor(&tidy_globals TSRMLS_CC); -#endif - return SUCCESS; -} + PHPTidyObj *intern = (PHPTidyObj *)object; -PHP_RINIT_FUNCTION(tidy) -{ - if (TG(used) && tidyOptDiffThanSnapshot((TG(tdoc))->doc)) { - tidyOptResetToSnapshot((TG(tdoc))->doc); - TG(used) = 0; - } - /* if a user provided a default configuration file, use it */ - if (TG(default_config) && TG(default_config)[0]) { - if (tidyLoadConfig((TG(tdoc))->doc, TG(default_config)) < 0) { - zend_error(E_ERROR, "Unable to load Tidy configuration file at '%s'.", TG(default_config)); - } - TG(used) = 1; + zend_hash_destroy(intern->std.properties); + FREE_HASHTABLE(intern->std.properties); + + intern->ptdoc->ref_count--; + + if(intern->ptdoc->ref_count <= 0) { + + tidyBufFree(intern->ptdoc->errbuf); + efree(intern->ptdoc->errbuf); + tidyRelease(intern->ptdoc->doc); + efree(intern->ptdoc); } - return SUCCESS; + + efree(object); } -PHP_MINFO_FUNCTION(tidy) +static void tidy_object_new(zend_class_entry *class_type, zend_object_handlers *handlers, + zend_object_value *retval, tidy_obj_type objtype TSRMLS_DC) { - TidyIterator itOpt = tidyGetOptionList(TG(tdoc)->doc); - void *opt_value; - TidyOptionType optt; - char buf[255]; - - php_info_print_table_start(); - php_info_print_table_header(2, "Tidy support", "enabled"); - php_info_print_table_row(2, "libTidy Build Date", (char *)tidyReleaseDate()); - php_info_print_table_end(); - - DISPLAY_INI_ENTRIES(); + PHPTidyObj *intern; + zval *tmp; - php_info_print_table_start(); - php_info_print_table_header(2, "Tidy Configuration Directive", "Value"); - while (itOpt) { - TidyOption opt = tidyGetNextOption(TG(tdoc)->doc, &itOpt); + intern = emalloc(sizeof(PHPTidyObj)); + memset(intern, 0, sizeof(PHPTidyObj)); + intern->std.ce = class_type; - opt_value = php_tidy_get_opt_val(opt, &optt TSRMLS_CC); - switch (optt) { - case TidyString: - php_info_print_table_row(2, (char *)tidyOptGetName(opt), (char*)opt_value); - efree(opt_value); - break; + ALLOC_HASHTABLE(intern->std.properties); + zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - case TidyInteger: - sprintf(buf, "%d", (int)opt_value); - php_info_print_table_row(2, (char *)tidyOptGetName(opt), (char*)buf); - break; + switch(objtype) { + + case is_node: + break; + case is_attr: + break; + case is_doc: - case TidyBoolean: - php_info_print_table_row(2, (char *)tidyOptGetName(opt), (opt_value ? "TRUE" : "FALSE")); - break; - } + tidySetMallocCall(php_tidy_malloc); + tidySetReallocCall(php_tidy_realloc); + tidySetFreeCall(php_tidy_free); + tidySetPanicCall(php_tidy_panic); + + intern->ptdoc = emalloc(sizeof(PHPTidyDoc)); + intern->ptdoc->doc = tidyCreate(); + intern->ptdoc->parsed = FALSE; + intern->ptdoc->repaired = FALSE; + intern->ptdoc->ref_count = 1; + intern->ptdoc->errbuf = emalloc(sizeof(TidyBuffer)); + tidyBufInit(intern->ptdoc->errbuf); + + if(tidySetErrorBuffer(intern->ptdoc->doc, intern->ptdoc->errbuf) != 0) { + zend_error(E_ERROR, "Could not set Tidy error buffer"); + } + + + tidyOptSetBool(intern->ptdoc->doc, TidyForceOutput, yes); + tidyOptSetBool(intern->ptdoc->doc, TidyMark, no); + + TIDY_SET_DEFAULT_CONFIG(intern->ptdoc->doc); + + tidy_add_default_properities(intern, is_doc TSRMLS_CC); + break; + default: + break; } - php_info_print_table_end(); + + retval->handle = zend_objects_store_put(intern, tidy_object_dtor, NULL TSRMLS_CC); + retval->handlers = handlers; } -/* {{{ proto bool tidy_parse_string(string input) - Parse a document stored in a string */ -PHP_FUNCTION(tidy_parse_string) +static zend_object_value tidy_object_new_node(zend_class_entry *class_type TSRMLS_DC) { - char *input; - int input_len; + zend_object_value retval; + tidy_object_new(class_type, &tidy_object_handlers_node, &retval, is_node TSRMLS_CC); + return retval; +} - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &input, &input_len) == FAILURE) { - RETURN_FALSE; - } +static zend_object_value tidy_object_new_attr(zend_class_entry *class_type TSRMLS_DC) +{ + zend_object_value retval; + tidy_object_new(class_type, &tidy_object_handlers_attr, &retval, is_attr TSRMLS_CC); + return retval; + +} - if(tidyParseString(TG(tdoc)->doc, input) < 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "[Tidy error] %s", TG(tdoc)->errbuf->bp); - RETURN_FALSE; - } +static zend_object_value tidy_object_new_doc(zend_class_entry *class_type TSRMLS_DC) +{ + zend_object_value retval; + tidy_object_new(class_type, &tidy_object_handlers_doc, &retval, is_doc TSRMLS_CC); + return retval; + +} - TG(tdoc)->parsed = TRUE; - RETURN_TRUE; +static zend_object_value tidy_object_new_exception(zend_class_entry *class_type TSRMLS_DC) +{ + zend_object_value retval; + tidy_object_new(class_type, &tidy_object_handlers_exception, &retval, is_exception TSRMLS_CC); + return retval; + } -/* }}} */ -/* {{{ proto string tidy_get_error_buffer([boolean detailed]) - Return warnings and errors which occured parsing the specified document*/ -PHP_FUNCTION(tidy_get_error_buffer) +static zend_class_entry *tidy_get_ce_node(zval *object TSRMLS_DC) { - zend_bool detailed = 0; + return tidy_ce_node; +} - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &detailed) == FAILURE) { - RETURN_FALSE; - } +static zend_class_entry *tidy_get_ce_attr(zval *object TSRMLS_DC) +{ + return tidy_ce_attr; +} - TIDY_PARSED_CHECK(); +static zend_class_entry *tidy_get_ce_doc(zval *object TSRMLS_DC) +{ + return tidy_ce_doc; +} - if (detailed) { - tidyErrorSummary(TG(tdoc)->doc); +static zval * tidy_instanciate(zend_class_entry *pce, zval *object TSRMLS_DC) +{ + if (!object) { + ALLOC_ZVAL(object); } - - RETVAL_STRING(TG(tdoc)->errbuf->bp, 1); - tidyBufClear(TG(tdoc)->errbuf); + Z_TYPE_P(object) = IS_OBJECT; + object_init_ex(object, pce); + object->refcount = 1; + object->is_ref = 1; + return object; } -/* }}} */ -/* {{{ proto string tidy_get_output() - Return a string representing the parsed tidy markup */ -PHP_FUNCTION(tidy_get_output) +static int tidy_doc_cast_handler(zval *in, zval *out, int type, int free TSRMLS_DC) { TidyBuffer output = {0}; + PHPTidyObj *obj; - if (ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; + switch(type) { + case IS_LONG: + ZVAL_LONG(out, 0); + break; + case IS_DOUBLE: + ZVAL_DOUBLE(out, 0); + break; + case IS_BOOL: + ZVAL_BOOL(out, TRUE); + break; + case IS_STRING: + obj = (PHPTidyObj *)zend_object_store_get_object(in TSRMLS_CC); + tidySaveBuffer (obj->ptdoc->doc, &output); + ZVAL_STRINGL(out, output.bp, output.size, TRUE); + tidyBufFree(&output); + break; + default: + return FAILURE; } - - TIDY_PARSED_CHECK(); - - tidySaveBuffer (TG(tdoc)->doc, &output); - - RETVAL_STRING(output.bp, 1); - - tidyBufFree(&output); + + return SUCCESS; } -/* }}} */ -/* {{{ proto boolean tidy_parse_file(string file [, bool use_include_path]) - Parse markup in file or URI */ -PHP_FUNCTION(tidy_parse_file) +static int tidy_node_cast_handler(zval *in, zval *out, int type, int free TSRMLS_DC) { - char *inputfile; - int input_len; - zend_bool use_include_path = 0; - char *contents; + TidyBuffer buf = {0}; + PHPTidyObj *obj; - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &inputfile, &input_len) == FAILURE) { + switch(type) { + case IS_LONG: + ZVAL_LONG(out, 0); + break; + case IS_DOUBLE: + ZVAL_DOUBLE(out, 0); + break; + case IS_BOOL: + ZVAL_BOOL(out, TRUE); + break; + case IS_STRING: + obj = (PHPTidyObj *)zend_object_store_get_object(in TSRMLS_CC); + tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf); + buf.bp[buf.size-1] = '\0'; + ZVAL_STRINGL(out, buf.bp, buf.size, TRUE); + tidyBufFree(&buf); + break; + default: + return FAILURE; + } + + return SUCCESS; +} + +static void tidy_doc_update_properties(PHPTidyObj *obj TSRMLS_DC) +{ + + zval *temp; + + if(obj->ptdoc->parsed) { + TidyBuffer output = {0}; + + tidySaveBuffer (obj->ptdoc->doc, &output); + + if(output.size) { + MAKE_STD_ZVAL(temp); + ZVAL_STRINGL(temp, output.bp, output.size, TRUE); + zend_hash_update(obj->std.properties, "value", sizeof("value"), (void *)&temp, sizeof(zval *), NULL); + + } + + tidyBufFree(&output); + + if(obj->ptdoc->errbuf->size) { + MAKE_STD_ZVAL(temp); + ZVAL_STRINGL(temp, obj->ptdoc->errbuf->bp, obj->ptdoc->errbuf->size, TRUE); + zend_hash_update(obj->std.properties, "error_buf", sizeof("error_buf"), (void *)&temp, sizeof(zval *), NULL); + } + + } + +} + + +static void tidy_globals_ctor(zend_tidy_globals *g TSRMLS_DC) +{ +} + +/* +static void tidy_globals_dtor(zend_tidy_globals *g TSRMLS_DC) +{ +} +*/ + +static void tidy_add_default_properities(PHPTidyObj *obj, tidy_obj_type type TSRMLS_DC) +{ + + TidyBuffer buf; + TidyAttr tempattr; + TidyNode tempnode; + zval *attribute, *children, *temp; + PHPTidyObj *newobj; + + switch(type) { + + case is_node: + + memset(&buf, 0, sizeof(buf)); + tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf); + buf.bp[buf.size-1] = '\0'; + ADD_PROPERITY_STRING(obj->std.properties, value, buf.bp); + tidyBufFree(&buf); + + ADD_PROPERITY_STRING(obj->std.properties, name, tidyNodeGetName(obj->node)); + ADD_PROPERITY_LONG(obj->std.properties, type, tidyNodeGetType(obj->node)); + + switch(tidyNodeGetType(obj->node)) { + + case TidyNode_Root: + case TidyNode_DocType: + case TidyNode_Text: + case TidyNode_Comment: + break; + default: + ADD_PROPERITY_LONG(obj->std.properties, id, tidyNodeGetId(obj->node)); + } + + + tempattr = tidyAttrFirst(obj->node); + MAKE_STD_ZVAL(attribute); + + if(tempattr) { + char *name, *val; + array_init(attribute); + + do { + name = (char *)tidyAttrName(tempattr); + val = (char *)tidyAttrValue(tempattr); + if(name && val) { + add_assoc_string(attribute, name, val, TRUE); + } + } while((tempattr = tidyAttrNext(tempattr))); + + + } else { + ZVAL_NULL(attribute); + } + zend_hash_update(obj->std.properties, "attribute", sizeof("attribute"), (void *)&attribute, sizeof(zval *), NULL); + + tempnode = tidyGetChild(obj->node); + + MAKE_STD_ZVAL(children); + if(tempnode) { + array_init(children); + do { + + MAKE_STD_ZVAL(temp); + tidy_instanciate(tidy_ce_node, temp TSRMLS_CC); + newobj = (PHPTidyObj *) zend_object_store_get_object(temp TSRMLS_CC); + newobj->attr = NULL; + newobj->node = tempnode; + newobj->type = is_node; + newobj->ptdoc = obj->ptdoc; + newobj->ptdoc->ref_count++; + + tidy_add_default_properities(newobj, is_node TSRMLS_DC); + add_next_index_zval(children, temp); + + } while((tempnode = tidyGetNext(tempnode))); + + } else { + ZVAL_NULL(children); + } + + zend_hash_update(obj->std.properties, "child", sizeof("child"), (void *)&children, sizeof(zval *), NULL); + + break; + case is_attr: + ADD_PROPERITY_STRING(obj->std.properties, name, tidyAttrName(obj->attr)); + ADD_PROPERITY_STRING(obj->std.properties, value, tidyAttrValue(obj->attr)); + ADD_PROPERITY_LONG(obj->std.properties, id, tidyAttrGetId(obj->attr)); + break; + + case is_doc: + ADD_PROPERITY_NULL(obj->std.properties, error_buf); + ADD_PROPERITY_NULL(obj->std.properties, value); + break; + case is_exception: + default: + break; + } +} + +static void *php_tidy_get_opt_val(PHPTidyDoc *ptdoc, TidyOption opt, TidyOptionType *type TSRMLS_DC) +{ + *type = tidyOptGetType(opt); + + switch (*type) { + case TidyString: { + char *val = (char *) tidyOptGetValue(ptdoc->doc, tidyOptGetId(opt)); + if (val) { + return (void *) estrdup(val); + } else { + return (void *) estrdup(""); + } + } + break; + + case TidyInteger: + return (void *) tidyOptGetInt(ptdoc->doc, tidyOptGetId(opt)); + break; + + case TidyBoolean: + return (void *) tidyOptGetBool(ptdoc->doc, tidyOptGetId(opt)); + break; + } + + /* should not happen */ + return NULL; +} + +static void php_tidy_create_node(INTERNAL_FUNCTION_PARAMETERS, tidy_base_nodetypes node) +{ + + zval *object = getThis(); + PHPTidyObj *obj, *newobj; + + if(object) { + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "O", &object, tidy_ce_doc) == FAILURE) { + RETURN_FALSE; + } + + } + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + TIDY_PARSED_CHECK(obj); + + tidy_instanciate(tidy_ce_node, return_value TSRMLS_CC); + newobj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC); + newobj->attr = NULL; + newobj->type = is_node; + newobj->ptdoc = obj->ptdoc; + newobj->ptdoc->ref_count++; + + switch(node) { + + case is_root_node: + newobj->node = tidyGetRoot(newobj->ptdoc->doc); + break; + case is_html_node: + newobj->node = tidyGetHtml(newobj->ptdoc->doc); + break; + case is_head_node: + newobj->node = tidyGetHead(newobj->ptdoc->doc); + break; + case is_body_node: + newobj->node = tidyGetBody(newobj->ptdoc->doc); + + break; + } + + tidy_add_default_properities(newobj, is_node TSRMLS_CC); + +} + +static void php_tidy_parse_file(INTERNAL_FUNCTION_PARAMETERS) +{ + char *inputfile; + int input_len; + zend_bool use_include_path = 0; + char *contents; + + zend_bool is_object = FALSE; + + zval *object = getThis(); + PHPTidyObj *obj; + + if(zend_parse_parameters(1 TSRMLS_CC, "s|b", &inputfile, &input_len, &use_include_path) == FAILURE) { + RETURN_FALSE; + } + + if(object) { + + is_object = TRUE; + obj = (PHPTidyObj *)zend_object_store_get_object(object TSRMLS_CC); + + if(obj->ptdoc->parsed) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot parse two documents with the same tidy instance"); + RETURN_FALSE; + } + + } else { + + tidy_instanciate(tidy_ce_doc, return_value TSRMLS_CC); + obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC); + + } + + if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path TSRMLS_CC))) { RETURN_FALSE; } + + if(tidyParseString(obj->ptdoc->doc, contents) < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "[Tidy error] %s", obj->ptdoc->errbuf->bp); + RETVAL_FALSE; + } else { + + obj->ptdoc->parsed = TRUE; + tidy_doc_update_properties(obj TSRMLS_DC); + + if(is_object) { + RETVAL_TRUE; + } + + } + + efree(contents); + +} + +PHP_MINIT_FUNCTION(tidy) +{ + REGISTER_INI_ENTRIES(); + REGISTER_TIDY_CLASS(doc, NULL); + REGISTER_TIDY_CLASS(node, NULL); + REGISTER_TIDY_CLASS(attr, NULL); + REGISTER_TIDY_CLASS(exception, zend_exception_get_default()); + + tidy_object_handlers_doc.get_class_entry = tidy_get_ce_doc; + tidy_object_handlers_node.get_class_entry = tidy_get_ce_node; + tidy_object_handlers_attr.get_class_entry = tidy_get_ce_attr; + + tidy_object_handlers_doc.cast_object = tidy_doc_cast_handler; + tidy_object_handlers_node.cast_object = tidy_node_cast_handler; + + ZEND_INIT_MODULE_GLOBALS(tidy, tidy_globals_ctor, tidy_globals_dtor); + + _php_tidy_register_tags(INIT_FUNC_ARGS_PASSTHRU); + _php_tidy_register_attributes(INIT_FUNC_ARGS_PASSTHRU); + _php_tidy_register_nodetypes(INIT_FUNC_ARGS_PASSTHRU); + + return SUCCESS; +} + + +PHP_MSHUTDOWN_FUNCTION(tidy) +{ + return SUCCESS; +} + +PHP_RINIT_FUNCTION(tidy) +{ + if (INI_BOOL("tidy.clean_output") == TRUE) { + + if (php_start_ob_buffer_named("ob_tidyhandler", 0, 1 TSRMLS_CC) == FAILURE) { + zend_error(E_NOTICE, "Unable to use Tidy for output buffering."); + } + } + + return SUCCESS; +} + + + +PHP_RSHUTDOWN_FUNCTION(tidy) +{ + return SUCCESS; +} + + +PHP_MINFO_FUNCTION(tidy) +{ + php_info_print_table_start(); + php_info_print_table_header(2, "tidy support", "enabled"); + php_info_print_table_end(); + +} + +TIDY_ATTR_METHOD(__construct) +{ +} + +PHP_FUNCTION(ob_tidyhandler) +{ + char *input; + int input_len; + long mode; + TidyBuffer output = {0}, errbuf = {0}; + TidyDoc doc; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &input, &input_len, &mode) == FAILURE) { + WRONG_PARAM_COUNT; + } + + doc = tidyCreate(); + tidyBufInit(&errbuf); + tidyBufInit(&output); + + tidyOptSetBool(doc, TidyForceOutput, yes); + tidyOptSetBool(doc, TidyMark, no); + + if(tidySetErrorBuffer(doc, &errbuf) != 0) { + zend_error(E_ERROR, "Could not set Tidy error buffer"); + } + + TIDY_SET_DEFAULT_CONFIG(doc); + + if(input_len > 1) { + if(tidyParseString(doc, input) < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "[Tidy error] %s", errbuf.bp); + } + + if(tidyCleanAndRepair(doc) < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "[Tidy error] %s", errbuf.bp); + } + + tidySaveBuffer (doc, &output); + RETVAL_STRING(output.bp, 1); + } else { + RETVAL_NULL(); + } + + tidyRelease(doc); + tidyBufFree(&output); + tidyBufFree(&errbuf); +} + +/* {{{ proto bool tidy_parse_string(string input) + Parse a document stored in a string */ +PHP_FUNCTION(tidy_parse_string) +{ + char *input; + int input_len; + + zend_bool is_object = FALSE; + + zval *object = getThis(); + PHPTidyObj *obj; + + if(object) { + + + if(zend_parse_parameters(1 TSRMLS_CC, "s", &input, &input_len) == FAILURE) { + RETURN_FALSE; + } + + is_object = TRUE; + obj = (PHPTidyObj *)zend_object_store_get_object(object TSRMLS_CC); + + if(obj->ptdoc->parsed) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot parse two documents with the same tidy instance"); + RETURN_FALSE; + } + + } else { + + if(zend_parse_parameters(1 TSRMLS_CC, "s", &input, &input_len) == FAILURE) { + return; + } + + tidy_instanciate(tidy_ce_doc, return_value TSRMLS_CC); + obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC); + + } + + if(tidyParseString(obj->ptdoc->doc, input) < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "[Tidy error] %s", obj->ptdoc->errbuf->bp); + return; + } + + obj->ptdoc->parsed = TRUE; + + tidy_doc_update_properties(obj TSRMLS_DC); + + if(is_object) { + + RETURN_TRUE; + + } +} +/* }}} */ - if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path TSRMLS_CC))) { - RETURN_FALSE; +/* {{{ proto string tidy_get_error_buffer([boolean detailed]) + Return warnings and errors which occured parsing the specified document*/ +PHP_FUNCTION(tidy_get_error_buffer) +{ + zval *object = getThis(); + PHPTidyObj *obj; + + if(object) { + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "O", &object, tidy_ce_doc) == FAILURE) { + RETURN_FALSE; + } + } - if(tidyParseString(TG(tdoc)->doc, contents) < 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "[Tidy error] %s", TG(tdoc)->errbuf->bp); - RETVAL_FALSE; + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + RETURN_STRING(obj->ptdoc->errbuf->bp, 1); +} +/* }}} */ + +/* {{{ proto string tidy_get_output() + Return a string representing the parsed tidy markup */ +PHP_FUNCTION(tidy_get_output) +{ + zval *object = getThis(); + PHPTidyObj *obj; + TidyBuffer output = {0}; + + if(object) { + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + } else { - TG(tdoc)->parsed = TRUE; - RETVAL_TRUE; + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "O", &object, tidy_ce_doc) == FAILURE) { + RETURN_FALSE; + } + } + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + TIDY_PARSED_CHECK(obj); + + tidySaveBuffer (obj->ptdoc->doc, &output); + + RETVAL_STRING(output.bp, 1); + + tidyBufFree(&output); +} +/* }}} */ - efree(contents); +/* {{{ proto boolean tidy_parse_file(string file [, bool use_include_path]) + Parse markup in file or URI */ +PHP_FUNCTION(tidy_parse_file) +{ + php_tidy_parse_file(INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* }}} */ @@ -468,16 +962,32 @@ PHP_FUNCTION(tidy_parse_file) Execute configured cleanup and repair operations on parsed markup */ PHP_FUNCTION(tidy_clean_repair) { - if(ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; + zval *object = getThis(); + PHPTidyObj *obj; + + if(object) { + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "O", &object, tidy_ce_doc) == FAILURE) { + RETURN_FALSE; + } + } - - TIDY_PARSED_CHECK(); - - if (tidyCleanAndRepair(TG(tdoc)->doc) >= 0) { + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + TIDY_PARSED_CHECK(obj); + if (tidyCleanAndRepair(obj->ptdoc->doc) >= 0) { + obj->ptdoc->repaired = TRUE; + tidy_doc_update_properties(obj TSRMLS_DC); RETURN_TRUE; } - + RETURN_FALSE; } /* }}} */ @@ -486,7 +996,7 @@ PHP_FUNCTION(tidy_clean_repair) Repair a string using an optionally provided configuration file */ PHP_FUNCTION(tidy_repair_string) { - php_tidy_quick_repair(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); + php_tidy_quick_repair(INTERNAL_FUNCTION_PARAM_PASSTHRU, FALSE); } /* }}} */ @@ -494,7 +1004,7 @@ PHP_FUNCTION(tidy_repair_string) Repair a file using an optionally provided configuration file */ PHP_FUNCTION(tidy_repair_file) { - php_tidy_quick_repair(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); + php_tidy_quick_repair(INTERNAL_FUNCTION_PARAM_PASSTHRU, TRUE); } /* }}} */ @@ -502,16 +1012,32 @@ PHP_FUNCTION(tidy_repair_file) Run configured diagnostics on parsed and repaired markup. */ PHP_FUNCTION(tidy_diagnose) { - if(ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; + zval *object = getThis(); + PHPTidyObj *obj; + + if(object) { + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "O", &object, tidy_ce_doc) == FAILURE) { + RETURN_FALSE; + } + } - - TIDY_PARSED_CHECK(); - - if (tidyRunDiagnostics(TG(tdoc)->doc) >= 0) { + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + TIDY_PARSED_REPAIR_CHECK(obj); + + if (tidyRunDiagnostics(obj->ptdoc->doc) >= 0) { + tidy_doc_update_properties(obj TSRMLS_DC); RETURN_TRUE; } - + RETURN_FALSE; } /* }}} */ @@ -523,58 +1049,63 @@ PHP_FUNCTION(tidy_get_release) if(ZEND_NUM_ARGS()) { WRONG_PARAM_COUNT; } - + RETURN_STRING((char *)tidyReleaseDate(), 1); } /* }}} */ -/* {{{ proto string tidy_reset_config() - Restore Tidy configuration to default values */ -PHP_FUNCTION(tidy_reset_config) -{ - if(ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; - } - - RETURN_BOOL(tidyOptResetToSnapshot(TG(tdoc)->doc)); -} -/* }}} */ - /* {{{ proto array tidy_get_config() Get current Tidy configuarion */ PHP_FUNCTION(tidy_get_config) { - TidyIterator itOpt = tidyGetOptionList(TG(tdoc)->doc); + TidyIterator itOpt; char *opt_name; void *opt_value; TidyOptionType optt; - - if(ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; + + zval *object = getThis(); + PHPTidyObj *obj; + + if(object) { + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "O", &object, tidy_ce_doc) == FAILURE) { + RETURN_FALSE; + } + } - + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + itOpt = tidyGetOptionList(obj->ptdoc->doc); + array_init(return_value); - + while (itOpt) { - TidyOption opt = tidyGetNextOption(TG(tdoc)->doc, &itOpt); - + TidyOption opt = tidyGetNextOption(obj->ptdoc->doc, &itOpt); + opt_name = (char *)tidyOptGetName(opt); - opt_value = php_tidy_get_opt_val(opt, &optt TSRMLS_CC); + opt_value = php_tidy_get_opt_val(obj->ptdoc, opt, &optt TSRMLS_CC); switch (optt) { case TidyString: add_assoc_string(return_value, opt_name, (char*)opt_value, 0); break; - + case TidyInteger: add_assoc_long(return_value, opt_name, (long)opt_value); break; - + case TidyBoolean: add_assoc_bool(return_value, opt_name, (long)opt_value); break; } } - + return; } /* }}} */ @@ -584,11 +1115,26 @@ PHP_FUNCTION(tidy_get_config) Get status of specfied document. */ PHP_FUNCTION(tidy_get_status) { - if(ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; + zval *object = getThis(); + PHPTidyObj *obj; + + if(object) { + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "O", &object, tidy_ce_doc) == FAILURE) { + RETURN_FALSE; + } + } - - RETURN_LONG(tidyStatus(TG(tdoc)->doc)); + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + RETURN_LONG(tidyStatus(obj->ptdoc->doc)); } /* }}} */ @@ -596,13 +1142,28 @@ PHP_FUNCTION(tidy_get_status) Get the Detected HTML version for the specified document. */ PHP_FUNCTION(tidy_get_html_ver) { - if(ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; + zval *object = getThis(); + PHPTidyObj *obj; + + if(object) { + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "O", &object, tidy_ce_doc) == FAILURE) { + RETURN_FALSE; + } + } - - TIDY_PARSED_CHECK(); - - RETURN_LONG(tidyDetectedHtmlVersion(TG(tdoc)->doc)); + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + TIDY_PARSED_CHECK(obj); + + RETURN_LONG(tidyDetectedHtmlVersion(obj->ptdoc->doc)); } /* }}} */ @@ -610,13 +1171,28 @@ PHP_FUNCTION(tidy_get_html_ver) Indicates if the document is a XHTML document. */ PHP_FUNCTION(tidy_is_xhtml) { - if(ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; + zval *object = getThis(); + PHPTidyObj *obj; + + if(object) { + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "O", &object, tidy_ce_doc) == FAILURE) { + RETURN_FALSE; + } + } - - TIDY_PARSED_CHECK(); - - RETURN_BOOL(tidyDetectedXhtml(TG(tdoc)->doc)); + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + TIDY_PARSED_CHECK(obj); + + RETURN_BOOL(tidyDetectedXhtml(obj->ptdoc->doc)); } /* }}} */ @@ -624,13 +1200,28 @@ PHP_FUNCTION(tidy_is_xhtml) Indicates if the document is a generic (non HTML/XHTML) XML document. */ PHP_FUNCTION(tidy_is_xml) { - if(ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; + zval *object = getThis(); + PHPTidyObj *obj; + + if(object) { + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "O", &object, tidy_ce_doc) == FAILURE) { + RETURN_FALSE; + } + } - - TIDY_PARSED_CHECK(); - - RETURN_BOOL(tidyDetectedGenericXml(TG(tdoc)->doc)); + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + TIDY_PARSED_CHECK(obj); + + RETURN_BOOL(tidyDetectedGenericXml(obj->ptdoc->doc)); } /* }}} */ @@ -638,13 +1229,28 @@ PHP_FUNCTION(tidy_is_xml) Returns the Number of Tidy errors encountered for specified document. */ PHP_FUNCTION(tidy_error_count) { - if(ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; + zval *object = getThis(); + PHPTidyObj *obj; + + if(object) { + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "O", &object, tidy_ce_doc) == FAILURE) { + RETURN_FALSE; + } + } - - TIDY_PARSED_CHECK(); - - RETURN_LONG(tidyErrorCount(TG(tdoc)->doc)); + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + TIDY_PARSED_CHECK(obj); + + RETURN_LONG(tidyErrorCount(obj->ptdoc->doc)); } /* }}} */ @@ -652,13 +1258,28 @@ PHP_FUNCTION(tidy_error_count) Returns the Number of Tidy warnings encountered for specified document. */ PHP_FUNCTION(tidy_warning_count) { - if(ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; + zval *object = getThis(); + PHPTidyObj *obj; + + if(object) { + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "O", &object, tidy_ce_doc) == FAILURE) { + RETURN_FALSE; + } + } - - TIDY_PARSED_CHECK(); - - RETURN_LONG(tidyWarningCount(TG(tdoc)->doc)); + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + TIDY_PARSED_CHECK(obj); + + RETURN_LONG(tidyWarningCount(obj->ptdoc->doc)); } /* }}} */ @@ -666,13 +1287,28 @@ PHP_FUNCTION(tidy_warning_count) Returns the Number of Tidy accessibility warnings encountered for specified document. */ PHP_FUNCTION(tidy_access_count) { - if(ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; + zval *object = getThis(); + PHPTidyObj *obj; + + if(object) { + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "O", &object, tidy_ce_doc) == FAILURE) { + RETURN_FALSE; + } + } - - TIDY_PARSED_CHECK(); - - RETURN_LONG(tidyAccessWarningCount(TG(tdoc)->doc)); + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + TIDY_PARSED_CHECK(obj); + + RETURN_LONG(tidyAccessWarningCount(obj->ptdoc->doc)); } /* }}} */ @@ -680,13 +1316,28 @@ PHP_FUNCTION(tidy_access_count) Returns the Number of Tidy configuration errors encountered for specified document. */ PHP_FUNCTION(tidy_config_count) { - if(ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; + zval *object = getThis(); + PHPTidyObj *obj; + + if(object) { + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "O", &object, tidy_ce_doc) == FAILURE) { + RETURN_FALSE; + } + } - - TIDY_PARSED_CHECK(); - - RETURN_LONG(tidyConfigErrorCount(TG(tdoc)->doc)); + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + TIDY_PARSED_CHECK(obj); + + RETURN_LONG(tidyConfigErrorCount(obj->ptdoc->doc)); } /* }}} */ @@ -696,19 +1347,33 @@ PHP_FUNCTION(tidy_load_config) { char *filename; int filename_len; - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { - RETURN_FALSE; + + zval *object = getThis(); + PHPTidyObj *obj; + + if(object) { + + if(zend_parse_parameters(1 TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { + RETURN_FALSE; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "Os", &object, tidy_ce_doc, &filename, &filename_len) == FAILURE) { + RETURN_FALSE; + } + } - + TIDY_SAFE_MODE_CHECK(filename); - - if(tidyLoadConfig(TG(tdoc)->doc, filename) < 0) { + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + if(tidyLoadConfig(obj->ptdoc->doc, filename) < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not load configuration file '%s'", filename); RETURN_FALSE; } - - TG(used) = 1; + RETURN_TRUE; } /* }}} */ @@ -718,21 +1383,37 @@ PHP_FUNCTION(tidy_load_config) PHP_FUNCTION(tidy_load_config_enc) { char *filename, *encoding; - int enc_len, file_len; - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &filename, &file_len, &encoding, &enc_len) == FAILURE) { - RETURN_FALSE; + int file_len, enc_len; + + zval *object = getThis(); + PHPTidyObj *obj; + + if(object) { + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &filename, &file_len, &encoding, &enc_len) == FAILURE) { + RETURN_FALSE; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "Oss", &object, tidy_ce_doc, + &filename, &file_len, &encoding, &enc_len) == FAILURE) { + RETURN_FALSE; + } + } - + TIDY_SAFE_MODE_CHECK(filename); - - if(tidyLoadConfigEnc(TG(tdoc)->doc, filename, encoding) < 0) { + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + if(tidyLoadConfigEnc(obj->ptdoc->doc, filename, encoding) < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not load configuration file '%s' using encoding '%s'", filename, encoding); RETURN_FALSE; } - - TG(used) = 1; + RETURN_TRUE; + } /* }}} */ @@ -742,41 +1423,165 @@ PHP_FUNCTION(tidy_load_config_enc) utf16be, utf16, big5 and shiftjis. */ PHP_FUNCTION(tidy_set_encoding) { + zval *object = getThis(); + PHPTidyObj *obj; char *encoding; int enc_len; - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &encoding, &enc_len) == FAILURE) { - RETURN_FALSE; + + if(object) { + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &encoding, &enc_len) == FAILURE) { + RETURN_FALSE; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "Os", &object, tidy_ce_doc, &encoding, &enc_len) == FAILURE) { + RETURN_FALSE; + } + } - - if(tidySetCharEncoding(TG(tdoc)->doc, encoding) < 0) { + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + if(tidySetCharEncoding(obj->ptdoc->doc, encoding) < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not set encoding '%s'", encoding); RETURN_FALSE; } - - TG(used) = 1; + RETURN_TRUE; } /* }}} */ + +/* {{{ proto boolean tidy_snapshot_config() + Take a snapshot of the configuration for this document so it can be modified + and later restored. */ +PHP_FUNCTION(tidy_snapshot_config) +{ + zval *object = getThis(); + PHPTidyObj *obj; + + if(object) { + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "O", &object, tidy_ce_doc) == FAILURE) { + RETURN_FALSE; + } + + } + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + if(tidyOptSnapshot(obj->ptdoc->doc)) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} + +/* {{{ proto boolean tidy_restore_config() + Restore the configuration for the document to the last snapshot */ +PHP_FUNCTION(tidy_restore_config) +{ + zval *object = getThis(); + PHPTidyObj *obj; + + if(object) { + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "O", &object, tidy_ce_doc) == FAILURE) { + RETURN_FALSE; + } + + } + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + if(tidyOptResetToSnapshot(obj->ptdoc->doc)) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} + +/* {{{ proto boolean tidy_restore_config(boolean ignore_default) + Reset the configuration for the document to default config */ +PHP_FUNCTION(tidy_reset_config) +{ + zval *object = getThis(); + PHPTidyObj *obj; + + if(object) { + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "O", &object, tidy_ce_doc) == FAILURE) { + RETURN_FALSE; + } + + } + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + if(tidyOptResetAllToDefault(obj->ptdoc->doc)) { + if (TG(default_config) && TG(default_config)[0]) { + if (tidyLoadConfig(obj->ptdoc->doc, TG(default_config)) < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to load Tidy configuration file at '%s'.", TG(default_config)); + RETURN_FALSE; + } + } + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} + /* {{{ proto boolean tidy_save_config(string filename) Save current settings to named file. Only non-default values are written. */ PHP_FUNCTION(tidy_save_config) { + zval *object = getThis(); + PHPTidyObj *obj; char *filename; int file_len; - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &file_len) == FAILURE) { - RETURN_FALSE; + + if(object) { + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &file_len) == FAILURE) { + RETURN_FALSE; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "Os", &object, tidy_ce_doc, &filename, &file_len) == FAILURE) { + RETURN_FALSE; + } + } - + TIDY_SAFE_MODE_CHECK(filename); - - if(tidyOptSaveFile(TG(tdoc)->doc, filename) < 0) { + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + if(tidyOptSaveFile(obj->ptdoc->doc, filename) < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not write tidy configuration file '%s'", filename); RETURN_FALSE; } - + RETURN_TRUE; } /* }}} */ @@ -785,42 +1590,61 @@ PHP_FUNCTION(tidy_save_config) Updates the configuration settings for the specified tidy document. */ PHP_FUNCTION(tidy_setopt) { + zval *object = getThis(); + PHPTidyObj *obj; + zval *value; char *optname; int optname_len; TidyOption opt; - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &optname, &optname_len, &value) == FAILURE) { - RETURN_FALSE; + + if(object) { + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &optname, &optname_len, &value) == FAILURE) { + RETURN_FALSE; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "Osz", &object, tidy_ce_doc, &optname, &optname_len, &value) == FAILURE) { + RETURN_FALSE; + } + } - opt = tidyGetOptionByName(TG(tdoc)->doc, optname); + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + opt = tidyGetOptionByName(obj->ptdoc->doc, optname); + if (!opt) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown Tidy Configuration Option '%s'", optname); RETURN_FALSE; } - + + if(tidyOptIsReadOnly(opt)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted to set read-only option '%s'", optname); + RETURN_FALSE; + } + switch(tidyOptGetType(opt)) { + case TidyString: convert_to_string_ex(&value); - if(tidyOptSetValue(TG(tdoc)->doc, tidyOptGetId(opt), Z_STRVAL_P(value))) { - TG(used) = 1; + if(tidyOptSetValue(obj->ptdoc->doc, tidyOptGetId(opt), Z_STRVAL_P(value))) { RETURN_TRUE; } break; case TidyInteger: convert_to_long_ex(&value); - if(tidyOptSetInt(TG(tdoc)->doc, tidyOptGetId(opt), Z_LVAL_P(value))) { - TG(used) = 1; + if(tidyOptSetInt(obj->ptdoc->doc, tidyOptGetId(opt), Z_LVAL_P(value))) { RETURN_TRUE; } break; case TidyBoolean: convert_to_long_ex(&value); - if(tidyOptSetBool(TG(tdoc)->doc, tidyOptGetId(opt), Z_LVAL_P(value))) { - TG(used) = 1; + if(tidyOptSetBool(obj->ptdoc->doc, tidyOptGetId(opt), Z_LVAL_P(value))) { RETURN_TRUE; } break; @@ -829,206 +1653,80 @@ PHP_FUNCTION(tidy_setopt) php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to determine type of Tidy configuration constant to set"); break; } - RETURN_FALSE; -} -/* }}} */ - -/* {{{ proto mixed tidy_getopt(string option) - Returns the value of the specified configuration option for the tidy document. */ -PHP_FUNCTION(tidy_getopt) -{ - char *optname; - void *optval; - int optname_len; - TidyOption opt; - TidyOptionType optt; - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &optname, &optname_len) == FAILURE) { - RETURN_FALSE; - } - - opt = tidyGetOptionByName(TG(tdoc)->doc, optname); - if (!opt) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown Tidy Configuration Option '%s'", optname); - RETURN_FALSE; - } - - optval = php_tidy_get_opt_val(opt, &optt TSRMLS_CC); - switch (optt) { - case TidyString: - RETVAL_STRING((char *)optval, 0); - break; - - case TidyInteger: - RETURN_LONG((long)optval); - break; - - case TidyBoolean: - if (optval) { - RETURN_TRUE; - } else { - RETURN_NULL(); - } - break; - - default: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to determine type of Tidy configuration constant to get"); - break; - } - - RETURN_FALSE; -} -/* }}} */ - -#ifdef ZEND_ENGINE_2 -static void tidy_object_dtor(void *object, zend_object_handle handle TSRMLS_DC) -{ - PHPTidyObj *intern = (PHPTidyObj *)object; - - zend_hash_destroy(intern->std.properties); - FREE_HASHTABLE(intern->std.properties); - - efree(object); -} - -static void tidy_object_new(zend_class_entry *class_type, zend_object_handlers *handlers, zend_object_value *retval TSRMLS_DC) -{ - PHPTidyObj *intern; - zval *tmp; - - intern = emalloc(sizeof(PHPTidyObj)); - memset(intern, 0, sizeof(PHPTidyObj)); - intern->std.ce = class_type; - - ALLOC_HASHTABLE(intern->std.properties); - zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0); - zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - - retval->handle = zend_objects_store_put(intern, tidy_object_dtor, NULL TSRMLS_CC); - retval->handlers = handlers; -} - -static zend_object_value tidy_object_new_node(zend_class_entry *class_type TSRMLS_DC) -{ - zend_object_value retval; - tidy_object_new(class_type, &tidy_object_handlers_node, &retval TSRMLS_CC); - return retval; -} - -static zend_object_value tidy_object_new_attr(zend_class_entry *class_type TSRMLS_DC) -{ - zend_object_value retval; - tidy_object_new(class_type, &tidy_object_handlers_attr, &retval TSRMLS_CC); - return retval; - -} - -static zend_object_value tidy_object_new_exception(zend_class_entry *class_type TSRMLS_DC) -{ - zend_object_value retval; - tidy_object_new(class_type, &tidy_object_handlers_exception, &retval TSRMLS_CC); - return retval; + RETURN_FALSE; } +/* }}} */ -static zend_class_entry *tidy_get_ce_node(zval *object TSRMLS_DC) -{ - return tidy_ce_node; -} - -static zend_class_entry *tidy_get_ce_attr(zval *object TSRMLS_DC) -{ - return tidy_ce_attr; -} - -static zval * tidy_instanciate(zend_class_entry *pce, zval *object TSRMLS_DC) +/* {{{ proto mixed tidy_getopt(string option) + Returns the value of the specified configuration option for the tidy document. */ +PHP_FUNCTION(tidy_getopt) { - if (!object) { - ALLOC_ZVAL(object); + zval *object = getThis(); + PHPTidyObj *obj; + char *optname; + void *optval; + int optname_len; + TidyOption opt; + TidyOptionType optt; + + if(object) { + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &optname, &optname_len) == FAILURE) { + RETURN_FALSE; + } + + } else { + + if(zend_parse_method_parameters(1 TSRMLS_CC, NULL, "Os", &object, tidy_ce_doc, &optname, &optname_len) == FAILURE) { + RETURN_FALSE; + } + } - Z_TYPE_P(object) = IS_OBJECT; - object_init_ex(object, pce); - object->refcount = 1; - object->is_ref = 1; - return object; -} -#define ADD_PROPERITY_STRING(_table, _key, _string) \ - { \ - zval *tmp; \ - MAKE_STD_ZVAL(tmp); \ - if(_string) { \ - ZVAL_STRING(tmp, (char *)_string, 1); \ - } else { \ - ZVAL_EMPTY_STRING(tmp); \ - } \ - zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \ - } + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + -#define ADD_PROPERITY_LONG(_table, _key, _long) \ - { \ - zval *tmp; \ - MAKE_STD_ZVAL(tmp); \ - ZVAL_LONG(tmp, _long); \ - zend_hash_update(_table, #_key, sizeof(#_key), (void *)&tmp, sizeof(zval *), NULL); \ + opt = tidyGetOptionByName(obj->ptdoc->doc, optname); + if (!opt) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown Tidy Configuration Option '%s'", optname); + RETURN_FALSE; } + + optval = php_tidy_get_opt_val(obj->ptdoc, opt, &optt TSRMLS_CC); + switch (optt) { + case TidyString: + RETVAL_STRING((char *)optval, 0); + break; -static void tidy_add_default_properities(PHPTidyObj *obj, tidy_obj_type type TSRMLS_DC) { - - TidyBuffer buf; - - switch(type) { - - case is_node: - memset(&buf, 0, sizeof(buf)); - tidyNodeGetText(TG(tdoc)->doc, obj->node, &buf); - ADD_PROPERITY_STRING(obj->std.properties, value, buf.bp); - tidyBufFree(&buf); - -/* fprintf(stderr, "type: %d\n",tidyNodeGetType(obj->node)); */ + case TidyInteger: + RETURN_LONG((long)optval); + break; - ADD_PROPERITY_STRING(obj->std.properties, name, tidyNodeGetName(obj->node)); - ADD_PROPERITY_LONG(obj->std.properties, type, tidyNodeGetType(obj->node)); - switch(tidyNodeGetType(obj->node)) { - - case TidyNode_Root: - case TidyNode_DocType: - case TidyNode_Text: - case TidyNode_Comment: - break; - default: - ADD_PROPERITY_LONG(obj->std.properties, id, tidyNodeGetId(obj->node)); + case TidyBoolean: + if (optval) { + RETURN_TRUE; + } else { + RETURN_NULL(); } - - break; - case is_attr: - ADD_PROPERITY_STRING(obj->std.properties, name, tidyAttrName(obj->attr)); - ADD_PROPERITY_STRING(obj->std.properties, value, tidyAttrValue(obj->attr)); - ADD_PROPERITY_LONG(obj->std.properties, id, tidyAttrGetId(obj->attr)); + break; + + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to determine type of Tidy configuration constant to get"); break; } - + + RETURN_FALSE; + } +/* }}} */ + /* {{{ proto TidyNode tidy_get_root() Returns a TidyNode Object representing the root of the tidy parse tree */ PHP_FUNCTION(tidy_get_root) { - PHPTidyObj *obj; - - if(ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; - } - - TIDY_PARSED_CHECK(); - - tidy_instanciate(tidy_ce_node, return_value TSRMLS_CC); - obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC); - obj->node = tidyGetRoot(TG(tdoc)->doc); - obj->attr = NULL; - obj->type = is_node; + php_tidy_create_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, is_root_node); - tidy_add_default_properities(obj, is_node TSRMLS_CC); - } /* }}} */ @@ -1036,21 +1734,7 @@ PHP_FUNCTION(tidy_get_root) Returns a TidyNode Object starting from the tag of the tidy parse tree */ PHP_FUNCTION(tidy_get_html) { - PHPTidyObj *obj; - - if(ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; - } - - TIDY_PARSED_CHECK(); - - tidy_instanciate(tidy_ce_node, return_value TSRMLS_CC); - obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC); - obj->node = tidyGetHtml(TG(tdoc)->doc); - obj->attr = NULL; - obj->type = is_node; - - tidy_add_default_properities(obj, is_node TSRMLS_CC); + php_tidy_create_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, is_html_node); } /* }}} */ @@ -1058,21 +1742,7 @@ PHP_FUNCTION(tidy_get_html) Returns a TidyNode Object starting from the tag of the tidy parse tree */ PHP_FUNCTION(tidy_get_head) { - PHPTidyObj *obj; - - if(ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; - } - - TIDY_PARSED_CHECK(); - - tidy_instanciate(tidy_ce_node, return_value TSRMLS_CC); - obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC); - obj->node = tidyGetHead(TG(tdoc)->doc); - obj->attr = NULL; - obj->type = is_node; - - tidy_add_default_properities(obj, is_node TSRMLS_CC); + php_tidy_create_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, is_head_node); } /* }}} */ @@ -1080,87 +1750,29 @@ PHP_FUNCTION(tidy_get_head) Returns a TidyNode Object starting from the tag of the tidy parse tree */ PHP_FUNCTION(tidy_get_body) { - PHPTidyObj *obj; - - if(ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; - } - - TIDY_PARSED_CHECK(); - - tidy_instanciate(tidy_ce_node, return_value TSRMLS_CC); - obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC); - obj->node = tidyGetBody(TG(tdoc)->doc); - obj->attr = NULL; - obj->type = is_node; - - tidy_add_default_properities(obj, is_node TSRMLS_CC); + php_tidy_create_node(INTERNAL_FUNCTION_PARAM_PASSTHRU, is_body_node); } /* }}} */ /* {{{ proto void tidy_node::tidy_node() Constructor. */ -PHP_NODE_METHOD(__construct) -{ -} -/* }}} */ - -/* {{{ proto tidy_attr tidy_node::attributes() - Returns an array of attribute objects for node */ -PHP_NODE_METHOD(attributes) -{ - TidyAttr tempattr; - zval *object; - PHPTidyObj *objtemp; - GET_THIS_CONTAINER(); - - tempattr = tidyAttrFirst(obj->node); - - if(tempattr) { - array_init(return_value); - - do { - - MAKE_STD_ZVAL(object); - INSTANCIATE_ATTR(object, objtemp, tempattr); - add_next_index_zval(return_value, object); - - } while((tempattr = tidyAttrNext(tempattr))); - } -} -/* }}} */ - - - -/* {{{ proto tidy_node tidy_node::children() - Returns an array of child nodes */ -PHP_NODE_METHOD(children) +TIDY_NODE_METHOD(__construct) { - TidyNode tempnode; - zval *object; - PHPTidyObj *objtemp; - GET_THIS_CONTAINER(); - - tempnode = tidyGetChild(obj->node); - - if(tempnode) { - array_init(return_value); - do { - - MAKE_STD_ZVAL(object); - INSTANCIATE_NODE(object, objtemp, tempnode); - add_next_index_zval(return_value, object); - - } while((tempnode = tidyGetNext(tempnode))); - } } /* }}} */ /* {{{ proto boolean tidy_node::has_children() Returns true if this node has children */ -PHP_NODE_METHOD(has_children) +TIDY_NODE_METHOD(has_children) { - GET_THIS_CONTAINER(); + zval *object = getThis(); + PHPTidyObj *obj; + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); if(tidyGetChild(obj->node)) { RETURN_TRUE; @@ -1173,9 +1785,16 @@ PHP_NODE_METHOD(has_children) /* {{{ proto boolean tidy_node::has_siblings() Returns true if this node has siblings */ -PHP_NODE_METHOD(has_siblings) +TIDY_NODE_METHOD(has_siblings) { - GET_THIS_CONTAINER(); + zval *object = getThis(); + PHPTidyObj *obj; + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); if(tidyGetNext(obj->node)) { RETURN_TRUE; @@ -1188,9 +1807,17 @@ PHP_NODE_METHOD(has_siblings) /* {{{ proto boolean tidy_node::is_comment() Returns true if this node represents a comment */ -PHP_NODE_METHOD(is_comment) +TIDY_NODE_METHOD(is_comment) { - GET_THIS_CONTAINER(); + zval *object = getThis(); + PHPTidyObj *obj; + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + if(tidyNodeGetType(obj->node) == TidyNode_Comment) { RETURN_TRUE; } else { @@ -1202,13 +1829,21 @@ PHP_NODE_METHOD(is_comment) /* {{{ proto boolean tidy_node::is_html() Returns true if this node is part of a HTML document */ -PHP_NODE_METHOD(is_html) +TIDY_NODE_METHOD(is_html) { - GET_THIS_CONTAINER(); + zval *object = getThis(); + PHPTidyObj *obj; + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); if(tidyNodeGetType(obj->node) & (TidyNode_Start | TidyNode_End | TidyNode_StartEnd)) { RETURN_TRUE; } + RETURN_FALSE; } @@ -1216,10 +1851,18 @@ PHP_NODE_METHOD(is_html) /* {{{ proto boolean tidy_node::is_xhtml() Returns true if this node is part of a XHTML document */ -PHP_NODE_METHOD(is_xhtml) +TIDY_NODE_METHOD(is_xhtml) { - GET_THIS_CONTAINER(); - if(tidyDetectedXhtml(TG(tdoc)->doc)) { + zval *object = getThis(); + PHPTidyObj *obj; + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + if(tidyDetectedXhtml(obj->ptdoc->doc)) { RETURN_TRUE; } else { RETURN_FALSE; @@ -1229,10 +1872,18 @@ PHP_NODE_METHOD(is_xhtml) /* {{{ proto boolean tidy_node::is_xml() Returns true if this node is part of a XML document */ -PHP_NODE_METHOD(is_xml) +TIDY_NODE_METHOD(is_xml) { - GET_THIS_CONTAINER(); - if(tidyDetectedGenericXml(TG(tdoc)->doc)) { + zval *object = getThis(); + PHPTidyObj *obj; + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + + if(tidyDetectedGenericXml(obj->ptdoc->doc)) { RETURN_TRUE; } else { RETURN_FALSE; @@ -1242,9 +1893,17 @@ PHP_NODE_METHOD(is_xml) /* {{{ proto boolean tidy_node::is_text() Returns true if this node represents text (no markup) */ -PHP_NODE_METHOD(is_text) +TIDY_NODE_METHOD(is_text) { - GET_THIS_CONTAINER(); + zval *object = getThis(); + PHPTidyObj *obj; + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + if(tidyNodeGetType(obj->node) == TidyNode_Text) { RETURN_TRUE; } else { @@ -1256,9 +1915,17 @@ PHP_NODE_METHOD(is_text) /* {{{ proto boolean tidy_node::is_jste() Returns true if this node is JSTE */ -PHP_NODE_METHOD(is_jste) +TIDY_NODE_METHOD(is_jste) { - GET_THIS_CONTAINER(); + zval *object = getThis(); + PHPTidyObj *obj; + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + if(tidyNodeGetType(obj->node) == TidyNode_Jste) { RETURN_TRUE; } else { @@ -1269,9 +1936,17 @@ PHP_NODE_METHOD(is_jste) /* {{{ proto boolean tidy_node::is_asp() Returns true if this node is ASP */ -PHP_NODE_METHOD(is_asp) +TIDY_NODE_METHOD(is_asp) { - GET_THIS_CONTAINER(); + zval *object = getThis(); + PHPTidyObj *obj; + + if(ZEND_NUM_ARGS()) { + WRONG_PARAM_COUNT; + } + + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); + if(tidyNodeGetType(obj->node) == TidyNode_Asp) { RETURN_TRUE; } else { @@ -1282,107 +1957,25 @@ PHP_NODE_METHOD(is_asp) /* {{{ proto boolean tidy_node::is_jsp() Returns true if this node is JSP */ -PHP_NODE_METHOD(is_php) -{ - GET_THIS_CONTAINER(); - if(tidyNodeGetType(obj->node) == TidyNode_Php) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } -} -/* }}} */ - -/* {{{ proto tidy_node tidy_node::next() - Returns the next sibling to this node */ -PHP_NODE_METHOD(next) +TIDY_NODE_METHOD(is_php) { - PHPTidyObj *obj; - - if(ZEND_NUM_ARGS()) { - WRONG_PARAM_COUNT; - } + zval *object = getThis(); + PHPTidyObj *obj; - TIDY_PARSED_CHECK(); - - tidy_instanciate(tidy_ce_node, return_value TSRMLS_CC); - obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC); - obj->node = tidyGetNext(obj->node); - obj->attr = NULL; - obj->type = is_node; - - tidy_add_default_properities(obj, is_node TSRMLS_CC); -} -/* }}} */ - -/* {{{ proto tidy_node tidy_node::prev() - Returns the previous sibiling to this node */ -PHP_NODE_METHOD(prev) -{ - PHPTidyObj *obj; - if(ZEND_NUM_ARGS()) { WRONG_PARAM_COUNT; } - - TIDY_PARSED_CHECK(); - - tidy_instanciate(tidy_ce_node, return_value TSRMLS_CC); - obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC); - obj->node = tidyGetPrev(obj->node); - obj->attr = NULL; - obj->type = is_node; - - tidy_add_default_properities(obj, is_node TSRMLS_CC); -} -/* }}} */ - -/* {{{ proto tidy_attr tidy_node::get_attr(int attrib_id) - Return the attribute with the provided attribute id */ -PHP_NODE_METHOD(get_attr) -{ - TidyAttr tempattr; - long param; - GET_THIS_CONTAINER(); - - if(ZEND_NUM_ARGS() != 1) { - WRONG_PARAM_COUNT; - } - - TIDY_PARSED_CHECK(); - - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", ¶m) == FAILURE) { - RETURN_FALSE; - } - - for(tempattr = tidyAttrFirst(obj->node); tempattr; tempattr = tidyAttrNext(tempattr)) { - if(tidyAttrGetId(tempattr) == param) { - - tidy_instanciate(tidy_ce_node, return_value TSRMLS_CC); - - obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC); - obj->node = NULL; - obj->attr = tempattr; - obj->type = is_attr; + obj = (PHPTidyObj *) zend_object_store_get_object(object TSRMLS_CC); - tidy_add_default_properities(obj, is_attr TSRMLS_CC); - } + if(tidyNodeGetType(obj->node) == TidyNode_Php) { + RETURN_TRUE; + } else { + RETURN_FALSE; } - -} -/* }}} */ - -/* {{{ proto tidy_node tidy_node::get_nodes(int node_id) - Return an array of nodes under this node with the specified id */ -PHP_NODE_METHOD(get_nodes) -{ - /* TODO */ } /* }}} */ -#endif /* ZEND_ENGINE_2 */ - void _php_tidy_register_nodetypes(INIT_FUNC_ARGS) { @@ -1688,3 +2281,4 @@ void _php_tidy_register_attributes(INIT_FUNC_ARGS) TIDY_ATTR_CONST(XMLNS); } + -- 2.40.0