@@ -65,32 +65,34 @@ static void xsl_proxy_factory(xmlNodePtr node, zval *child, dom_object *intern,
6565 php_dom_create_object (node , child , intern );
6666}
6767
68- static void xsl_ext_function_php (xmlXPathParserContextPtr ctxt , int nargs , php_dom_xpath_nodeset_evaluation_mode evaluation_mode ) /* {{{ */
68+ static xsl_object * xsl_ext_fetch_intern (xmlXPathParserContextPtr ctxt )
6969{
70- bool error = false;
71- xsl_object * intern ;
72-
73- if (! zend_is_executing ()) {
70+ if (!zend_is_executing ()) {
7471 xsltGenericError (xsltGenericErrorContext ,
7572 "xsltExtFunctionTest: Function called from outside of PHP\n" );
76- error = true;
7773 } else {
7874 xsltTransformContextPtr tctxt = xsltXPathGetTransformContext (ctxt );
7975 if (tctxt == NULL ) {
8076 xsltGenericError (xsltGenericErrorContext ,
8177 "xsltExtFunctionTest: failed to get the transformation context\n" );
82- error = true;
8378 } else {
84- intern = (xsl_object * ) tctxt -> _private ;
79+ xsl_object * intern = (xsl_object * ) tctxt -> _private ;
8580 if (intern == NULL ) {
8681 xsltGenericError (xsltGenericErrorContext ,
8782 "xsltExtFunctionTest: failed to get the internal object\n" );
88- error = true ;
83+ return NULL ;
8984 }
85+ return intern ;
9086 }
9187 }
9288
93- if (error ) {
89+ return NULL ;
90+ }
91+
92+ static void xsl_ext_function_php (xmlXPathParserContextPtr ctxt , int nargs , php_dom_xpath_nodeset_evaluation_mode evaluation_mode ) /* {{{ */
93+ {
94+ xsl_object * intern = xsl_ext_fetch_intern (ctxt );
95+ if (!intern ) {
9496 php_dom_xpath_callbacks_clean_argument_stack (ctxt , nargs );
9597 } else {
9698 php_dom_xpath_callbacks_call_php_ns (& intern -> xpath_callbacks , ctxt , nargs , evaluation_mode , (dom_object * ) intern -> doc , xsl_proxy_factory );
@@ -110,6 +112,16 @@ void xsl_ext_function_object_php(xmlXPathParserContextPtr ctxt, int nargs) /* {{
110112}
111113/* }}} */
112114
115+ static void xsl_ext_function_trampoline (xmlXPathParserContextPtr ctxt , int nargs )
116+ {
117+ xsl_object * intern = xsl_ext_fetch_intern (ctxt );
118+ if (!intern ) {
119+ php_dom_xpath_callbacks_clean_argument_stack (ctxt , nargs );
120+ } else {
121+ php_dom_xpath_callbacks_call_custom_ns (& intern -> xpath_callbacks , ctxt , nargs , PHP_DOM_XPATH_EVALUATE_NODESET_TO_NODESET , (dom_object * ) intern -> doc , xsl_proxy_factory );
122+ }
123+ }
124+
113125/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#
114126Since:
115127*/
@@ -193,6 +205,12 @@ PHP_METHOD(XSLTProcessor, importStylesheet)
193205}
194206/* }}} end XSLTProcessor::importStylesheet */
195207
208+ static void php_xsl_delayed_lib_registration (void * ctxt , const zend_string * ns , const zend_string * name )
209+ {
210+ xsltTransformContextPtr xsl = (xsltTransformContextPtr ) ctxt ;
211+ xsltRegisterExtFunction (xsl , (const xmlChar * ) ZSTR_VAL (name ), (const xmlChar * ) ZSTR_VAL (ns ), xsl_ext_function_trampoline );
212+ }
213+
196214static xmlDocPtr php_xsl_apply_stylesheet (zval * id , xsl_object * intern , xsltStylesheetPtr style , zval * docp ) /* {{{ */
197215{
198216 xmlDocPtr newdocp = NULL ;
@@ -299,6 +317,8 @@ static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStyl
299317 }
300318 }
301319
320+ php_dom_xpath_callbacks_delayed_lib_registration (& intern -> xpath_callbacks , ctxt , php_xsl_delayed_lib_registration );
321+
302322 if (secPrefsError == 1 ) {
303323 php_error_docref (NULL , E_WARNING , "Can't set libxslt security properties, not doing transformation for security reasons" );
304324 } else {
@@ -592,6 +612,35 @@ PHP_METHOD(XSLTProcessor, registerPHPFunctions)
592612}
593613/* }}} end XSLTProcessor::registerPHPFunctions(); */
594614
615+ PHP_METHOD (XSLTProcessor , registerPHPFunctionsNS )
616+ {
617+ xsl_object * intern = Z_XSL_P (ZEND_THIS );
618+
619+ zend_string * namespace ;
620+ zend_string * callable_name ;
621+ HashTable * callable_ht ;
622+
623+ ZEND_PARSE_PARAMETERS_START (2 , 2 )
624+ Z_PARAM_PATH_STR (namespace )
625+ Z_PARAM_ARRAY_HT_OR_STR (callable_ht , callable_name )
626+ ZEND_PARSE_PARAMETERS_END ();
627+
628+ if (zend_string_equals_literal (namespace , "http://php.net/xsl" )) {
629+ zend_argument_value_error (1 , "must not be \"http://php.net/xsl\" because it is reserved for PHP" );
630+ RETURN_THROWS ();
631+ }
632+
633+ php_dom_xpath_callbacks_update_method_handler (
634+ & intern -> xpath_callbacks ,
635+ NULL ,
636+ namespace ,
637+ callable_name ,
638+ callable_ht ,
639+ PHP_DOM_XPATH_CALLBACK_NAME_VALIDATE_NCNAME ,
640+ NULL
641+ );
642+ }
643+
595644/* {{{ */
596645PHP_METHOD (XSLTProcessor , setProfiling )
597646{
0 commit comments