Ticket #14671: 14671.4.diff
File 14671.4.diff, 7.5 KB (added by , 12 years ago) |
---|
-
wp-includes/plugin.php
59 59 * @param string $tag The name of the filter to hook the $function_to_add to. 60 60 * @param callback $function_to_add The name of the function to be called when the filter is applied. 61 61 * @param int $priority optional. Used to specify the order in which the functions associated with a particular action are executed (default: 10). Lower numbers correspond with earlier execution, and functions with the same priority are executed in the order in which they were added to the action. 62 * @param int $accepted_args optional. The number of arguments the function accept (default 1).62 * @param int $accepted_args optional. The number of arguments the function accept (default: number of required arguments introspected from $function_to_add via the PHP Reflection API). 63 63 * @return boolean true 64 64 */ 65 function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) {65 function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = null) { 66 66 global $wp_filter, $merged_filters; 67 67 68 68 $idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority); … … 167 167 $args = func_get_args(); 168 168 169 169 do { 170 foreach( (array) current($wp_filter[$tag]) as $the_ ) 170 foreach( (array) current($wp_filter[$tag]) as $the_ ) { 171 171 if ( !is_null($the_['function']) ){ 172 $accepted_args = _wp_get_hook_handler_accepted_arg_count($the_['function'], $the_['accepted_args']); 172 173 $args[1] = $value; 173 $value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));174 $value = call_user_func_array($the_['function'], array_slice($args, 1, $accepted_args)); 174 175 } 176 } 175 177 176 178 } while ( next($wp_filter[$tag]) !== false ); 177 179 … … 226 228 227 229 do { 228 230 foreach( (array) current($wp_filter[$tag]) as $the_ ) 229 if ( !is_null($the_['function']) ) 230 $args[0] = call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args'])); 231 if ( !is_null($the_['function']) ) { 232 $accepted_args = _wp_get_hook_handler_accepted_arg_count($the_['function'], $the_['accepted_args']); 233 $args[0] = call_user_func_array($the_['function'], array_slice($args, 0, $accepted_args)); 234 } 231 235 232 236 } while ( next($wp_filter[$tag]) !== false ); 233 237 … … 254 258 * @param string $tag The filter hook to which the function to be removed is hooked. 255 259 * @param callback $function_to_remove The name of the function which should be removed. 256 260 * @param int $priority optional. The priority of the function (default: 10). 257 * @param int $accepted_args optional. The number of arguments the function accepts (default: 1).258 261 * @return boolean Whether the function existed before it was removed. 259 262 */ 260 263 function remove_filter( $tag, $function_to_remove, $priority = 10 ) { … … 328 331 * @param string $tag The name of the action to which the $function_to_add is hooked. 329 332 * @param callback $function_to_add The name of the function you wish to be called. 330 333 * @param int $priority optional. Used to specify the order in which the functions associated with a particular action are executed (default: 10). Lower numbers correspond with earlier execution, and functions with the same priority are executed in the order in which they were added to the action. 331 * @param int $accepted_args optional. The number of arguments the function accept (default 1).334 * @param int $accepted_args Optional. The number of arguments the function accept (default: number of required arguments introspected from $function_to_add via the PHP Reflection API). 332 335 */ 333 function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) {336 function add_action($tag, $function_to_add, $priority = 10, $accepted_args = null) { 334 337 return add_filter($tag, $function_to_add, $priority, $accepted_args); 335 338 } 336 339 … … 402 405 403 406 do { 404 407 foreach ( (array) current($wp_filter[$tag]) as $the_ ) 405 if ( !is_null($the_['function']) ) 406 call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args'])); 408 if ( !is_null($the_['function']) ){ 409 $accepted_args = _wp_get_hook_handler_accepted_arg_count($the_['function'], $the_['accepted_args']); 410 call_user_func_array($the_['function'], array_slice($args, 0, $accepted_args)); 411 } 407 412 408 413 } while ( next($wp_filter[$tag]) !== false ); 409 414 … … 483 488 484 489 do { 485 490 foreach( (array) current($wp_filter[$tag]) as $the_ ) 486 if ( !is_null($the_['function']) ) 487 call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args'])); 491 if ( !is_null($the_['function']) ) { 492 $accepted_args = _wp_get_hook_handler_accepted_arg_count($the_['function'], $the_['accepted_args']); 493 call_user_func_array($the_['function'], array_slice($args, 0, $accepted_args)); 494 } 488 495 489 496 } while ( next($wp_filter[$tag]) !== false ); 490 497 … … 787 794 return $function[0].$function[1]; 788 795 } 789 796 } 797 798 /** 799 * Obtain the argument count for a hook callback (function/method/closure) via Reflection 800 * 801 * It used to be that if hook (filter/action) is called with more than one 802 * argument, you would have to supply a 4th argument to 803 * add_action()/add_filter() in order for those extra arguments to be passed 804 * into the function. This is painful because it usually violates DRY 805 * principles since the number of arguments that a function takes is already 806 * defined when the function was defined and so it should already be known. It 807 * is also painful to have to pass in the number of arguments because 808 * add_action() and add_filter() take positional arguments and so you always 809 * have to define the 3rd argument ($priority) in order to be able to specify 810 * the 4th ($accepted_args). PHP now has an always-included Reflection 811 * extension that allows it to introspect to programmatically determine the 812 * number of arguments that a function or method takes. In older versions of 813 * WordPress when support for PHP 4 was required, WordPress was not able to 814 * take advantage of Reflection because it was first introduced in PHP 5. But 815 * now that PHP 5.2 is required, we can take advantage of Reflection and 816 * simplify the calls to add_action() and add_filter(). 817 * 818 * This function is a helper that is re-used in do_action(), apply_filters(), 819 * and do_action_ref_array(). If the accepted_args has been supplied when 820 * add_action()/add_filter() was called (and it is not the default of null) 821 * then it will return that instead of trying to introspect for the number of 822 * args. 823 * 824 * @package WordPress 825 * @subpackage Plugin 826 * @access private 827 * @since 3.6 828 * @link http://core.trac.wordpress.org/ticket/14671 829 * @link http://php.net/manual/en/book.reflection.php 830 * 831 * @param callable $function The filter/action handler supplied when calling add_action()/add_filter() 832 * @param int $accepted_args The 4th argument passed into add_action()/add_filter() 833 * @return int The number of arguments to pass into hook handler 834 */ 835 function _wp_get_hook_handler_accepted_arg_count($function, $accepted_args) { 836 // Note is_callable() is better for methods than method_exists() because it will work with __call magic methods 837 if ( is_null($accepted_args) && is_callable($function) ) { 838 if ( is_array($function) ) { 839 list( $object, $method ) = $function; 840 $reflection = new ReflectionMethod( $object, $method ); 841 } else { 842 $reflection = new ReflectionFunction( $function ); 843 } 844 $accepted_args = $reflection->getNumberOfParameters(); 845 } 846 return (int) $accepted_args; 847 }