-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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
Prevent translations from being loaded too early #47113
Conversation
Hi , @woocommerce/mothra Apart from reviewing the code changes, please make sure to review the testing instructions as well. You can follow this guide to find out what good testing instructions should look like: |
@swissspidy thank you for taking the time to work on this PR. There are some conflicts on your PR as there were some changes on the Additional fields side. Would you mind fixing those and updating the branch? |
Sure, addressed now! 👍 |
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.
@swissspidy Thanks for this PR! I'm excited that this could potentially be a performance improvement for WooCommerce, and also improve how we implement translations.
I'm going to take another pass at this to do some specific testing (and others may as well) but I wanted to get some initial thoughts out here.
Switching a bunch of things from one action hook (plugins_loaded
) to a later hook (init
) makes me nervous because there are so many other plugins that integrate with WooCommerce, we can't really anticipate what assumptions they might be making about when things will be available, or what will break if we make a change like this. That said, it looks like several of these changes you make are in our Internal
namespace, and so are probably relatively safe. I did note a couple that seem unnecessary because they don't look like they are actually triggering any gettext calls, but I could be wrong about that.
This is particularly suboptimal because WooCommerce itself calls load_plugin_textdomain() later on on init, causing yet another translation call, which is just unnecessary at this point and not good for performance.
This is a good call out, and it's something I had actually noticed just recently, and was wondering if we still needed it. I notice that you didn't remove it as part of this PR though. Do you think that would be worth doing here?
@@ -26,7 +26,7 @@ public static function load() { | |||
add_action( 'pre_set_site_transient_update_themes', array( __CLASS__, 'transient_update_themes' ), 21, 1 ); | |||
add_action( 'upgrader_process_complete', array( __CLASS__, 'upgrader_process_complete' ) ); | |||
add_action( 'upgrader_pre_download', array( __CLASS__, 'block_expired_updates' ), 10, 2 ); | |||
add_action( 'plugins_loaded', array( __CLASS__, 'add_hook_for_modifying_update_notices' ) ); | |||
add_action( 'init', array( __CLASS__, 'add_hook_for_modifying_update_notices' ) ); |
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.
🤔 Does this one really need to change? Looks like it doesn't actually use any gettext
functions in the callback, just queues up a callback on another action hook that's after init
...
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.
You're right, it's not. I was getting fatal errors from WC_Woo_Update_Manager_Plugin::is_plugin_active()
though because is_plugin_active_for_network
wasn't yet available. That can be addressed better.
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 changed this in 2fad07c, but not happy with it.
Actually, it would be even better to change this to admin_init
, because the hooks there are only relevant for the admin, as they add admin notices.
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.
Changed in c5c3e26
/** | ||
* Returns the keys of all core fields. | ||
* | ||
* @return array An array of field keys. | ||
*/ | ||
public function get_core_fields_keys() { | ||
return [ | ||
'email', | ||
'first_name', | ||
'last_name', | ||
'company', | ||
'address_1', | ||
'address_2', | ||
'country', | ||
'city', | ||
'state', | ||
'postcode', | ||
'phone', | ||
]; | ||
} | ||
|
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 see why this is added, so that fields_locations
can be populated in the constructor, but it's obviously not ideal since it means the keys have to be updated in two places if they change. But, since both the core_fields
and the fields_locations
properties in this class are set to private, we could do the same treatment for fields_locations
, i.e. create a new private method called get_fields_locations
and use that instead of referencing the class property. Then you could remove the property assignment from the class constructor.
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.
Agreed, the duplication is not ideal. A slight difference here is that fields_locations
can be mutated via register_checkout_field()
/deregister_checkout_field
. Plus, it's accessed in quite a few places throughout the class. Any suggestions on how best to handle that?
I think I resolved the The stack trace is basically this:
The current workaround works, but makes it easy to call too early translation calls elsehwere, because everything in The |
@coreymckrill @senadir can someone help approve the workflow runs here? |
Closing and reopening to force them to start. |
This comment was marked as resolved.
This comment was marked as resolved.
I did approve them before closing and opening, just did that again. |
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 reviewed this yesterday and everything seems to be working fine in Checkout flows, what's left is more testing with some plugins and figuring out why tests aren't passing.
Tests should be passing now, but they need to be approved again. |
FWIW |
I took anther look at the PR code and it's honestly not touching any critical stuff, the main stuff I can think about are the blocks related code (which I tested) + order attribution (with @layoutd tested). I think this is good to go but I'd love for us to avoid reintroducing this in the future. @swissspidy is it possible for us to add a unit test that would check if translation is loaded too early and will fail if so? If you're ensure how to write the test, just an example of how that hook would look like is enough for me. |
Discussed this with @senadir in person at WCEU: I am planning to add warnings for translations being loaded too early in WP 6.7, see WordPress/wordpress-develop#6462 and https://core.trac.wordpress.org/ticket/44937. This will make it easy to detect regressions in the future. Until then there is not a very good way to test this. So my suggestion would be to merge this for now, accepting the small risk of a regression between now and WP 6.7. |
Hey @swissspidy I discussed with internally with the release team and while I feel confident we can merge this, merging this today means it will land on WooCommerce 9.1 and won't get a lot of testing time, so I'd wait and merge it tomorrow so it lands on 9.2 and gives it even more time in local developer devs and testing time. |
* Prevent translations from being loaded too early * Undo accidental changes to `CheckoutFields` * Keep plugins_loaded, but include required file * Update order in the meantime * Change to admin_init * Add changelog file * Undo `init_jetpack_connection_config` change * Undo change to Packages class * Fix LocalPickupUtils instead * PHPCS fixes * Update method name in test
Submission Review Guidelines:
Changes proposed in this Pull Request:
Since WordPress 4.6, WordPress has supported so-called just-in-time translation loading. Whenever it encounters a
__()
call, it tries to load the translations for that domain if it hasn't already. That means one theoretically doesn't needload_plugin_textdomain()
anymore, though it still can be used.Ideally, this should only happen after the
init
hook, as that's when the current user has been fully set up in WordPress. This is important as users can set their locale in the user profile, which is used in the admin. Triggering translation loading before that means they will be loaded in the wrong locale. Unfortunately, some plugins are_doing_it_wrong()
and load translations right when the plugin is executed, or uponplugins_loaded
.In my attempt to identify such plugins, I noticed that WooCommerce was a particularly stubborn case. There is a lot of code triggering just-in-time translation loading too early. This is particularly suboptimal because WooCommerce itself calls
load_plugin_textdomain()
later on oninit
, causing yet another translation call, which is just unnecessary at this point and not good for performance.This PR is an attempt at identifying and eliminating all cases in WooCommerce triggering just-in-time translation loading before
init
.This way, if core starts adding warnings for such cases, there won't be any warnings anymore for WooCommerce.
How to test the changes in this Pull Request:
Using the WooCommerce Testing Instructions Guide, include your detailed testing instructions:
Some examples:
Remove autoloader
vendor/autoload_packages.php
file so the missing autoloader warning kicks inTemporarily remove
load_plugin_textdomain()
call\WooCommerce::load_plugin_textdomain()
so thatload_plugin_textdomain()
isn't calledWith core PR
_doing_it_wrong()
warningsChangelog entry
Adjust code loading order to prevent just-in-time translation loading from happening too early.
Significance
Type
Message
Comment