diff --git a/src/wp-includes/class-wp-hook.php b/src/wp-includes/class-wp-hook.php index 3675070106236..5a5874e39cabb 100644 --- a/src/wp-includes/class-wp-hook.php +++ b/src/wp-includes/class-wp-hook.php @@ -201,6 +201,7 @@ private function resort_active_iterations( $new_priority = false, $priority_exis * a callback that may or may not exist. * @param int $priority The exact priority used when adding the original filter callback. * @return bool Whether the callback existed before it was removed. + * @phpstan-param Maybe_Callable $callback */ public function remove_filter( $hook_name, $callback, $priority ) { if ( null === $priority ) { @@ -248,13 +249,14 @@ public function remove_filter( $hook_name, $callback, $priority ) { * of that hook is returned, or false if the function is not attached. * If `$callback` and `$priority` are both provided, a boolean is returned * for whether the specific function is registered at that priority. + * @phpstan-param Maybe_Callable|false $callback */ public function has_filter( $hook_name = '', $callback = false, $priority = false ) { if ( false === $callback ) { return $this->has_filters(); } - $function_key = _wp_filter_build_unique_id( $hook_name, $callback, false ); + $function_key = _wp_filter_build_unique_id( $hook_name, $callback, is_int( $priority ) ? $priority : 10 ); if ( ! $function_key ) { return false; @@ -320,9 +322,11 @@ public function remove_all_filters( $priority = false ) { * * @since 4.7.0 * - * @param mixed $value The value to filter. - * @param array $args Additional parameters to pass to the callback functions. - * This array is expected to include $value at index 0. + * @param mixed $value The value to filter. + * @param list $args Additional parameters to pass to the callback functions. + * When filtering, this array is expected to include $value + * at index 0. When called for an action by WP_Hook::do_action(), + * it contains only the action arguments. * @return mixed The filtered value after all hooked functions are applied to it. */ public function apply_filters( $value, $args ) { @@ -337,9 +341,14 @@ public function apply_filters( $value, $args ) { $num_args = count( $args ); do { - $this->current_priority[ $nesting_level ] = current( $this->iterations[ $nesting_level ] ); + $priority = current( $this->iterations[ $nesting_level ] ); + + if ( false === $priority ) { + // This is not expected to occur since the hook is known to have callbacks at one or more priorities. + break; + } - $priority = $this->current_priority[ $nesting_level ]; + $this->current_priority[ $nesting_level ] = $priority; foreach ( $this->callbacks[ $priority ] as $the_ ) { if ( ! $this->doing_action ) { @@ -370,7 +379,7 @@ public function apply_filters( $value, $args ) { * * @since 4.7.0 * - * @param array $args Parameters to pass to the callback functions. + * @param list $args Parameters to pass to the callback functions. */ public function do_action( $args ) { $this->doing_action = true; @@ -387,7 +396,7 @@ public function do_action( $args ) { * * @since 4.7.0 * - * @param array $args Arguments to pass to the hook callbacks. Passed by reference. + * @param list $args Arguments to pass to the hook callbacks. Passed by reference. */ public function do_all_hook( &$args ) { $nesting_level = $this->nesting_level++; diff --git a/src/wp-includes/plugin.php b/src/wp-includes/plugin.php index 717aebb0e5860..38e88aa96bb00 100644 --- a/src/wp-includes/plugin.php +++ b/src/wp-includes/plugin.php @@ -169,6 +169,7 @@ function add_filter( $hook_name, $callback, $priority = 10, $accepted_args = 1 ) * @param string $hook_name The name of the filter hook. * @param mixed $value The value to filter. * @param mixed ...$args Optional. Additional parameters to pass to the callback functions. + * @no-named-arguments * @return mixed The filtered value after all hooked functions are applied to it. */ function apply_filters( $hook_name, $value, ...$args ) { @@ -222,8 +223,8 @@ function apply_filters( $hook_name, $value, ...$args ) { * @global int[] $wp_filters Stores the number of times each filter was triggered. * @global string[] $wp_current_filter Stores the list of current filters with the current one last. * - * @param string $hook_name The name of the filter hook. - * @param array $args The arguments supplied to the functions hooked to `$hook_name`. + * @param string $hook_name The name of the filter hook. + * @param non-empty-list $args The arguments supplied to the functions hooked to `$hook_name`. * @return mixed The filtered value after all hooked functions are applied to it. */ function apply_filters_ref_array( $hook_name, $args ) { @@ -283,6 +284,7 @@ function apply_filters_ref_array( $hook_name, $args ) { * of that hook is returned, or false if the function is not attached. * If `$callback` and `$priority` are both provided, a boolean is returned * for whether the specific function is registered at that priority. + * @phpstan-param Maybe_Callable|false $callback */ function has_filter( $hook_name, $callback = false, $priority = false ) { global $wp_filter; @@ -315,6 +317,7 @@ function has_filter( $hook_name, $callback = false, $priority = false ) { * @param int $priority Optional. The exact priority used when adding the original * filter callback. Default 10. * @return bool Whether the function existed before it was removed. + * @phpstan-param Maybe_Callable $callback */ function remove_filter( $hook_name, $callback, $priority = 10 ) { global $wp_filter; @@ -484,6 +487,7 @@ function add_action( $hook_name, $callback, $priority = 10, $accepted_args = 1 ) * @param string $hook_name The name of the action to be executed. * @param mixed ...$arg Optional. Additional arguments which are passed on to the * functions hooked to the action. Default empty. + * @no-named-arguments */ function do_action( $hook_name, ...$arg ) { global $wp_filter, $wp_actions, $wp_current_filter; @@ -537,8 +541,8 @@ function do_action( $hook_name, ...$arg ) { * @global int[] $wp_actions Stores the number of times each action was triggered. * @global string[] $wp_current_filter Stores the list of current filters with the current one last. * - * @param string $hook_name The name of the action to be executed. - * @param array $args The arguments supplied to the functions hooked to `$hook_name`. + * @param string $hook_name The name of the action to be executed. + * @param list $args The arguments supplied to the functions hooked to `$hook_name`. */ function do_action_ref_array( $hook_name, $args ) { global $wp_filter, $wp_actions, $wp_current_filter; @@ -595,6 +599,7 @@ function do_action_ref_array( $hook_name, $args ) { * of that hook is returned, or false if the function is not attached. * If `$callback` and `$priority` are both provided, a boolean is returned * for whether the specific function is registered at that priority. + * @phpstan-param Maybe_Callable|false $callback */ function has_action( $hook_name, $callback = false, $priority = false ) { return has_filter( $hook_name, $callback, $priority ); @@ -619,6 +624,7 @@ function has_action( $hook_name, $callback = false, $priority = false ) { * @param int $priority Optional. The exact priority used when adding the original * action callback. Default 10. * @return bool Whether the function is removed. + * @phpstan-param Maybe_Callable $callback */ function remove_action( $hook_name, $callback, $priority = 10 ) { return remove_filter( $hook_name, $callback, $priority ); @@ -713,11 +719,11 @@ function did_action( $hook_name ) { * * @see _deprecated_hook() * - * @param string $hook_name The name of the filter hook. - * @param array $args Array of additional function arguments to be passed to apply_filters(). - * @param string $version The version of WordPress that deprecated the hook. - * @param string $replacement Optional. The hook that should have been used. Default empty. - * @param string $message Optional. A message regarding the change. Default empty. + * @param string $hook_name The name of the filter hook. + * @param non-empty-list $args Array of additional function arguments to be passed to apply_filters(). + * @param string $version The version of WordPress that deprecated the hook. + * @param string $replacement Optional. The hook that should have been used. Default empty. + * @param string $message Optional. A message regarding the change. Default empty. * @return mixed The filtered value after all hooked functions are applied to it. */ function apply_filters_deprecated( $hook_name, $args, $version, $replacement = '', $message = '' ) { @@ -741,11 +747,11 @@ function apply_filters_deprecated( $hook_name, $args, $version, $replacement = ' * * @see _deprecated_hook() * - * @param string $hook_name The name of the action hook. - * @param array $args Array of additional function arguments to be passed to do_action(). - * @param string $version The version of WordPress that deprecated the hook. - * @param string $replacement Optional. The hook that should have been used. Default empty. - * @param string $message Optional. A message regarding the change. Default empty. + * @param string $hook_name The name of the action hook. + * @param list $args Array of additional function arguments to be passed to do_action(). + * @param string $version The version of WordPress that deprecated the hook. + * @param string $replacement Optional. The hook that should have been used. Default empty. + * @param string $message Optional. A message regarding the change. Default empty. */ function do_action_deprecated( $hook_name, $args, $version, $replacement = '', $message = '' ) { if ( ! has_action( $hook_name ) ) { @@ -967,7 +973,7 @@ function register_uninstall_hook( $file, $callback ) { * * @global WP_Hook[] $wp_filter Stores all of the filters and actions. * - * @param array $args The collected parameters from the hook that was called. + * @param list $args The collected parameters from the hook that was called. */ function _wp_call_all_hook( $args ) { global $wp_filter; @@ -993,13 +999,13 @@ function _wp_call_all_hook( $args ) { * * @access private * - * @param string $hook_name Unused. The name of the filter to build ID for. - * @param callable $callback The callback to generate ID for. The callback may - * or may not exist. - * @param int $priority Unused. The order in which the functions - * associated with a particular action are executed. + * @param string $hook_name Unused. The name of the filter to build ID for. + * @param callable|string|array $callback The callback to generate ID for. The callback may + * or may not exist. + * @param int $priority Unused. The order in which the functions + * associated with a particular action are executed. * @return string|null Unique function ID for usage as array key, or null if it couldn't be determined. - * + * @phpstan-param Maybe_Callable $callback * @phpstan-return non-decimal-int-string|null */ function _wp_filter_build_unique_id( $hook_name, $callback, $priority ): ?string { diff --git a/tests/phpstan/base.neon b/tests/phpstan/base.neon index ab07051c9ad7a..0d519928c0928 100644 --- a/tests/phpstan/base.neon +++ b/tests/phpstan/base.neon @@ -210,3 +210,11 @@ parameters: - ../../src/wp-includes/pomo - ../../src/wp-includes/rss.php - ../../src/wp-includes/sodium_compat + typeAliases: + # A callable that may not be defined in the current scope. + Maybe_Callable: ''' + callable|string|array{ + 0: string|object, + 1: string, + } + ''' diff --git a/tests/phpstan/baselines/argument.type.neon b/tests/phpstan/baselines/argument.type.neon index da71134bcaf34..97f8d47e7eeb8 100644 --- a/tests/phpstan/baselines/argument.type.neon +++ b/tests/phpstan/baselines/argument.type.neon @@ -853,11 +853,6 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-includes/class-wp-duotone.php - - - message: '#^Parameter \#3 \$priority of function _wp_filter_build_unique_id expects int, false given\.$#' - identifier: argument.type - count: 1 - path: ../../../src/wp-includes/class-wp-hook.php - message: '#^Parameter \#3 \$value of function curl_setopt expects int, string given\.$#' identifier: argument.type