@@ -61,28 +61,30 @@ static void dom_xpath_proxy_factory(xmlNodePtr node, zval *child, dom_object *in
61
61
php_dom_create_object (node , child , intern );
62
62
}
63
63
64
- static void dom_xpath_ext_function_php (xmlXPathParserContextPtr ctxt , int nargs , php_dom_xpath_nodeset_evaluation_mode evaluation_mode ) /* {{{ */
64
+ static dom_xpath_object * dom_xpath_ext_fetch_intern (xmlXPathParserContextPtr ctxt )
65
65
{
66
- bool error = false;
67
- dom_xpath_object * intern ;
68
-
69
- if (! zend_is_executing ()) {
66
+ if (!zend_is_executing ()) {
70
67
xmlGenericError (xmlGenericErrorContext ,
71
68
"xmlExtFunctionTest: Function called from outside of PHP\n" );
72
- error = true;
73
69
} else {
74
- intern = (dom_xpath_object * ) ctxt -> context -> userData ;
70
+ dom_xpath_object * intern = (dom_xpath_object * ) ctxt -> context -> userData ;
75
71
if (intern == NULL ) {
76
72
xmlGenericError (xmlGenericErrorContext ,
77
73
"xmlExtFunctionTest: failed to get the internal object\n" );
78
- error = true ;
74
+ return NULL ;
79
75
}
76
+ return intern ;
80
77
}
78
+ return NULL ;
79
+ }
81
80
82
- if (error ) {
81
+ static void dom_xpath_ext_function_php (xmlXPathParserContextPtr ctxt , int nargs , php_dom_xpath_nodeset_evaluation_mode evaluation_mode ) /* {{{ */
82
+ {
83
+ dom_xpath_object * intern = dom_xpath_ext_fetch_intern (ctxt );
84
+ if (!intern ) {
83
85
php_dom_xpath_callbacks_clean_argument_stack (ctxt , nargs );
84
86
} else {
85
- php_dom_xpath_callbacks_call (& intern -> xpath_callbacks , ctxt , nargs , evaluation_mode , & intern -> dom , dom_xpath_proxy_factory );
87
+ php_dom_xpath_callbacks_call_php_ns (& intern -> xpath_callbacks , ctxt , nargs , evaluation_mode , & intern -> dom , dom_xpath_proxy_factory );
86
88
}
87
89
}
88
90
/* }}} */
@@ -99,6 +101,16 @@ static void dom_xpath_ext_function_object_php(xmlXPathParserContextPtr ctxt, int
99
101
}
100
102
/* }}} */
101
103
104
+ static void dom_xpath_ext_function_trampoline (xmlXPathParserContextPtr ctxt , int nargs )
105
+ {
106
+ dom_xpath_object * intern = dom_xpath_ext_fetch_intern (ctxt );
107
+ if (!intern ) {
108
+ php_dom_xpath_callbacks_clean_argument_stack (ctxt , nargs );
109
+ } else {
110
+ php_dom_xpath_callbacks_call_custom_ns (& intern -> xpath_callbacks , ctxt , nargs , PHP_DOM_XPATH_EVALUATE_NODESET_TO_NODESET , & intern -> dom , dom_xpath_proxy_factory );
111
+ }
112
+ }
113
+
102
114
/* {{{ */
103
115
PHP_METHOD (DOMXPath , __construct )
104
116
{
@@ -378,18 +390,60 @@ PHP_METHOD(DOMXPath, registerPhpFunctions)
378
390
{
379
391
dom_xpath_object * intern = Z_XPATHOBJ_P (ZEND_THIS );
380
392
381
- zend_string * name = NULL ;
393
+ zend_string * callable_name = NULL ;
382
394
HashTable * callable_ht = NULL ;
383
395
384
396
ZEND_PARSE_PARAMETERS_START (0 , 1 )
385
397
Z_PARAM_OPTIONAL
386
- Z_PARAM_ARRAY_HT_OR_STR_OR_NULL (callable_ht , name )
398
+ Z_PARAM_ARRAY_HT_OR_STR_OR_NULL (callable_ht , callable_name )
387
399
ZEND_PARSE_PARAMETERS_END ();
388
400
389
- php_dom_xpath_callbacks_update_method_handler (& intern -> xpath_callbacks , NULL , name , callable_ht );
401
+ php_dom_xpath_callbacks_update_method_handler (
402
+ & intern -> xpath_callbacks ,
403
+ intern -> dom .ptr ,
404
+ NULL ,
405
+ callable_name ,
406
+ callable_ht ,
407
+ PHP_DOM_XPATH_CALLBACK_NAME_VALIDATE_NULLS ,
408
+ NULL
409
+ );
390
410
}
391
411
/* }}} end dom_xpath_register_php_functions */
392
412
413
+ static void dom_xpath_register_func_in_ctx (xmlXPathContextPtr ctxt , const zend_string * ns , const zend_string * name )
414
+ {
415
+ xmlXPathRegisterFuncNS (ctxt , (const xmlChar * ) ZSTR_VAL (name ), (const xmlChar * ) ZSTR_VAL (ns ), dom_xpath_ext_function_trampoline );
416
+ }
417
+
418
+ PHP_METHOD (DOMXPath , registerPhpFunctionsNS )
419
+ {
420
+ dom_xpath_object * intern = Z_XPATHOBJ_P (ZEND_THIS );
421
+
422
+ zend_string * namespace ;
423
+ zend_string * callable_name ;
424
+ HashTable * callable_ht ;
425
+
426
+ ZEND_PARSE_PARAMETERS_START (2 , 2 )
427
+ Z_PARAM_PATH_STR (namespace )
428
+ Z_PARAM_ARRAY_HT_OR_STR (callable_ht , callable_name )
429
+ ZEND_PARSE_PARAMETERS_END ();
430
+
431
+ if (zend_string_equals_literal (namespace , "http://php.net/xpath" )) { // TODO: this is different for XSL!!!
432
+ zend_argument_value_error (1 , "must not be \"http://php.net/xpath\" because it is reserved for PHP" );
433
+ RETURN_THROWS ();
434
+ }
435
+
436
+ php_dom_xpath_callbacks_update_method_handler (
437
+ & intern -> xpath_callbacks ,
438
+ intern -> dom .ptr ,
439
+ namespace ,
440
+ callable_name ,
441
+ callable_ht ,
442
+ PHP_DOM_XPATH_CALLBACK_NAME_VALIDATE_NCNAME ,
443
+ dom_xpath_register_func_in_ctx
444
+ );
445
+ }
446
+
393
447
#endif /* LIBXML_XPATH_ENABLED */
394
448
395
449
#endif
0 commit comments