Icons: Fix collection unregister not removing icons after core added its own registry - #80292
Conversation
Core now ships WP_Icons_Registry and WP_Icon_Collections_Registry, so the Gutenberg compat classes are skipped. Core's collection unregister cascade calls WP_Icons_Registry::get_instance(), but WP_Icons_Registry_Gutenberg redefined its own static $instance, splitting the singleton into two slots. The cascade then operated on a different instance than the one callers held, so icons were not removed when their collection was unregistered. Stop redefining $instance so the subclass shares the base slot; both WP_Icons_Registry::get_instance() and WP_Icons_Registry_Gutenberg::get_instance() now resolve to the same object. get_instance() upgrades an existing base registry in place, replaying non-core icons, which also removes the need for the reflection-based override. Co-Authored-By: Claude <noreply@anthropic.com>
Temporarily disable the test-php exclude matrix so PRs run against all PHP versions and both the current and previous major WordPress versions. The previous major WP lacks the core icon registry, exercising the Gutenberg shim path this change must keep working. Revert before merge. Co-Authored-By: Claude <noreply@anthropic.com>
|
Since the same error is occurring on the wp/7.1 branch, I will backport this to wp/7.1 as well. |
Now that WP_Icons_Registry_Gutenberg shares the base singleton slot, resetting the singleton in another suite's tear_down wipes the default icons that `init` only registers once. The REST controller tests depend on those defaults, so they failed with an empty registry when run after such a suite. Mirror WordPress core's Tests_REST_WpRestIconsController::set_up() by re-registering the default collection and icons when the registry is empty, using the Gutenberg registration functions. Core already does this; the Gutenberg test previously got away without it because the old dual-slot design shielded the base registry from those resets. Co-Authored-By: Claude <noreply@anthropic.com>
| public function set_up() { | ||
| parent::set_up(); | ||
|
|
||
| /* | ||
| * Other suites reset the `WP_Icons_Registry` singleton, wiping the core icons that | ||
| * `init` only registers once. Re-register them when empty so order-dependent tests pass. | ||
| */ | ||
| if ( ! WP_Icon_Collections_Registry::get_instance()->is_registered( 'core' ) ) { | ||
| gutenberg_register_default_icon_collections(); | ||
| } | ||
| if ( empty( WP_Icons_Registry::get_instance()->get_registered_icons() ) ) { | ||
| gutenberg_register_default_icons(); | ||
| } | ||
| } |
There was a problem hiding this comment.
Mirrors core's Tests_REST_WpRestIconsController::set_up().
Same root cause as the REST controller test: sharing the base registry singleton means another suite's tear_down reset wipes the default icons that `init` registers only once. Because Gutenberg's test files sort `class-wp-icon-collections-registry-test.php` (which resets the singleton) before `class-wp-icon-test.php`, wp_get_icon() ran against an empty registry and returned '' for every icon. Add the same set_up() repopulation used by the REST controller test so these tests are order-independent. In core the equivalent wpGetIcon test happens to run before the resetting suite, so it needs no such guard; Gutenberg's file naming reverses that order. Co-Authored-By: Claude <noreply@anthropic.com>
|
All unit tests have passed. I will revert the matrix and merge this once all CI checks are complete. |
Revert the temporary full-matrix change now that CI has verified icon registry compatibility across all PHP versions and both the current and previous major WordPress versions. PRs go back to the reduced matrix (PHP 7.4/8.5, single site, latest WP). Co-Authored-By: Claude <noreply@anthropic.com>
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If 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. |
…its own registry (#80292) * Icons: Share the base registry singleton in WP_Icons_Registry_Gutenberg Core now ships WP_Icons_Registry and WP_Icon_Collections_Registry, so the Gutenberg compat classes are skipped. Core's collection unregister cascade calls WP_Icons_Registry::get_instance(), but WP_Icons_Registry_Gutenberg redefined its own static $instance, splitting the singleton into two slots. The cascade then operated on a different instance than the one callers held, so icons were not removed when their collection was unregistered. Stop redefining $instance so the subclass shares the base slot; both WP_Icons_Registry::get_instance() and WP_Icons_Registry_Gutenberg::get_instance() now resolve to the same object. get_instance() upgrades an existing base registry in place, replaying non-core icons, which also removes the need for the reflection-based override. Co-Authored-By: Claude <noreply@anthropic.com> * [TEMP] CI: Run full unit-test matrix to verify icon registry WP compat Temporarily disable the test-php exclude matrix so PRs run against all PHP versions and both the current and previous major WordPress versions. The previous major WP lacks the core icon registry, exercising the Gutenberg shim path this change must keep working. Revert before merge. Co-Authored-By: Claude <noreply@anthropic.com> * Icons: Repopulate default icons in REST controller test set_up Now that WP_Icons_Registry_Gutenberg shares the base singleton slot, resetting the singleton in another suite's tear_down wipes the default icons that `init` only registers once. The REST controller tests depend on those defaults, so they failed with an empty registry when run after such a suite. Mirror WordPress core's Tests_REST_WpRestIconsController::set_up() by re-registering the default collection and icons when the registry is empty, using the Gutenberg registration functions. Core already does this; the Gutenberg test previously got away without it because the old dual-slot design shielded the base registry from those resets. Co-Authored-By: Claude <noreply@anthropic.com> * Icons: Repopulate default icons in wp_get_icon() test set_up Same root cause as the REST controller test: sharing the base registry singleton means another suite's tear_down reset wipes the default icons that `init` registers only once. Because Gutenberg's test files sort `class-wp-icon-collections-registry-test.php` (which resets the singleton) before `class-wp-icon-test.php`, wp_get_icon() ran against an empty registry and returned '' for every icon. Add the same set_up() repopulation used by the REST controller test so these tests are order-independent. In core the equivalent wpGetIcon test happens to run before the resetting suite, so it needs no such guard; Gutenberg's file naming reverses that order. Co-Authored-By: Claude <noreply@anthropic.com> * CI: Restore test-php exclude matrix Revert the temporary full-matrix change now that CI has verified icon registry compatibility across all PHP versions and both the current and previous major WordPress versions. PRs go back to the reduced matrix (PHP 7.4/8.5, single site, latest WP). Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: t-hamano <wildworks@git.wordpress.org>
|
I just cherry-picked this PR to the wp/7.1 branch to get it included in the next release: 54d2fe8 |
This updates the pinned commit hash of the Gutenberg repository from `2872d71cde528d82675f14862a1b84e2b8abbaea` to `e73c3c481db0650183f092af157f6e42efe9ee2d`. A full list of changes included in this commit can be found on GitHub: WordPress/gutenberg@2872d71...e73c3c4 - Icon block: Show text and background color controls by default. (WordPress/gutenberg#80251) - fix: set dataviews popover hover text color (WordPress/gutenberg#80105) - DataViews: Fix the unintended gap between `list` layout items when `groupBy` is set (WordPress/gutenberg#80254) - DataViews: Fix the `list` layout ignoring some settings when `groupBy` is set (WordPress/gutenberg#80255) - DataViews: Add shift-click range selection (WordPress/gutenberg#80046) - Responsive Editing: support editing pattern styles (WordPress/gutenberg#80233) - Tab List: Add toolbar buttons to reorder tabs (WordPress/gutenberg#80107) - Hide color controls for Navigation and Social Icons when viewport states are active (WordPress/gutenberg#80289) - Icons: Fix collection unregister not removing icons after core added its own registry (WordPress/gutenberg#80292) - Notes: increase contrast between avatar border colors (WordPress/gutenberg#80285) - Playlist: Fix track insertion (WordPress/gutenberg#80200) - Fix: Allow icon labels to wrap with word breaks and no ellipsis (WordPress/gutenberg#80309) - Core Abilities: Restore the ready promise and lazy-load via dynamic import (WordPress/gutenberg#79155) Props wildworks. See #65529. git-svn-id: https://develop.svn.wordpress.org/trunk@62757 602fd350-edb4-49c9-b593-d223f7449a82
This updates the pinned commit hash of the Gutenberg repository from `2872d71cde528d82675f14862a1b84e2b8abbaea` to `e73c3c481db0650183f092af157f6e42efe9ee2d`. A full list of changes included in this commit can be found on GitHub: WordPress/gutenberg@2872d71...e73c3c4 - Icon block: Show text and background color controls by default. (WordPress/gutenberg#80251) - fix: set dataviews popover hover text color (WordPress/gutenberg#80105) - DataViews: Fix the unintended gap between `list` layout items when `groupBy` is set (WordPress/gutenberg#80254) - DataViews: Fix the `list` layout ignoring some settings when `groupBy` is set (WordPress/gutenberg#80255) - DataViews: Add shift-click range selection (WordPress/gutenberg#80046) - Responsive Editing: support editing pattern styles (WordPress/gutenberg#80233) - Tab List: Add toolbar buttons to reorder tabs (WordPress/gutenberg#80107) - Hide color controls for Navigation and Social Icons when viewport states are active (WordPress/gutenberg#80289) - Icons: Fix collection unregister not removing icons after core added its own registry (WordPress/gutenberg#80292) - Notes: increase contrast between avatar border colors (WordPress/gutenberg#80285) - Playlist: Fix track insertion (WordPress/gutenberg#80200) - Fix: Allow icon labels to wrap with word breaks and no ellipsis (WordPress/gutenberg#80309) - Core Abilities: Restore the ready promise and lazy-load via dynamic import (WordPress/gutenberg#79155) Props wildworks. See #65529. Built from https://develop.svn.wordpress.org/trunk@62757 git-svn-id: http://core.svn.wordpress.org/trunk@62041 1a063a9b-81f0-0310-95a4-ce76da25c4cd
…its own registry (#80292) * Icons: Share the base registry singleton in WP_Icons_Registry_Gutenberg Core now ships WP_Icons_Registry and WP_Icon_Collections_Registry, so the Gutenberg compat classes are skipped. Core's collection unregister cascade calls WP_Icons_Registry::get_instance(), but WP_Icons_Registry_Gutenberg redefined its own static $instance, splitting the singleton into two slots. The cascade then operated on a different instance than the one callers held, so icons were not removed when their collection was unregistered. Stop redefining $instance so the subclass shares the base slot; both WP_Icons_Registry::get_instance() and WP_Icons_Registry_Gutenberg::get_instance() now resolve to the same object. get_instance() upgrades an existing base registry in place, replaying non-core icons, which also removes the need for the reflection-based override. Co-Authored-By: Claude <noreply@anthropic.com> * [TEMP] CI: Run full unit-test matrix to verify icon registry WP compat Temporarily disable the test-php exclude matrix so PRs run against all PHP versions and both the current and previous major WordPress versions. The previous major WP lacks the core icon registry, exercising the Gutenberg shim path this change must keep working. Revert before merge. Co-Authored-By: Claude <noreply@anthropic.com> * Icons: Repopulate default icons in REST controller test set_up Now that WP_Icons_Registry_Gutenberg shares the base singleton slot, resetting the singleton in another suite's tear_down wipes the default icons that `init` only registers once. The REST controller tests depend on those defaults, so they failed with an empty registry when run after such a suite. Mirror WordPress core's Tests_REST_WpRestIconsController::set_up() by re-registering the default collection and icons when the registry is empty, using the Gutenberg registration functions. Core already does this; the Gutenberg test previously got away without it because the old dual-slot design shielded the base registry from those resets. Co-Authored-By: Claude <noreply@anthropic.com> * Icons: Repopulate default icons in wp_get_icon() test set_up Same root cause as the REST controller test: sharing the base registry singleton means another suite's tear_down reset wipes the default icons that `init` registers only once. Because Gutenberg's test files sort `class-wp-icon-collections-registry-test.php` (which resets the singleton) before `class-wp-icon-test.php`, wp_get_icon() ran against an empty registry and returned '' for every icon. Add the same set_up() repopulation used by the REST controller test so these tests are order-independent. In core the equivalent wpGetIcon test happens to run before the resetting suite, so it needs no such guard; Gutenberg's file naming reverses that order. Co-Authored-By: Claude <noreply@anthropic.com> * CI: Restore test-php exclude matrix Revert the temporary full-matrix change now that CI has verified icon registry compatibility across all PHP versions and both the current and previous major WordPress versions. PRs go back to the reduced matrix (PHP 7.4/8.5, single site, latest WP). Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: t-hamano <wildworks@git.wordpress.org>
|
I just cherry-picked this PR to the release/23.6 branch to get it included in the next release: a62d375 |
What?
Fixes the icon registry so that unregistering an icon collection also removes its icons, which stopped working after WordPress core added its own icon registry.
Why?
WordPress core now ships its own icon registry classes (
WP_Icons_RegistryandWP_Icon_Collections_Registry). When core has them, Gutenberg's compatibility copies are skipped, and core's versions are used.Gutenberg uses a subclass,
WP_Icons_Registry_Gutenberg, and it kept its own separate singleton instance. Core'sunregister a collection()logic looks up icons through the base class instance, but the rest of the code held a different instance. So the two sides no longer pointed at the same registry, and icons were not removed when their collection was unregistered.This broke a unit test (
WP_Test_Icon_Collections_Registry::test_unregister_collection_cascades_to_icons).How?
Stop giving the subclass its own instance. By not redefining the
$instanceslot, the subclass and the base class share a single instance, soWP_Icons_Registry::get_instance()andWP_Icons_Registry_Gutenberg::get_instance()always return the same object.get_instance()now upgrades an already-created base registry in place (keeping any non-core/icons). This also let us drop the old reflection-based override.Testing Instructions
To ensure this PR works on older WordPress versions, I have temporarily disabled the unit test exclusion rule. Once all CI checks pass, I will revert the matrix to its previous state before merging.
Use of AI Tools
This PR was written with the help of Claude Code (Anthropic). The investigation, fix, and description were reviewed and verified by the author.