View source
<?php
namespace Drupal\gutenberg;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Site\Settings;
use Drupal\Core\Url;
use Drupal\media\OEmbed\ProviderException;
use Drupal\media\OEmbed\ResourceException;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\RequestException;
use Symfony\Component\DependencyInjection\ContainerInterface;
class OEmbedResolver implements OEmbedResolverInterface {
protected $httpClient;
protected $renderer;
protected $moduleHandler;
protected $mediaOembedResolver;
protected $mediaOembedResourceFetcher;
public function __construct(ContainerInterface $container, ClientInterface $client, RendererInterface $renderer, ModuleHandlerInterface $module_handler) {
$this->httpClient = $client;
$this->renderer = $renderer;
$this->moduleHandler = $module_handler;
if ($module_handler
->moduleExists('media')) {
$this->mediaOembedResolver = $container
->get('media.oembed.url_resolver', ContainerInterface::NULL_ON_INVALID_REFERENCE);
$this->mediaOembedResourceFetcher = $container
->get('media.oembed.resource_fetcher', ContainerInterface::NULL_ON_INVALID_REFERENCE);
}
}
public function resolveOembed($url, $maxwidth) {
$output = NULL;
if ($this->mediaOembedResolver && $this->mediaOembedResourceFetcher) {
try {
$resource_url = $this->mediaOembedResolver
->getResourceUrl($url, $maxwidth);
if ($resource_url) {
$output = $this->mediaOembedResourceFetcher
->fetchResource($resource_url)
->getHtml();
}
} catch (ResourceException $exception) {
if (!empty($exception
->getData()['html'])) {
$output = $exception
->getData()['html'];
}
} catch (ProviderException $exception) {
}
}
if (!$output) {
$query_params = rawurldecode(UrlHelper::buildQuery([
'url' => $url,
'origin' => 'drupal',
'format' => 'json',
'maxwidth' => $maxwidth,
]));
$default_provider_uri = $this
->getDefaultFallbackOembedProviderUri();
$arg_separator = strpos($default_provider_uri, '?') === FALSE ? '?' : '&';
$output = $this
->fetchOembedHtml($default_provider_uri . $arg_separator . $query_params);
}
return $output;
}
public function fetchOembedHtml($url) {
$output = NULL;
try {
$request = $this->httpClient
->get($url);
$response = $request
->getBody();
$output = '';
if (!empty($response)) {
$embed = json_decode($response);
if (!empty($embed->html)) {
$output = $embed->html;
}
elseif ($embed->type === 'link') {
$render = [
'#title' => $embed->title,
'#type' => 'link',
'#url' => Url::fromUri($embed->url),
];
$output = $this->renderer
->renderPlain($render);
}
elseif ($embed->type === 'photo') {
$render = [
'#type' => 'html_tag',
'#tag' => 'img',
'#attributes' => [
'alt' => $embed->title,
'src' => $embed->url,
'title' => $embed->title,
'class' => [
'gutenberg-oembed-image',
],
'style' => 'width:100%',
],
'#prefix' => '<a href="' . htmlentities($url, ENT_QUOTES) . '">',
'#suffix' => '</a>',
'#gutenberg_embed_photo' => TRUE,
'#gutenberg_embed_url' => $url,
];
$output = $this->renderer
->renderPlain($render);
}
}
} catch (RequestException $e) {
watchdog_exception('gutenberg_oembed', $e);
}
return $output;
}
public function getDefaultFallbackOembedProviderUri() {
return Settings::get('gutenberg.default_oembed_provider', 'https://open.iframe.ly/api/oembed');
}
}