Fix fatal error in WP_Fonts_Resolver::get_settings()#56067
Conversation
4e999f0 to
913d5dd
Compare
noahtallen
left a comment
There was a problem hiding this comment.
I was able to replicate the issue, and can confirm that the Gutenberg build on this PR fixes the issue.
PHP's Ummm, sorry but this doesn't look like a proper fix? Please add a test where Doing the |
|
|
||
| // Make sure there are no duplicates. | ||
| $settings['typography']['fontFamilies'] = array_unique( $settings['typography']['fontFamilies'] ); | ||
| $settings['typography']['fontFamilies'] = array_unique( $settings['typography']['fontFamilies'], SORT_REGULAR ); |
There was a problem hiding this comment.
This doesn't make sense to be in the loop.
There was a problem hiding this comment.
This is the existing behavior for a long time, so I think it's out of the scope of this PR to address the fatal error. We can plan to move it outside the loop in the follow-up PR. Does it make sense?
Additionally, I'm not sure why we want to remove the duplicates on $settings['typography']['fontFamilies']. Instead, I think doing it on $settings['typography']['fontFamilies']['theme'] makes more sense as we merge the variation settings into $settings['typography']['fontFamilies']['theme'] above and it might have the duplicates.
There was a problem hiding this comment.
I'm not sure why we want to remove the duplicates on $settings['typography']['fontFamilies']. Instead, I think doing it on $settings['typography']['fontFamilies']['theme']
Yep, same. Thinking this is one of the problems here that caused the fatal error (see comment below). I'd be a +1 to fix that array_unique() as it seems to be a bug.
| $settings['typography']['fontFamilies'] = array_unique( $settings['typography']['fontFamilies'], SORT_REGULAR ); | ||
|
|
||
| // The font families from settings might become null after running the `array_unique`. | ||
| if ( ! isset( $settings['typography']['fontFamilies']['theme'] ) || ! is_array( $settings['typography']['fontFamilies']['theme'] ) ) { |
There was a problem hiding this comment.
This check should be before the array_merge() not after it? Also ideally outside of the loop, it's pointless to repeat it all the time.
There was a problem hiding this comment.
The $settings['typography']['fontFamilies']['theme'] is removed after the array_unique call, so I think we can also do it here to ensure the $settings['typography']['fontFamilies']['theme'] is set.
I agreed the check should be before the array_merge() but we still need to set the value outside the loop again after the last iteration to ensure the value is set. I think the better approach is to move the array_unique call outside the loop if possible.
There was a problem hiding this comment.
@arthur791004
Could you provide a code snippet that would show how array_unique() removes $settings['typography']['fontFamilies']['theme'] ?
I've asked this in the previous PR, and I got no reply.
You could modify this snippet and post a link to the new snippet here.
IMO, array_unique() only removes duplicate values. array_unique() doesn't set values to null.
There was a problem hiding this comment.
Here is it: https://3v4l.org/v8DYU#v8.0.0, and I also mentioned the example here, #56067 (comment).
IMO, array_unique() only removes duplicate values. array_unique() doesn't set values to null.
Yes, it removes duplicates. When you access the value after that, the value doesn't exist anymore and returns NULL (maybe this is better than null 😅)
There was a problem hiding this comment.
@arthur791004, thank you for expanding on this so I can better understand the proposed idea.
I see your point with this PR.
When you access the value after that, the value doesn't exist anymore and returns NULL.
Yes. And if an array element doesn't exist, it shouldn't be accessed directly, as accessing an undefined array element generally results in a PHP warning.
Maybe this is better than null 😅.
I respectfully disagree with that.
In the general PHP context, it's correct to use both NULL and null as it makes no difference (code-wise).
In the WordPress context, null is being used in all the *.php files and in the PHP coding standards. 😅
The
The issue is the Before passing the flag, doing $settings = array(
'typography' => array(
'fontFamilies' => array(
'default' => array(),
'theme' => array(),
),
),
);
array_unique( $settings['typography']['fontFamilies'] );
// Result:
// $settings = array(
// 'typography' => array(
// 'fontFamilies' => array(
// 'default' => array(),
// ),
// ),
// ); |
Yea, because it is not checking the actual array that needs to be checked for uniqueness, but its "parent array" :) As far as I see the I.e. should the |
|
I suspect we have to do the |
Yea, lets fix this and also move it after the loop. Re-checked again today and am positive this was the main problem that was causing the fatal errors. Will also have to move the What is "the etiquette" here when something that was merged needs to be changed/fixed? Continue in the same PR or open a new one? If it was core trac I would have reopened the ticket, unfortunately GH cannot do that.. |
|
I always just open a new PR and link back as much as possible. I guess the equivalent to a reopen-able "ticket" would be a GitHub issue. |
|
Can I confirm whether you feel this will need a Core backport for WP 6.5? |
|
Looking into this I believe these APIs will be removed in 6.5 and thus we do not need to backport this PR. |
|
cc @mikachan for confidence check |
Yes that's correct! The file changed in this PR will be removed as part of #57972, and so won't need a backport. |
What?
This PR aims to fix a PHP fatal error that occurs within WP_Fonts_Resolver::get_settings() under certain conditions.
Why?
Generally, the code should not trigger PHP fatal errors because certain variables do not match the expected type.
How?
This PR ensures that the
$settings['typography']['fontFamilies']['theme']won't becomenullafter thearray_unique()function inside WP_Fonts_Resolver::get_settings()Testing Instructions
array_mergeTesting Instructions for Keyboard
Screenshots or screencast