]> granicus.if.org Git - php/commitdiff
Added XsltStylesheet class with methods:
authorJaroslaw Kolakowski <jarkol@php.net>
Thu, 17 Jan 2002 01:13:39 +0000 (01:13 +0000)
committerJaroslaw Kolakowski <jarkol@php.net>
Thu, 17 Jan 2002 01:13:39 +0000 (01:13 +0000)
- domxml_xslt_stylesheet(string),
- domxml_xslt_stylesheet_doc(DomDocument),
- domxml_xslt_stylesheet_file(filename),
- process(DomDocument,parameters array) - previously domxml_xslt_process().

ext/domxml/php_domxml.c
ext/domxml/php_domxml.h

index 09c6a680521ddb245061b6dd2ddc09e736a48a29..08340312e88032b18b7086501820dfbbbfa46f8f 100644 (file)
@@ -120,6 +120,9 @@ static int le_domxmlnotationp;
 /*static int le_domxmlentityp;*/
 static int le_domxmlentityrefp;
 /*static int le_domxmlnsp;*/
+#if HAVE_DOMXSLT
+static int le_domxsltstylesheetp;
+#endif
 
 #if defined(LIBXML_XPATH_ENABLED)
 static int le_xpathctxp;
@@ -144,6 +147,9 @@ zend_class_entry *domxmlns_class_entry;
 zend_class_entry *xpathctx_class_entry;
 zend_class_entry *xpathobject_class_entry;
 #endif
+#if HAVE_DOMXSLT
+zend_class_entry *domxsltstylesheet_class_entry;
+#endif
 
 
 static int node_attributes(zval **attributes, xmlNode *nodep TSRMLS_DC);
@@ -185,6 +191,9 @@ static zend_function_entry domxml_functions[] = {
 #endif
 #if HAVE_DOMXSLT
        PHP_FE(domxml_xslt_version,                                                                                     NULL)
+       PHP_FE(domxml_xslt_stylesheet,                                                                                  NULL)
+       PHP_FE(domxml_xslt_stylesheet_doc,                                                                                      NULL)
+       PHP_FE(domxml_xslt_stylesheet_file,                                                                                     NULL)
        PHP_FE(domxml_xslt_process,                                                                                                     NULL)
 #endif
 
@@ -360,6 +369,14 @@ static zend_function_entry php_domxmlns_class_functions[] = {
        {NULL, NULL, NULL}
 };
 
+#if HAVE_DOMXSLT
+static zend_function_entry php_domxsltstylesheet_class_functions[] = {
+/* TODO */
+       PHP_FALIAS(process,                             domxml_xslt_process,                    NULL)
+       {NULL, NULL, NULL}
+};
+#endif
+
 zend_module_entry domxml_module_entry = {
     STANDARD_MODULE_HEADER,
        "domxml",
@@ -500,6 +517,92 @@ static void php_free_xpath_object(zend_rsrc_list_entry *rsrc TSRMLS_DC)
 #endif
 
 
+#if HAVE_DOMXSLT
+static void php_free_xslt_stylesheet(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+{
+       xsltStylesheetPtr sheet = (xsltStylesheetPtr) rsrc->ptr;
+
+       if (sheet) {
+               node_wrapper_dtor((xmlNodePtr) sheet);
+               xsltFreeStylesheet(sheet);
+       }
+}
+
+static void xsltstylesheet_set_data(void *obj, zval *wrapper)
+{
+/*
+       char tmp[20];
+       sprintf(tmp, "%08X", obj);
+       fprintf(stderr, "Adding %s to hash\n", tmp);
+*/
+       ((xsltStylesheetPtr) obj)->_private = wrapper;
+}
+
+
+static zval *xsltstylesheet_get_data(void *obj)
+{
+/*  
+       char tmp[20];
+       sprintf(tmp, "%08X", obj);
+       fprintf(stderr, "Trying getting %s from object ...", tmp);
+       if(((xmlNodePtr) obj)->_private)
+               fprintf(stderr, " found\n");
+       else
+               fprintf(stderr, " not found\n"); 
+*/
+       return ((zval *) (((xsltStylesheetPtr) obj)->_private));
+}
+
+void *php_xsltstylesheet_get_object(zval *wrapper, int rsrc_type1, int rsrc_type2 TSRMLS_DC)
+{
+       void *obj;
+       zval **handle;
+       int type;
+
+       if (NULL == wrapper) {
+               php_error(E_WARNING, "xsltstylesheet_get_object() invalid wrapper object passed");
+               return NULL;
+       }
+
+       if (Z_TYPE_P(wrapper) != IS_OBJECT) {
+               php_error(E_WARNING, "%s(): wrapper is not an object", get_active_function_name(TSRMLS_C));
+               return NULL;
+       }
+
+       if (zend_hash_index_find(Z_OBJPROP_P(wrapper), 0, (void **) &handle) == FAILURE) {
+               php_error(E_WARNING, "%s(): underlying object missing", get_active_function_name(TSRMLS_C));
+               return NULL;
+       }
+
+       obj = zend_list_find(Z_LVAL_PP(handle), &type);
+       if (!obj || ((type != rsrc_type1) && (type != rsrc_type2))) {
+               php_error(E_WARNING, "%s(): underlying object missing or of invalid type", get_active_function_name(TSRMLS_C));
+               return NULL;
+       }
+
+       return obj;
+}
+
+static void php_xsltstylesheet_set_object(zval *wrapper, void *obj, int rsrc_type)
+{
+       zval *handle, *addr;
+
+       MAKE_STD_ZVAL(handle);
+       Z_TYPE_P(handle) = IS_LONG;
+       Z_LVAL_P(handle) = zend_list_insert(obj, rsrc_type);
+
+       MAKE_STD_ZVAL(addr);
+       Z_TYPE_P(addr) = IS_LONG;
+       Z_LVAL_P(addr) = (int) obj;
+
+       zend_hash_index_update(Z_OBJPROP_P(wrapper), 0, &handle, sizeof(zval *), NULL);
+       zend_hash_index_update(Z_OBJPROP_P(wrapper), 1, &addr, sizeof(zval *), NULL);
+       zval_add_ref(&wrapper);
+       xsltstylesheet_set_data(obj, wrapper);
+}
+#endif  /* HAVE_DOMXSLT */
+
+
 void *php_xpath_get_object(zval *wrapper, int rsrc_type1, int rsrc_type2 TSRMLS_DC)
 {
        void *obj;
@@ -987,6 +1090,10 @@ PHP_MINIT_FUNCTION(domxml)
 
 /*     le_domxmlnsp = register_list_destructors(NULL, NULL); */
 
+#if HAVE_DOMXSLT
+       le_domxsltstylesheetp = zend_register_list_destructors_ex(php_free_xslt_stylesheet, NULL, "xsltstylesheet", module_number);
+#endif
+
        INIT_OVERLOADED_CLASS_ENTRY(ce, "DomNode", php_domxmlnode_class_functions, NULL, NULL, NULL);
        domxmlnode_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
 
@@ -1037,6 +1144,11 @@ PHP_MINIT_FUNCTION(domxml)
        xpathobject_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
 #endif
 
+#if HAVE_DOMXSLT
+       INIT_OVERLOADED_CLASS_ENTRY(ce, "XsltStylesheet", php_domxsltstylesheet_class_functions, NULL, NULL, NULL);
+       domxsltstylesheet_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+#endif
+
        REGISTER_LONG_CONSTANT("XML_ELEMENT_NODE",                      XML_ELEMENT_NODE,                       CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_NODE",            XML_ATTRIBUTE_NODE,                     CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("XML_TEXT_NODE",                         XML_TEXT_NODE,                          CONST_CS | CONST_PERSISTENT);
@@ -2528,7 +2640,7 @@ PHP_FUNCTION(domxml_html_dump_mem)
 }
 /* }}} */
 
-/* {{{ proto object html_doc(string html_doc)
+/* {{{ proto object html_doc(string html_doc [, bool from_file])
    Creates DOM object of HTML document */
 PHP_FUNCTION(html_doc)
 {
@@ -3081,10 +3193,44 @@ PHP_FUNCTION(domxml_version)
 /* }}} */
 
 #if HAVE_DOMXSLT
+static zval *php_xsltstylesheet_new(xsltStylesheetPtr obj, int *found TSRMLS_DC)
+{
+       zval *wrapper;
+       int rsrc_type;
+
+       if (! found) {
+           *found = 0;
+       }
+
+       if (!obj) {
+               MAKE_STD_ZVAL(wrapper);
+               ZVAL_NULL(wrapper);
+               return wrapper;
+       }
+
+       if ((wrapper = (zval *) dom_object_get_data((void *) obj))) {
+               zval_add_ref(&wrapper);
+               *found = 1;
+               return wrapper;
+       }
+
+       MAKE_STD_ZVAL(wrapper);
+
+       object_init_ex(wrapper, domxsltstylesheet_class_entry);
+       rsrc_type = le_domxsltstylesheetp;
+       php_xsltstylesheet_set_object(wrapper, (void *) obj, rsrc_type);
+
+       return (wrapper);
+}
+
 /* {{{ _php_libxslt_ht_char()
    Translates a PHP array to a libxslt character array */
 static void _php_libxslt_ht_char(HashTable *php, char **arr)
 {
+/* TODO: 
+    - make parameters array('key'=>'string',...) instead of array('key'=>'XPathExpression')
+    - change error reporting
+*/
     zval **value;
     char *string_key = NULL;
     ulong num_key;
@@ -3109,67 +3255,148 @@ static void _php_libxslt_ht_char(HashTable *php, char **arr)
     arr[i++] = NULL;
 }
 
+/* {{{ proto object domxml_xslt_stylesheet(string xsltstylesheet)
+   Creates XSLT Stylesheet object from string */
+PHP_FUNCTION(domxml_xslt_stylesheet)
+{
+       zval *rv;
+       xmlDocPtr docp;
+       xsltStylesheetPtr sheetp;
+       int ret;
+       char *buffer;
+       int buffer_len;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buffer, &buffer_len) == FAILURE) {
+               RETURN_FALSE;
+       }
+
+       docp = xmlParseDoc(buffer);
+
+       if (!docp)
+               RETURN_FALSE;
+
+       sheetp = xsltParseStylesheetDoc(docp);
+
+       if (!sheetp)
+               RETURN_FALSE;
+
+       rv = php_xsltstylesheet_new(sheetp, &ret TSRMLS_CC);
+       DOMXML_RET_ZVAL(rv);
+}
+/* }}} */
+
+/* {{{ proto object domxml_xslt_stylesheet_doc(object xmldoc)
+   Creates XSLT Stylesheet object from DOM Document object */
+PHP_FUNCTION(domxml_xslt_stylesheet_doc)
+{
+       zval *rv, *idxml;
+       xmlDocPtr docp;
+       xmlDocPtr newdocp;
+       xsltStylesheetPtr sheetp;
+       int ret;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &idxml) == FAILURE) {
+               RETURN_FALSE;
+       }
+
+       DOMXML_GET_OBJ(docp, idxml, le_domxmldocp);
+
+       newdocp = xmlCopyDoc(docp, 1);
+
+       if (!newdocp)
+               RETURN_FALSE;
+
+       sheetp = xsltParseStylesheetDoc(newdocp);
+
+       if (!sheetp)
+               RETURN_FALSE;
+
+       rv = php_xsltstylesheet_new(sheetp, &ret TSRMLS_CC);
+       DOMXML_RET_ZVAL(rv);
+}
+/* }}} */
+
+/* {{{ proto object domxml_xslt_stylesheet_file(string filename)
+   Creates XSLT Stylesheet object from file */
+PHP_FUNCTION(domxml_xslt_stylesheet_file)
+{
+       zval *rv;
+       xsltStylesheetPtr sheetp;
+       int ret, file_len;
+       char *file;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &file_len) == FAILURE) {
+               RETURN_FALSE;
+       }
+
+       sheetp = xsltParseStylesheetFile(file);
+
+       if (!sheetp)
+               RETURN_FALSE;
+
+       rv = php_xsltstylesheet_new(sheetp, &ret TSRMLS_CC);
+       DOMXML_RET_ZVAL(rv);
+}
+/* }}} */
+
 
-/* {{{ proto object domxml_xslt_process(int xsldoc_handle, int xmldoc_handle, [array xslt_parameters])
+/* {{{ proto object domxml_xslt_process(object xslstylesheet, object xmldoc, [array xslt_parameters])
    Perform an XSLT transformation */
 PHP_FUNCTION(domxml_xslt_process)
 {
 /* TODO:
-    - add functions for dealing with xsltStylesheet objects
-    - split this function: domxml_xslt_process will receive:
-       - a handle to the xsltStylesheet object
-        - a handle to the xmlDoc object
-       - an optional array of parameters
-    - memory deallocation
+    - make & test memory deallocation
+    - test other stuff
+    - move HashTable operations outside the function
+    - check xsltsp->errors ???
 */
        zval *rv, *idxsl, *idxml, *idvars = NULL;
-       xmlDocPtr xsldocp, xmldocp, docp;
-       char **params = NULL;
        xsltStylesheetPtr xsltstp;
+       xmlDocPtr xmldocp;
+       xmlDocPtr docp;
+       char **params = NULL;
        int ret, parsize;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oo|a", &idxsl, &idxml, &idvars) == FAILURE) {
-               return;
-       }
 
-       DOMXML_GET_OBJ(xsldocp, idxsl, le_domxmldocp);
-       DOMXML_GET_OBJ(xmldocp, idxml, le_domxmldocp);
+       DOMXML_GET_THIS(idxsl);
 
-       xsltstp = xsltParseStylesheetDoc(xsldocp);
+       xsltstp = php_xsltstylesheet_get_object(idxsl, le_domxsltstylesheetp, 0 TSRMLS_CC);
        if (!xsltstp) {
-               RETURN_FALSE;
+               php_error(E_WARNING, "%s(): cannot fetch XSLT Stylesheet", get_active_function_name(TSRMLS_C));
+               RETURN_FALSE;
        }
-       if (xsltstp->errors) {
-/*             xsltFreeStylesheet(xsltstp);*/
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|a", &idxml, &idvars) == FAILURE) {
                RETURN_FALSE;
        }
 
-       if (idvars)
-       {
-           HashTable *parht = HASH_OF(idvars);
-           parsize = (2 * zend_hash_num_elements(parht) + 1) * sizeof(char *);
-            params = (char **)emalloc(parsize);
-            memset((char *)params, 0, parsize);
-            _php_libxslt_ht_char(parht, params);
+       DOMXML_GET_OBJ(xmldocp, idxml, le_domxmldocp);
+
+       if (idvars) {
+               HashTable *parht = HASH_OF(idvars);
+               parsize = (2 * zend_hash_num_elements(parht) + 1) * sizeof(char *);
+               params = (char **)emalloc(parsize);
+               memset((char *)params, 0, parsize);
+               _php_libxslt_ht_char(parht, params);
        }
 
        docp = xsltApplyStylesheet(xsltstp, xmldocp, (const char**)params);
 
-/*     xsltFreeStylesheet(xsltstp);
-       efree(params);*/
+/* ???: */
+       efree(params);
        
        if (!docp) {
                RETURN_FALSE;
        }
 
        DOMXML_RET_OBJ(rv, (xmlNodePtr) docp, &ret);
-
+/* ???: */
+/*
        add_property_resource(return_value, "doc", ret);
        if(docp->name)
                add_property_stringl(return_value, "name", (char *) docp->name, strlen(docp->name), 1);
        if(docp->URL)
                add_property_stringl(return_value, "url", (char *) docp->name, strlen(docp->name), 1);
-/*     add_property_stringl(return_value, "version", (char *) docp->version, strlen(docp->version), 1);*/
        if(docp->version)
            add_property_stringl(return_value, "version", (char *) docp->version, strlen(docp->version), 1);
        if(docp->encoding)
@@ -3179,6 +3406,7 @@ PHP_FUNCTION(domxml_xslt_process)
        add_property_long(return_value, "compression", docp->compression);
        add_property_long(return_value, "charset", docp->charset);
        zend_list_addref(ret);
+*/
 }
 /* }}} */
 
index 4028188171a3a8ee52fb2652c5b04f14a2f02287..3d31e6adebddbfcf82ee3234ca0697e688654656 100644 (file)
@@ -166,8 +166,11 @@ PHP_FUNCTION(domxml_test);
 
 /* DOMXSLT functions */
 #if HAVE_DOMXSLT
-PHP_FUNCTION(domxml_xslt_version);
+PHP_FUNCTION(domxml_xslt_stylesheet);
+PHP_FUNCTION(domxml_xslt_stylesheet_doc);
+PHP_FUNCTION(domxml_xslt_stylesheet_file);
 PHP_FUNCTION(domxml_xslt_process);
+PHP_FUNCTION(domxml_xslt_version);
 #endif
 
 #else