Skip to content

Editor: Ignore unsupported duotone attribute types - #14286

Closed
yotatameguchi-boop wants to merge 1 commit into
WordPress:trunkfrom
yotatameguchi-boop:fix/65817-invalid-duotone-attribute
Closed

yotatameguchi-boop wants to merge 1 commit into
WordPress:trunkfrom
yotatameguchi-boop:fix/65817-invalid-duotone-attribute

Conversation

@yotatameguchi-boop

Copy link
Copy Markdown

When style.color.duotone is a boolean or a number, WP_Duotone::render_duotone_support() reaches add_class() with an undefined $filter_id. Return the original block HTML for attribute types other than string or array, and make the remaining branches exhaustive using the existing early return for blocks without local or global duotone settings.

Add regression coverage for false, true, an integer and a float, and regenerate the variable.undefined PHPStan baseline to remove the resolved occurrence.

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

Validation on PHP 8.3:

  • The four regression cases fail on unmodified trunk with Undefined variable $filter_id.
  • vendor/bin/phpunit --group block-supports: 449 tests, 605 assertions pass.
  • vendor/bin/phpstan analyse --memory-limit=2G: no errors.
  • WordPress PHPCS for both changed PHP files and git diff --check: pass.

AI assistance: OpenAI Codex generated the code, regression tests and PR description.

@github-actions

github-actions Bot commented Oct 14, 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. You can also manually ask me to refresh this list by adding the props-bot label.

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @yotatameguchi-boop.

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

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

Props westonruter, ramonopoly, isabel_brison.

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

@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.

@westonruter
westonruter requested a review from ramonjd October 15, 2026 05:02
@westonruter

Copy link
Copy Markdown
Member

I see “preset” mentioned and I immediately think of @ramonjd's PR #14262 which seems related (as it's also about type safety). Requesting his review as well.

@westonruter westonruter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Actually, I see the code was introduced by @tellthemachines in d966798. So maybe she can review as well.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good. I can see that $filter_id is now assigned in all branches of the conditional.

Before this change, PhpStorm also flags an error:

Image

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.

Thanks for checking this in PhpStorm as well! With the early type guard, unsupported attribute values return unchanged and every remaining branch assigns $filter_id.

$is_preset = is_string( $duotone_attr ) && self::is_preset( $duotone_attr );
$is_css = is_string( $duotone_attr ) && ! $is_preset;
$is_custom = is_array( $duotone_attr );
if ( ! is_string( $duotone_attr ) && ! is_array( $duotone_attr ) ) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hello! I think we'd need to sync Gutenberg's copy as well lib/class-wp-duotone-gutenberg.php

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.

Thanks for pointing out the Gutenberg copy! I have opened WordPress/gutenberg#84801 to sync the early type guard and exhaustive branches, with coverage for the four unsupported attribute values. The existing isset( $filter_id ) guard in Gutenberg is preserved.

Validation: all 27 duotone tests (27 assertions), Gutenberg PHPCS for both changed PHP files, and the production build pass. PHP syntax checks also pass on PHP 7.4 and 8.3. The Gutenberg PR includes a backport-changelog entry linking it to this Core PR.

@ramonjd

ramonjd commented Oct 15, 2026

Copy link
Copy Markdown
Member

Thanks for the ping, @westonruter. I checked for overlaps. #14262 cleans theme.json preset definitions in WP_Theme_JSON::sanitize(), and not at render time, so no dependencies.

I was just checking against #14262, which drops invalid types by the time they get to the loop that's changed in this PR.

@tellthemachines

Copy link
Copy Markdown
Contributor

Actually, I see the code was introduced by @tellthemachines in d966798. So maybe she can review as well.

I just committed that PR years ago, didn't actually write it 😅
This looks like a sensible change though!

@tellthemachines

Copy link
Copy Markdown
Contributor

I was just checking against #14262, which drops invalid types by the time they get to the loop that's changed in this PR.

Still worth making this change IMO, if for no other reason than it makes the code a little more readable.

@yotatameguchi-boop

Copy link
Copy Markdown
Author

Thanks @tellthemachines for reviewing and clarifying the history! Agreed: making the supported types explicit and the remaining branches exhaustive improves readability even where the upstream sanitization already filters invalid values. The corresponding Gutenberg change is in WordPress/gutenberg#84801, which you have also tested and approved. Thanks for checking both implementations!

@yotatameguchi-boop

Copy link
Copy Markdown
Author

The corresponding Gutenberg change has now been merged: WordPress/gutenberg#84801 (96a5cfaaabd629d5908a1d17b0c3bf7683343f36). This completes the Gutenberg sync requested above. Thanks everyone for the reviews and testing!

@tellthemachines

Copy link
Copy Markdown
Contributor

@yotatameguchi-boop would you like to create a wordpress.org account so we can give you props on the commit?

@yotatameguchi-boop

Copy link
Copy Markdown
Author

Thanks @tellthemachines! My WordPress.org username is yotatameguchi, and my profile is https://profiles.wordpress.org/yotatameguchi/. Please use that username for the props. Thank you for making sure my contribution is credited!

@tellthemachines tellthemachines left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM!

@tellthemachines

Copy link
Copy Markdown
Contributor

Closing as committed in https://core.trac.wordpress.org/changeset/64493. Thanks everyone!

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.

4 participants