diff --git a/oembed/Oembed.php b/oembed/Oembed.php index 7918c8407..72a810111 100644 --- a/oembed/Oembed.php +++ b/oembed/Oembed.php @@ -101,27 +101,37 @@ class Oembed { * @param $url Human readable URL. * @returns string/bool Oembed URL, or false. */ - protected static function autodiscover_from_url($url) { + protected static function autodiscover_from_url($url) + { // Fetch the URL (cache for a week by default) - $service = new RestfulService($url, 60*60*24*7); + $service = new RestfulService($url, 60 * 60 * 24 * 7); $body = $service->request(); - if(!$body || $body->isError()) { + if (!$body || $body->isError()) { return false; } $body = $body->getBody(); + return static::autodiscover_from_body($body); + } + /** + * Given a response body, determine if there is an autodiscover url + * + * @param string $body + * @return bool|string + */ + public static function autodiscover_from_body($body) { // Look within the body for an oembed link. - $pcreOmbed = '#]+?(?:href=[\'"](.+?)[\'"][^>]+?)' + $pcreOmbed = '#]+?(?:href=[\'"](?[^\'"]+?)[\'"][^>]+?)' . '?type=["\']application/json\+oembed["\']' - . '(?:[^>]+?href=[\'"](.+?)[\'"])?#'; + . '(?:[^>]+?href=[\'"](?[^\'"]+?)[\'"])?#'; if(preg_match_all($pcreOmbed, $body, $matches, PREG_SET_ORDER)) { $match = $matches[0]; - if(!empty($match[2])) { - return html_entity_decode($match[2]); + if(!empty($match['second'])) { + return html_entity_decode($match['second']); } - if(!empty($match[1])) { - return html_entity_decode($match[1]); + if(!empty($match['first'])) { + return html_entity_decode($match['first']); } } return false; @@ -297,11 +307,11 @@ class Oembed_Result extends ViewableData { // Convert all keys to lowercase $data = array_change_key_case($data, CASE_LOWER); - if( isset($data['provider_name']) && $data['provider_name'] == "Facebook" ) { - $id = preg_replace("/.*\/(\d+?)\/?($|\?.*)/", "$1", $data["url"]); - $data['thumbnail_url'] = "https://graph.facebook.com/{$id}/picture"; + // Check if we can guess thumbnail + if(empty($data['thumbnail_url']) && $thumbnail = $this->findThumbnail($data)) { + $data['thumbnail_url'] = $thumbnail; } - + // Purge everything if the type does not match. if($this->type && $this->type != $data['type']) { $data = array(); @@ -310,6 +320,27 @@ class Oembed_Result extends ViewableData { $this->data = $data; } + /** + * Find thumbnail if omitted from data + * + * @param array $data + * @return string + */ + public function findThumbnail($data) { + if(!empty($data['thumbnail_url'])) { + return $data['thumbnail_url']; + } + + // Hack in facebook graph thumbnail + if(!empty($data['provider_name']) && $data['provider_name'] === 'Facebook') { + $id = preg_replace("/.*\\/(\\d+?)\\/?($|\\?.*)/", "$1", $data["url"]); + return "https://graph.facebook.com/{$id}/picture"; + } + + // no thumbnail found + return null; + } + /** * Wrap the check for looking into Oembed JSON within $this->data. */ diff --git a/tests/oembed/OembedTest.php b/tests/oembed/OembedTest.php index 73d94c49b..06cd8ffb0 100644 --- a/tests/oembed/OembedTest.php +++ b/tests/oembed/OembedTest.php @@ -38,6 +38,70 @@ class OembedTest extends SapphireTest { $this->assertEquals($query['maxwidth'], 'bar', 'Magically creates maxwidth option'); } + public function testAutodiscover() { + // Test href after type tag + $body = <<Some content + + +EOS; + $this->assertEquals( + 'https://www.facebook.com/plugins/post/oembed.json/?url=https%3A%2F%2Fwww.facebook.com%2Fsomeusername%2Fposts%2F10209305859558135', + Oembed::autodiscover_from_body($body) + ); + + // Test href before the type tag + $body2 = <<Some content + + +EOS; + $this->assertEquals( + 'https://www.facebook.com/plugins/post/oembed.json/?url=https%3A%2F%2Fwww.facebook.com%2Fsomeusername%2Fposts%2F10209305859558135', + Oembed::autodiscover_from_body($body2) + ); + } + + public function testFindThumbnail() + { + $data = array( + "author_name"=> "Some User", + "author_url"=> null, + "provider_url" => "https://www.facebook.com", + "provider_name" => "Facebook", + "success" => true, + "height" => null, + "html" => "
", + "type" => "rich", + "version" => "1.0", + "url" => "https://www.facebook.com/someuser/posts/6465132161654421654", + "width" => 552 + ); + + // Test facebook url + $result = new Oembed_Result('https://www.facebook.com/someuser/posts/6465132161654421654'); + $this->assertEquals( + "https://graph.facebook.com/6465132161654421654/picture", + $result->findThumbnail($data) + ); + + // Test respect existing url + $data['thumbnail_url'] = 'http://www.silverstripe.com/picture.jpg'; + $this->assertEquals( + "http://www.silverstripe.com/picture.jpg", + $result->findThumbnail($data) + ); + } + public function testRequestProtocolReflectedInGetOembedFromUrl() { Config::inst()->update('Oembed', 'providers', array( 'http://*.silverstripe.com/watch*'=> array(