Automattic\WooCommerce\EmailEditor\Integrations\Core\Renderer\Blocks
Embed::fetch_embed_page_data │ private │ WC 1.0 Fetch metadata from a WordPress embed page.
WordPress sites expose a {url}/embed/ endpoint that renders a post preview containing the title, excerpt, featured image, provider name, and site icon. This single fetch provides all the data needed for the rich embed card.
Method of the class: Embed{}
Returns
Array{ . title: string, thumbnail_url: string, provider_name: string, provider_url: string, excerpt: string, site_icon_url: string } Embed page metadata.
Usage
// private - for code of main (parent) class only
$result = $this->fetch_embed_page_data( $url ): array;
$url(string) (required)
URL of the post to fetch metadata for.
Embed::fetch_embed_page_data() Embed::fetch embed page data code
WC 10.8.1
private function fetch_embed_page_data( string $url ): array {
$empty_result = array(
'title' => '',
'thumbnail_url' => '',
'provider_name' => '',
'provider_url' => '',
'excerpt' => '',
'site_icon_url' => '',
);
$parsed = wp_parse_url( $url );
if ( empty( $parsed['scheme'] ) || empty( $parsed['host'] ) ) {
return $empty_result;
}
$embed_url = $parsed['scheme'] . '://' . $parsed['host']
. ( isset( $parsed['port'] ) ? ':' . $parsed['port'] : '' )
. trailingslashit( $parsed['path'] ?? '/' ) . 'embed/';
if ( ! $this->is_valid_url( $embed_url ) ) {
return $empty_result;
}
$cache_key = 'wc_email_embed_pg_' . md5( $url );
$cached = get_transient( $cache_key );
if ( false !== $cached && is_array( $cached )
&& isset( $cached['title'], $cached['thumbnail_url'], $cached['provider_name'], $cached['provider_url'], $cached['excerpt'], $cached['site_icon_url'] )
&& is_string( $cached['title'] ) && is_string( $cached['thumbnail_url'] )
&& is_string( $cached['provider_name'] ) && is_string( $cached['provider_url'] )
&& is_string( $cached['excerpt'] ) && is_string( $cached['site_icon_url'] )
) {
return array(
'title' => $cached['title'],
'thumbnail_url' => $cached['thumbnail_url'],
'provider_name' => $cached['provider_name'],
'provider_url' => $cached['provider_url'],
'excerpt' => $cached['excerpt'],
'site_icon_url' => $cached['site_icon_url'],
);
}
if ( is_string( $cached ) ) {
// Negative cache (empty string from previous failure).
return $empty_result;
}
/** This filter is documented in packages/php/email-editor/src/Integrations/Core/Renderer/Blocks/class-embed.php */
$cache_ttl = (int) apply_filters( 'oembed_ttl', DAY_IN_SECONDS, $url, array(), '' );
$response = wp_safe_remote_get(
$embed_url,
array(
'timeout' => 5,
'limit_response_size' => 150 * KB_IN_BYTES,
)
);
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
set_transient( $cache_key, '', $cache_ttl );
return $empty_result;
}
$body = wp_remote_retrieve_body( $response );
if ( empty( $body ) ) {
set_transient( $cache_key, '', $cache_ttl );
return $empty_result;
}
// Parse HTML and extract metadata using XPath.
$previous_libxml_errors = libxml_use_internal_errors( true );
try {
$dom = new \DOMDocument();
$dom->loadHTML( '<?xml encoding="UTF-8">' . $body, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD );
libxml_clear_errors();
} finally {
libxml_use_internal_errors( $previous_libxml_errors );
}
$xpath = new \DOMXPath( $dom );
// Extract title from wp-embed-heading.
$title = '';
$heading_nodes = $xpath->query( "//*[contains(concat(' ', normalize-space(@class), ' '), ' wp-embed-heading ')]" );
$heading_node = ( false !== $heading_nodes && $heading_nodes->length > 0 ) ? $heading_nodes->item( 0 ) : null;
if ( $heading_node instanceof \DOMElement ) {
$title = trim( $heading_node->textContent ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
}
// Extract thumbnail from featured image.
$thumbnail_url = '';
$featured_nodes = $xpath->query( "//*[contains(concat(' ', normalize-space(@class), ' '), ' wp-embed-featured-image ')]//img" );
$featured_node = ( false !== $featured_nodes && $featured_nodes->length > 0 ) ? $featured_nodes->item( 0 ) : null;
if ( $featured_node instanceof \DOMElement ) {
$img_src = $featured_node->getAttribute( 'src' );
if ( $this->is_valid_url( $img_src ) ) {
$thumbnail_url = $img_src;
}
}
// Extract provider name from site title.
$provider_name = '';
$site_title_nodes = $xpath->query( "//*[contains(concat(' ', normalize-space(@class), ' '), ' wp-embed-site-title ')]//span" );
$site_title_node = ( false !== $site_title_nodes && $site_title_nodes->length > 0 ) ? $site_title_nodes->item( 0 ) : null;
if ( $site_title_node instanceof \DOMElement ) {
$provider_name = trim( $site_title_node->textContent ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
}
// Extract provider URL from site title link.
$provider_url = '';
$site_link_nodes = $xpath->query( "//*[contains(concat(' ', normalize-space(@class), ' '), ' wp-embed-site-title ')]//a" );
$site_link_node = ( false !== $site_link_nodes && $site_link_nodes->length > 0 ) ? $site_link_nodes->item( 0 ) : null;
if ( $site_link_node instanceof \DOMElement ) {
$href = $site_link_node->getAttribute( 'href' );
if ( $this->is_valid_url( $href ) ) {
$provider_url = $href;
}
}
// Extract excerpt.
$excerpt = '';
$excerpt_nodes = $xpath->query( "//*[contains(concat(' ', normalize-space(@class), ' '), ' wp-embed-excerpt ')]" );
$excerpt_node = ( false !== $excerpt_nodes && $excerpt_nodes->length > 0 ) ? $excerpt_nodes->item( 0 ) : null;
if ( $excerpt_node instanceof \DOMElement ) {
$excerpt = trim( $excerpt_node->textContent ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
}
// Cap at 200 characters as a safety limit.
if ( mb_strlen( $excerpt ) > 200 ) {
$excerpt = mb_substr( $excerpt, 0, 200 );
$excerpt = rtrim( $excerpt ) . '…';
}
// Extract site icon URL.
$site_icon_url = '';
$icon_nodes = $xpath->query( "//img[contains(concat(' ', normalize-space(@class), ' '), ' wp-embed-site-icon ')]" );
$icon_node = ( false !== $icon_nodes && $icon_nodes->length > 0 ) ? $icon_nodes->item( 0 ) : null;
if ( $icon_node instanceof \DOMElement ) {
$icon_src = $icon_node->getAttribute( 'src' );
if ( $this->is_valid_url( $icon_src ) ) {
$site_icon_url = $icon_src;
}
}
$result = array(
'title' => $title,
'thumbnail_url' => $thumbnail_url,
'provider_name' => $provider_name,
'provider_url' => $provider_url,
'excerpt' => $excerpt,
'site_icon_url' => $site_icon_url,
);
set_transient( $cache_key, $result, $cache_ttl );
return $result;
}