diff --git a/src/Detectors/Code.php b/src/Detectors/Code.php index 870c82c9..994bada6 100644 --- a/src/Detectors/Code.php +++ b/src/Detectors/Code.php @@ -38,7 +38,7 @@ private function detectFromEmbed(): ?EmbedCode $html = $oembed->html('html'); if ($html === null) { - return null; + return $this->detectFromOEmbedPhoto(); } return new EmbedCode( @@ -48,6 +48,33 @@ private function detectFromEmbed(): ?EmbedCode ); } + private function detectFromOEmbedPhoto(): ?EmbedCode + { + $oembed = $this->extractor->getOEmbed(); + + if ($oembed->str('type') !== 'photo') { + return null; + } + + $url = $oembed->url('url'); + + if ($url === null) { + return null; + } + + $width = $oembed->int('width'); + $height = $oembed->int('height'); + + $code = html('img', [ + 'src' => $url, + 'alt' => $oembed->str('title'), + 'width' => $width, + 'height' => $height, + ]); + + return new EmbedCode($code, $width, $height); + } + private function detectFromOpenGraph(): ?EmbedCode { $metas = $this->extractor->getMetas(); diff --git a/tests/OEmbedPhotoCodeTest.php b/tests/OEmbedPhotoCodeTest.php new file mode 100644 index 00000000..cd53f589 --- /dev/null +++ b/tests/OEmbedPhotoCodeTest.php @@ -0,0 +1,106 @@ +embed([ + 'type' => 'photo', + 'version' => '1.0', + 'title' => 'Funny "cat" GIF', + 'url' => 'https://media.public.test/cat.gif', + 'width' => 480, + 'height' => 270, + ])->get('http://public.test/gifs/cat'); + + $code = $info->code; + $this->assertNotNull($code); + $this->assertSame( + 'Funny "cat" GIF', + $code->html + ); + $this->assertSame(480, $code->width); + $this->assertSame(270, $code->height); + } + + public function testPhotoWithoutSizeOmitsDimensions(): void + { + $info = $this->embed([ + 'type' => 'photo', + 'version' => '1.0', + 'url' => 'https://media.public.test/cat.gif', + ])->get('http://public.test/gifs/cat'); + + $code = $info->code; + $this->assertNotNull($code); + $this->assertSame('', $code->html); + $this->assertNull($code->width); + $this->assertNull($code->height); + } + + public function testHtmlStillWinsOverPhotoUrl(): void + { + $info = $this->embed([ + 'type' => 'photo', + 'version' => '1.0', + 'url' => 'https://media.public.test/cat.gif', + 'html' => '
cat
', + ])->get('http://public.test/gifs/cat'); + + $code = $info->code; + $this->assertNotNull($code); + $this->assertSame('
cat
', $code->html); + } + + public function testNonPhotoWithoutHtmlHasNoCode(): void + { + $info = $this->embed([ + 'type' => 'link', + 'version' => '1.0', + 'url' => 'https://media.public.test/cat.gif', + ])->get('http://public.test/gifs/cat'); + + $this->assertNull($info->code); + } + + /** + * @param array $oembed + */ + private function embed(array $oembed): Embed + { + $json = (string) json_encode($oembed, JSON_UNESCAPED_SLASHES); + $page = 'Page title' + .'' + .''; + + $client = new RecordingClient(static function (RequestInterface $request) use ($json, $page): ResponseInterface { + $factory = new Psr17Factory(); + $isOEmbed = $request->getUri()->getPath() === '/oembed'; + + return $factory->createResponse(200) + ->withHeader('Content-Type', $isOEmbed ? 'application/json' : 'text/html') + ->withBody($factory->createStream($isOEmbed ? $json : $page)); + }); + + $crawler = new Crawler($client); + $crawler->setUrlPolicy(UrlPolicy::default()->withResolver(static function (string $host): array { + return ['1.1.1.1']; + })); + + return new Embed($crawler); + } +} diff --git a/tests/fixtures/pachunka.deviantart.com.art-cope-145564099.php b/tests/fixtures/pachunka.deviantart.com.art-cope-145564099.php index c67c22f7..754bebcb 100644 --- a/tests/fixtures/pachunka.deviantart.com.art-cope-145564099.php +++ b/tests/fixtures/pachunka.deviantart.com.art-cope-145564099.php @@ -5,7 +5,12 @@ 'authorName' => 'pachunka', 'authorUrl' => 'https://www.deviantart.com/pachunka', 'cms' => null, - 'code' => null, + 'code' => [ + 'html' => 'Cope', + 'width' => 448, + 'height' => 672, + 'ratio' => 150.0 + ], 'description' => null, 'favicon' => 'https://st.deviantart.net/eclipse/icons/da_favicon_v2.ico', 'feeds' => [], diff --git a/tests/fixtures/www.23hq.com.zzleeper-photo-16600737.php b/tests/fixtures/www.23hq.com.zzleeper-photo-16600737.php index 04207dcb..582a593d 100644 --- a/tests/fixtures/www.23hq.com.zzleeper-photo-16600737.php +++ b/tests/fixtures/www.23hq.com.zzleeper-photo-16600737.php @@ -5,7 +5,12 @@ 'authorName' => 'Zzleeper', 'authorUrl' => 'https://www.23hq.com/Zzleeper/', 'cms' => null, - 'code' => null, + 'code' => [ + 'html' => 'På god väns inrådan kommer det även bultförband vid pilarna. Låter bra tycker jag. (Better safe than sorry)', + 'width' => 756, + 'height' => 567, + 'ratio' => 75.0 + ], 'description' => 'På god väns inrådan kommer det även bultförband vid pilarna. Låter bra tycker jag. (Better safe than sorry)', 'favicon' => 'https://www.23hq.com/favicon.ico', 'feeds' => [], diff --git a/tests/fixtures/www.deviantart.com.art-misty-510056679.php b/tests/fixtures/www.deviantart.com.art-misty-510056679.php index 040b3629..fcc56cb1 100644 --- a/tests/fixtures/www.deviantart.com.art-misty-510056679.php +++ b/tests/fixtures/www.deviantart.com.art-misty-510056679.php @@ -5,7 +5,12 @@ 'authorName' => 'sakimichan', 'authorUrl' => 'https://www.deviantart.com/sakimichan', 'cms' => null, - 'code' => null, + 'code' => [ + 'html' => 'Misty', + 'width' => 695, + 'height' => 900, + 'ratio' => 129.496 + ], 'description' => null, 'favicon' => 'https://st.deviantart.net/eclipse/icons/da_favicon_v2.ico', 'feeds' => [],