Chris@17: providers = $providers; Chris@17: $this->resourceFetcher = $resource_fetcher; Chris@17: $this->httpClient = $http_client; Chris@17: $this->moduleHandler = $module_handler; Chris@17: $this->cacheBackend = $cache_backend; Chris@17: $this->useCaches = isset($cache_backend); Chris@17: } Chris@17: Chris@17: /** Chris@17: * Runs oEmbed discovery and returns the endpoint URL if successful. Chris@17: * Chris@17: * @param string $url Chris@17: * The resource's URL. Chris@17: * Chris@17: * @return string|bool Chris@17: * URL of the oEmbed endpoint, or FALSE if the discovery was unsuccessful. Chris@17: * Chris@17: * @throws \Drupal\media\OEmbed\ResourceException Chris@17: * If the resource cannot be retrieved. Chris@17: */ Chris@17: protected function discoverResourceUrl($url) { Chris@17: try { Chris@17: $response = $this->httpClient->get($url); Chris@17: } Chris@17: catch (RequestException $e) { Chris@17: throw new ResourceException('Could not fetch oEmbed resource.', $url, [], $e); Chris@17: } Chris@17: Chris@17: $document = Html::load((string) $response->getBody()); Chris@17: $xpath = new \DOMXpath($document); Chris@17: Chris@17: return $this->findUrl($xpath, 'json') ?: $this->findUrl($xpath, 'xml'); Chris@17: } Chris@17: Chris@17: /** Chris@17: * Tries to find the oEmbed URL in a DOM. Chris@17: * Chris@17: * @param \DOMXPath $xpath Chris@17: * Page HTML as DOMXPath. Chris@17: * @param string $format Chris@17: * Format of oEmbed resource. Possible values are 'json' and 'xml'. Chris@17: * Chris@17: * @return bool|string Chris@17: * A URL to an oEmbed resource or FALSE if not found. Chris@17: */ Chris@17: protected function findUrl(\DOMXPath $xpath, $format) { Chris@17: $result = $xpath->query("//link[@type='application/$format+oembed']"); Chris@17: return $result->length ? $result->item(0)->getAttribute('href') : FALSE; Chris@17: } Chris@17: Chris@17: /** Chris@17: * {@inheritdoc} Chris@17: */ Chris@17: public function getProviderByUrl($url) { Chris@17: // Check the URL against every scheme of every endpoint of every provider Chris@17: // until we find a match. Chris@17: foreach ($this->providers->getAll() as $provider_name => $provider_info) { Chris@17: foreach ($provider_info->getEndpoints() as $endpoint) { Chris@17: if ($endpoint->matchUrl($url)) { Chris@17: return $provider_info; Chris@17: } Chris@17: } Chris@17: } Chris@17: Chris@17: $resource_url = $this->discoverResourceUrl($url); Chris@17: if ($resource_url) { Chris@17: return $this->resourceFetcher->fetchResource($resource_url)->getProvider(); Chris@17: } Chris@17: Chris@17: throw new ResourceException('No matching provider found.', $url); Chris@17: } Chris@17: Chris@17: /** Chris@17: * {@inheritdoc} Chris@17: */ Chris@17: public function getResourceUrl($url, $max_width = NULL, $max_height = NULL) { Chris@17: // Try to get the resource URL from the static cache. Chris@17: if (isset($this->urlCache[$url])) { Chris@17: return $this->urlCache[$url]; Chris@17: } Chris@17: Chris@17: // Try to get the resource URL from the persistent cache. Chris@17: $cache_id = "media:oembed_resource_url:$url:$max_width:$max_height"; Chris@17: Chris@17: $cached = $this->cacheGet($cache_id); Chris@17: if ($cached) { Chris@17: $this->urlCache[$url] = $cached->data; Chris@17: return $this->urlCache[$url]; Chris@17: } Chris@17: Chris@17: $provider = $this->getProviderByUrl($url); Chris@17: $endpoints = $provider->getEndpoints(); Chris@17: $endpoint = reset($endpoints); Chris@17: $resource_url = $endpoint->buildResourceUrl($url); Chris@17: Chris@17: $parsed_url = UrlHelper::parse($resource_url); Chris@17: if ($max_width) { Chris@17: $parsed_url['query']['maxwidth'] = $max_width; Chris@17: } Chris@17: if ($max_height) { Chris@17: $parsed_url['query']['maxheight'] = $max_height; Chris@17: } Chris@17: // Let other modules alter the resource URL, because some oEmbed providers Chris@17: // provide extra parameters in the query string. For example, Instagram also Chris@17: // supports the 'omitscript' parameter. Chris@17: $this->moduleHandler->alter('oembed_resource_url', $parsed_url, $provider); Chris@17: $resource_url = $parsed_url['path'] . '?' . UrlHelper::buildQuery($parsed_url['query']); Chris@17: Chris@17: $this->urlCache[$url] = $resource_url; Chris@17: $this->cacheSet($cache_id, $resource_url); Chris@17: Chris@17: return $resource_url; Chris@17: } Chris@17: Chris@17: }