Repository navigation
WP Build Polyfills: own the screen-ID alias ordering in one place - #52583
Conversation
…ld dashboards Nine packages (Activity Log, Backup, My Jetpack, Newsletter, Podcast, Publicize, Search, SEO, VideoPress) each carried their own copy of the three-line sequence that hooks a wp-build dashboard's screen-ID alias before its generated enqueue check and the restore after. Getting the restore dropped, or the two hooked out of order, is the actual bug history here (JETPACK-2689): five of the nine originally shipped alias-with-no-restore, invisibly breaking JITM's message path and Core's pagenow. Add WP_Build_Screen_Id::load_with_alias() to wp-build-polyfills. It takes each package's own alias/restore callables and owns only their order, so a new call site can't reproduce that ordering bug. Each package's alias_screen_id_for_wp_build() / restore_screen_id_after_wp_build() are unchanged from trunk - the screen-ID swap itself never broke, so there is nothing to centralize there. Each package's orchestration call site is guarded with method_exists() and falls back to the original three-line sequence per AGENTS.md, since the jetpack-autoloader can still serve an older wp-build-polyfills without the helper (JETPACK-2649 was this exact autoloader race in production). Boost and the Jetpack plugin's AI page keep the old pattern; someone else is already working in them. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.
Interested in more tips and information?
|
|
Thank you for your PR! When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:
This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖 Follow this PR Review Process:
If you have questions about anything, reach out in #jetpack-developers for guidance! |
Code Coverage SummaryCoverage changed in 9 files. Only the first 5 are listed here.
1 file is newly checked for coverage.
|
The version-skew rationale was copy-pasted verbatim into all nine consumers. Each site keeps a one-line local reason instead. wp-build-polyfills adds a public class and method, so its entry is minor/added, matching the package's precedent for a new helper. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Reviewed at standard depth. No blockers. Three suggestions; two are fixed in Fixed
Left open
Also checked and clear: the — Terminator |
dhasilva
left a comment
There was a problem hiding this comment.
Reviewed at thorough depth. The refactor preserves behaviour: at all nine sites the helper hooks the same alias and restore callables, in the same order and at the same default priority, from the same admin_menu callback as trunk. Each package's generated page-wp-admin.php enqueue callback is still the only thing hooked inside the window. I have three small suggestions, none of them blocking.
Verdict: Minor issues, can merge after addressing.
Tests: jp test php passes for wp-build-polyfills and all nine consumers. That includes Podcast, whose 213 tests all passed here. jp phan is clean on all ten packages, and PHPCS is clean on the changed files. As a check on the new test, I reordered and dropped hooks in load_with_alias(), and every variant failed test_generated_check_sees_only_the_aliased_id.
Version skew: all nine packages require wp-build-polyfills. The jetpack-autoloader picks a version for each class separately, so an older copy can't hide a class it doesn't ship. That makes the method_exists() guards extra caution rather than a requirement here. They're harmless, though, and they follow AGENTS.md.
Findings: see inline comments.
Generated by Claude.
Core prints pagenow in admin-header.php before admin_enqueue_scripts fires, so the alias never reaches it. JITM is the only casualty. Search had no test reaching maybe_load_wp_build(), which turned the coverage check red. A wp_build_index() seam, beside the existing render-function seam, lets a test load a stub build file. The registration test only failed when the restore was dropped, which the behavioural test also catches. Removed with its three spies. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
All three addressed in
Thanks for the mutation run. — Terminator |
Fixes JETPACK-2689
Proposed changes
WP_Build_Screen_Id::load_with_alias()topackages/wp-build-polyfills. It takes the consumer's alias callback, its restore callback, and a callable that loads wp-build's generated file, and owns nothing but their order:Why the ordering and nothing else
The alias exists because wp-build's generated enqueue callback is gated on
$screen->idmatching the page's build-time slug. Aliasing without restoring leaves every later hook reading a screen that does not exist — JITM builds its message path from it onadmin_notices.Five of the nine shipped with no restore at all and nobody noticed, because nothing on the page looks wrong. That is an ordering failure, so the ordering is what this centralizes.
The screen-ID swap itself never broke, so it stays in each package, byte-identical to trunk. No hunk in this PR touches an
alias_screen_id_for_wp_build()orrestore_screen_id_after_wp_build()body, and each package's existing round-trip test passes unmodified — which is the check that they really are untouched.The trade-off, stated plainly
Each package grows ~31 lines to centralize three. That is because
AGENTS.mdrequires amethod_exists()guard and a working fallback when calling a newly added shared-package method: the jetpack-autoloader picks the highest version of each package independently, so a newer consumer can run against an olderwp-build-polyfills. JETPACK-2649 was this exact race in production. Dropping the fallback is worse than it sounds — with no alias the generated check never fires, whileis_wp_build_dashboard_active()still returns true becausebuild/exists, so the page renders empty.A first draft also shared the swap itself. That added ~400 lines and removed no duplication, since the guard forced the original implementation to stay at all nine call sites as a fallback. This version is the half that pays for itself.
Out of scope:
plugins/boostand the Jetpack plugin's AI page keep the old pattern — both have work in flight from other people. Worth migrating once that lands.Related product discussion/links
Does this pull request change what data or activity we track or use?
No. Internal refactor; ten
patch/changedchangelog entries, no dependent-plugin entries.Testing instructions
Run here:
jetpack test php packages/wp-build-polyfills— passes. Two tests: hook priority, and that the generated check sees the aliased ID while anything after the restore sees the real one. The second fails if the twoadd_action()calls are reordered.jetpack test php packages/seo— passes, with the round-trip test unmodified.jetpack test php packages/search— passes.Dashboard_Wp_Build_Test::test_maybe_load_wp_build_aliases_the_screen_only_for_the_generated_checkdrives the realmaybe_load_wp_build()against a stub build file. It fails if either hook is dropped, if the two are hooked out of order, or if both move off the default priority.jetpack test phpandjetpack phanacross all ten packages; Phan is clean on all ten and PHPCS is clean on every touched file.Known unrelated failure:
packages/podcast'stests/php/blocks/Podcast_Episode_Block_Test.phpfails 14 tests on this branch. It fails identically without this change, and this PR touches onlyclass-admin-page.phpin that package. Not introduced here, not fixed here.To check the behaviour by hand, on any site with a wp-build dashboard: open it and confirm the page still loads its scripts, then confirm
get_current_screen()->idreads the real screen ID in anadmin_noticescallback rather than the build-time slug.🤖 Generated with Claude Code