Skip to content

Type hook callbacks to match WP_Hook::$callbacks - #226

Merged
swissspidy merged 1 commit into
mainfrom
claude/phpstan-profile-command-ltjx8k
Sep 2, 2026
Merged

Type hook callbacks to match WP_Hook::$callbacks#226
swissspidy merged 1 commit into
mainfrom
claude/phpstan-profile-command-ltjx8k

Conversation

@swissspidy

@swissspidy swissspidy commented Sep 2, 2026

Copy link
Copy Markdown
Member

The WordPress stubs now declare WP_Hook::$callbacks as
array<int, array<string, array{function: callable, accepted_args: int}>>,
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 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_018HA88i255g4t7hdAUkmW2A

Summary by CodeRabbit

  • Refactor
    • Improved internal type documentation for filter callback handling.
    • Simplified filter callback retrieval behavior for unset or unsupported filters.
    • Removed redundant internal type annotations.

The WordPress stubs now declare WP_Hook::$callbacks as
array<int, array<string, array{function: callable, accepted_args: int}>>,
so handing it the loosely typed array<mixed> 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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018HA88i255g4t7hdAUkmW2A
@swissspidy
swissspidy requested a review from a team as a code owner September 2, 2026 12:40
Copilot AI lite review requested due to automatic review settings September 2, 2026 12:40
@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 082cd99f-a57a-43bf-81c4-406513785283

📥 Commits

Reviewing files that changed from the base of the PR and between 40bc251 and b53eac6.

📒 Files selected for processing (1)
  • src/Profiler.php

Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review.


📝 Walkthrough

Walkthrough

Profiler.php adds a Hook_Callbacks PHPStan alias, applies it to callback properties and methods, and simplifies get_filter_callbacks() to handle only WP_Hook instances.

Changes

Filter callback typing

Layer / File(s) Summary
Type filter callbacks and simplify access
src/Profiler.php
Defines the Hook_Callbacks alias and applies it to callback state and method contracts. get_filter_callbacks() returns false for unset or non-WP_Hook filters and returns the hook callbacks directly.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to b53ea

This PR aligns internal callback handling with the supported WordPress hook representation without changing public behavior or system boundaries. No actionable merge-blocking risk remains beyond normal checks and review.

Suggested reviewers: brianhenryie

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: aligning hook callback typing with WP_Hook::$callbacks.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 1 files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/phpstan-profile-command-ltjx8k

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new is_a( $wp_filter[ $filter ], 'WP_Hook' ) checks can fatally error on PHP 8+ if the value is not an object/string, so they should be guarded (e.g., is_object() check) to avoid runtime TypeErrors.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR updates Profiler’s filter callback handling to align with the newer WordPress stub typing for WP_Hook::$callbacks, introducing a Hook_Callbacks PHPStan alias and propagating that shape through related helpers/state while removing the old pre-WP_Hook getter fallback.

Changes:

  • Introduces a @phpstan-type Hook_Callbacks alias matching WP_Hook::$callbacks and updates $previous_filter_callbacks to use it.
  • Refactors get_filter_callbacks() / set_filter_callbacks() docblocks and behavior to operate directly on WP_Hook instances.
  • Removes the getter’s legacy array-based fallback path.
File summaries
File Description
src/Profiler.php Adds a PHPStan type alias for hook callbacks and refactors getter/setter helpers to use WP_Hook::$callbacks directly.
Review details

Suppressed comments (1)

src/Profiler.php:744

  • Same is_a() issue here: on PHP 8+ this can fatally error if $wp_filter[$filter] is not an object/string. Adding an is_object() guard keeps the fallback branch safe.
		if ( is_a( $wp_filter[ $filter ], 'WP_Hook' ) ) {
			$wp_filter[ $filter ]->callbacks = $callbacks;
		} else {
			$wp_filter[ $filter ] = $callbacks; // phpcs:ignore
		}
  • Files reviewed: 1/1 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/Profiler.php
Comment on lines +719 to +723
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;
@swissspidy swissspidy added this to the 3.0.1 milestone Sep 2, 2026
@swissspidy
swissspidy merged commit 4264d5a into main Sep 2, 2026
58 checks passed
@swissspidy
swissspidy deleted the claude/phpstan-profile-command-ltjx8k branch September 2, 2026 13:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug command:profile-hook Related to 'profile hook' command

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants