Repository navigation
PA - VideoPress: drop unregistered widget types from default layouts - #52866
Conversation
the default-layout policy asks the widget registry once it can answer
|
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! |
|
Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.
Interested in more tips and information?
|
Code Coverage SummaryCoverage changed in 2 files.
|
phan cannot see past the finally
…ity-videopress-layout-validation # Conflicts: # projects/packages/premium-analytics/docs/dashboard-widgets.md
louwie17
left a comment
There was a problem hiding this comment.
Thanks @retrofox, this tested well on a local Docker site and code looks good! On trunk the unregistered type showed up in the Traffic default_layout, on this branch it's gone, and the Ads instances still survive the check.
I did leave one inline comment around a non-string type fatalling the new check, not a blocker, but given more plugins will hook into this filter it may be worth a quick fix before merging. Also a small thing, the route in the testing instructions has an extra premium-analytics/ segment, it's /wp-json/wpcom/v2/dashboards/jetpack-premium-analytics_dashboard/sections.
LGTM 🚀
| array_filter( | ||
| $layout, | ||
| static function ( $item ) use ( $registered ) { | ||
| return ! is_array( $item ) || isset( $registered[ $item['type'] ?? '' ] ); |
There was a problem hiding this comment.
Should we check that type is a string before using it as a key? If a plugin hands us an array or object here, isset() throws a TypeError on PHP 8, meaning the sections route fails and none of the tabs load, not only the one that plugin touched. On trunk the same instance passes through fine, as the fixed-list check uses a strict in_array().
An easy one to hit: register_widget_type() returns the Widget_Type object, and it accepts one as well, so this reads natural but passes the object as the type:
$type = register_widget_type( 'my-plugin/revenue', $args );
$layout[] = get_dashboard_default_widget_instance( 'revenue', $type, 30 );| return ! is_array( $item ) || isset( $registered[ $item['type'] ?? '' ] ); | |
| if ( ! is_array( $item ) ) { | |
| return true; | |
| } | |
| $type = $item['type'] ?? ''; | |
| return is_string( $type ) && isset( $registered[ $type ] ); |
Dropping it matches what the policy is for anyway. Fine as a follow up too.
There was a problem hiding this comment.
Thanks 👍
Handled in #52874, which refactors this callback: both default-layout passes now treat non-string types as unknown and drop them, with a test using the Widget_Type object and an array as the type.
Fixes WOOA7S-2172
Proposed changes
Step 1 of the VideoPress consumer stack (WOOA7S-2221).
remove_unsupported_default_layout_items(), the package's policy on default layouts, drops only the types on a fixed list inget_unsupported_widget_types().It never asks the widget type registry, so a default that names a type the site has not registered reaches the client and renders as a "Widget is no longer available" tile.
The policy asks the registry
After the fixed list, the callback drops every instance whose type
Widget_Type_Registrydoes not know.It does so only once the registry can answer: after
init, with the widget type API loaded (ensure_widget_registry_ready()exists in both loaders), and at least one type registered.Before
init, or on a checkout without a build, the default stays as declared instead of emptying itself.Reading the registry hydrates it, so the sections REST route now fires
jetpack_premium_analytics_register_widget_typeswhen it serializes the default layouts.By then, every consumer's types are registered, and the Ads instances survive the check.
Why now
The next steps move the Top videos widget into the VideoPress package.
On a site without VideoPress, the type isn't registered, and this check keeps the Traffic default clean; the
VIDEOPRESS_WIDGET_TYPESlist stops being the mechanism.Tests
Dashboard_Layout_Teststages an absent manifest, so the registry holds only what a test registers: an unregistered type is dropped while a registered one survives; beforeinit, the default is left alone; with nothing registered, it is left alone.The test that adds a plugin instance now registers its type first, as a plugin would.
Related product discussion/links
Linear: WOOA7S-2221 for the stack, WOOA7S-2172 for this step. Raised in the review of #52452.
Does this pull request change what data or activity we track or use?
No.
Testing instructions
jetpack test php packages/premium-analyticsOn a connected site, add to a mu-plugin:
Reset the Traffic section layout.
On trunk, a "Widget is no longer available" tile appears; on this branch, it does not.
GET /wp-json/wpcom/v2/premium-analytics/dashboards/jetpack-premium-analytics_dashboard/sectionsshows noexample/missingin the Trafficdefault_layout.trunk