JezK
Edit File: youtube.php
<?php defined( 'ABSPATH' ) or die( 'you do not have access to this page!' ); add_filter( 'cmplz_known_script_tags', 'cmplz_youtube_script' ); function cmplz_youtube_script( $tags ) { $tags[] = array( 'name' => 'youtube', 'placeholder' => 'youtube', 'category' => 'marketing', 'urls' => array( 'www.youtube.com/iframe_api', 'youtube.com', 'youtube-nocookie.com', 'youtu.be', ), ); return $tags; } /** * Get the first video id from a video series * * @param string $src * * @return string */ /** * Whether $src is a YouTube URL that is safe to fetch server-side. * * The YouTube placeholder detection upstream is intentionally permissive * (substring match + greedy regex), so the actual server-side fetch must verify * that the parsed host is a real YouTube domain over http(s) before any request * is made. Prevents SSRF via a crafted iframe src pointing at an arbitrary host. * * @param string $src URL to validate. * @return bool True when $src targets an allowed YouTube host over http(s). */ function cmplz_youtube_is_fetchable_url( $src ) { $parts = wp_parse_url( $src ); $scheme = strtolower( (string) ( $parts['scheme'] ?? '' ) ); $host = strtolower( rtrim( (string) ( $parts['host'] ?? '' ), '.' ) ); if ( ! in_array( $scheme, array( 'http', 'https' ), true ) || '' === $host ) { return false; } $allowed_hosts = array( 'youtube.com', 'youtube-nocookie.com', 'youtu.be' ); foreach ( $allowed_hosts as $allowed_host ) { if ( $host === $allowed_host || substr( $host, - ( strlen( $allowed_host ) + 1 ) ) === '.' . $allowed_host ) { return true; } } return false; } function cmplz_youtube_get_video_id_from_series( $src ) { // SSRF guard: only fetch real YouTube hosts, and use wp_safe_remote_get() so // WordPress re-validates every redirect hop and rejects private/reserved IPs. if ( ! cmplz_youtube_is_fetchable_url( $src ) ) { return false; } $output = wp_safe_remote_get( $src, array( 'redirection' => 2 ) ); $youtube_id = false; if ( isset( $output['body'] ) ) { $body = $output['body']; $body = stripcslashes( $body ); $series_pattern = '/VIDEO_ID\': "([^#\&\?].*?)"/i'; if ( preg_match( $series_pattern, $body, $matches ) ) { $youtube_id = $matches[1]; } } return $youtube_id; } /** * Get screenshot from youtube as placeholder * * @param $new_src * @param $src * * @return mixed|string */ function cmplz_youtube_placeholder( $new_src, $src ) { $youtube_pattern = '/.*(?:youtu.be\/|v\/|u\/\w\/|embed\/videoseries\?list=RD|embed\/|watch\?v=)([^#\&\?]*).*/i'; if ( preg_match( $youtube_pattern, $src, $matches ) ) { $youtube_id = $matches[1]; // check if it's a video series. If so, we get the first video if ( $youtube_id === 'videoseries' ) { // get the videoseries id $series_pattern = '/.*(?:youtu.be\/|v\/|u\/\w\/|embed\/videoseries\?list=RD|embed\/|watch\?v=)[^#\&\?]*\?list=(.*)/i'; // if we find the unique id, we save it in the cache if ( preg_match( $series_pattern, $src, $matches ) ) { $series_id = $matches[1]; $youtube_id = cmplz_get_transient( "cmplz_youtube_videoseries_video_id_$series_id" ); if ( ! $youtube_id ) { // we do a get on the url to retrieve the first video $youtube_id = cmplz_youtube_get_video_id_from_series( $src ); cmplz_set_transient( "cmplz_youtube_videoseries_video_id_$series_id", $youtube_id, WEEK_IN_SECONDS ); } } else { $youtube_id = cmplz_youtube_get_video_id_from_series( $src ); } } /** * The highest resolution of youtube thumbnail is the maxres, but it does not * always exist. In that case, we take the hq thumb * To lower the number of file exists checks, we cache the result. * */ $new_src = cmplz_get_transient( "cmplz_youtube_image_$youtube_id" ); if ( ! $new_src || ! cmplz_file_exists_on_url( $new_src ) ) { $new_src = "https://img.youtube.com/vi/$youtube_id/maxresdefault.jpg"; if ( ! cmplz_remote_file_exists( $new_src ) ) { $new_src = "https://img.youtube.com/vi/$youtube_id/hqdefault.jpg"; } $new_src = cmplz_download_to_site( $new_src, 'youtube' . $youtube_id ); cmplz_set_transient( "cmplz_youtube_image_$youtube_id", $new_src, WEEK_IN_SECONDS ); } } return $new_src; } add_filter( 'cmplz_placeholder_youtube', 'cmplz_youtube_placeholder', 10, 2 );