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(); ?> … …
> get_the_title( $post_id ), 'loading' => $is_archive_lead ? 'eager' : 'lazy', 'fetchpriority' => $is_archive_lead ? 'high' : 'auto', 'decoding' => 'async', 'sizes' => '(min-width: 1320px) 25vw, (min-width: 621px) 50vw, 100vw', ) ) ); ?>

max_num_pages ) ? (int) $wp_query->max_num_pages : 0; if ( $total < 2 ) { return; } $current = max( 1, (int) get_query_var( 'paged' ) ); $mode = (string) SG7G_Settings::get( 'pagination_mode', 'numbers' ); if ( 'numbers' === $mode ) { $links = paginate_links( array( 'base' => str_replace( 999999999, '%#%', esc_url( get_pagenum_link( 999999999 ) ) ), 'format' => '?paged=%#%', 'current' => $current, 'total' => $total, 'mid_size' => 1, 'end_size' => 1, 'prev_text' => '' . esc_html__( 'Previous', '7sgaleri' ) . '', 'next_text' => '' . esc_html__( 'Next', '7sgaleri' ) . '', 'add_args' => SG7G_Search::request_term() ? array( 'sg7q' => SG7G_Search::request_term() ) : array(), 'type' => 'array', ) ); if ( empty( $links ) || ! is_array( $links ) ) { return; } ?> = $total ) { return; } $next_page = $current + 1; $next_url = get_pagenum_link( $next_page ); if ( SG7G_Search::request_term() ) { $next_url = add_query_arg( 'sg7q', SG7G_Search::request_term(), $next_url ); } $is_infinite = 'infinite' === $mode; ?> %2$s%6$s', esc_attr( $classes ), esc_html__( 'Loading player…', '7sgaleri' ), $src, $title, $source_url ?: $src, esc_html__( 'Open content at source', '7sgaleri' ) ); } private static function lazy_oembed( string $deferred, string $original, string $source_url ): string { return sprintf( '
%1$s%2$s%4$s
', esc_html__( 'Loading player…', '7sgaleri' ), $deferred, esc_url( $source_url ), esc_html__( 'Open content at source', '7sgaleri' ), $original ); } private static function defer_oembed_iframes( string $html, string $title ): string { if ( ! class_exists( 'WP_HTML_Tag_Processor' ) ) { return $html; } $processor = new WP_HTML_Tag_Processor( $html ); $changed = false; while ( $processor->next_tag( 'iframe' ) ) { $src = html_entity_decode( (string) $processor->get_attribute( 'src' ), ENT_QUOTES, 'UTF-8' ); $src = esc_url( $src ); if ( '' === $src ) { continue; } $processor->remove_attribute( 'src' ); $processor->set_attribute( 'data-sg7g-src', $src ); $processor->set_attribute( 'loading', 'lazy' ); if ( ! $processor->get_attribute( 'title' ) ) { $processor->set_attribute( 'title', $title ); } if ( ! $processor->get_attribute( 'referrerpolicy' ) ) { $processor->set_attribute( 'referrerpolicy', 'strict-origin-when-cross-origin' ); } if ( ! $processor->get_attribute( 'allow' ) ) { $processor->set_attribute( 'allow', 'autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture' ); } if ( null === $processor->get_attribute( 'allowfullscreen' ) ) { $processor->set_attribute( 'allowfullscreen', '' ); } $changed = true; } return $changed ? $processor->get_updated_html() : $html; } private static function source_error( int $post_id, string $url, string $message = '' ): string { $message = trim( $message ); if ( '' === $message ) { $message = trim( (string) get_post_meta( $post_id, '_sg7g_source_error', true ) ); } if ( '' === $message ) { $message = __( 'No valid media source was found for this content.', '7sgaleri' ); } $link = ''; if ( $url && wp_http_validate_url( $url ) ) { $link = sprintf( ' %2$s', esc_url( $url ), esc_html__( 'Open at source', '7sgaleri' ) ); } return '

' . esc_html( $message ) . $link . '

'; } private static function allowed_embed_html(): array { return array( 'iframe' => array( 'src' => true, 'width' => true, 'height' => true, 'frameborder' => true, 'allow' => true, 'allowfullscreen' => true, 'loading' => true, 'title' => true, 'data-sg7g-src' => true, 'referrerpolicy' => true, 'class' => true, ), 'blockquote' => array( 'class' => true, 'data-secret' => true ), 'a' => array( 'href' => true, 'target' => true, 'rel' => true ), 'p' => array(), 'div' => array( 'class' => true, 'style' => true ), 'span' => array( 'class' => true, 'style' => true ), ); } }