Aller au contenu
login
arrow_backRetour aux issues
Yoast/wordpress-seo #23527

[Bug]: set_oembed_data` ignores its `$post` argument — second embed in a post returns the first embed's data

ecoDébutant patch welcome good first issue bug

descriptionDescription

### Prerequisites - [x] I've read and understood the [contribution guidelines](https://github.com/Yoast/wordpress-seo/blob/trunk/.github/CONTRIBUTING.md). - [x] I've searched for any related issues and avoided creating a duplicate issue. ### Please give us a description of what happened ### Environment - Yoast SEO 27.7 (free) - WordPress 6.8.2, PHP 8.3, LiteSpeed - Reproduced with WP-CLI on a clean render, no page cache involved ### Summary When a single post contains two or more internal WordPress embeds (`wp:embed` blocks pointing at other posts on the same site), the second and subsequent embeds render with the **first** embed's title, permalink and iframe `src`. The reader sees a link to the wrong article. Removing the `oembed_response_data` callback registered in `src/integrations/front-end/open-graph-oembed.php` resolves it completely. ### Reproduction 1. Create post A and post B, both published. 2. Create post C containing two `wp:embed` blocks: first post A, then post B. 3. Render post C's content (front end, or `apply_filters( 'the_content', ... )`). 4. Both embeds render as post A. ### Evidence that the lookup itself is healthy Called in isolation, in the same post context, every layer returns the correct result for post B's URL: ``` url_to_postid() -> correct post ID get_oembed_response_data_for_url() -> correct title wp_oembed_get() -> correct permalink in the returned HTML ``` The failure only occurs during a full `the_content` pass where more than one embed is processed in the same request. Logging `embed_oembed_html` shows the mismatch clearly — `$url` is post B, the returned HTML is post A: ``` post_ID=197058 in=.../post-a/ out=.../post-a/ <- first embed, correct post_ID=197058 in=.../post-b/ out=.../post-a/ <- second embed, wrong ``` ### Isolating the cause With all `_oembed_*` postmeta deleted and the object cache flushed before each run: - Default: second embed returns post A. **Fails.** - With `WPSEO\Integrations\Front_End\Open_Graph_OEmbed::set_oembed_data` unhooked from `oembed_response_data`: second embed returns post B. **Passes.** Other callbacks on the same hook (`get_oembed_response_data_rich`, WooCommerce, Wordfence) were left in place and are not involved. Nothing is hooked to `oembed_request_post_id`, `pre_oembed_result` or `post_link`. ### Suspected cause `set_oembed_data( $data, $post )` receives the correct `$post` object but appears to build its values from the memoized front-end/meta-tags context for the current request rather than from that argument. The first embed populates the memoizer; subsequent embeds are then served the first one's context. ### Why this is worse than a display glitch The incorrect HTML is persisted by `WP_Embed` into `_oembed_` postmeta. The cache key is derived from the requested URL, so post B's cache key ends up holding post A's HTML. WordPress will not refetch while that row exists, so the wrong link survives indefinitely — long after the page cache is cleared. Recovery required deleting the `_oembed_*` rows site-wide (~85,000 on our site) and letting them rebuild. This is presumably why the bug has gone unreported: it needs two or more embeds in one post, and once it happens the wrong value looks permanent rather than intermittent. ### Current workaround A theme-level filter at priority 11 that restores the values from the `$post` argument after Yoast has run: ```php add_filter( 'oembed_response_data', function( $data, $post ) { if ( ! $post instanceof WP_Post ) { return $data; } $data['url'] = get_permalink( $post ); $data['title'] = get_the_title( $post ); if ( ! empty( $data['html'] ) ) { $width = ! empty( $data['width'] ) ? (int) $data['width'] : 600; $height = ! empty( $data['height'] ) ? (int) $data['height'] : 338; $data['html'] = get_post_embed_html( $width, $height, $post ); } return $data; }, 11, 2 ); ```
codeOuvre sur GitHub