get_error_message() );
}
$file_url = $file_id ? wp_get_attachment_url( $file_id ) : '';
if ( ! $file_url ) {
return self::source_error( $post_id, '' );
}
return self::html5_media( 'audio' === $type ? 'audio' : 'video', $file_url, $autoplay );
}
if ( in_array( $source, array( 'external_video', 'external_audio' ), true ) ) {
if ( ! $url || ! wp_http_validate_url( $url ) ) {
return self::source_error( $post_id, $url );
}
return self::html5_media( 'external_audio' === $source ? 'audio' : 'video', $url, $autoplay );
}
$validation = SG7G_Meta_Boxes::validate_source( (string) $type, (string) $source, $url, $file_id );
if ( is_wp_error( $validation ) ) {
return self::source_error( $post_id, $url, $validation->get_error_message() );
}
if ( ! $url ) {
return self::source_error( $post_id, '' );
}
$embed_url = self::embed_url( (string) $source, $url );
if ( ! $embed_url ) {
$oembed = wp_oembed_get( $url, array( 'width' => 1200 ) );
if ( $oembed ) {
$safe_oembed = wp_kses( $oembed, self::allowed_embed_html() );
$deferred = self::defer_oembed_iframes( $safe_oembed, get_the_title( $post_id ) );
return self::lazy_oembed( $deferred, $safe_oembed, $url );
}
return self::source_error( $post_id, $url );
}
$frame_classes = self::embed_frame_classes( (string) $source, $url );
return self::lazy_iframe(
$embed_url,
implode( ' ', $frame_classes ),
get_the_title( $post_id ),
$url
);
}
/**
* Resolve the canonical media URL for structured data and integrations.
*
* @return array{content_url?:string,embed_url?:string}
*/
public static function resolved_media_url( int $post_id ): array {
$type = (string) get_post_meta( $post_id, '_sg7g_media_type', true );
$source = (string) get_post_meta( $post_id, '_sg7g_source', true );
$file_id = absint( get_post_meta( $post_id, '_sg7g_file_id', true ) );
$url = html_entity_decode( (string) get_post_meta( $post_id, '_sg7g_source_url', true ), ENT_QUOTES, 'UTF-8' );
$validation = SG7G_Meta_Boxes::validate_source( $type, $source, $url, $file_id );
if ( is_wp_error( $validation ) ) {
return array();
}
if ( in_array( $source, array( 'local_video', 'local_audio' ), true ) ) {
$file_url = $file_id ? wp_get_attachment_url( $file_id ) : '';
return $file_url ? array( 'content_url' => esc_url_raw( $file_url ) ) : array();
}
if ( in_array( $source, array( 'external_video', 'external_audio' ), true ) ) {
return $url && wp_http_validate_url( $url ) ? array( 'content_url' => esc_url_raw( $url ) ) : array();
}
$embed_url = $url ? self::embed_url( $source, $url ) : '';
return $embed_url ? array( 'embed_url' => esc_url_raw( $embed_url ) ) : array();
}
/**
* Return source-aware classes so audio embeds can use their natural height
* instead of the 16:9 video frame.
*/
private static function embed_frame_classes( string $source, string $url ): array {
$classes = array( 'sg7g-embed-frame', 'sg7g-embed-frame--' . sanitize_html_class( $source ) );
$path = trim( (string) wp_parse_url( $url, PHP_URL_PATH ), '/' );
if ( 'spotify' === $source ) {
$segments = self::normalized_segments( $path );
if ( isset( $segments[0] ) && 'embed' === strtolower( $segments[0] ) ) {
array_shift( $segments );
}
if ( isset( $segments[0] ) ) {
$classes[] = 'sg7g-embed-frame--spotify-' . sanitize_html_class( $segments[0] );
}
} elseif ( 'apple_music' === $source ) {
parse_str( (string) wp_parse_url( $url, PHP_URL_QUERY ), $query );
$classes[] = isset( $query['i'] ) || str_contains( '/' . $path . '/', '/song/' )
? 'sg7g-embed-frame--apple-music-song'
: 'sg7g-embed-frame--apple-music-collection';
} elseif ( 'soundcloud' === $source ) {
$classes[] = str_contains( '/' . $path . '/', '/sets/' )
? 'sg7g-embed-frame--soundcloud-set'
: 'sg7g-embed-frame--soundcloud-track';
}
return array_values( array_unique( $classes ) );
}
private static function html5_media( string $type, string $url, bool $autoplay ): string {
$attributes = array(
'src' => esc_url_raw( $url ),
'preload' => 'metadata',
'autoplay' => $autoplay ? 'on' : '',
);
return 'audio' === $type
? wp_audio_shortcode( $attributes )
: wp_video_shortcode( $attributes );
}
private static function embed_url( string $source, string $url ): string {
$url = html_entity_decode( $url, ENT_QUOTES, 'UTF-8' );
$host = strtolower( (string) wp_parse_url( $url, PHP_URL_HOST ) );
$path = trim( (string) wp_parse_url( $url, PHP_URL_PATH ), '/' );
parse_str( (string) wp_parse_url( $url, PHP_URL_QUERY ), $query );
switch ( $source ) {
case 'youtube':
case 'youtube_music':
$id = SG7G_Meta_Boxes::youtube_id( $url );
$playlist = SG7G_Meta_Boxes::youtube_playlist_id( $url );
if ( ! $id && ! $playlist ) {
return '';
}
$youtube_host = SG7G_Settings::enabled( 'youtube_nocookie' )
? 'https://www.youtube-nocookie.com/embed/'
: 'https://www.youtube.com/embed/';
$youtube_url = $id
? $youtube_host . rawurlencode( $id )
: $youtube_host . 'videoseries';
if ( $playlist ) {
$youtube_url = add_query_arg( 'list', $playlist, $youtube_url );
}
$youtube_autoplay = 'youtube_music' === $source
? SG7G_Settings::enabled( 'autoplay_audio' )
: SG7G_Settings::enabled( 'autoplay_video' );
return $youtube_autoplay ? add_query_arg( 'autoplay', '1', $youtube_url ) : $youtube_url;
case 'vimeo':
$vimeo_id = SG7G_Meta_Boxes::vimeo_id( $url );
if ( ! $vimeo_id ) {
return '';
}
$vimeo_url = 'https://player.vimeo.com/video/' . rawurlencode( $vimeo_id );
$vimeo_hash = SG7G_Meta_Boxes::vimeo_hash( $url );
if ( $vimeo_hash ) {
$vimeo_url = add_query_arg( 'h', $vimeo_hash, $vimeo_url );
}
return SG7G_Settings::enabled( 'autoplay_video' )
? add_query_arg( 'autoplay', '1', $vimeo_url )
: $vimeo_url;
case 'spotify':
if ( ! self::host_matches( $host, 'open.spotify.com' ) ) {
return '';
}
$segments = self::normalized_segments( $path );
if ( isset( $segments[0] ) && 'embed' === strtolower( $segments[0] ) ) {
array_shift( $segments );
}
$allowed = array( 'track', 'album', 'playlist', 'episode', 'show', 'artist' );
if ( count( $segments ) >= 2 && in_array( $segments[0], $allowed, true ) ) {
return 'https://open.spotify.com/embed/' . rawurlencode( $segments[0] ) . '/' . rawurlencode( $segments[1] );
}
return '';
case 'apple_music':
if ( ! self::host_matches( $host, 'music.apple.com' ) || '' === $path ) {
return '';
}
if ( str_starts_with( $host, 'embed.' ) ) {
return esc_url_raw( $url );
}
return 'https://embed.music.apple.com/' . $path . ( $query ? '?' . http_build_query( $query ) : '' );
case 'soundcloud':
if ( ! self::host_matches( $host, 'soundcloud.com' ) ) {
return '';
}
if ( 'w.soundcloud.com' === $host && str_starts_with( $path, 'player' ) ) {
return esc_url_raw( $url );
}
return 'https://w.soundcloud.com/player/?url=' . rawurlencode( $url ) . '&auto_play=' . ( SG7G_Settings::enabled( 'autoplay_audio' ) ? 'true' : 'false' ) . '&visual=true';
case 'deezer':
if ( ! self::host_matches( $host, 'deezer.com' ) ) {
return '';
}
$segments = self::normalized_segments( $path );
if ( isset( $segments[0], $segments[1] ) && 'widget' === $segments[0] && 'auto' === $segments[1] ) {
$segments = array_slice( $segments, 2 );
}
$allowed = array( 'track', 'album', 'playlist', 'artist', 'show', 'episode' );
if ( isset( $segments[0], $segments[1] ) && in_array( $segments[0], $allowed, true ) ) {
$deezer_url = 'https://widget.deezer.com/widget/auto/' . rawurlencode( $segments[0] ) . '/' . rawurlencode( $segments[1] );
return SG7G_Settings::enabled( 'autoplay_audio' )
? add_query_arg( 'autoplay', 'true', $deezer_url )
: $deezer_url;
}
return '';
}
return '';
}
private static function host_matches( string $host, string $domain ): bool {
$host = strtolower( trim( $host, '.' ) );
$domain = strtolower( trim( $domain, '.' ) );
return $host === $domain || str_ends_with( $host, '.' . $domain );
}
private static function normalized_segments( string $path ): array {
$segments = array_values( array_filter( explode( '/', trim( $path, '/' ) ) ) );
if ( isset( $segments[0] ) && ( preg_match( '/^intl-[a-z]{2}$/i', $segments[0] ) || preg_match( '/^[a-z]{2}(?:-[a-z]{2})?$/i', $segments[0] ) ) ) {
array_shift( $segments );
}
return $segments;
}
/**
* Return the compact media-type icon used beside card view counts.
*/
public static function media_type_icon( string $media_type ): string {
if ( 'audio' === $media_type ) {
return '';
}
return '';
}
/**
* Return the compact view/like metric group used inside archive media cards.
*/
public static function card_metrics_markup( int $post_id, string $extra_class = '' ): string {
$class = trim( 'sg7g-card__metrics ' . sanitize_html_class( $extra_class ) );
$show_likes = SG7G_Settings::enabled( 'show_likes' );
ob_start();
?>
…
…
' . esc_html( $message ) . $link . '