diff --git a/oembed/Oembed.php b/oembed/Oembed.php index 8609dfeb3..4c40cfea0 100644 --- a/oembed/Oembed.php +++ b/oembed/Oembed.php @@ -1,24 +1,55 @@ get('Oembed', 'autodiscover'); } + /** + * Gets providers from config. + */ public static function get_providers() { return Config::inst()->get('Oembed', 'providers'); } - - protected static function match_url($url) { + + /** + * Returns an endpoint (a base Oembed URL) from first matching provider. + * + * @param $url Human-readable URL. + * @returns string/bool URL of an endpoint, or false if no matching provider exists. + */ + protected static function find_endpoint($url) { foreach(self::get_providers() as $scheme=>$endpoint) { - if(self::match_scheme($url, $scheme)) { + if(self::matches_scheme($url, $scheme)) { return $endpoint; } } return false; } - protected static function match_scheme($url, $scheme) { + /** + * Checks the URL if it matches against the scheme (pattern). + * + * @param $url Human-readable URL to be checked. + * @param $scheme Pattern to be matched against. + * @returns bool Whether the pattern matches or not. + */ + protected static function matches_scheme($url, $scheme) { $urlInfo = parse_url($url); $schemeInfo = parse_url($scheme); foreach($schemeInfo as $k=>$v) { @@ -40,15 +71,24 @@ class Oembed { } return true; } - + + /** + * Performs a HTTP request to the URL and scans the response for resource links + * that mention oembed in their type. + * + * @param $url Human readable URL. + * @returns string/bool Oembed URL, or false. + */ protected static function autodiscover_from_url($url) { + // Fetch the URL $service = new RestfulService($url); $body = $service->request(); if(!$body || $body->isError()) { return false; } $body = $body->getBody(); - + + // Look within the body for an oembed link. if(preg_match_all('#]+?(?:href=[\'"](.+?)[\'"][^>]+?)?type=["\']application/json\+oembed["\'](?:[^>]+?href=[\'"](.+?)[\'"])?#', $body, $matches, PREG_SET_ORDER)) { $match = $matches[0]; if(!empty($match[1])) { @@ -61,19 +101,32 @@ class Oembed { return false; } - public static function get_oembed_from_url($url, $type = false, Array $options = array()) { - $endpoint = self::match_url($url); - $ourl = false; + /** + * Takes the human-readable URL of an embeddable resource and converts it into an + * Oembed_Result descriptor (which contains a full Oembed resource URL). + * + * @param $url Human-readable URL + * @param $type ? + * @param $options array Options to be used for constructing the resulting descriptor. + * @returns Oembed_Result/bool An Oembed descriptor, or false + */ + public static function get_oembed_from_url($url, $type = false, array $options = array()) { + // Find or build the Oembed URL. + $endpoint = self::find_endpoint($url); + $oembedUrl = false; if(!$endpoint) { if(self::get_autodiscover()) { - $ourl = self::autodiscover_from_url($url); + $oembedUrl = self::autodiscover_from_url($url); } } elseif($endpoint === true) { - $ourl = self::autodiscover_from_url($url); + $oembedUrl = self::autodiscover_from_url($url); } else { - $ourl = Controller::join_links($endpoint, '?format=json&url=' . rawurlencode($url)); + // Build the url manually - we gave all needed information. + $oembedUrl = Controller::join_links($endpoint, '?format=json&url=' . rawurlencode($url)); } - if($ourl) { + + if($oembedUrl) { + // Inject the options into the Oembed URL. if($options) { if(isset($options['width']) && !isset($options['maxwidth'])) { $options['maxwidth'] = $options['width']; @@ -81,10 +134,13 @@ class Oembed { if(isset($options['height']) && !isset($options['maxheight'])) { $options['maxheight'] = $options['height']; } - $ourl = Controller::join_links($ourl, '?' . http_build_query($options, '', '&')); + $oembedUrl = Controller::join_links($oembedUrl, '?' . http_build_query($options, '', '&')); } - return new Oembed_Result($ourl, $url, $type, $options); + + return new Oembed_Result($oembedUrl, $url, $type, $options); } + + // No matching Oembed resource found. return false; } @@ -105,17 +161,37 @@ class Oembed { } class Oembed_Result extends ViewableData { + /** + * JSON data fetched from the Oembed URL. + * This data is accessed dynamically by getField and hasField. + */ protected $data = false; + + /** + * Human readable URL + */ protected $origin = false; + + /** + * ? + */ protected $type = false; + + /** + * Oembed URL + */ protected $url; + + /** + * Class to be injected into the resulting HTML element. + */ protected $extraClass; public static $casting = array( 'html' => 'HTMLText', ); - public function __construct($url, $origin = false, $type = false, Array $options = array()) { + public function __construct($url, $origin = false, $type = false, array $options = array()) { $this->url = $url; $this->origin = $origin; $this->type = $type; @@ -127,10 +203,16 @@ class Oembed_Result extends ViewableData { parent::__construct(); } + /** + * Fetches the JSON data from the Oembed URL (cached). + * Only sets the internal variable. + */ protected function loadData() { if($this->data !== false) { return; } + + // Fetch from Oembed URL $service = new RestfulService($this->url); $body = $service->request(); if(!$body || $body->isError()) { @@ -149,14 +231,21 @@ class Oembed_Result extends ViewableData { if($this->type && $this->type != $data['type']) { $data = array(); } + $this->data = $data; } + /** + * Wrap the check for looking into Oembed JSON within $this->data. + */ public function hasField($field) { $this->loadData(); return array_key_exists(strtolower($field), $this->data); } + /** + * Wrap the field calls to fetch data from Oembed JSON (within $this->data) + */ public function getField($field) { $field = strtolower($field); if($this->hasField($field)) {