Вопрос

We followed Brian Fegter's answer to display YouTube videos using WordPress' oEmbed feature:

// Public video.
$video_url = 'https://www.youtube.com/watch?v=1lODe0i7dNw';

require_once(ABSPATH . 'wp-includes/class-wp-oembed.php');
$oembed = new WP_oEmbed;

// Auto-detect the video provider with the following
$provider = $oembed->discover($video_url);

$video = $oembed->fetch($provider, $video_url);

echo $video->html;

The code worked earlier. But right now it's not working. We're using WordPress 5.3.2. We tried updating WordPress to 5.3.6, but no luck.

The main issue is: $oEmbed->discover() cannot detect any provider and returning false. :(

You can see the issue live at this link. (For some time, we're showing some of the debug information, if you need them)

Debug information

Это было полезно?

Решение

So apparently the issue also happens in WordPress 5.6 (the latest release as of writing), and YouTube is probably at fault because the (oEmbed) <link> tags are in the body instead of the head (see screenshot below), and that in turn causes the issue because WP_oEmbed::discover() looks for the <link> tags in the head only. And secondly, YouTube uses http:// instead of https:// (secure protocol) in the <link> tags, so you would need to replace that http:// with https:// if your site uses https:// or is SSL-enabled.

Screenshot 1: Elements inspector tab (in Chrome)

Chrome DevTools

Screenshot 2: Server-generated HTML source (press Ctrl+U on Chrome)

Chrome view-source

And maybe (YouTube is not at fault and) the WordPress core team should revise the function so that it tries to also search in the body? Or perhaps use a better way to find the tags like using DOMDocument ...?

But anyway, as mentioned by @Rup, you could alternatively use WP_oEmbed::get_provider() which will load the sanctioned/trusted oEmbed providers defined in the class constructor, and (as of writing) YouTube is actually the very first in the providers list.

// So instead of:
// this fetches the <link> tags from the provider site
$provider = $oembed->discover( $video_url );

// Use this one:
// this finds in the sanctioned oEmbed providers first
// then tries with the above discover()..
$provider = $oembed->get_provider( $video_url );

Or as I said in the comments, if you just wanted to get the HTML/embed code, then you could simply use wp_oembed_get() which should work since, although indirectly, the function uses WP_oEmbed::get_data() which uses WP_oEmbed::get_provider():

// I'd prefer this:
echo wp_oembed_get( $video_url );

// But that is equivalent to:
$video = $oembed->get_data( $video_url );
echo $video->html;

// And that is equivalent to:
$provider = $oembed->get_provider( $video_url );
$video = $oembed->fetch( $provider, $video_url );
echo $video->html;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с wordpress.stackexchange
scroll top