Skip to content

Cast $parent_column_value to a string before exploding in gutenberg_get_child_layout_style_rules() - #68404

Merged
westonruter merged 3 commits into
WordPress:trunkfrom
justlevine:fix/cant-explode-float_gutenberg_render_layout_support_flag
Oct 25, 2026
Merged

westonruter merged 3 commits into
WordPress:trunkfrom
justlevine:fix/cant-explode-float_gutenberg_render_layout_support_flag

Conversation

@justlevine

Copy link
Copy Markdown
Contributor

What?

This PR fixes an issue in gutenberg_render_layout_support_flag() where a float type is passed into expode() which requires a string.

Why?

While this issue was surfaced by PHPStan (via #66693) it can be remediated independently as part of #66598

How?

Testing Instructions

Testing Instructions for Keyboard

Screenshots or screencast

Before After

@carolinan carolinan added [Type] Code Quality Issues or PRs that relate to code quality Needs PHP backport Needs PHP backport to Core labels Jan 29, 2025
@carolinan

Copy link
Copy Markdown
Contributor

@justlevine
justlevine force-pushed the fix/cant-explode-float_gutenberg_render_layout_support_flag branch from 6071fed to 9f0ac02 Compare April 18, 2025 23:04
Resolve the conflict in `lib/block-supports/layout.php`: trunk moved the
child layout logic out of `gutenberg_render_layout_support_flag()` into
`gutenberg_get_child_layout_style_rules()`, so the `(string)` cast is
reapplied to the `explode()` call at its new location.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fix is being brought to core in WordPress/wordpress-develop#14862,
along with the related PHPStan fixes from three other Gutenberg PRs, which
share this entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@westonruter westonruter changed the title fix: cast $parent_column_value before exploding in gutenberg_render_layout_support_flag() Cast $parent_column_value to a string before exploding in gutenberg_get_child_layout_style_rules() Oct 25, 2026
@westonruter

Copy link
Copy Markdown
Member

🤖 Comment by Claude Opus 5.5

trunk was merged in. The column-span logic has since moved from gutenberg_render_layout_support_flag() to gutenberg_get_child_layout_style_rules(), so the merge conflict was resolved by applying the cast there. A backport changelog entry was also added for WordPress/wordpress-develop#14862, which applies the same cast in wp_get_child_layout_style_rules() in core, along with three related PHPStan fixes, under Core-65817.

@github-actions

Copy link
Copy Markdown

🤖 PR meta 🤖

🎉 Props

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: justlevine <justlevine@git.wordpress.org>
Co-authored-by: westonruter <westonruter@git.wordpress.org>
Co-authored-by: carolinan <poena@git.wordpress.org>

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.

Updated as activity occurs, without notifying anyone named here. Add the props-bot label to refresh.

@westonruter

Copy link
Copy Markdown
Member

🤖 Comment by Claude Opus 5.5

For context on the code being changed in gutenberg_get_child_layout_style_rules():

When a grid child has a columnSpan or columnStart and its parent grid is responsive (it has a minimumColumnWidth, or no fixed columnCount), the grid loses columns as its container narrows. Once there are fewer columns than the child spans or starts at, its placement has to be reset, so a container query is emitted, e.g.:

@container (max-width: 25.5rem) { .wp-container-content-xyz { grid-column: 1/-1; grid-row: auto; } }

To compute that width, the minimum column width (default 12rem) is split into a number and a unit:

$parent_column_width = $minimum_column_width ? $minimum_column_width : '12rem'; // '12rem'
$parent_column_value = floatval( $parent_column_width );                       // 12.0
$parent_column_unit  = explode( (string) $parent_column_value, $parent_column_width ); // explode( '12', '12rem' ) → [ '', 'rem' ]

The original string is split on the number, so the second element is the unit. Without a second element, the width is treated as mangled and reset to 12rem; a unit other than px, rem, or em falls back to rem. The width is then cols × value + (cols − 1) × gap, with a gap of 24 for px and 1.5 otherwise, subject to a minimum.

The (string) cast in this PR does not change behavior: explode() requires a string separator, and the cast does exactly what PHP's implicit conversion of the float did ((string) 12.0 is '12', and since PHP 8 this is locale-independent). It only makes the conversion explicit, which resolves the PHPStan argument.type error.

That said, the parsing itself, which this PR does not change, is fragile. Since the number is re-stringified before splitting, some valid values do not round-trip:

Input floatval() Separator explode() result Outcome
12rem 12.0 12 ['', 'rem'] ✅ 12rem
0.5em 0.5 0.5 ['', 'em'] ✅ 0.5em
1.50rem 1.5 1.5 ['', '0rem'] ⚠️ unit 0rem is invalid and falls back to rem, so 1.5rem is correct only by luck
.5em 0.5 0.5 ['.5em'] ❌ treated as mangled and reset to 12rem
10.0px 10.0 10 ['', '.0px'] ❌ unit .0px is invalid and falls back to rem, so 10px becomes 10rem

Matching with a regular expression, such as /^(\d*\.?\d+)(px|r?em)$/, similar to what gutenberg_get_typography_value_and_unit() now does, would be more robust. Since that is a behavior change, and wp_get_child_layout_style_rules() in core has the same code, it would be better handled in a separate PR and Trac ticket than in this PHPStan fix.

@westonruter

Copy link
Copy Markdown
Member

@westonruter
westonruter merged commit 389149a into WordPress:trunk Oct 25, 2026
82 checks passed
@github-actions github-actions Bot added this to the Gutenberg 24.4 milestone Oct 25, 2026
wporg-sync pushed a commit to WordPress/wordpress-develop that referenced this pull request Oct 26, 2026
These fixes were made in Gutenberg while resolving the PHPStan errors in the plugin, ahead of adding PHPStan to its CI, and are brought to core to keep the two codebases in sync. They were developed in:

* WordPress/gutenberg#68398
* WordPress/gutenberg#68404
* WordPress/gutenberg#68405
* WordPress/gutenberg#68407

The first one fixes a bug in core. Since r56046 the `array_key_exists()` checks in `wp_register_shadow_support()` have lacked their negation, so a block type with shadow support but no `style` or `shadow` attribute never had them registered, while one that already defined them had its definitions replaced, dropping any `default`. Gutenberg already had the negation. Tests are added for the attribute registration.

The others make implicit type conversions explicit in the layout and duotone code, and narrow the types used by `WP_Theme_JSON::get_feature_declarations_for_node()` so that it reports no errors even at PHPStan rule level 10. Since the node comes from `theme.json` data, that method now also checks that a feature is an array before reading its subfeatures. This fixes a fatal error ("Cannot unset string offsets") when a feature's value is a string, such as a `shadow`, and the block's selectors for that feature are a list rather than keyed by subfeature name, since each numeric key then reads a character of the string instead of a subfeature. The baseline entries for the resolved errors are removed.

Developed in #14862.
Follow-up to r56046, r56058, r56101, r62478, r63426.

Props justlevine, westonruter, poena, ramonopoly.
See #65817.


git-svn-id: https://develop.svn.wordpress.org/trunk@64727 602fd350-edb4-49c9-b593-d223f7449a82
wporg-sync pushed a commit to WordPress/WordPress that referenced this pull request Oct 26, 2026
These fixes were made in Gutenberg while resolving the PHPStan errors in the plugin, ahead of adding PHPStan to its CI, and are brought to core to keep the two codebases in sync. They were developed in:

* WordPress/gutenberg#68398
* WordPress/gutenberg#68404
* WordPress/gutenberg#68405
* WordPress/gutenberg#68407

The first one fixes a bug in core. Since r56046 the `array_key_exists()` checks in `wp_register_shadow_support()` have lacked their negation, so a block type with shadow support but no `style` or `shadow` attribute never had them registered, while one that already defined them had its definitions replaced, dropping any `default`. Gutenberg already had the negation. Tests are added for the attribute registration.

The others make implicit type conversions explicit in the layout and duotone code, and narrow the types used by `WP_Theme_JSON::get_feature_declarations_for_node()` so that it reports no errors even at PHPStan rule level 10. Since the node comes from `theme.json` data, that method now also checks that a feature is an array before reading its subfeatures. This fixes a fatal error ("Cannot unset string offsets") when a feature's value is a string, such as a `shadow`, and the block's selectors for that feature are a list rather than keyed by subfeature name, since each numeric key then reads a character of the string instead of a subfeature. The baseline entries for the resolved errors are removed.

Developed in WordPress/wordpress-develop#14862.
Follow-up to r56046, r56058, r56101, r62478, r63426.

Props justlevine, westonruter, poena, ramonopoly.
See #65817.

Built from https://develop.svn.wordpress.org/trunk@64727


git-svn-id: http://core.svn.wordpress.org/trunk@63877 1a063a9b-81f0-0310-95a4-ce76da25c4cd
@ingeniumed ingeniumed added the [Feature] Layout Layout block support, its UI controls, and style output. label Nov 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Feature] Layout Layout block support, its UI controls, and style output. Needs PHP backport Needs PHP backport to Core [Type] Code Quality Issues or PRs that relate to code quality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants