Skip to content

Icons: Prevent unregistering core-admin icons (Trac #66344) - #14621

Open
ArkaPrabhaChowdhury wants to merge 3 commits into
WordPress:trunkfrom
ArkaPrabhaChowdhury:trac-66344-protect-admin-icons
Open

ArkaPrabhaChowdhury wants to merge 3 commits into
WordPress:trunkfrom
ArkaPrabhaChowdhury:trac-66344-protect-admin-icons

Conversation

@ArkaPrabhaChowdhury

@ArkaPrabhaChowdhury ArkaPrabhaChowdhury commented Oct 21, 2026 •

Copy link
Copy Markdown

The admin menu and admin bar depend on the non-public core-admin icon collection. Unregistering that collection, or one of its icons, currently leaves the corresponding admin UI without icons.

Reject those operations with _doing_it_wrong() and return false before changing either registry. The guards live in the registry methods so both direct calls and the public helpers are covered. Only core-admin is protected: the public core collection and third-party collections remain removable, including cascading removal of their icons.

Regression tests exercise both blocked operations, unchanged SVG output, and successful removal of core icons and their collection. The REST icon test fixture now uses temporary registry instances instead of unregistering the protected collection, and restores the original instances afterward.

Trac ticket: https://core.trac.wordpress.org/ticket/66344

Use of AI Tools

AI assistance: Yes
Tool(s): OpenAI Codex
Model(s): GPT-6
Used for: Ticket analysis, implementation, regression tests, local verification, and PR text.


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs.

Core Committers: Use this line as a base for the props when committing in SVN:

Props arkaprabhachowdhury, nathanrice.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.


Props Bot commands

You can trigger Props Bot actions by commenting on this PR:

  • @propsbot add <username> to give props to a GitHub user. Requires write access.
  • @propsbot remove <username> to leave a user out of the props. Requires write access.
  • @propsbot refresh to refresh this list. Adding the props-bot label works too.

@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@nathanrice

Copy link
Copy Markdown

Thinking through edge cases here, if a person wanted to swap core icons for their own, because they were skinning the Admin, this would prevent that, I think.

I don't know how common that would be, but we should probably think through an official "how to" for anyone who may want to do this in the future.

@ArkaPrabhaChowdhury

Copy link
Copy Markdown
Author

Thanks for raising that great edge case point @nathanrice. It makes sense and I have tried to add that functionality. Can you please check if it makes sense and matches expectations?

Comment thread src/wp-includes/icons.php
* @return string SVG markup for the icon, or empty string if not found.
*/
function wp_get_icon( $name, $args = array() ) {
$icon = WP_Icons_Registry::get_instance()->get_registered_icon( $name );

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The filter is a good option. One thing to consider (others may disagree, so I'm not insisting here) would be a pre_ filter.

Here's an example from core:

$pre_menu_item = apply_filters( 'pre_wp_setup_nav_menu_item', null, $menu_item );

By applying the pre_ filter early and checking for a null value, you can short circuit the function to avoid the unnecessary processing that the function does on the HTML, only for the callback to have to do it all over again.

@ArkaPrabhaChowdhury ArkaPrabhaChowdhury Oct 23, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Agreed, an early filter is a better fit for replacing an icon completely. Added pre_wp_get_icon before the registry lookup in 68a7436. Returning null continues normal rendering; returning SVG markup or an empty string short-circuits both the lookup and HTML processing. The callback supplies the complete markup, including any sizing and accessibility attributes.

Kept wp_get_icon for callbacks that modify the rendered SVG.

Comment thread src/wp-includes/icons.php
* @param string $name The icon name.
* @param array $args The arguments passed to `wp_get_icon()`.
*/
return apply_filters( 'wp_get_icon', $processor->get_updated_html(), $name, $args );

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

it might be good to pass the $processor instance to the filter too. If a person wanted to transform the html, rather than replace it entirely, it comes with handy helper methods that make this safer. Then, they can just return $processor->get_updated_html() in the callback when they're done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants