diff --git a/README.md b/README.md index 43a32f7..a96441c 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,11 @@ OEmbed: - X (Twitter) - TikTok - Reddit -- Facebook Custom: - Youtube +- Facebook - Instagram - Github Gist diff --git a/src/Embed/Embed.php b/src/Embed/Embed.php index f7d9aed..80ab284 100644 --- a/src/Embed/Embed.php +++ b/src/Embed/Embed.php @@ -17,10 +17,15 @@ class Embed public static function getParsers(): array { $namespace = __NAMESPACE__ . '\\Platforms\\'; - return array_map( + + $parsers = array_map( fn ($file) => $namespace . pathinfo((string)$file, PATHINFO_FILENAME), (array)glob(__DIR__ . '/Platforms/*.php') ); + + usort($parsers, fn ($a, $b) => $b::PRIORITY <=> $a::PRIORITY); + + return $parsers; } /** @@ -40,6 +45,25 @@ public static function parse( throw new EmbedUnableToResolveException(); } + /** + * @param string $url + * @return array{parser: EmbedParserAbstract, matches: string[]}|null + */ + public static function getMatchingParser(string $url): ?array + { + foreach (self::getParsers() as $parserClass) { + /** @var EmbedParserAbstract $parser */ + $parser = new $parserClass($url); + if ($parser->match()) { + return [ + 'parser' => $parser, + 'matches' => $parser->match(), + ]; + } + } + return null; + } + /** * @throws UnfoldException */ diff --git a/src/Embed/EmbedParserAbstract.php b/src/Embed/EmbedParserAbstract.php index c5abee0..e780e75 100644 --- a/src/Embed/EmbedParserAbstract.php +++ b/src/Embed/EmbedParserAbstract.php @@ -16,6 +16,9 @@ */ abstract class EmbedParserAbstract { + // define priority relatively + public const PRIORITY = 0; + protected UnfoldConfig $config; public function __construct( diff --git a/src/Embed/PlatformHelpers/FacebookHelper.php b/src/Embed/PlatformHelpers/FacebookHelper.php new file mode 100644 index 0000000..59a9619 --- /dev/null +++ b/src/Embed/PlatformHelpers/FacebookHelper.php @@ -0,0 +1,15 @@ + + +HTML; + } + +} diff --git a/src/Embed/Platforms/FacebookPage.php b/src/Embed/Platforms/FacebookPage.php new file mode 100644 index 0000000..6702801 --- /dev/null +++ b/src/Embed/Platforms/FacebookPage.php @@ -0,0 +1,36 @@ +url; + + $name = explode('/', $url)[3] ?? ''; + $sdk = FacebookHelper::sdkScript(); + + return <<
$name
+HTML; + } +} diff --git a/src/Embed/Platforms/FacebookPost.php b/src/Embed/Platforms/FacebookPost.php new file mode 100644 index 0000000..35731ae --- /dev/null +++ b/src/Embed/Platforms/FacebookPost.php @@ -0,0 +1,50 @@ +url; + $sdk = FacebookHelper::sdkScript(); + + return << +HTML; + } +} diff --git a/src/Embed/Platforms/FacebookVideo.php b/src/Embed/Platforms/FacebookVideo.php new file mode 100644 index 0000000..1b49b6a --- /dev/null +++ b/src/Embed/Platforms/FacebookVideo.php @@ -0,0 +1,46 @@ +url; + return << +HTML; + } +} diff --git a/src/Embed/Platforms/Reddit.php b/src/Embed/Platforms/Reddit.php index c1bb944..105040c 100644 --- a/src/Embed/Platforms/Reddit.php +++ b/src/Embed/Platforms/Reddit.php @@ -11,11 +11,7 @@ public function regex() { return [ // oembed - "https://reddit.com/r/.*/comments/.*/.*", - "https://www.reddit.com/r/.*/comments/.*/.*", - - // custom - "https://old.reddit.com/r/.*/comments/.*/.*", // added: 2024-10-19 + "https://(?:(?:www|old)\.)?reddit.com/r/.*/comments/.*/.*", ]; } diff --git a/src/UnfoldConfig.php b/src/UnfoldConfig.php index bc7007a..2c36853 100644 --- a/src/UnfoldConfig.php +++ b/src/UnfoldConfig.php @@ -75,7 +75,7 @@ public function __construct( /** * Meta requires an access_token to access the OEmbed Read Graph API - * This is required for both Facebook & Instagram + * This is required for both FacebookPost & Instagram * @todo */ public ?string $facebookAccessToken = null, diff --git a/tests/Unit/Embed/EmbedTest.php b/tests/Unit/Embed/EmbedTest.php new file mode 100644 index 0000000..c543d6d --- /dev/null +++ b/tests/Unit/Embed/EmbedTest.php @@ -0,0 +1,14 @@ +toBeTrue(); +}); diff --git a/tests/Unit/EmbedParsers/OEmbedTest.php b/tests/Unit/Embed/OEmbedTest.php similarity index 100% rename from tests/Unit/EmbedParsers/OEmbedTest.php rename to tests/Unit/Embed/OEmbedTest.php diff --git a/tests/Unit/Embed/Platforms/FacebookPageTest.php b/tests/Unit/Embed/Platforms/FacebookPageTest.php new file mode 100644 index 0000000..d005327 --- /dev/null +++ b/tests/Unit/Embed/Platforms/FacebookPageTest.php @@ -0,0 +1,61 @@ +parse($parser->match()); +// var_dump($response->html); +// expect($response->html)->toBeString(); +//}); + +it('embeds facebook page', function () { + $url = 'https://www.facebook.com/geonarah'; + + $parser = new FacebookPage($url); + $match = $parser->match(); + $response = $parser->parse($match); + + $html = $response->html; + expect($html)->toContain('
' + ); +}); + +it('embed class prioritizes facebook post before page', function () { + $url = 'https://www.facebook.com/permalink.php?story_fbid=10159000000000000&id=100000000000000'; + $match = Embed::getMatchingParser($url); + expect($match['parser'])->toBeInstanceOf(FacebookPost::class); + expect($match['matches'])->toBeArray(); +}) + ->with([ + 'https://www.facebook.com/permalink.php?story_fbid=10159000000000000&id=100000000000000', + 'https://www.facebook.com/media/set/?set=a.10159000000000000&type=3', + 'https://www.facebook.com/photo.php?fbid=10159000000000000', + ]); + +it('matches', function ($url) { + $parser = new FacebookPage($url); + expect($parser->match())->toBeArray(); +})->with([ + 'https://www.facebook.com/MyPage', + 'https://www.facebook.com/MyPage/about', + 'https://www.facebook.com/MyPage/photos', + 'https://www.facebook.com/MyPage/videos', + 'https://www.facebook.com/MyPage/events', + 'https://www.facebook.com/MyPage/timeline', +]); + +it('does not match', function ($url) { + $parser = new FacebookPage($url); + expect($parser->match())->toBeFalse(); +})->with([ + 'https://www.facebook.com/Mypage/other', +]); diff --git a/tests/Unit/Embed/Platforms/FacebookPostTest.php b/tests/Unit/Embed/Platforms/FacebookPostTest.php new file mode 100644 index 0000000..cedee52 --- /dev/null +++ b/tests/Unit/Embed/Platforms/FacebookPostTest.php @@ -0,0 +1,43 @@ +match(); + $response = $parser->parse($match); + + $html = $response->html; + expect($html)->toContain('
' + ); +}); + +it('matches', function ($url) { + $parser = new FacebookPost($url); + $match = $parser->match(); + expect($match)->toBeArray(); +})->with([ + + // post with username + 'https://www.facebook.com/geonarah/posts/027mqcVugNt1ChK6dwvjR2SkVJrtN754X1toi1XA1auyHgrng1g3bb3Ph2DoYANAhnl', + 'https://www.facebook.com/geonarah/activity/027mqcVugNt1ChK6dwvjR2SkVJrtN754X1toi1XA1auyHgrng1g3bb3Ph2Do', + 'https://www.facebook.com/geonarah/photos/027mqcVugNt1ChK6dwvjR2SkVJrtN754X1toi1XA1auyHgrng1g3bb3Ph2Do', + + // photo.php + 'https://www.facebook.com/photo.php?fbid=934147948738763&set=a.414821727338057&type=3', + 'https://www.facebook.com/photo.php?set=a&fbid=934147948738763', + + // permalink.php + 'https://www.facebook.com/permalink.php?id=100064783864247&story_fbid=pfbid091orNDfpRpetrjS4JfNXPdctLCWG4mjhjP38xCzKxqvWFzHT9Cd4txnuV3MGs1zql', + // story.php + 'https://www.facebook.com/story.php?story_fbid=1098197861821196&id=100048929783038', + + // media set + 'https://www.facebook.com/media/set/?set=a.301563726371715', +]); diff --git a/tests/Unit/Embed/Platforms/FacebookVideoTest.php b/tests/Unit/Embed/Platforms/FacebookVideoTest.php new file mode 100644 index 0000000..c282c86 --- /dev/null +++ b/tests/Unit/Embed/Platforms/FacebookVideoTest.php @@ -0,0 +1,51 @@ +getEmbedHtml($facebook->match()); +// +// dd($embed); +//}); + +it('embeds facebook videos', function () { + $url = 'https://www.facebook.com/username/videos/123456789'; + + $parser = new FacebookVideo($url); + $match = $parser->match(); + $response = $parser->parse($match); + + $html = $response->html; + expect($html)->toContain('
' + ); +}); + +it('matches', function ($url) { + $facebook = new FacebookVideo($url); + expect($facebook->match())->toBeArray(); +})->with([ + // with username + 'https://www.facebook.com/username/videos/123456789', + + // video.php with id + 'https://www.facebook.com/video.php?id=123456789', + 'https://www.facebook.com/video.php?s=1&id=123456789', + + // video.php with v + 'https://www.facebook.com/video.php?v=123456789', + 'https://www.facebook.com/video.php?s=1&v=123456789', + + // watch + 'https://www.facebook.com/watch/?v=123456789', + 'https://www.facebook.com/watch/?s=1&v=123456789', + 'https://www.facebook.com/watch?v=123456789', + + // reel + 'https://www.facebook.com/reel/123456789', +]); diff --git a/tests/Unit/EmbedParsers/Platforms/GithubGistTest.php b/tests/Unit/Embed/Platforms/GithubGistTest.php similarity index 100% rename from tests/Unit/EmbedParsers/Platforms/GithubGistTest.php rename to tests/Unit/Embed/Platforms/GithubGistTest.php diff --git a/tests/Unit/EmbedParsers/Platforms/InstagramTest.php b/tests/Unit/Embed/Platforms/InstagramTest.php similarity index 100% rename from tests/Unit/EmbedParsers/Platforms/InstagramTest.php rename to tests/Unit/Embed/Platforms/InstagramTest.php diff --git a/tests/Unit/EmbedParsers/Platforms/RedditTest.php b/tests/Unit/Embed/Platforms/RedditTest.php similarity index 91% rename from tests/Unit/EmbedParsers/Platforms/RedditTest.php rename to tests/Unit/Embed/Platforms/RedditTest.php index 70bd6c3..fcc1a3e 100644 --- a/tests/Unit/EmbedParsers/Platforms/RedditTest.php +++ b/tests/Unit/Embed/Platforms/RedditTest.php @@ -22,10 +22,10 @@ ]); //it('test', function () { -// $url = 'https://old.reddit.com/r/math/comments/66k3c0/ive_just_start_reading_this_1910_book_calculus/'; +// $url = 'https://www.reddit.com/r/math/comments/66k3c0/ive_just_start_reading_this_1910_book_calculus/'; // $parser = new Reddit($url); // $response = $parser->parse(); // -// var_dump($response); +// dd($response->html); // expect($response)->toBeObject(); //}); diff --git a/tests/Unit/EmbedParsers/Platforms/TiktokTest.php b/tests/Unit/Embed/Platforms/TiktokTest.php similarity index 100% rename from tests/Unit/EmbedParsers/Platforms/TiktokTest.php rename to tests/Unit/Embed/Platforms/TiktokTest.php diff --git a/tests/Unit/EmbedParsers/Platforms/TwitterTest.php b/tests/Unit/Embed/Platforms/TwitterTest.php similarity index 100% rename from tests/Unit/EmbedParsers/Platforms/TwitterTest.php rename to tests/Unit/Embed/Platforms/TwitterTest.php diff --git a/tests/Unit/EmbedParsers/Platforms/YoutubeTest.php b/tests/Unit/Embed/Platforms/YoutubeTest.php similarity index 100% rename from tests/Unit/EmbedParsers/Platforms/YoutubeTest.php rename to tests/Unit/Embed/Platforms/YoutubeTest.php