-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix fatal error in WP_Fonts_Resolver::get_settings() #56067
Fix fatal error in WP_Fonts_Resolver::get_settings() #56067
Conversation
4e999f0
to
913d5dd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good iteration over #56050. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
@@ -219,7 +214,12 @@ private static function get_settings() { | |||
); | |||
|
|||
// 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't make sense to be in the loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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 becomenull
after thearray_unique()
function inside WP_Fonts_Resolver::get_settings()Testing Instructions
array_merge
Testing Instructions for Keyboard
Screenshots or screencast