The code in this article is considered a customisation. It's provided as is, without guarantees or support. Should you need assistance implementing the code, please feel free to contact us to request a consultation.


To use the code, simply add it to your theme's functions.php file. See How to Safely Add Custom Code to WordPress Sites for more information on how to do that.


Background

When using the Aelia Prices by Country plugin, the most common cause of products "disappearing" on language specific pages is the "Filter invisible products from the catalogue query", which is located at WooCommerce > Prices by Country > Catalogue (see below).

Prices by Country - Pricing and Catalogue settings


How the product filtering works

The purpose of that option is to improve the accuracy of the calculations performed by WooCommerce to determine the total amount of products, as well as the number of catalogue pages to display. As indicated on the settings page, such could slow down the site, due to the additional processing required to fetch the list of visible products.


To mitigate this issue, the Prices by Country plugin includes an optimisation mechanism, which caches the list of visible product IDs for a period of time. This greatly improves performance, as the list is fetched quickly after the initial processing performed to prepare it.



How the product filtering can affect language-specific pages

Some multi-language plugins, such as WPML, create a clone of each posts, or products, for each language. The clone is language-specific and, and its ID is different from the one of the original product. 


Due to that, the following can happen when the "product filtering" feature is enabled:

  1. The Prices by Country plugin determines that product with IDs 1, 2, 3 and 4 should be visible.
  2. The Prices by Country plugin stores the list of IDs in the cache.
  3. WPML loads the clones of the products for the active language (e.g. Italian).
  4. The IDs loaded by WPML are the language-specific ones, for example 10, 11, 12 and 13.
  5. The "get products" query is filtered to show only products with the IDs from #1.
  6. Since the IDs loaded by WPML don't match the list of visible products prepared by the Prices by Country plugin, the products are not displayed.


Solution

Starting from version 1.10.3.200514, the Prices by Country plugin includes a filter that can be used to generate a custom cache key to store the list of visible products. This new filter can be used to tell the plugin to use different cache keys for each language.


Example 1 - Generate a language-specific cache key using WPML

/**
 * Alters the key used by the Prices by Country plugin to cache the list of 
 * visible product IDs, byWith this code, the cache key used by the Prices by Country plugin will change depending on the active language. This will allow to store a separate list of IDs for each language, which will reflect the IDs actually loaded by WPML when displaying language-specific content. adding the language code set by WPML.
 *
 * @param array $hash_args
 * @return array
 */
add_filter('wc_aelia_pbc_filter_visible_products_hash', function($hash_args) {
  // If the ICL_LANGUAGE_CODE symbol is defined, it means that WPML is enabled.
  // In such case, we can add such value to the arguments, to generate a language-specific
  // cache key. The string "default" is used to represent a "default language" when the
  // ICL_LANGUAGE_CODE is not defined (e.g. if WPML has been disabled, for any reason)
  $hash_args[] = defined('ICL_LANGUAGE_CODE') ? ICL_LANGUAGE_CODE : 'default';

  return $hash_args;
});

With this code, the cache key used by the Prices by Country plugin will change depending on the active language. This will allow to store a separate list of IDs for each language, which will reflect the IDs actually loaded by WPML when displaying language-specific content.


Example 2 - Generate language-specific cache key using Polylang

/**
 * Alters the key used by the Prices by Country plugin to cache the list of 
 * visible product IDs, by adding the language code set by Polylang.
 *
 * @param array $hash_args
 * @return array
 */
add_filter('wc_aelia_pbc_filter_visible_products_hash', function($hash_args) {
  // If function pll_current_language() is defined, it means that Polylang is enabled.
  // In such case, we can call that function to fetch the active language and use it
  // to generate a language-specific cache key. The string "default" is used to represent 
  // a "default language" when function pll_current_language() is not defined (e.g. if 
  // Polylang has been disabled, for any reason)
  $hash_args[] = function_exists('pll_current_language') ? pll_current_language() : 'default';

  return $hash_args;
});
With this code, the cache key used by the Prices by Country plugin will change depending on the active language. This will allow to store a separate list of IDs for each language, which will reflect the IDs loaded by Polylang when displaying language-specific content.