Updated to Drupal 8.6.4, which is PHP 7.3 friendly. Also updated HTMLaw library....
[yaffs-website] / web / core / modules / media / src / OEmbed / ResourceFetcher.php
1 <?php
2
3 namespace Drupal\media\OEmbed;
4
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;
11
12 /**
13  * Fetches and caches oEmbed resources.
14  */
15 class ResourceFetcher implements ResourceFetcherInterface {
16
17   use UseCacheBackendTrait;
18
19   /**
20    * The HTTP client.
21    *
22    * @var \GuzzleHttp\Client
23    */
24   protected $httpClient;
25
26   /**
27    * The oEmbed provider repository service.
28    *
29    * @var \Drupal\media\OEmbed\ProviderRepositoryInterface
30    */
31   protected $providers;
32
33   /**
34    * Constructs a ResourceFetcher object.
35    *
36    * @param \GuzzleHttp\ClientInterface $http_client
37    *   The 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.
42    */
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);
48   }
49
50   /**
51    * {@inheritdoc}
52    */
53   public function fetchResource($url) {
54     $cache_id = "media:oembed_resource:$url";
55
56     $cached = $this->cacheGet($cache_id);
57     if ($cached) {
58       return $this->createResource($cached->data, $url);
59     }
60
61     try {
62       $response = $this->httpClient->get($url);
63     }
64     catch (RequestException $e) {
65       throw new ResourceException('Could not retrieve the oEmbed resource.', $url, [], $e);
66     }
67
68     list($format) = $response->getHeader('Content-Type');
69     $content = (string) $response->getBody();
70
71     if (strstr($format, 'text/xml') || strstr($format, 'application/xml')) {
72       $encoder = new XmlEncoder();
73       $data = $encoder->decode($content, 'xml');
74     }
75     elseif (strstr($format, 'text/javascript') || strstr($format, 'application/json')) {
76       $data = Json::decode($content);
77     }
78     // If the response is neither XML nor JSON, we are in bat country.
79     else {
80       throw new ResourceException('The fetched resource did not have a valid Content-Type header.', $url);
81     }
82
83     $this->cacheSet($cache_id, $data);
84
85     return $this->createResource($data, $url);
86   }
87
88   /**
89    * Creates a Resource object from raw resource data.
90    *
91    * @param array $data
92    *   The resource data returned by the provider.
93    * @param string $url
94    *   The URL of the resource.
95    *
96    * @return \Drupal\media\OEmbed\Resource
97    *   A value object representing the resource.
98    *
99    * @throws \Drupal\media\OEmbed\ResourceException
100    *   If the resource cannot be created.
101    */
102   protected function createResource(array $data, $url) {
103     $data += [
104       'title' => NULL,
105       'author_name' => NULL,
106       'author_url' => NULL,
107       'provider_name' => NULL,
108       'cache_age' => NULL,
109       'thumbnail_url' => NULL,
110       'thumbnail_width' => NULL,
111       'thumbnail_height' => NULL,
112       'width' => NULL,
113       'height' => NULL,
114       'url' => NULL,
115       'html' => NULL,
116       'version' => NULL,
117     ];
118
119     if ($data['version'] !== '1.0') {
120       throw new ResourceException("Resource version must be '1.0'", $url, $data);
121     }
122
123     // Prepare the arguments to pass to the factory method.
124     $provider = $data['provider_name'] ? $this->providers->get($data['provider_name']) : NULL;
125
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.
129     try {
130       switch ($data['type']) {
131         case Resource::TYPE_LINK:
132           return Resource::link(
133             $data['url'],
134             $provider,
135             $data['title'],
136             $data['author_name'],
137             $data['author_url'],
138             $data['cache_age'],
139             $data['thumbnail_url'],
140             $data['thumbnail_width'],
141             $data['thumbnail_height']
142           );
143
144         case Resource::TYPE_PHOTO:
145           return Resource::photo(
146             $data['url'],
147             $data['width'],
148             $data['height'],
149             $provider,
150             $data['title'],
151             $data['author_name'],
152             $data['author_url'],
153             $data['cache_age'],
154             $data['thumbnail_url'],
155             $data['thumbnail_width'],
156             $data['thumbnail_height']
157           );
158
159         case Resource::TYPE_RICH:
160           return Resource::rich(
161             $data['html'],
162             $data['width'],
163             $data['height'],
164             $provider,
165             $data['title'],
166             $data['author_name'],
167             $data['author_url'],
168             $data['cache_age'],
169             $data['thumbnail_url'],
170             $data['thumbnail_width'],
171             $data['thumbnail_height']
172           );
173         case Resource::TYPE_VIDEO:
174           return Resource::video(
175             $data['html'],
176             $data['width'],
177             $data['height'],
178             $provider,
179             $data['title'],
180             $data['author_name'],
181             $data['author_url'],
182             $data['cache_age'],
183             $data['thumbnail_url'],
184             $data['thumbnail_width'],
185             $data['thumbnail_height']
186           );
187
188         default:
189           throw new ResourceException('Unknown resource type: ' . $data['type'], $url, $data);
190       }
191     }
192     catch (\InvalidArgumentException $e) {
193       throw new ResourceException($e->getMessage(), $url, $data, $e);
194     }
195   }
196
197 }