wp-media / wp-rocket

Performance optimization plugin for WordPress
https://wp-rocket.me
GNU General Public License v2.0
690 stars 215 forks source link

Multilingual Plugins - Caching is not working when second-language WooCommerce pages are not active #3271

Open vmanthos opened 3 years ago

vmanthos commented 3 years ago

Before submitting an issue please check that you’ve completed the following steps:

Describe the bug

When:

  1. WPML is used on a WooCommerce site
  2. One of the pages that we exclude by default e.g. "my-account" is set to draft

WP Rocket's caching is not working.

This is because the get_rocket_i18n_translated_post_urls() function returns / for the draft page here: https://github.com/wp-media/wp-rocket/blob/e49355167e75f1d3cf51ee65c429b75f3e28682e/inc/functions/i18n.php#L459

So here: https://github.com/wp-media/wp-rocket/blob/e49355167e75f1d3cf51ee65c429b75f3e28682e/inc/ThirdParty/Plugins/Ecommerce/WooCommerceSubscriber.php#L186

the $account_urls includes the actual /my-account/(.*) page and /(.*).

The latter excludes all pages from caching.

To Reproduce Steps to reproduce the behavior:

  1. Use WPML and WooCommerce.
  2. Do not create a translation for the "my-account" page.
  3. Check if pages are cached.

Expected behavior

Caching should work even when the WooCommerce pages we automatically exclude are not translated.

Additional context

The icl_object_id() function we are using has been deprecated: https://wpml.org/documentation/support/creating-multilingual-wordpress-themes/language-dependent-ids/#2

They recommend using wpml_object_id.

Related ticket: https://secure.helpscout.net/conversation/1313353514/203623?folderId=2135277

Backlog Grooming (for WP Media dev team use only)

vmanthos commented 3 years ago

Related ticket: https://secure.helpscout.net/conversation/1525947388/267278/

In this case, the customer is using "A different domain per language" in WMPL's language settings, but they didn't add a URL in the respective text area:

That resulted in these URLs:

https:///payment/
https:///basket/
https:///my-account/

being reported from icl_object_id() as the translations of WooCommerce's pages here: https://github.com/wp-media/wp-rocket/blob/0e62e05e753fe77992c14a09eed53b793dff8e82/inc/functions/i18n.php#L459

Those had the same post ID as their translated counterparts, and their status was publish.

When those are handled by wp_parse_url() the previous URLs are added to the $rocket_cache_reject_uri in WP Rocket's config file like so: (.*) thus preventing caching/optimizations.

On the customer's site, I resolved this by adding a dummy URL for the EN translation. I had to uncheck the "Validate on save" to force WPML to treat this as a proper domain:

In this case, it seems the issue arises from a misconfiguration of WPML. Regardless, it would be awesome if we could prevent this from happening.

webtrainingwheels commented 2 years ago

Related ticket: https://secure.helpscout.net/conversation/1775589790/323499?folderId=273766 An empty domain in the WPML settings was the cause (thanks @vmanthos for the confirmation!)

NataliaDrause commented 2 years ago

Related: https://secure.helpscout.net/conversation/1820946124/332572/ Cart page translation was set to draftand that stopped caching for homepage.

alfonso100 commented 3 months ago

The same happens with Polylang. ticket: https://secure.helpscout.net/conversation/2622431226/496659/

I logged the values in the i18n and WooCommerce exclusions using Vasilis method, and also before and after rocket_cache_reject_uri

For untranslated URLs, we end up adding global exclusions such as:

    [5] => /??(.*)
    [9] => /?

this is the full log:

Initial list of exclusions before the rocket_cache_reject_uri: Array
(
    [0] => /testera/
    [1] => /(?:.+/)?feed(?:/(?:.+/?)?)?$
    [2] => /(?:.+/)?embed/
)

 i18n: Array
(
    [0] => /lt/apmokejimas/??(.*)
    [1] => /??(.*)
    [2] => /et/??(.*)
    [3] => /lv/??(.*)
    [4] => /lt/apmokejimas/??(.*)
)

 i18n: Array
(
    [0] => /lt/pirkiniu-krepselis/?
    [1] => /?
    [2] => /et/?
    [3] => /lv/?
    [4] => /lt/pirkiniu-krepselis/?
)

 i18n: Array
(
    [0] => /lt/paskyra/??(.*)
    [1] => /??(.*)
    [2] => /et/??(.*)
    [3] => /lv/??(.*)
    [4] => /lt/paskyra/??(.*)
)

 woocommerce  Urls: Array
(
    [0] => /testera/
    [1] => /(?:.+/)?feed(?:/(?:.+/?)?)?$
    [2] => /(?:.+/)?embed/
    [3] => /ms_admin09/
)

woocommerce Checkout: Array
(
    [0] => /lt/apmokejimas/??(.*)
    [1] => /??(.*)
    [2] => /et/??(.*)
    [3] => /lv/??(.*)
)

woocommerce Cart: Array
(
    [0] => /lt/pirkiniu-krepselis/?
    [1] => /?
    [2] => /et/?
    [3] => /lv/?
)

woocommerce account: Array
(
    [0] => /lt/paskyra/??(.*)
    [1] => /??(.*)
    [2] => /et/??(.*)
    [3] => /lv/??(.*)
)

final list after rocket_cache_reject_uri: Array
(
    [0] => /testera/
    [1] => /(?:.+/)?feed(?:/(?:.+/?)?)?$
    [2] => /(?:.+/)?embed/
    [4] => /lt/apmokejimas/??(.*)
    [5] => /??(.*)
    [6] => /et/??(.*)
    [7] => /lv/??(.*)
    [8] => /lt/pirkiniu-krepselis/?
    [9] => /?
    [10] => /et/?
    [11] => /lv/?
    [12] => /lt/paskyra/??(.*)
    [13] => /??(.*)
    [14] => /et/??(.*)
    [15] => /lv/??(.*)
    [16] => /wc-api/v(.*)
    [17] => /(index\.php/)?(.*)wp\-json(/.*|$)
)
piotrbak commented 3 months ago

Not enough customer feedback here to implement this in the nearest future.