Skip to content

Commit 972d21c

Browse files
committed
Embeds: Add wp_oembed_add_discovery_links() to run earlier at wp_head priority 4.
This results in the oEmbed discovery links being printed before scripts and styles are printed. This helps ensure they appear within the first 150K bytes of the HTML response, which is required by `WP_oEmbed::discover()`. With increasing the `styles_inline_size_limit` from 20K to 40K in #63018, it becomes more probable that the oEmbed discovery links will be pushed out of range. For backwards compatibility with themes and plugins that disable the oEmbed discovery links by unhooking `wp_oembed_add_discovery_links()` from running at `wp_head` priority 10 (even though the `oembed_discovery_links` filter is available to disable such links), this callback is added a second time to run earlier at priority 4. The first time the function runs, it checks to see if the callback is still hooked at priority 10. If not, the function short circuits. If it is still hooked at priority 10, however, the function then unhooks itself at priority 10 so that it won't run a second time later during the `wp_head` action, before proceeding with printing the discovery links. A similar back-compat approach was taken previously in [60910]. The back-compat checks are only performed if the function is invoked during the `wp_head` action, allowing the function to be called "idempotently" elsewhere. Developed in #10449 Follow-up to [61118], [61117]. Props westonruter, swissspidy. See #64186, #63018. Fixes #64178. git-svn-id: https://develop.svn.wordpress.org/trunk@61119 602fd350-edb4-49c9-b593-d223f7449a82
1 parent faf3d46 commit 972d21c

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

src/wp-includes/default-filters.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,8 @@
704704
add_action( 'rest_api_init', 'wp_oembed_register_route' );
705705
add_filter( 'rest_pre_serve_request', '_oembed_rest_pre_serve_request', 10, 4 );
706706

707-
add_action( 'wp_head', 'wp_oembed_add_discovery_links' );
707+
add_action( 'wp_head', 'wp_oembed_add_discovery_links', 4 ); // Printed after feed_links() and feed_links_extra().
708+
add_action( 'wp_head', 'wp_oembed_add_discovery_links' ); // Unhooked the first time that wp_oembed_add_discovery_links() runs for back-compat.
708709
add_action( 'wp_head', 'wp_oembed_add_host_js' ); // Back-compat for sites disabling oEmbed host JS by removing action.
709710
add_filter( 'embed_oembed_html', 'wp_maybe_enqueue_oembed_host_js' );
710711

src/wp-includes/embed.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,19 @@ function wp_oembed_register_route() {
332332
*
333333
* @since 4.4.0
334334
* @since 6.8.0 Output was adjusted to only embed if the post supports it.
335+
* @since 6.9.0 Now runs first at `wp_head` priority 4, with a fallback to priority 10. This helps ensure the discovery links appear within the first 150KB.
335336
*/
336337
function wp_oembed_add_discovery_links() {
338+
if ( doing_action( 'wp_head' ) ) {
339+
// For back-compat, short-circuit if a plugin has removed the action at the original priority.
340+
if ( ! has_action( 'wp_head', 'wp_oembed_add_discovery_links', 10 ) ) {
341+
return;
342+
}
343+
344+
// Prevent running again at the original priority.
345+
remove_action( 'wp_head', 'wp_oembed_add_discovery_links' );
346+
}
347+
337348
$output = '';
338349

339350
if ( is_singular() && is_post_embeddable() ) {

tests/phpunit/tests/oembed/discovery.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ public function test_add_oembed_discovery_links_to_post() {
4949
$expected .= '<link rel="alternate" title="oEmbed (XML)" type="text/xml+oembed" href="' . esc_url( get_oembed_endpoint_url( get_permalink(), 'xml' ) ) . '" />' . "\n";
5050

5151
$this->assertSame( $expected, get_echo( 'wp_oembed_add_discovery_links' ) );
52+
53+
add_filter( 'oembed_discovery_links', '__return_empty_string' );
54+
$this->assertSame( '', get_echo( 'wp_oembed_add_discovery_links' ), 'Expected filtering oembed_discovery_links to empty string to result in no wp_oembed_add_discovery_links() output.' );
5255
}
5356

5457
public function test_add_oembed_discovery_links_to_page() {
@@ -100,4 +103,39 @@ public function test_wp_oembed_add_discovery_links_non_embeddable_post_type_outp
100103

101104
$this->assertFalse( get_oembed_response_data( $post, 100 ) );
102105
}
106+
107+
/**
108+
* @ticket 64178
109+
* @covers ::wp_oembed_add_discovery_links
110+
*/
111+
public function test_wp_oembed_add_discovery_links_back_compat() {
112+
$action = 'wp_head';
113+
$old_priority = 10;
114+
$new_priority = 4;
115+
$callback = 'wp_oembed_add_discovery_links';
116+
117+
$this->assertTrue( has_action( $action, $callback, $old_priority ), 'Expected wp_oembed_add_discovery_links() to be hooked at wp_head with old priority.' );
118+
$this->assertTrue( has_action( $action, $callback, $new_priority ), 'Expected wp_oembed_add_discovery_links() to be hooked at wp_head with new priority.' );
119+
120+
// Remove all wp_head actions and re-add just the one being tested.
121+
remove_all_actions( $action );
122+
add_action( $action, $callback, $old_priority );
123+
add_action( $action, $callback, $new_priority );
124+
125+
$post_id = self::factory()->post->create();
126+
$this->go_to( get_permalink( $post_id ) );
127+
$this->assertQueryTrue( 'is_single', 'is_singular' );
128+
129+
$mock_action = new MockAction();
130+
add_filter( 'oembed_discovery_links', array( $mock_action, 'filter' ) );
131+
132+
$wp_head_output = get_echo( 'wp_head' );
133+
$this->assertSame( 1, $mock_action->get_call_count() );
134+
135+
$expected = '<link rel="alternate" title="oEmbed (JSON)" type="application/json+oembed" href="' . esc_url( get_oembed_endpoint_url( get_permalink() ) ) . '" />' . "\n";
136+
$expected .= '<link rel="alternate" title="oEmbed (XML)" type="text/xml+oembed" href="' . esc_url( get_oembed_endpoint_url( get_permalink(), 'xml' ) ) . '" />' . "\n";
137+
138+
$this->assertSame( $expected, $wp_head_output, 'Expected wp_head output to be the same as the wp_oembed_add_discovery_links() output.' );
139+
$this->assertSame( $expected, get_echo( $callback ), 'Expected wp_oembed_add_discovery_links() output to be the same as the wp_head output when called outside of wp_head.' );
140+
}
103141
}

0 commit comments

Comments
 (0)