wordpress-seo icon indicating copy to clipboard operation
wordpress-seo copied to clipboard

`YoastSEO()` doesn't work in a loop within WPGraphQL results

Open tsdexter opened this issue 3 years ago • 5 comments

  • [x] I've read and understood the contribution guidelines.
  • [x] I've searched for any related issues and avoided creating a duplicate issue.

Please give us a description of what happened.

YoastSEO()->meta->for_post($post->ID) doesn't work inside a loop (more specifically in WPGraphQL multiple results loop)

Please describe what you expected to happen and why.

YoastSEO()->meta->for_post($post->ID) should return data for the ID that is passed to it

How can we reproduce this behavior?

  1. install WPGraphQL
  2. Create custom fields
add_action('graphql_register_types', function() {
  register_graphql_field( 'ContentNode', 'breadcrumbs', [
		'type' => 'String',
		'description' => __( 'The Yoast breadcrumb string', 'namespace' ),
		'resolve' => function( \WPGraphQL\Model\Post $post, $args, $context, $info ) {
      return json_encode(YoastSEO()->meta->for_post($post->databaseId)->breadcrumbs);
		}
	]);
  register_graphql_field( 'ContentNode', 'seoTitle', [
		'type' => 'String',
		'description' => __( 'The Yoast seo title string', 'namespace' ),
		'resolve' => function( \WPGraphQL\Model\Post $post, $args, $context, $info ) {
      return json_encode(YoastSEO()->meta->for_post($post->databaseId)->title);
		}
	]);
  register_graphql_field( 'ContentNode', 'seoDesc', [
		'type' => 'String',
		'description' => __( 'The Yoast seo description string', 'namespace' ),
		'resolve' => function( \WPGraphQL\Model\Post $post, $args, $context, $info ) {
      return json_encode(YoastSEO()->meta->for_post($post->databaseId)->description);
		}
	]);
  register_graphql_field( 'ContentNode', 'testId', [
		'type' => 'String',
		'description' => __( 'The Yoast breadcrumb string', 'namespace' ),
		'resolve' => function( \WPGraphQL\Model\Post $post, $args, $context, $info ) {
      return "$post->databaseId";
		}
	]);
})
  1. Call for the fields in a plural call (ie: pages vs. page)
query TEST {
  pages(where: {in: [206097,206098,206099]}) {
    nodes {
      testId
      title
      seoTitle
      seoDesc
      breadcrumbs
    }
  }
}

Which results in the data from the first result being duplicated in the successive results, even though the ID being passed is correct as evidenced by the testId field which outputs the ID being passed to the for_post call

{
  "data": {
    "pages": {
      "nodes": [
        {
          "testId": "206097",
          "title": "TEST PAGE 1",
          "seoTitle": "\"TEST PAGE 1 - Site Name\"",
          "seoDesc": "\"test page 1 meta description\"",
          "breadcrumbs": "[{\"url\":\"https:\\/\\/site.com\\/\",\"text\":\"Home\",\"id\":7292},{\"url\":\"https:\\/\\/site.com\\/test-page-1\\/\",\"text\":\"TEST PAGE 1\",\"id\":206097}]"
        },
        {
          "testId": "206098",
          "title": "test page 2",
          "seoTitle": "\"TEST PAGE 1 - Site Name\"",
          "seoDesc": "\"test page 1 meta description\"",
          "breadcrumbs": "[{\"url\":\"https:\\/\\/site.com\\/\",\"text\":\"Home\",\"id\":7292},{\"url\":\"https:\\/\\/site.com\\/test-page-1\\/\",\"text\":\"TEST PAGE 1\",\"id\":206097}]"
        },
        {
          "testId": "206099",
          "title": "test page 3",
          "seoTitle": "\"TEST PAGE 1 - Site Name\"",
          "seoDesc": "\"test page 1 meta description\"",
          "breadcrumbs": "[{\"url\":\"https:\\/\\/site..com\\/\",\"text\":\"Home\",\"id\":7292},{\"url\":\"https:\\/\\/site.com\\/test-page-1\\/\",\"text\":\"TEST PAGE 1\",\"id\":206097}]"
        }
      ]
    }
  },
  "extensions": {
    "debug": []
  }
}

@jasonbahl I'm not sure if this is possibly a WPGraphQL issue? Any ideas?

Technical info

  • If relevant, which editor is affected (or editors):
  • [ ] Classic Editor
  • [ ] Gutenberg
  • [ ] Classic Editor plugin
  • Which browser is affected (or browsers):
  • [ ] Chrome
  • [ ] Firefox
  • [ ] Safari
  • [ ] Other

Used versions

  • WordPress version: 5.9
  • Yoast SEO version: 17.4, 19, 19.2
  • Gutenberg plugin version:
  • Classic Editor plugin version:
  • Relevant plugins in case of a bug:
  • Tested with theme:

tsdexter avatar Jul 05 '22 19:07 tsdexter

I am working on creating a reproduction - I'm not seeing it in a barebones install, am trying to track down the conflict

tsdexter avatar Jul 05 '22 20:07 tsdexter

Thanks for the report @tsdexter. Were you able to reproduce the issue on a fresh install with a traditional foreach loop instead of using WPGraphQL?

mmikhan avatar Jul 11 '22 15:07 mmikhan

@iamazik I had to work on other things in the meantime. I will get back to creating a more barebones reproduction this week. Thanks for taking a look, I'll post back if/when I can get a repro working

tsdexter avatar Jul 11 '22 16:07 tsdexter

Do you have any update on this yet @tsdexter?

mmikhan avatar Aug 24 '22 22:08 mmikhan

@iamazik I had to continue development of other more important features since...however, we do still need this for launch, so I will be coming back to it in the next couple of weeks.

tsdexter avatar Aug 25 '22 17:08 tsdexter

@iamazik I could not reproduce this anywhere except my production environment or clones of it, with or without our theme and with or without all plugins except WPGraphQL and Yoast disabled.

I finally managed to track down the issue though, somehow my database tables for the indexables had no auto_increment flag on the ID columns so all entries into indexables tried to use id=0 causing none of them to be input - the tables only had one record (the yoast plugin did not pick up on this issue, it finished indexing as if everything was fine and never showed any issues with indexables in the UI - some sort of verification of indexables could be handy)

I manually fixed the table structure and re-indexed and everything is working as expected now.

note: I believe the missing auto_increment flags was introduced during a database migration last year from MS SQL (using a fork of wordpress https://github.com/ProjectNami/projectnami) back to MySQL. I'm not sure what the impact of not having any indexable entries is, but I assume it has been affecting our SEO all this time?

tsdexter avatar Sep 28 '22 01:09 tsdexter

Thanks for the detailed investigation @tsdexter. There's no SEO impact by not having the auto_increment flag on a database table.

mmikhan avatar Sep 28 '22 09:09 mmikhan

No problem @iamazik - though it's not just that the flag wasn't there, but rather that the yoast indexables tables had no entries due to not being able to insert any data... so I assumed anything in the yoast plugin that relies on the indexables data wouldn't work right, it would only get the one entry with id=0

tsdexter avatar Sep 28 '22 12:09 tsdexter