class UrlResolver

Same name in this branch
  1. 8.9.x core/modules/media/tests/modules/media_test_oembed/src/UrlResolver.php \Drupal\media_test_oembed\UrlResolver
Same name in other branches
  1. 9 core/modules/media/src/OEmbed/UrlResolver.php \Drupal\media\OEmbed\UrlResolver
  2. 9 core/modules/media/tests/modules/media_test_oembed/src/UrlResolver.php \Drupal\media_test_oembed\UrlResolver
  3. 10 core/modules/media/src/OEmbed/UrlResolver.php \Drupal\media\OEmbed\UrlResolver
  4. 10 core/modules/media/tests/modules/media_test_oembed/src/UrlResolver.php \Drupal\media_test_oembed\UrlResolver
  5. 11.x core/modules/media/src/OEmbed/UrlResolver.php \Drupal\media\OEmbed\UrlResolver
  6. 11.x core/modules/media/tests/modules/media_test_oembed/src/UrlResolver.php \Drupal\media_test_oembed\UrlResolver

Converts oEmbed media URLs into endpoint-specific resource URLs.

Hierarchy

Expanded class hierarchy of UrlResolver

1 file declares its use of UrlResolver
UrlResolver.php in core/modules/media/tests/modules/media_test_oembed/src/UrlResolver.php
1 string reference to 'UrlResolver'
media.services.yml in core/modules/media/media.services.yml
core/modules/media/media.services.yml
1 service uses UrlResolver
media.oembed.url_resolver in core/modules/media/media.services.yml
Drupal\media\OEmbed\UrlResolver

File

core/modules/media/src/OEmbed/UrlResolver.php, line 16

Namespace

Drupal\media\OEmbed
View source
class UrlResolver implements UrlResolverInterface {
    use UseCacheBackendTrait;
    
    /**
     * The HTTP client.
     *
     * @var \GuzzleHttp\Client
     */
    protected $httpClient;
    
    /**
     * The OEmbed provider repository service.
     *
     * @var \Drupal\media\OEmbed\ProviderRepositoryInterface
     */
    protected $providers;
    
    /**
     * The OEmbed resource fetcher service.
     *
     * @var \Drupal\media\OEmbed\ResourceFetcherInterface
     */
    protected $resourceFetcher;
    
    /**
     * The module handler service.
     *
     * @var \Drupal\Core\Extension\ModuleHandlerInterface
     */
    protected $moduleHandler;
    
    /**
     * Static cache of discovered oEmbed resource URLs, keyed by canonical URL.
     *
     * A discovered resource URL is the actual endpoint URL for a specific media
     * object, fetched from its canonical URL.
     *
     * @var string[]
     */
    protected $urlCache = [];
    
    /**
     * Constructs a UrlResolver object.
     *
     * @param \Drupal\media\OEmbed\ProviderRepositoryInterface $providers
     *   The oEmbed provider repository service.
     * @param \Drupal\media\OEmbed\ResourceFetcherInterface $resource_fetcher
     *   The OEmbed resource fetcher service.
     * @param \GuzzleHttp\ClientInterface $http_client
     *   The HTTP client.
     * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
     *   The module handler service.
     * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
     *   (optional) The cache backend.
     */
    public function __construct(ProviderRepositoryInterface $providers, ResourceFetcherInterface $resource_fetcher, ClientInterface $http_client, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend = NULL) {
        $this->providers = $providers;
        $this->resourceFetcher = $resource_fetcher;
        $this->httpClient = $http_client;
        $this->moduleHandler = $module_handler;
        $this->cacheBackend = $cache_backend;
        $this->useCaches = isset($cache_backend);
    }
    
    /**
     * Runs oEmbed discovery and returns the endpoint URL if successful.
     *
     * @param string $url
     *   The resource's URL.
     *
     * @return string|bool
     *   URL of the oEmbed endpoint, or FALSE if the discovery was unsuccessful.
     */
    protected function discoverResourceUrl($url) {
        try {
            $response = $this->httpClient
                ->get($url);
        } catch (RequestException $e) {
            return FALSE;
        }
        $document = Html::load((string) $response->getBody());
        $xpath = new \DOMXpath($document);
        return $this->findUrl($xpath, 'json') ?: $this->findUrl($xpath, 'xml');
    }
    
    /**
     * Tries to find the oEmbed URL in a DOM.
     *
     * @param \DOMXPath $xpath
     *   Page HTML as DOMXPath.
     * @param string $format
     *   Format of oEmbed resource. Possible values are 'json' and 'xml'.
     *
     * @return bool|string
     *   A URL to an oEmbed resource or FALSE if not found.
     */
    protected function findUrl(\DOMXPath $xpath, $format) {
        $result = $xpath->query("//link[@type='application/{$format}+oembed']");
        return $result->length ? $result->item(0)
            ->getAttribute('href') : FALSE;
    }
    
    /**
     * {@inheritdoc}
     */
    public function getProviderByUrl($url) {
        // Check the URL against every scheme of every endpoint of every provider
        // until we find a match.
        foreach ($this->providers
            ->getAll() as $provider_name => $provider_info) {
            foreach ($provider_info->getEndpoints() as $endpoint) {
                if ($endpoint->matchUrl($url)) {
                    return $provider_info;
                }
            }
        }
        $resource_url = $this->discoverResourceUrl($url);
        if ($resource_url) {
            return $this->resourceFetcher
                ->fetchResource($resource_url)
                ->getProvider();
        }
        throw new ResourceException('No matching provider found.', $url);
    }
    
    /**
     * {@inheritdoc}
     */
    public function getResourceUrl($url, $max_width = NULL, $max_height = NULL) {
        // Try to get the resource URL from the static cache.
        if (isset($this->urlCache[$url])) {
            return $this->urlCache[$url];
        }
        // Try to get the resource URL from the persistent cache.
        $cache_id = "media:oembed_resource_url:{$url}:{$max_width}:{$max_height}";
        $cached = $this->cacheGet($cache_id);
        if ($cached) {
            $this->urlCache[$url] = $cached->data;
            return $this->urlCache[$url];
        }
        $provider = $this->getProviderByUrl($url);
        $endpoints = $provider->getEndpoints();
        $endpoint = reset($endpoints);
        $resource_url = $endpoint->buildResourceUrl($url);
        $parsed_url = UrlHelper::parse($resource_url);
        if ($max_width) {
            $parsed_url['query']['maxwidth'] = $max_width;
        }
        if ($max_height) {
            $parsed_url['query']['maxheight'] = $max_height;
        }
        // Let other modules alter the resource URL, because some oEmbed providers
        // provide extra parameters in the query string. For example, Instagram also
        // supports the 'omitscript' parameter.
        $this->moduleHandler
            ->alter('oembed_resource_url', $parsed_url, $provider);
        $resource_url = $parsed_url['path'] . '?' . rawurldecode(UrlHelper::buildQuery($parsed_url['query']));
        $this->urlCache[$url] = $resource_url;
        $this->cacheSet($cache_id, $resource_url);
        return $resource_url;
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
UrlResolver::$httpClient protected property The HTTP client.
UrlResolver::$moduleHandler protected property The module handler service.
UrlResolver::$providers protected property The OEmbed provider repository service.
UrlResolver::$resourceFetcher protected property The OEmbed resource fetcher service.
UrlResolver::$urlCache protected property Static cache of discovered oEmbed resource URLs, keyed by canonical URL.
UrlResolver::discoverResourceUrl protected function Runs oEmbed discovery and returns the endpoint URL if successful.
UrlResolver::findUrl protected function Tries to find the oEmbed URL in a DOM.
UrlResolver::getProviderByUrl public function Tries to determine the oEmbed provider for a media asset URL. Overrides UrlResolverInterface::getProviderByUrl
UrlResolver::getResourceUrl public function Builds the resource URL for a media asset URL. Overrides UrlResolverInterface::getResourceUrl 1
UrlResolver::__construct public function Constructs a UrlResolver object.
UseCacheBackendTrait::$cacheBackend protected property Cache backend instance.
UseCacheBackendTrait::$useCaches protected property Flag whether caches should be used or skipped.
UseCacheBackendTrait::cacheGet protected function Fetches from the cache backend, respecting the use caches flag. 1
UseCacheBackendTrait::cacheSet protected function Stores data in the persistent cache, respecting the use caches flag.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.