wp-graphql-polylang icon indicating copy to clipboard operation
wp-graphql-polylang copied to clipboard

nodeByURI not returning correct node when translations have same slug

Open kuuak opened this issue 2 years ago • 6 comments

Hi,

First: thanks for the plugin which is great! 👏

My setup:

  • WP 5.8.3
  • Polylang Pro 3.1.2 (the pro version gives the possibility to share the same slug between translations)
  • WPGraphql 1.6.12
  • WPGraphql Polylang 0.6.0
  • Active theme: TwentyTwentyOne 1.4.0
  • Three languages set: FR*, EN & DE (FR is the default)

When I have posts or pages sharing the same slug between translations, the RootQuery nodeByUri field does not return the correct node according to the localized URI.

As you can see the queries in the GraphQLi (screenshot below), the three queries return the same node which can be any of the translated node.

Capture d’écran 2022-01-21 à 17 49 38 Capture d’écran 2022-01-21 à 17 49 59

I could find a workaround to make it work, but it feels really dirty:


// Add lang arg to $extra_query_vars to nodeByURI rootquery
add_filter( 'graphql_RootQuery_fields',  function ($fields) {
	if ( isset($fields['nodeByUri']) ) {
		$fields['nodeByUri']['resolve'] = function ( $root, $args, AppContext $context ) {
			if ( empty( $args['uri'] ) ) return null;

			$extra_query_vars = [];
			$parsed_url = wp_parse_url( $args['uri'] );

			// If we match a language in the URI
			if ( preg_match("/^\/?(\w{2})\/.+/", $parsed_url['path'], $matches) ) {
				$extra_query_vars['lang'] = $matches[1];
				$extra_query_vars['is_graphql_nodebyuri'] = true;
			}

			return $context->node_resolver->resolve_uri( $args['uri'], $extra_query_vars );
		};
	}
	return $fields;
}, 20);

// rewrite SQL query to include lang for pages & posts
add_filter( 'query', function query_pagename_nodebyuri( $query ) {
	global $wp;

	if ( isset($wp->query_vars['is_graphql_nodebyuri']) && isset($wp->query_vars['lang']) ) {
		global $wpdb;
		if ( isset($wp->query_vars['pagename']) ) {
			$pagename_in = implode("','", explode('/', $wp->query_vars['pagename']));
			if ( preg_match("/post_name IN \('$pagename_in'\)/", $query) ) {
				$query = "
					SELECT p.ID, p.post_name, p.post_parent, p.post_type
					FROM {$wpdb->posts} AS p
						LEFT JOIN {$wpdb->term_relationships} AS tr ON p.ID=tr.object_id
						LEFT JOIN {$wpdb->term_taxonomy} AS tt ON tr.term_taxonomy_id=tt.term_taxonomy_id
						LEFT JOIN {$wpdb->terms} AS t ON tt.term_id=t.term_id
					WHERE
						p.post_name IN ('$pagename_in')
						AND p.post_type IN ('post','page','attachment')
						AND tt.taxonomy='language'
						AND t.slug='{$wp->query_vars['lang']}'
				";
			}
		}
		else if ( isset($wp->query_vars['name']) && preg_match("/post_name IN \('{$wp->query_vars['name']}'\)/", $query) ) {
			$query = "
				SELECT p.ID, p.post_name, p.post_parent, p.post_type
				FROM {$wpdb->posts} AS p
					LEFT JOIN {$wpdb->term_relationships} AS tr ON p.ID=tr.object_id
					LEFT JOIN {$wpdb->term_taxonomy} AS tt ON tr.term_taxonomy_id=tt.term_taxonomy_id
					LEFT JOIN {$wpdb->terms} AS t ON tt.term_id=t.term_id
				WHERE
					p.post_name IN ('{$wp->query_vars['name']}')
					AND post_type IN ('post','attachment')
					AND tt.taxonomy='language'
					AND t.slug='{$wp->query_vars['lang']}'
			";
		}
} );

However, this is really risky business as I'm changing the SQL query to the DB to handle the language. So I'm wondering if there is a better solution to fix this translation issues with nodeByUri ??

kuuak avatar Jan 21 '22 17:01 kuuak

Thanks for the problem description. I am facing the same issue.

smesterheide avatar Feb 09 '22 15:02 smesterheide

I am reposting the conversation I had with the Polylang team regading the issue:

Sébastien replied

Feb 14, 16:33 Hello,

Posting here or in our GH is the same, we do not support GraphQL. As per our lead developer the idea developed on the issue you mentioned is the right one.

Regards

Jan replied

Feb 14, 12:42 Hi Sebastian,

thanks for your message.

Do you mind if I post this message verbatim to Github?

Best regards,

Sébastien replied

Feb 14, 9:30 Hello,

Thank you for contacting us.

As you know, "WP Graphql Polylang" is 13rd party plugin we're not involved in. We do not know how it works and won't be able to help without digging in the code... and it's not in our current roadmap. If "WP Graphql Polylang" developers need help to solve this, they can of course contact us and our developers will try to help the best as they can. We can also provide them Polylang pro license to correct this.

I suggest you to contact & check with them how to fix this.

Regards

Jan sent a message

Feb 13, 14:13 Hello, I am using Polylang in a decoupled scenario with GraphQL connecting the frontend to WP. There is a 3rd party plugin for Polylang you might be familiar with: https://github.com/valu-digital/wp-graphql-polylang

Unfortunately I cannot use the Pro feature of slug sharing as described in the ongoing issue: https://github.com/valu-digital/wp-graphql-polylang/issues/67

I am hoping you can contribute to the GraphQL extension and help fix the issue.

Best regards Jan

smesterheide avatar Feb 14 '22 15:02 smesterheide

The same bug applies to all queries with an URI even for tags. One may use different slugs work posts or taxonomies to overcome this issue, but it even affects tags! It would be great if we can find a solution!

evrenbal avatar May 04 '22 21:05 evrenbal

+1

krishaamer avatar Jun 15 '22 07:06 krishaamer