Repository navigation
Style Engine, Navigation: Fix docblocks reported by PHPStan - #86105
Conversation
🤖 PR meta 🤖🎉 PropsIf you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. Props Bot commandsYou can trigger Props Bot actions by commenting on this PR:
Updated as activity occurs, without notifying anyone named here. Add the |
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues remain for the PHPStan typing and Navigation return-contract updates.
No open issues 🎉
What changed in this PR
Addresses three baselined PHPStan errors toward #86088 by aligning Style Engine docblocks with Core and clarifying the deprecated Navigation fallback’s return contract, without changing runtime behavior.
Changes:
- Corrects the Style Engine parameter type and adds a consistent-constructor annotation.
- Documents the Navigation fallback’s nullable return and explicitly returns
nullwhen no classic menus exist. - Removes three resolved baseline entries and updates one affected diagnostic.
| File | Description |
|---|---|
tools/phpstan/baseline.neon |
Removes resolved errors and updates inferred Navigation field types. |
packages/style-engine/src/class-wp-style-engine.php |
Corrects the documented $style_value type to string. |
packages/style-engine/src/class-wp-style-engine-css-rules-store.php |
Adds the consistent-constructor PHPStan annotation. |
packages/block-library/src/navigation/index.php |
Documents `WP_Term |
Review effort: Balanced
Deepak-Bhojwani
left a comment
There was a problem hiding this comment.
Tested this locally against current trunk (6504787).
The branch conflicts with trunk in tools/phpstan/baseline.neon, since other PRs for #86088 have since removed entries from it. To test, I merged this branch into trunk, kept trunk's baseline, and ran composer phpstan:baselines:
- The only change to the baseline from
trunkis the removal of the 3 entries this PR targets (return.missinginnavigation/index.php,new.staticinclass-wp-style-engine-css-rules-store.php, andargument.typeinclass-wp-style-engine.php). The baseline goes from 13 to 10 errors, with no new ones. composer phpstanthen passes with no errors and no unmatched ignored errors.- The
wp_insert_post()baseline entry updated in e2e2cae is no longer intrunk's baseline, so that change drops out when resolving the conflict.
I also compared the Style Engine changes with Core: the @param string $style_value docblock on get_classnames() and @phpstan-consistent-constructor on WP_Style_Engine_CSS_Rules_Store match wordpress-develop trunk. get_slug_from_preset_value() already guards with is_string( $style_value ), so documenting it as string doesn't change behavior.
For the Navigation change, returning null explicitly is equivalent to the previous implicit return, and the only caller, block_core_navigation_maybe_use_classic_menu_fallback(), returns early on a falsy result.
So this looks good to me once it is rebased on trunk and the baseline is regenerated.
Environment: Windows 11, PHP 8.2.29, Composer 2.11.1, stubs generated from wordpress-develop@27307a20f9ba. I did not run the Style Engine PHPUnit tests, since I don't have wp-env available here.
- Mark WP_Style_Engine_CSS_Rules_Store with @phpstan-consistent-constructor, which makes ew static() safe, as in Core. - Document the $style_value parameter of WP_Style_Engine::get_classnames() as a string, as in Core. - Return ull explicitly, and document it, when the deprecated �lock_core_navigation_get_classic_menu_fallback() finds no classic menu. Remove the 3 resolved entries from the PHPStan baseline. See WordPress#86088.
e2e2cae to
ebc0933
Compare
The `array|string[]` return type was redundant, since `string[]` already covers the empty array. The method only ever appends strings, so its PHPStan return type is `list<string>`. Also give `$style_definition` a shape for the one key the method reads: `classnames`, which maps a classname (or pattern) to either `true` or the CSS property to match against a preset value. Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com> Claude-Code-Session-Id: 1064defd-b2b0-40d4-bfca-0c5b60899c05
`parse_block_styles()` passes the value found at each definition's `path` to `is_valid_style_value()` and `get_classnames()` for every definition, not just those with classnames. Those values are often not strings: spacing and border radius values are arrays, font weights and text columns can be numbers, and block attributes are unvalidated. `get_slug_from_preset_value()` receives the same value and already guards it with `is_string()`. Document `$style_value` as `mixed` on all three methods instead of `string`, matching `get_css_declarations()` in core. Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com> Claude-Code-Session-Id: 1064defd-b2b0-40d4-bfca-0c5b60899c05
`get_css_declarations()` documented `$style_value` as `array`, but it receives the same raw style value as `get_classnames()` and handles strings explicitly. Document it as `mixed`, matching core. Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com> Claude-Code-Session-Id: 1064defd-b2b0-40d4-bfca-0c5b60899c05
The `mixed` style value docblocks are not yet in core, so link the core PR that syncs them. Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com> Claude-Code-Session-Id: 1064defd-b2b0-40d4-bfca-0c5b60899c05
What?
See #86088
Fixes docblocks in the Style Engine and the Navigation block reported by PHPStan, and removes the resolved entries from the PHPStan baseline.
Core backport: WordPress/wordpress-develop#15823
Why?
The
@phpstan-consistent-constructorchange is already in WordPress Core, so the Gutenberg copy was out of sync. The$style_valuedocblocks were inaccurate in both Gutenberg and Core, so they are corrected here and synced to Core in the backport above. The Navigation change is in a deprecated function whose documented return type did not cover every path. This addresses 3 of the 226 errors initially baselined in #66693.How?
WP_Style_Engine_CSS_Rules_Storecallsnew static()inget_store(), which PHPStan reports as unsafe unless subclasses are guaranteed a compatible constructor. Added@phpstan-consistent-constructorto the class docblock, matching Core. (new.static)WP_Style_Engine::get_classnames()documented$style_valueasarray, but passes it on toget_slug_from_preset_value(), which expected a string. (argument.type) Neither is accurate:parse_block_styles()callsget_classnames()for every style definition with whatever value is found at the definition'spath, so spacing and border radius values arrive as arrays and numeric settings such astextColumnsas integers.$style_valueis now documented asmixedonget_classnames(),get_slug_from_preset_value()(which already narrows it withis_string()),is_valid_style_value(), andget_css_declarations(), the last matching Core.get_classnames()also gets alist<string>return type, replacing the redundantarray|string[], and a PHPStan shape for theclassnameskey it reads from$style_definition.block_core_navigation_get_classic_menu_fallback()fell off the end without a return value when there were no classic menus. It now returnsnullexplicitly, and its@returnisWP_Term|null. Its only caller,block_core_navigation_maybe_use_classic_menu_fallback(), already returns early when the result is falsy. (return.missing)tools/phpstan/baseline.neon.There is no change in behavior.
Testing Instructions
composer phpstanand confirm it passes with no unmatched ignored errors.composer phpstan:baselinesand confirmtools/phpstan/baseline.neonhas no further changes.npm run test:php -- --filter Style_Engine.Testing Instructions for Keyboard
Not applicable. There are no UI changes.
Screenshots or screencast
Not applicable.
Use of AI Tools
I used Claude Code to identify the affected occurrences and draft the change. I reviewed the diff and take responsibility for it. Follow-up commits correcting the
$style_valuetypes and adding the Core backport were made with Claude Code (Claude Opus 5.5, medium effort).