diff options
| -rw-r--r-- | Digitigrade/LinkPreview.php | 42 |
1 files changed, 17 insertions, 25 deletions
diff --git a/Digitigrade/LinkPreview.php b/Digitigrade/LinkPreview.php index 4716cc8..706c3c7 100644 --- a/Digitigrade/LinkPreview.php +++ b/Digitigrade/LinkPreview.php @@ -29,38 +29,30 @@ class LinkPreview implements \JsonSerializable { return false; } - $d = new \DOMDocument(); + // TODO: Respect Content-Type header from response, maybe set an Accept header in the request? + // I was able to find a URL serving SHIFT-JIS, but they do not specify a charset in the Content-Type header. + // https://www2d.biglobe.ne.jp/~msyk/charcode/cp932/Windows-31J-charset.html $c = @file_get_contents($this->url); if (!$c) return false; - @$d->loadHTML($c); + $d = \Dom\HTMLDocument::createFromString($c, LIBXML_NOERROR); $url = $this->url; $siteName = hostname_from_uri($this->url); $style = 'text'; - $title = $d->getElementsByTagName('title')->item(0)?->textContent; - $metas = $d->getElementsByTagName('meta'); - foreach ($metas as $tag) { - if ($tag->attributes->getNamedItem('name')?->textContent == 'description') { - // <meta name="description" content="..."> - $description = $tag->attributes->getNamedItem('content')?->textContent; - } elseif ($prop = $tag->attributes->getNamedItem('property')) { - // <meta property="og:..." content="..."> - $content = $tag->attributes->getNamedItem('content')?->textContent; - match ($prop->textContent) { - 'og:title' => $title = $content, - 'og:description' => $description = $content, - 'og:url' => $url = $content, - 'og:site_name' => $siteName = $content, - 'og:image' => $imageUrl = $content, - default => null - }; - } elseif ($tag->attributes->getNamedItem('name')?->textContent == 'twitter:card' - && $tag->attributes->getNamedItem("content")?->textContent == 'summary_large_image') { - // <meta name="twitter:card" content="summary_large_image"> - $style = 'largeImage'; - } + // opengraph + $title = $d->querySelector("meta[property='og:title']")?->getAttribute('content'); + $description = $d->querySelector("meta[property='og:description']")?->getAttribute('content'); + $url = $d->querySelector("meta[property='og:url']")?->getAttribute('content'); + $siteName = $d->querySelector("meta[property='og:site_name']")?->getAttribute('content'); + $imageUrl = $d->querySelector("meta[property='og:image']")?->getAttribute('content'); + // fallbacks + $title = $title ?? $d->querySelector('title')?->textContent; + $description = $description ?? $d->querySelector('meta[name=description]')?->getAttribute('content'); + + if ($d->querySelector("meta[name='twitter:card'][content=summary_large_image]") != null) { + $style = 'largeImage'; } // turn text into smallImage if an image is present $style = ($style == 'text' && isset($imageUrl)) ? 'smallImage' : $style; @@ -88,4 +80,4 @@ class LinkPreview implements \JsonSerializable { 'imageUrl' => $this->imageUrl ]; } -}
\ No newline at end of file +} |
