From 94a35100c0026585190fe5347879cf8f30b8ea1f Mon Sep 17 00:00:00 2001 From: arthur791004 Date: Wed, 11 Sep 2024 16:54:35 +0800 Subject: [PATCH] Shortcode: Fix the youtube url cannot be embedded due to the trailing question mark of the youtube id (#39309) * Shortcode: Fix the youtube url cannot be embeded due to the trailing question mark of the youtube id * changelog * Add tests * Update projects/plugins/jetpack/tests/php/modules/shortcodes/test-class.youtube.php --------- Co-authored-by: Jeremy Herve --- .../fix-youtube-embed-trailing-question-mark | 4 ++ .../jetpack/modules/shortcodes/youtube.php | 36 ++++++++++++++++ .../modules/shortcodes/test-class.youtube.php | 43 +++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 projects/plugins/jetpack/changelog/fix-youtube-embed-trailing-question-mark diff --git a/projects/plugins/jetpack/changelog/fix-youtube-embed-trailing-question-mark b/projects/plugins/jetpack/changelog/fix-youtube-embed-trailing-question-mark new file mode 100644 index 0000000000000..4116d7e9da198 --- /dev/null +++ b/projects/plugins/jetpack/changelog/fix-youtube-embed-trailing-question-mark @@ -0,0 +1,4 @@ +Significance: patch +Type: bugfix + +Shortcode: Fix the youtube url cannot be embeded due to the trailing question mark of the youtube id diff --git a/projects/plugins/jetpack/modules/shortcodes/youtube.php b/projects/plugins/jetpack/modules/shortcodes/youtube.php index 249068e6d0617..5783c9695dcc8 100644 --- a/projects/plugins/jetpack/modules/shortcodes/youtube.php +++ b/projects/plugins/jetpack/modules/shortcodes/youtube.php @@ -548,6 +548,42 @@ function wpcom_youtube_embed_crazy_url_init() { wp_embed_register_handler( 'wpcom_youtube_embed_crazy_url', '#https?://(?:www\.)?(?:youtube.com/(?:v/|playlist|watch[/\#?])|youtu\.be/).*#i', 'wpcom_youtube_embed_crazy_url' ); } +/** + * Remove the ending question mark from the video id of the YouTube URL. + * + * Example: https://www.youtube.com/watch?v=AVAWwXeOyyQ? + * + * @since $$next-version$$ + * + * @param string $provider URL of the oEmbed provider. + * @param string $url URL of the content to be embedded. + * + * @return string + */ +function wpcom_youtube_oembed_fetch_url( $provider, $url ) { + if ( ! wp_startswith( $provider, 'https://www.youtube.com/oembed' ) ) { + return $provider; + } + + $parsed = wp_parse_url( $url ); + if ( ! isset( $parsed['query'] ) ) { + return $provider; + } + + $query_vars = array(); + wp_parse_str( $parsed['query'], $query_vars ); + if ( isset( $query_vars['v'] ) && wp_endswith( $query_vars['v'], '?' ) ) { + $url = remove_query_arg( array( 'v' ), $url ); + $url = add_query_arg( 'v', preg_replace( '/\?$/', '', $query_vars['v'] ), $url ); + } + + $provider = remove_query_arg( array( 'url' ), $provider ); + $provider = add_query_arg( 'url', rawurlencode( $url ), $provider ); + + return $provider; +} +add_filter( 'oembed_fetch_url', 'wpcom_youtube_oembed_fetch_url', 10, 2 ); + if ( ! is_admin() /** diff --git a/projects/plugins/jetpack/tests/php/modules/shortcodes/test-class.youtube.php b/projects/plugins/jetpack/tests/php/modules/shortcodes/test-class.youtube.php index b2268909170d0..3ca4e5724db29 100644 --- a/projects/plugins/jetpack/tests/php/modules/shortcodes/test-class.youtube.php +++ b/projects/plugins/jetpack/tests/php/modules/shortcodes/test-class.youtube.php @@ -299,4 +299,47 @@ public function test_jetpack_shortcode_youtube_dimensions( $query_args, $expecte $GLOBALS['content_width'] = self::CONTENT_WIDTH; $this->assertEquals( $expected, jetpack_shortcode_youtube_dimensions( $query_args ) ); } + + /** + * List of variation of YouTube embed URLs. + */ + public function get_youtube_urls() { + return array( + 'valid_url' => array( + 'https://www.youtube.com/watch?v=SVRiktFlWxI', + 'https://www.youtube.com/watch?v=SVRiktFlWxI', + ), + 'short_youtube_url' => array( + 'https://youtu.be/gS6_xOABTWo', + 'https://youtu.be/gS6_xOABTWo', + ), + 'video_id_ending_with_question_mark' => array( + 'https://www.youtube.com/watch?v=WVbQ-oro7FQ?', + 'https://www.youtube.com/watch?v=WVbQ-oro7FQ', + ), + ); + } + + /** + * Test different oEmbed URLs and their output. + * + * @covers ::wpcom_youtube_oembed_fetch_url + * @dataProvider get_youtube_urls + * + * @param string $original The original YouTube provider URL. + * @param string $expected The final YouTube provider URL after wpcom_youtube_oembed_fetch_url. + */ + public function test_youtube_oembed_fetch_url( $original, $expected ) { + $provider_url = apply_filters( + 'oembed_fetch_url', + 'https://www.youtube.com/oembed?url=' . rawurlencode( $original ), + $original, + '' + ); + + $this->assertEquals( + $provider_url, + 'https://www.youtube.com/oembed?url=' . rawurlencode( $expected ) + ); + } }