From b53eac6f25a7e65948ddf001aeb1f12032f755c3 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 1 Sep 2026 16:26:22 +0000 Subject: [PATCH] Type hook callbacks to match WP_Hook::$callbacks The WordPress stubs now declare WP_Hook::$callbacks as array>, so handing it the loosely typed array the profiler passed around no longer type checks. Read the callbacks straight off the WP_Hook instance that stores them and carry that shape through get_filter_callbacks(), set_filter_callbacks() and $previous_filter_callbacks with a Hook_Callbacks alias, instead of the inline @var that papered over the mismatch. WordPress has kept hooks in WP_Hook instances since 4.7 and WP-CLI requires 4.9 or later, so the pre-4.7 plain-array fallback in the getter goes away with it. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_018HA88i255g4t7hdAUkmW2A --- src/Profiler.php | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/Profiler.php b/src/Profiler.php index f4a3d7fe..bd43dd04 100644 --- a/src/Profiler.php +++ b/src/Profiler.php @@ -5,6 +5,9 @@ use WP_CLI; use WP_CLI\Path; +/** + * @phpstan-type Hook_Callbacks array> + */ class Profiler { /** @var string|false */ @@ -46,7 +49,7 @@ class Profiler { private $running_hook = null; /** @var string|null */ private $previous_filter = null; - /** @var array|null */ + /** @var Hook_Callbacks|null */ private $previous_filter_callbacks = null; /** @var int */ private $filter_depth = 0; @@ -708,31 +711,23 @@ private function set_stage_hooks( $hooks ) { * Get the callbacks for a given filter * * @param string $filter - * @return array|false + * @return Hook_Callbacks|false */ private static function get_filter_callbacks( $filter ) { global $wp_filter; - if ( ! isset( $wp_filter[ $filter ] ) ) { + if ( ! isset( $wp_filter[ $filter ] ) || ! is_a( $wp_filter[ $filter ], 'WP_Hook' ) ) { return false; } - if ( is_a( $wp_filter[ $filter ], 'WP_Hook' ) ) { - $callbacks = $wp_filter[ $filter ]->callbacks; - } else { - $callbacks = $wp_filter[ $filter ]; - } - if ( is_array( $callbacks ) ) { - return $callbacks; - } - return false; + return $wp_filter[ $filter ]->callbacks; } /** * Set the callbacks for a given filter * - * @param string $filter - * @param mixed $callbacks + * @param string $filter + * @param Hook_Callbacks $callbacks * @return void */ private static function set_filter_callbacks( $filter, $callbacks ) { @@ -743,7 +738,6 @@ private static function set_filter_callbacks( $filter, $callbacks ) { } if ( is_a( $wp_filter[ $filter ], 'WP_Hook' ) ) { - /** @var array $callbacks */ $wp_filter[ $filter ]->callbacks = $callbacks; } else { $wp_filter[ $filter ] = $callbacks; // phpcs:ignore