Yoast / wordpress-seo

Yoast SEO for WordPress
https://yoast.com/wordpress/plugins/seo/
Other
1.77k stars 891 forks source link

wp_set_object_terms doesn't add term into a breadcrumbs. #20469

Open Komarovski opened 1 year ago

Komarovski commented 1 year ago

Here's the example where you can see the bug:

$insert_post_id = wp_insert_post(array(
    'post_title'=>$some_title,
    'post_content'=>wp_slash($some_content),
    'post_status'=>'publish',
    'post_type'=>'question',
));
$question_category_insert = wp_set_object_terms($insert_post_id, $question_term, 'question-category');

When I create post programmaticaly and assigning the term to this post - yoast breadcrumbs doesn't show link to a term.

But if I go in admin - selecting newly created post and just pressing "Update" without any changes - the link to term in breadcrumbs appeared.

vraja-pro commented 1 year ago

@Komarovski I wasn't able to reproduce the error, these are the steps I followed:

Can you add more details to that errors?

Komarovski commented 1 year ago

Hey, I'm implementing breadcrumbs in my theme with yoast_breadcrumb('<p id="breadcrumbs">','</p>'); function in header.php file. In wp_set_object_terms function I'm using custom taxonomy "question-category" not the native "category" and in wp_insert_post I'm using custom post type "question" not the native "post". I haven't check how it works with native post types and taxonomies. The debug log is empty.

vraja-pro commented 1 year ago

@Komarovski I wasn't able to reproduce the error, these are the steps I followed:

balex25 commented 1 year ago

Hi,

I have the same problem.

Please check here: https://wordpress.org/support/topic/yoast_breadcrumb-problem-2/

You don't need to create a new post type, this bug is on any post type or taxonomy, even on the default one.

Just run this code on a page template: `$post_id = wp_insert_post( array( 'post_type' => 'post', 'post_title' => 'random title', 'post_content' => '', 'post_status' => 'publish' ));

if ($post_id != 0) { wp_set_object_terms($post_id, 'catname', 'category'); }`

Then check the created post page. It outputs something like as: Home » Uncategorized » random title inside of Home » catname » random title

You should create post from wp_insert_post and not update/change anything on wp-admin (as will fix breadcrumb bug on any update/changes to created post via wp_insert_post on wp-admin).

balex25 commented 1 year ago

After some tests, I see this bug happened only from version 19.14 to the latest version of the Yoast SEO plugin.

https://developer.yoast.com/changelog/yoast-seo/19.14/

Any version lower than 19.14 works as expected!

Tested with:

Plugins:

enricobattocchi commented 10 months ago

We cannot reproduce the bug anymore, not even with previous versions of Yoast SEO that were reported buggy. We are using WP 6.4 now, all the reports are dated before WP 6.3 was released, so we can't rule out that this had a role in triggering the problem. @Komarovski @balex25 are you still experiencing the issue?

balex25 commented 10 months ago

We cannot reproduce the bug anymore, not even with previous versions of Yoast SEO that were reported buggy. We are using WP 6.4 now, all the reports are dated before WP 6.3 was released, so we can't rule out that this had a role in triggering the problem. @Komarovski @balex25 are you still experiencing the issue?

Note: I tested on the latest versions:

Yes, problems are still there. I digged more and found something. Seem the problem comes from:

wp_yoast_indexable
wp_yoast_indexable_hierarchy

So, I created a post via the wp_insert_post function (custom post type "item"), then grabbed the post ID and updated a taxonomy on the created post via wp_set_object_terms.

$post_id = wp_insert_post( array(
  'post_type'    => 'item',
  'post_title'      => 'Post Title',
  'post_content'        => 'Post Content',
  'post_status'     => 'publish'
));

Now after the post is created and get the post id, I set the custom taxonomy as: wp_set_object_terms($post_id, 'Term Name', 'origin'); (origin taxonomy is attacked to "item" post type)

Also, I set on "Breadcrumbs for post types" settings:

Problems:

wp_yoast_indexable: Now when the post is created via wp_insert_post, it adds a row in wp_yoast_indexable, but has_ancestors set to 0, and when I go to edit the post and click on the "update" button (without any changes) value is updated, so has_ancestors is now 1.

wp_yoast_indexable_hierarchy: Here are the same as above, values after the post is created via wp_insert_post:

when I click on the update button whiout any changes to the post, values are updated like as:

So, it incorrectly updated (or not updated) the ancestor when post-taxonomy was updated via the wp_set_object_terms function. Yoast SEO seems to not see taxonomy updated via functionwp_set_object_terms and thinks posts have no taxonomy set (until the post is manually updated).

A current fix seems to trigger Yoast SEO to update its indexable data after I updated the custom taxonomy via wp_set_object_terms. This will generate correct Breadcrumbs and have correct ancestors in Yoast tables.

    // Update taxonomy
    wp_set_object_terms($post_id, $namespace, 'origin'); 

    // Trigger Yoast SEO to update its indexable data
    if (function_exists('YoastSEO')) {
      // Retrieve the Indexable for the post
      $indexable_repository = YoastSEO()->classes->get('Yoast\WP\SEO\Repositories\Indexable_Repository');
      $indexable = $indexable_repository->find_by_id_and_type($post_id, 'post', true);

      // If an Indexable is found or created, build its hierarchy
      if ($indexable) {
        $indexable_hierarchy_builder = YoastSEO()->classes->get('Yoast\WP\SEO\Builders\Indexable_Hierarchy_Builder');
        $indexable_hierarchy_builder->build($indexable);
      }
    }

So, the working solution so far for me is as:

  1. Created post via wp_insert_post.
  2. Attack a custom taxonomy to the created post.
  3. Trigger Yoast SEO to update indexable data.

You can easily implement a solution to detect when a post taxonomy is created or updated via hooks like set_object_terms, added_term_relationship, and regenerated post indexable, hierarchy, etc.

enricobattocchi commented 10 months ago

@balex25 thanks for the useful info! One thing that might be relevant: how do you trigger the post creation? Is it fired via a hook, and if so, which one? Or are you using any other way (a plugin adding a button, etc.)?

Just to be sure that we are not facing any timing/priority issue there.

josevarghese commented 8 months ago

Hi @balex25

I hope you are doing great. As we haven't heard back from you, can you please share more details asked by our development team above ? It would be helpful for us to replicate it and to narrow down the issue further.

Looking forward to hearing from you.