chregu Fri Nov 28 17:08:17 2003 EDT
Added files:
/php-src/ext/xsl/tests xslt011.phpt xslt011.xml xslt011.xsl
Modified files:
/php-src/ext/xsl php_xsl.c php_xsl.h
Log:
@- Added possibility to call php functions as XSLT-functions (chregu)
- Added possibility to call php functions as XSLT-functions
eg: <xsl:value-of select="php:function('date','r')"/>
Namespace is http://php.net/functions
Index: php-src/ext/xsl/php_xsl.c
diff -u php-src/ext/xsl/php_xsl.c:1.9 php-src/ext/xsl/php_xsl.c:1.10
--- php-src/ext/xsl/php_xsl.c:1.9 Wed Nov 19 07:07:59 2003
+++ php-src/ext/xsl/php_xsl.c Fri Nov 28 17:08:13 2003
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_xsl.c,v 1.9 2003/11/19 12:07:59 chregu Exp $ */
+/* $Id: php_xsl.c,v 1.10 2003/11/28 22:08:13 chregu Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -27,6 +27,9 @@
#include "ext/standard/info.h"
#include "php_xsl.h"
+static void xsl_ext_function_string_php(xmlXPathParserContextPtr ctxt, int nargs);
+static void xsl_ext_function_object_php(xmlXPathParserContextPtr ctxt, int nargs);
+
/* If you declare any globals in php_xsl.h uncomment this:
ZEND_DECLARE_MODULE_GLOBALS(xsl)
*/
@@ -136,11 +139,150 @@
#if HAVE_XSL_EXSLT
exsltRegisterAll();
#endif
+ xsltRegisterExtModuleFunction ((const xmlChar *) "functionString",
+ (const xmlChar *) "http://php.net/xsl",
+ xsl_ext_function_string_php);
+ xsltRegisterExtModuleFunction ((const xmlChar *) "function",
+ (const xmlChar *) "http://php.net/xsl",
+ xsl_ext_function_object_php);
return SUCCESS;
}
/* }}} */
+
+static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type)
+{
+ xsltTransformContextPtr tctxt;
+ zval **args;
+ zval *retval;
+ int result, i, ret;
+ zend_fcall_info fci;
+ zval handler;
+ xmlXPathObjectPtr obj;
+ char *str;
+
+ TSRMLS_FETCH();
+
+ tctxt = xsltXPathGetTransformContext(ctxt);
+ if (tctxt == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtFunctionTest: failed to get the transformation context\n");
+ return;
+ }
+
+ args = safe_emalloc(sizeof(zval **), nargs - 1, 0);
+ for (i = 0; i < nargs - 1; i++) {
+ obj = valuePop(ctxt);
+ MAKE_STD_ZVAL(args[i]);
+ switch (obj->type) {
+ case XPATH_STRING:
+ ZVAL_STRING(args[i], obj->stringval, 1);
+ break;
+ case XPATH_BOOLEAN:
+ ZVAL_BOOL(args[i], obj->boolval);
+ break;
+ case XPATH_NUMBER:
+ ZVAL_DOUBLE(args[i], obj->floatval);
+ break;
+ case XPATH_NODESET:
+ if (type == 1) {
+ str = xmlXPathCastToString(obj);
+ ZVAL_STRING(args[i], str, 1);
+ xmlFree(str);
+ } else if (type == 2) {
+ int j;
+ dom_object *intern;
+ array_init(args[i]);
+ if (obj->nodesetval->nodeNr > 0) {
+ intern = (dom_object *)
php_dom_object_get_data((void *) obj->nodesetval->nodeTab[0]->doc);
+ for (j = 0; j <
obj->nodesetval->nodeNr; j++) {
+ xmlNodePtr node =
obj->nodesetval->nodeTab[j];
+ zval *child;
+
+ MAKE_STD_ZVAL(child);
+ /* not sure, if we need
this... it's copied from xpath.c */
+ if (node->type ==
XML_NAMESPACE_DECL) {
+ xmlNsPtr curns;
+ xmlNodePtr nsparent;
+
+ nsparent =
node->_private;
+ curns = xmlNewNs(NULL,
node->name, NULL);
+ if (node->children) {
+ curns->prefix
= xmlStrdup((char *) node->children);
+ }
+ if (node->children) {
+ node =
xmlNewDocNode(node->doc, NULL, (char *) node->children, node->name);
+ } else {
+ node =
xmlNewDocNode(node->doc, NULL, "xmlns", node->name);
+ }
+ node->type =
XML_NAMESPACE_DECL;
+ node->parent =
nsparent;
+ node->ns = curns;
+ }
+ child =
php_dom_create_object(node, &ret, NULL, child, intern TSRMLS_CC);
+ add_next_index_zval(args[i],
child);
+ }
+ }
+ }
+ break;
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "php:function
object type %d is not supported yet", obj->type);
+ ZVAL_STRING(args[i], "", 0);
+ }
+ xmlXPathFreeObject(obj);
+ }
+
+ fci.size = sizeof(fci);
+ fci.function_table = EG(function_table);
+
+ obj = valuePop(ctxt);
+ INIT_PZVAL(&handler);
+ ZVAL_STRING(&handler, obj->stringval, 1);
+ xmlXPathFreeObject(obj);
+
+ fci.function_name = &handler;
+ fci.symbol_table = NULL;
+ fci.object_pp = NULL;
+ fci.retval_ptr_ptr = &retval;
+ fci.param_count = nargs - 1;
+ fci.params = &args;
+ fci.no_separation = 0;
+ /*fci.function_handler_cache = &function_ptr;*/
+
+ result = zend_call_function(&fci, NULL TSRMLS_CC);
+ if (result == FAILURE) {
+ if (Z_TYPE(handler) == IS_STRING) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call
handler %s()", Z_STRVAL_P(&handler));
+ }
+ } else {
+ if (retval->type == IS_BOOL) {
+ valuePush(ctxt, xmlXPathNewBoolean(retval->value.lval));
+ } else {
+ convert_to_string_ex(&retval);
+ valuePush(ctxt, xmlXPathNewString( Z_STRVAL_P(retval)));
+ }
+ zval_ptr_dtor(&retval);
+ }
+ zval_dtor(&handler);
+ for (i = 0; i < nargs - 1; i++) {
+ zval_ptr_dtor(&args[i]);
+ }
+ efree(args);
+}
+
+static void
+xsl_ext_function_string_php(xmlXPathParserContextPtr ctxt, int nargs)
+{
+ xsl_ext_function_php(ctxt, nargs, 1);
+}
+
+static void
+xsl_ext_function_object_php(xmlXPathParserContextPtr ctxt, int nargs)
+{
+ xsl_ext_function_php(ctxt, nargs, 2);
+}
+
/* {{{ xsl_object_get_data */
zval *xsl_object_get_data(void *obj)
{
Index: php-src/ext/xsl/php_xsl.h
diff -u php-src/ext/xsl/php_xsl.h:1.5 php-src/ext/xsl/php_xsl.h:1.6
--- php-src/ext/xsl/php_xsl.h:1.5 Wed Nov 19 07:07:59 2003
+++ php-src/ext/xsl/php_xsl.h Fri Nov 28 17:08:13 2003
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_xsl.h,v 1.5 2003/11/19 12:07:59 chregu Exp $ */
+/* $Id: php_xsl.h,v 1.6 2003/11/28 22:08:13 chregu Exp $ */
#ifndef PHP_XSL_H
#define PHP_XSL_H
@@ -46,6 +46,9 @@
#include "../dom/xml_common.h"
#include "xsl_fe.h"
+#include <libxslt/extensions.h>
+#include <libxml/xpathInternals.h>
+
typedef struct _xsl_object {
zend_object std;
void *ptr;
Index: php-src/ext/xsl/tests/xslt011.phpt
+++ php-src/ext/xsl/tests/xslt011.phpt
--TEST--
Test 11: php:function Support
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
print "Test 11: php:function Support\n";
$dom = new domDocument();
$dom->load(dirname(__FILE__)."/xslt011.xsl");
$proc = new xsltprocessor;
$xsl = $proc->importStylesheet($dom);
$xml = new DomDocument();
$xml->load(dirname(__FILE__)."/xslt011.xml");
print $proc->transformToXml($xml);
function foobar($id ) {
if (is_array($id)) {
return $id[0]->value;
} else {
return $id;
}
}
--EXPECT--
Test 11: php:function Support
<?xml version="1.0"?>
foobar
foobar
Index: php-src/ext/xsl/tests/xslt011.xml
+++ php-src/ext/xsl/tests/xslt011.xml
<doc id="foobar"></doc>
Index: php-src/ext/xsl/tests/xslt011.xsl
+++ php-src/ext/xsl/tests/xslt011.xsl
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:php="http://php.net/xsl"
xsl:extension-element-prefixes="php"
version='1.0'>
<xsl:template match="/">
<xsl:value-of select="php:functionString('foobar', /doc/@id)"/>
<xsl:text>
</xsl:text>
<xsl:value-of select="php:function('foobar', /doc/@id)"/>
</xsl:template>
</xsl:stylesheet>
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php