valu-digital / wp-graphql-polylang

WPGraphQL Polylang Extension for WordPress
https://packagist.org/packages/valu/wp-graphql-polylang
GNU General Public License v2.0
129 stars 22 forks source link

nodeByURI not returning correct node when translations have same slug #67

Open kuuak opened 2 years ago

kuuak commented 2 years ago

Hi,

First: thanks for the plugin which is great! 👏

My setup:

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 ??

smesterheide commented 2 years ago

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

smesterheide commented 2 years ago

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

evrenbal commented 2 years ago

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!

krishaamer commented 2 years ago

+1

predaytor commented 1 year ago

+1 :(

ehnsio commented 1 year ago

+1

FloLech commented 3 months ago

+1