diff --git a/plugins/Oembed/OembedPlugin.php b/plugins/Oembed/OembedPlugin.php index 7d66bdebef..4adf6d35c1 100644 --- a/plugins/Oembed/OembedPlugin.php +++ b/plugins/Oembed/OembedPlugin.php @@ -40,16 +40,16 @@ class OembedPlugin extends Plugin try { common_log(LOG_INFO, 'Trying to discover an oEmbed endpoint using link headers.'); $api = oEmbedHelper::oEmbedEndpointFromHTML($dom); - common_log(LOG_INFO, 'Found API endpoint ' . $api . ' for URL ' . $url); + common_log(LOG_INFO, 'Found oEmbed API endpoint ' . $api . ' for URL ' . $url); $params = array( 'maxwidth' => common_config('thumbnail', 'width'), 'maxheight' => common_config('thumbnail', 'height'), ); $metadata = oEmbedHelper::getOembedFrom($api, $url, $params); - } catch (Exception $e) { - common_log(LOG_INFO, 'Could not find an oEmbed endpoint using link headers.'); + common_log(LOG_INFO, 'Could not find an oEmbed endpoint using link headers, trying OpenGraph from HTML.'); // Just ignore it! + $metadata = OpenGraphHelper::ogFromHtml($dom); } } diff --git a/plugins/Oembed/lib/opengraphhelper.php b/plugins/Oembed/lib/opengraphhelper.php new file mode 100644 index 0000000000..07b5cf5d70 --- /dev/null +++ b/plugins/Oembed/lib/opengraphhelper.php @@ -0,0 +1,68 @@ + 'provider_name', + 'title' => 'title', + 'description' => 'html', + 'type' => 'type', + 'url' => 'url', + 'image' => 'thumbnail_url', + ]; + + // This regex map has: /pattern(match)/ => matchindex | string + protected static $type_regex_map = [ + '/^(video)/' => 1, + '/^image/' => 'photo', + ]; + + static function ogFromHtml(DOMDocument $dom) { + $obj = new stdClass(); + $nodes = $dom->getElementsByTagName('meta'); + for ($i = 0; $i < $nodes->length; $i++) { + $node = $nodes->item($i); + if (!$node->hasAttributes()) { + continue; + } + $property = $node->attributes->getNamedItem('property'); + $matches = array(); + if (!preg_match(self::KEY_REGEX, $property->value, $matches)) { + // not property="og:something" + continue; + } + if (!isset(self::$property_map[$matches[1]])) { + // unknown metadata property, nothing we would care about anyway + continue; + } + + $prop = self::$property_map[$matches[1]]; + $obj->{$prop} = $node->attributes->getNamedItem('content')->value; + // I don't care right now if they're empty + } + if (isset($obj->type)) { + // Loop through each known OpenGraph type where we have a match in oEmbed + foreach (self::$type_regex_map as $pattern=>$replacement) { + $matches = array(); + if (preg_match($pattern, $obj->type, $matches)) { + $obj->type = is_int($replacement) + ? $matches[$replacement] + : $replacement; + break; + } + } + // If it's not known to our type map, we just pass it through in hopes of it getting handled anyway + } elseif (isset($obj->url)) { + // If no type is set but we have a URL, let's set type=link + $obj->type = 'link'; + } + return $obj; + } +}