From 4b5f76d688fee47585aec0b3d0c92d0af8c0225b Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 6 Apr 2011 17:57:33 -0400 Subject: [PATCH] more flexible oEmbed handling --- README | 16 ++++++++-- lib/default.php | 5 ++- lib/oembedhelper.php | 76 ++++++++++++++++++++++++++++++++------------ 3 files changed, 73 insertions(+), 24 deletions(-) diff --git a/README b/README index ef032cad84..5f58179bfe 100644 --- a/README +++ b/README @@ -1393,12 +1393,22 @@ desclimit: maximum number of characters to allow in group descriptions. null (default) means to use the site-wide text limits. 0 means no limit. -oohembed +oembed -------- -oEmbed endpoint for multimedia attachments (links in posts). +oEmbed endpoint for multimedia attachments (links in posts). Will also +work as 'oohembed' for backwards compatibility. -endpoint: oohembed endpoint using http://oohembed.com/ software. +endpoint: oohembed endpoint using http://oohembed.com/ software. Defaults to + 'http://oohembed.com/oohembed/'. +order: Array of methods to check for OEmbed data. Methods include 'built-in' + (use a built-in function to simulate oEmbed for some sites), + 'well-known' (use well-known public oEmbed endpoints), + 'discovery' (discover using headers in HTML), 'service' (use + a third-party service, like oohembed or embed.ly. Default is + array('built-in', 'well-known', 'service', 'discovery'). Note that very + few sites implement oEmbed; 'discovery' is going to fail 99% of the + time. search ------ diff --git a/lib/default.php b/lib/default.php index 6c7b18bccd..84eaf3bf2a 100644 --- a/lib/default.php +++ b/lib/default.php @@ -269,7 +269,10 @@ $default = 'group' => array('maxaliases' => 3, 'desclimit' => null), - 'oohembed' => array('endpoint' => 'http://oohembed.com/oohembed/'), + 'oembed' => + array('endpoint' => 'http://oohembed.com/oohembed/', + 'order' => array('built-in', 'well-known', 'service', 'discovery'), + ), 'search' => array('type' => 'fulltext'), 'sessions' => diff --git a/lib/oembedhelper.php b/lib/oembedhelper.php index 3cd20c8e8e..4aae815918 100644 --- a/lib/oembedhelper.php +++ b/lib/oembedhelper.php @@ -43,6 +43,13 @@ class oEmbedHelper protected static $apiMap = array( 'flickr.com' => 'http://www.flickr.com/services/oembed/', 'yfrog.com' => 'http://www.yfrog.com/api/oembed', + 'youtube.com' => 'http://www.youtube.com/oembed', + 'viddler.com' => 'http://lab.viddler.com/services/oembed/', + 'qik.com' => 'http://qik.com/api/oembed.json', + 'revision3.com' => 'http://revision3.com/api/oembed/', + 'hulu.com' => 'http://www.hulu.com/api/oembed.json', + 'vimeo.com' => 'http://www.vimeo.com/api/oembed.json', + 'my.opera.com' => 'http://my.opera.com/service/oembed', ); protected static $functionMap = array( 'twitpic.com' => 'oEmbedHelper::twitPic', @@ -74,30 +81,59 @@ class oEmbedHelper $host = substr($host, 4); } - // Blacklist: systems with no oEmbed API of their own, which are - // either missing from or broken on oohembed.com's proxy. - // we know how to look data up in another way... - if (array_key_exists($host, self::$functionMap)) { - $func = self::$functionMap[$host]; - return call_user_func($func, $url, $params); - } + common_log(LOG_INFO, 'Checking for oEmbed data for ' . $url); - // Whitelist: known API endpoints for sites that don't provide discovery... - if (array_key_exists($host, self::$apiMap)) { - $api = self::$apiMap[$host]; - } else { - try { - $api = self::discover($url); - } catch (Exception $e) { - // Discovery failed... fall back to oohembed if enabled. - $oohembed = common_config('oohembed', 'endpoint'); - if ($oohembed) { - $api = $oohembed; - } else { - throw $e; + // You can fiddle with the order of discovery -- either skipping + // some types or re-ordering them. + + $order = common_config('oembed', 'order'); + + foreach ($order as $method) { + + switch ($method) { + case 'built-in': + common_log(LOG_INFO, 'Considering built-in oEmbed methods...'); + // Blacklist: systems with no oEmbed API of their own, which are + // either missing from or broken on oohembed.com's proxy. + // we know how to look data up in another way... + if (array_key_exists($host, self::$functionMap)) { + common_log(LOG_INFO, 'We have a built-in method for ' . $host); + $func = self::$functionMap[$host]; + return call_user_func($func, $url, $params); } + break; + case 'well-known': + common_log(LOG_INFO, 'Considering well-known oEmbed endpoints...'); + // Whitelist: known API endpoints for sites that don't provide discovery... + if (array_key_exists($host, self::$apiMap)) { + $api = self::$apiMap[$host]; + common_log(LOG_INFO, 'Using well-known endpoint "' . $api . '" for "' . $host . '"'); + break 2; + } + break; + case 'discovery': + try { + common_log(LOG_INFO, 'Trying to discover an oEmbed endpoint using link headers.'); + $api = self::discover($url); + common_log(LOG_INFO, 'Found API endpoint ' . $api . ' for URL ' . $url); + break 2; + } catch (Exception $e) { + common_log(LOG_INFO, 'Could not find an oEmbed endpoint using link headers.'); + // Just ignore it! + } + break; + case 'service': + $api = common_config('oembed', 'endpoint'); + common_log(LOG_INFO, 'Using service API endpoint ' . $api); + break 2; + break; } } + + if (empty($api)) { + throw new ServerException(_('No oEmbed API endpoint available.')); + } + return self::getObjectFrom($api, $url, $params); }