Skip Navigation

This thread is resolved. Here is a description of the problem and solution.

Problem:
If you're trying to retrieve product translations via GraphQL using the slug as the ID and are encountering issues where the translations array returns `null`, this might be due to a compatibility issue between the WPML GraphQL plugin and the WPGraphQL WooCommerce (WooGraphQL) plugin.

Solution:
We've identified that the problem stems from how product types are resolved in the GraphQL schema within the WooGraphQL plugin. Specifically, the issue arises because the product model is unexpectedly transformed into a post model when WPML is active, due to the function

resolveTranslationsField

in the WPML plugin. Unfortunately, there isn't a direct solution within the current setup as the WooGraphQL plugin isn't officially listed as compatible with WPML. A potential workaround is to use the standard post schema to fetch products and their translations, which bypasses the schema conflict.

Please note that this solution might be outdated or not applicable to your specific case. We highly recommend checking related known issues at https://wpml.org/known-issues/, verifying the version of the permanent fix, and confirming that you have installed the latest versions of themes and plugins. If the issue persists, please open a new support ticket at WPML support forum for further assistance.

This is the technical support forum for WPML - the multilingual WordPress plugin.

Everyone can read, but only WPML clients can post here. WPML team is replying on the forum 6 days per week, 22 hours per day.

Tagged: 

This topic contains 10 replies, has 2 voices.

Last updated by Bruno Kos 8 months, 3 weeks ago.

Assisted by: Bruno Kos.

Author Posts
September 30, 2024 at 12:00 pm #16235988

jakeS-3

<b>Background of the issue: </b>
I am trying to retrieve a product's translation(s) via GraphQL using the slug as the ID. On pages and posts, I would get back the translations as an array. With a product, however, I do not get the product's translations and instead I get `null`. I would expect products to follow the same logic and produce an array of translations. Given the following fragment:

fragment BasicProductContent on Product {
  __typename   # e.g. "SimpleProduct"
  type         # e.g. "SIMPLE"
  id           # The GraphQL ID
  databaseId   # The WP post's database ID
  sku          # A manually configured attribute of the WP post
  languageCode # 'en' or 'zh-hant'
  guid         # A URI using the WP post's database ID
  link         # The complete URI to the WP post using the slug
  uri          # All the path parameters for the WP post
  slug         # The WP post's slug path parameter
}

I am running the following query:

query GetProduct($productId: ID!, $productIdType: ProductIdTypeEnum!) {
  product(id: $productId, idType: $productIdType) {
    ...BasicProductContent
    translations {
      ...BasicProductContent
    }
  }
}

<b>Symptoms: </b>
I expected to see an array of translations for the product, but instead, I got `null` in the translations array.

Here's what I get:

{
  "data": {
    "product": {
      "__typename": "SimpleProduct",
      "type": "SIMPLE",
      "id": "graphql-id-obfuscated-native",
      "databaseId": 1234,
      "sku": "SKU0001",
      "languageCode": "en",
      "guid": "<em><u>hidden link</u></em>",
      "link": "<em><u>hidden link</u></em>",
      "uri": "/shop/native-slug/",
      "slug": "native-slug",
      "translations": [ null ]
    }
  }
}

I should be getting something like this:

{
  "data": {
    "product": {
      "__typename": "SimpleProduct",
      "type": "SIMPLE",
      "id": "graphql-id-obfuscated-native",
      "databaseId": 1234,
      "sku": "SKU0001",
      "languageCode": "en",
      "guid": "<em><u>hidden link</u></em>",
      "link": "<em><u>hidden link</u></em>",
      "uri": "/shop/native-slug/",
      "slug": "native-slug",
      "translations": [
        {
          "__typename": "SimpleProduct",
          "type": "SIMPLE",
          "id": "graphql-id-obfuscated-translated",
          "databaseId": 4321,
          "sku": "SKU0001",
          "languageCode": "zh-hant",
          "guid": "<em><u>hidden link</u></em>",
          "link": "<em><u>hidden link</u></em>",
          "uri": "/shop/native-slug/",
          "slug": "translated-slug"
        }
      ]
    }
  }
}

<b>Questions: </b>
Why am I getting `null` in the translations array for products?
Is there a different method to retrieve product translations via GraphQL?

October 1, 2024 at 5:48 am #16238343

Bruno Kos
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+02:00)

Hi,

Thank you for contacting WPML support!

Would you be willing to provide me with WordPress and FTP credentials so I could investigate the issue directly?

https://wpml.org/purchase/support-policy/privacy-and-security-when-providing-debug-information-for-support/

I marked your next reply as private so that you can safely add credentials.

Regards,
Bruno Kos

October 1, 2024 at 1:22 pm #16240691

Bruno Kos
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+02:00)

I tried with:

{
  "productId": "1698",
  "productIdType": "DATABASE_ID"
}

But I indeed I only get:

{
  "data": {
    "product": {
      "translations": [null]
    }
  }
}

I am checking this with our 2nd tier and will keep you posted.

October 1, 2024 at 2:29 pm #16241165

Bruno Kos
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+02:00)

Since we see server error in logs, can you get us logs?
hidden link

You can also do this:

1. Edit wp-config.php and insert the following lines (just before /* That's all, stop editing! Happy publishing. */ part)

define( 'WP_DEBUG', true);
define( 'WP_DEBUG_LOG', true);
define( 'WP_DEBUG_DISPLAY', false);

2. Reproduce the issue

3. Locate the debug log in: /wp-content/debug.log

4. Paste the latest lines here. No need to paste the entire log file, just 10 lines or so will do. Please censor any sensitive information.

https://codex.wordpress.org/Debugging_in_WordPress

We also need this:

- do the above reproducing (so from step 2)
- get the latest server debug logs (you can ask hosting support if unsure how to locate them)

And then run your queries with products to see if something comes up in error logs.

October 2, 2024 at 7:16 am #16243532

jakeS-3

I first tried it like this:

define( 'WP_DEBUG', true);
define( 'WP_DEBUG_LOG', true);
define( 'WP_DEBUG_DISPLAY', false);

define('SAVEQUERIES', true);
define('GRAPHQL_DEBUG', true);

Unfortunately that didn't produce much…

[02-Oct-2024 07:13:38 UTC] (graphql_purge) key: dGVybToyNzY=, event: term_updated, user: 6, page: /wp-admin/admin-ajax.php url: ….….com/graphql
[02-Oct-2024 07:13:38 UTC] (graphql_purge) key: skipped:term, event: term_updated, user: 6, page: /wp-admin/admin-ajax.php url: ….….com/graphql
[02-Oct-2024 07:13:38 UTC] (graphql_purge) key: list:productcategory, event: term_created, user: 6, page: /wp-admin/admin-ajax.php url: ….….com/graphql

Then I tried it like this:

define( 'WP_DEBUG', true);
define( 'WP_DEBUG_LOG', true);
define( 'WP_DEBUG_DISPLAY', false);
define('SAVEQUERIES', false);
define('GRAPHQL_DEBUG', false);

That added this line:

[02-Oct-2024 07:20:07 UTC] PHP Deprecated:  str_ireplace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /nas/content/live/…/wp-content/plugins/wp-graphql-jwt-authentication-0.7.0/src/ManageTokens.php on line 349
October 2, 2024 at 8:22 am #16243970

Bruno Kos
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+02:00)

To troubleshoot this problem, I'll install the Duplicator plugin and generate packages for further debugging purposes. I'll ensure to exclude all media files to maintain a minimal package size. You can find more information about the process here: [link](https://wpml.org/faq/provide-supporters-copy-site/). Please confirm if this approach is acceptable to you.

October 2, 2024 at 12:00 pm #16245383

jakeS-3

That's fine, thanks. Please go ahead and install the Duplicator plugin and do what you need to do.

October 2, 2024 at 1:07 pm #16245805

Bruno Kos
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+02:00)

This has been escalated to our 2nd tier team team and may take some debugging time, I'll get back to you as soon as I have any news or questions for you.

October 3, 2024 at 6:21 pm #16251686

jakeS-3

Hi Bruno,

Any news on this one? Just curious because it's blocking a release of a client application.

October 4, 2024 at 8:59 am #16252941

Bruno Kos
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+02:00)

We are still checking this, but unfortunately I have no news to share yet.

October 8, 2024 at 5:33 am #16263880

Bruno Kos
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+02:00)

We've identified the issue you're experiencing, which is due to the interaction between the WPML GraphQL plugin and the WPGraphQL WooCommerce (WooGraphQL) plugin that you're using.

Specifically, the problem originates from the following code in the WooGraphQL plugin (`wp-graphql-woocommerce-0.21.0/includes/class-core-schema-filters.php:123`):

public static function register_post_types( $args, $post_type ) {
    if ( 'product' === $post_type ) {
        $args['show_in_graphql'] = true;
        $args['model'] = \WPGraphQL\WooCommerce\Model\Product::class;
        $args['graphql_single_name'] = 'Product';
        $args['graphql_plural_name'] = 'Products';
        $args['graphql_kind'] = 'interface';
        $args['graphql_interfaces'] = [ 'ContentNode' ];
        $args['graphql_register_root_field'] = false;
        $args['graphql_register_root_connection'] = false;
        $args['graphql_resolve_type'] = static function ( $value ) {
            $type_registry = \WPGraphQL::get_type_registry();
            $possible_types = WooGraphQL::get_enabled_product_types();
            $product_type = $value->get_type();

This function defines how product types are resolved in the GraphQL schema. Without WPML, it works as expected because `$value` is an instance of `WPGraphQL\WooCommerce\Model\Product`, which includes the necessary `get_type` method. However, with WPML active, the code runs twice. The first time it behaves correctly, but the second time `$value` becomes an instance of `WPGraphQL\Model\Post`, which doesn't have the `get_type` method, resulting in an error.

This switch occurs due to the function `resolveTranslationsField` in the WPML plugin (`wpml-graphql/classes/Resolvers/PostFields.php`), where the product model is unexpectedly transformed into a post model.

We looked into possible workarounds, but unfortunately, we couldn't find a direct solution within the current setup. The WooGraphQL plugin isn't officially listed as compatible with WPML. It might be worth encouraging the plugin developers to join WPML’s Go Global program to ensure compatibility going forward. You can find more information about the program here: https://wpml.org/documentation/support/go-global-program/.

That said, there is one possible workaround: instead of retrieving product translations through the product schema field provided by the WooGraphQL plugin, you could use the standard post schema to fetch products and their translations. This approach would bypass the issue caused by the schema conflict.