View source
<?php
namespace Drupal\ckeditor_media_embed;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Link;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Path\CurrentPathStack;
use Drupal\Core\Render\Markup;
use Drupal\Core\Url;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Utility\UnroutedUrlAssemblerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\TransferException;
use Symfony\Component\HttpFoundation\RequestStack;
use Drupal\Core\Extension\ModuleHandlerInterface;
class Embed implements EmbedInterface {
use StringTranslationTrait;
protected $httpClient;
protected $urlAssembler;
protected $requestStack;
protected $messenger;
protected $configFactory;
protected $currentPath;
protected $moduleHandler;
public function __construct(ClientInterface $http_client, UnroutedUrlAssemblerInterface $url_assembler, RequestStack $request_stack, MessengerInterface $messenger, ConfigFactory $config_factory, CurrentPathStack $current_path, ModuleHandlerInterface $module_handler) {
$this->httpClient = $http_client;
$this->urlAssembler = $url_assembler;
$this->requestStack = $request_stack;
$this->configFactory = $config_factory;
$this->messenger = $messenger;
$this->currentPath = $current_path;
$this->moduleHandler = $module_handler;
$embed_provider = $this->configFactory
->get('ckeditor_media_embed.settings')
->get('embed_provider');
$this
->setEmbedProvider($embed_provider);
}
public function setEmbedProvider($provider) {
$provider_parsed = UrlHelper::parse($provider);
$provider_parsed['query'] = array_filter($provider_parsed['query'], function ($value) {
return $value !== '{callback}';
});
$provider_parsed['absolute'] = TRUE;
$this->embed_provider = $this->urlAssembler
->assemble($provider_parsed['path'], $provider_parsed);
}
public function getEmbedObject($url) {
$embed = NULL;
try {
$response = $this->httpClient
->get($this
->getEmbedProviderURL($url), [
'headers' => [
'content-type' => 'application/json',
],
]);
$embed = json_decode($response
->getBody());
} catch (TransferException $e) {
$this->messenger
->addWarning($this
->t('Unable to retrieve @url at this time, please check again later.', [
'@url' => $url,
]));
watchdog_exception('ckeditor_media_embed', $e);
}
$this->moduleHandler
->alter('ckeditor_media_embed_object', $embed);
return $embed;
}
protected function getEmbedProviderURL($url) {
$provider = $this->embed_provider;
if (strpos($provider, '//') === 0) {
$provider = $this->requestStack
->getCurrentRequest()
->getScheme() . ':' . $provider;
}
return str_replace('%7Burl%7D', urlencode($url), $provider);
}
public function processEmbeds($text) {
$document = Html::load($text);
$xpath = new \DOMXPath($document);
foreach ($xpath
->query('//oembed') as $node) {
$embed = $this
->getEmbedObject($node->nodeValue);
if (!empty($embed) && !empty($embed->html)) {
$this
->swapEmbedHtml($node, $embed);
}
}
return Html::serialize($document);
}
public function getSettingsLink() {
$url = Url::fromRoute('ckeditor_media_embed.ckeditor_media_embed_settings_form', [
'destination' => $this->currentPath
->getPath(),
]);
return Markup::create(Link::fromTextAndUrl($this
->t('CKEditor Media Embed plugin settings page'), $url)
->toString());
}
protected function swapEmbedHtml(\DOMNode &$node, $embed) {
$embed_node = $node->ownerDocument
->createElement('div');
$embed_node
->setAttribute('class', $this
->getClass($embed));
$child = NULL;
$embed_body_node = Html::load(trim($embed->html))
->getElementsByTagName('body')
->item(0);
foreach ($embed_body_node->childNodes as $child) {
if ($child = $node->ownerDocument
->importNode($child, TRUE)) {
$embed_node
->appendChild($child);
}
}
$node->parentNode
->replaceChild($embed_node, $node);
return $this;
}
protected function getClass($embed) {
return 'embed-media ' . Html::getClass("embed-media--{$embed->type}-{$embed->provider_name}");
}
}