3 namespace Drupal\media\OEmbed;
5 use Drupal\Component\Serialization\Json;
6 use Drupal\Core\Cache\CacheBackendInterface;
7 use Drupal\Core\Cache\UseCacheBackendTrait;
8 use GuzzleHttp\ClientInterface;
9 use GuzzleHttp\Exception\RequestException;
10 use Symfony\Component\Serializer\Encoder\XmlEncoder;
13 * Fetches and caches oEmbed resources.
15 class ResourceFetcher implements ResourceFetcherInterface {
17 use UseCacheBackendTrait;
22 * @var \GuzzleHttp\Client
24 protected $httpClient;
27 * The oEmbed provider repository service.
29 * @var \Drupal\media\OEmbed\ProviderRepositoryInterface
34 * Constructs a ResourceFetcher object.
36 * @param \GuzzleHttp\ClientInterface $http_client
38 * @param \Drupal\media\OEmbed\ProviderRepositoryInterface $providers
39 * The oEmbed provider repository service.
40 * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
41 * (optional) The cache backend.
43 public function __construct(ClientInterface $http_client, ProviderRepositoryInterface $providers, CacheBackendInterface $cache_backend = NULL) {
44 $this->httpClient = $http_client;
45 $this->providers = $providers;
46 $this->cacheBackend = $cache_backend;
47 $this->useCaches = isset($cache_backend);
53 public function fetchResource($url) {
54 $cache_id = "media:oembed_resource:$url";
56 $cached = $this->cacheGet($cache_id);
58 return $this->createResource($cached->data, $url);
62 $response = $this->httpClient->get($url);
64 catch (RequestException $e) {
65 throw new ResourceException('Could not retrieve the oEmbed resource.', $url, [], $e);
68 list($format) = $response->getHeader('Content-Type');
69 $content = (string) $response->getBody();
71 if (strstr($format, 'text/xml') || strstr($format, 'application/xml')) {
72 $encoder = new XmlEncoder();
73 $data = $encoder->decode($content, 'xml');
75 elseif (strstr($format, 'text/javascript') || strstr($format, 'application/json')) {
76 $data = Json::decode($content);
78 // If the response is neither XML nor JSON, we are in bat country.
80 throw new ResourceException('The fetched resource did not have a valid Content-Type header.', $url);
83 $this->cacheSet($cache_id, $data);
85 return $this->createResource($data, $url);
89 * Creates a Resource object from raw resource data.
92 * The resource data returned by the provider.
94 * The URL of the resource.
96 * @return \Drupal\media\OEmbed\Resource
97 * A value object representing the resource.
99 * @throws \Drupal\media\OEmbed\ResourceException
100 * If the resource cannot be created.
102 protected function createResource(array $data, $url) {
105 'author_name' => NULL,
106 'author_url' => NULL,
107 'provider_name' => NULL,
109 'thumbnail_url' => NULL,
110 'thumbnail_width' => NULL,
111 'thumbnail_height' => NULL,
119 if ($data['version'] !== '1.0') {
120 throw new ResourceException("Resource version must be '1.0'", $url, $data);
123 // Prepare the arguments to pass to the factory method.
124 $provider = $data['provider_name'] ? $this->providers->get($data['provider_name']) : NULL;
126 // The Resource object will validate the data we create it with and throw an
127 // exception if anything looks wrong. For better debugging, catch those
128 // exceptions and wrap them in a more specific and useful exception.
130 switch ($data['type']) {
131 case Resource::TYPE_LINK:
132 return Resource::link(
136 $data['author_name'],
139 $data['thumbnail_url'],
140 $data['thumbnail_width'],
141 $data['thumbnail_height']
144 case Resource::TYPE_PHOTO:
145 return Resource::photo(
151 $data['author_name'],
154 $data['thumbnail_url'],
155 $data['thumbnail_width'],
156 $data['thumbnail_height']
159 case Resource::TYPE_RICH:
160 return Resource::rich(
166 $data['author_name'],
169 $data['thumbnail_url'],
170 $data['thumbnail_width'],
171 $data['thumbnail_height']
173 case Resource::TYPE_VIDEO:
174 return Resource::video(
180 $data['author_name'],
183 $data['thumbnail_url'],
184 $data['thumbnail_width'],
185 $data['thumbnail_height']
189 throw new ResourceException('Unknown resource type: ' . $data['type'], $url, $data);
192 catch (\InvalidArgumentException $e) {
193 throw new ResourceException($e->getMessage(), $url, $data, $e);