diff --git a/src/wp-includes/class-wp-oembed.php b/src/wp-includes/class-wp-oembed.php index 3bc5de556c49e..b66c5e03afaf1 100644 --- a/src/wp-includes/class-wp-oembed.php +++ b/src/wp-includes/class-wp-oembed.php @@ -110,6 +110,8 @@ public function __construct() { '#https?://((play|www)\.)?anghami\.com/.*#i' => array( 'https://api.anghami.com/rest/v1/oembed.view', true ), '#https?://bsky.app/profile/.*/post/.*#i' => array( 'https://embed.bsky.app/oembed', true ), '#https?://(www\.)?canva\.com/design/.*/view.*#i' => array( 'https://canva.com/_oembed', true ), + '#https?://(www\.)?threads\.(com|net)/@[^/]+/post/.+#i' => array( 'https://graph.threads.com/oembed', true ), + '#https?://(www\.)?threads\.(com|net)/t/.+#i' => array( 'https://graph.threads.com/oembed', true ), ); if ( ! empty( self::$early_providers['add'] ) ) { @@ -191,6 +193,8 @@ public function __construct() { * | Anghami | anghami.com | 6.3.0 | * | Bluesky | bsky.app | 6.6.0 | * | Canva | canva.com | 6.8.0 | + * | Threads | threads.com | 7.1.0 | + * | Threads | threads.net | 7.1.0 | * * No longer supported providers: * diff --git a/tests/phpunit/tests/oembed/wpOembedThreadsProvider.php b/tests/phpunit/tests/oembed/wpOembedThreadsProvider.php new file mode 100644 index 0000000000000..c313f3b68d3bf --- /dev/null +++ b/tests/phpunit/tests/oembed/wpOembedThreadsProvider.php @@ -0,0 +1,124 @@ +oembed = _wp_oembed_get_object(); + } + + /** + * @ticket 64858 + * + * @dataProvider data_threads_provider_urls + * + * @param string $url The URL to test. + * @param string $expected The expected oEmbed provider URL. + */ + public function test_threads_provider_url( string $url, string $expected ): void { + $provider = $this->oembed->get_provider( $url, array( 'discover' => false ) ); + $this->assertSame( $expected, $provider ); + } + + /** + * Data provider for valid Threads URLs. + * + * @return array + */ + public function data_threads_provider_urls(): array { + return array( + // threads.com post URLs. + 'threads.com post URL' => array( + 'https://www.threads.com/@zuck/post/C1234567890', + 'https://graph.threads.com/oembed', + ), + 'threads.com post URL no www' => array( + 'https://threads.com/@zuck/post/C1234567890', + 'https://graph.threads.com/oembed', + ), + 'threads.com post URL http' => array( + 'http://www.threads.com/@zuck/post/C1234567890', + 'https://graph.threads.com/oembed', + ), + + // threads.com short URLs. + 'threads.com short URL' => array( + 'https://www.threads.com/t/C1234567890', + 'https://graph.threads.com/oembed', + ), + 'threads.com short URL no www' => array( + 'https://threads.com/t/C1234567890', + 'https://graph.threads.com/oembed', + ), + 'threads.com short URL http' => array( + 'http://www.threads.com/t/C1234567890', + 'https://graph.threads.com/oembed', + ), + + // threads.net post URLs. + 'threads.net post URL' => array( + 'https://www.threads.net/@zuck/post/C1234567890', + 'https://graph.threads.com/oembed', + ), + 'threads.net post URL no www' => array( + 'https://threads.net/@zuck/post/C1234567890', + 'https://graph.threads.com/oembed', + ), + + // threads.net short URLs. + 'threads.net short URL' => array( + 'https://www.threads.net/t/C1234567890', + 'https://graph.threads.com/oembed', + ), + 'threads.net short URL no www' => array( + 'https://threads.net/t/C1234567890', + 'https://graph.threads.com/oembed', + ), + ); + } + + /** + * @ticket 64858 + * + * @dataProvider data_threads_non_matching_urls + * + * @param string $url The URL to test. + */ + public function test_threads_provider_does_not_match_non_post_urls( string $url ): void { + $provider = $this->oembed->get_provider( $url, array( 'discover' => false ) ); + $this->assertFalse( $provider ); + } + + /** + * Data provider for URLs that should not match the Threads provider. + * + * @return array + */ + public function data_threads_non_matching_urls(): array { + return array( + 'threads.com profile URL' => array( + 'https://www.threads.com/@zuck', + ), + 'threads.com homepage' => array( + 'https://www.threads.com/', + ), + 'threads.com search' => array( + 'https://www.threads.com/search', + ), + 'non-threads URL with threads in path' => array( + 'https://example.com/threads/post/123', + ), + ); + } +}