public function OEmbedIframeController::render in Drupal 10
Same name and namespace in other branches
- 8 core/modules/media/src/Controller/OEmbedIframeController.php \Drupal\media\Controller\OEmbedIframeController::render()
- 9 core/modules/media/src/Controller/OEmbedIframeController.php \Drupal\media\Controller\OEmbedIframeController::render()
Renders an oEmbed resource.
Parameters
\Symfony\Component\HttpFoundation\Request $request: The request object.
Return value
\Symfony\Component\HttpFoundation\Response The response object.
Throws
\Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException Will be thrown if either
- the 'hash' parameter does not match the expected hash of the 'url' parameter;
- the iframe_domain is set in media.settings and does not match the host in the request.
1 string reference to 'OEmbedIframeController::render'
- media.routing.yml in core/
modules/ media/ media.routing.yml - core/modules/media/media.routing.yml
File
- core/
modules/ media/ src/ Controller/ OEmbedIframeController.php, line 125
Class
- OEmbedIframeController
- Controller which renders an oEmbed resource in a bare page (without blocks).
Namespace
Drupal\media\ControllerCode
public function render(Request $request) {
// @todo Move domain check logic to a separate method.
$allowed_domain = \Drupal::config('media.settings')
->get('iframe_domain');
if ($allowed_domain) {
$allowed_host = parse_url($allowed_domain, PHP_URL_HOST);
$host = parse_url($request
->getSchemeAndHttpHost(), PHP_URL_HOST);
if ($allowed_host !== $host) {
throw new AccessDeniedHttpException('This resource is not available');
}
}
$url = $request->query
->get('url');
$max_width = $request->query
->getInt('max_width');
$max_height = $request->query
->getInt('max_height');
// Hash the URL and max dimensions, and ensure it is equal to the hash
// parameter passed in the query string.
$hash = $this->iFrameUrlHelper
->getHash($url, $max_width, $max_height);
if (!hash_equals($hash, $request->query
->get('hash', ''))) {
throw new AccessDeniedHttpException('This resource is not available');
}
// Return a response instead of a render array so that the frame content
// will not have all the blocks and page elements normally rendered by
// Drupal.
$response = new HtmlResponse('', HtmlResponse::HTTP_OK, [
'Content-Type' => 'text/html; charset=UTF-8',
]);
$response
->addCacheableDependency(Url::createFromRequest($request));
try {
$resource_url = $this->urlResolver
->getResourceUrl($url, $max_width, $max_height);
$resource = $this->resourceFetcher
->fetchResource($resource_url);
$placeholder_token = Crypt::randomBytesBase64(55);
// Render the content in a new render context so that the cacheability
// metadata of the rendered HTML will be captured correctly.
$element = [
'#theme' => 'media_oembed_iframe',
'#resource' => $resource,
// Even though the resource HTML is untrusted, IFrameMarkup::create()
// will create a trusted string. The only reason this is okay is
// because we are serving it in an iframe, which will mitigate the
// potential dangers of displaying third-party markup.
'#media' => IFrameMarkup::create($resource
->getHtml()),
'#cache' => [
// Add the 'rendered' cache tag as this response is not processed by
// \Drupal\Core\Render\MainContent\HtmlRenderer::renderResponse().
'tags' => [
'rendered',
],
],
'#attached' => [
'html_response_attachment_placeholders' => [
'styles' => '<css-placeholder token="' . $placeholder_token . '">',
],
'library' => [
'media/oembed.frame',
],
],
'#placeholder_token' => $placeholder_token,
];
$context = new RenderContext();
$content = $this->renderer
->executeInRenderContext($context, function () use ($element) {
return $this->renderer
->render($element);
});
$response
->setContent($content)
->setAttachments($element['#attached'])
->addCacheableDependency($resource)
->addCacheableDependency(CacheableMetadata::createFromRenderArray($element));
// Modules and themes implementing hook_media_oembed_iframe_preprocess()
// can add additional #cache and #attachments to a render array. If this
// occurs, the render context won't be empty, and we need to ensure the
// added metadata is bubbled up to the response.
// @see \Drupal\Core\Theme\ThemeManager::render()
if (!$context
->isEmpty()) {
$bubbleable_metadata = $context
->pop();
assert($bubbleable_metadata instanceof BubbleableMetadata);
$response
->addCacheableDependency($bubbleable_metadata);
$response
->addAttachments($bubbleable_metadata
->getAttachments());
}
} catch (ResourceException $e) {
// Prevent the response from being cached.
$response
->setMaxAge(0);
// The oEmbed system makes heavy use of exception wrapping, so log the
// entire exception chain to help with troubleshooting.
do {
// @todo Log additional information from ResourceException, to help with
// debugging, in https://www.drupal.org/project/drupal/issues/2972846.
$this->logger
->error($e
->getMessage());
$e = $e
->getPrevious();
} while ($e);
}
return $response;
}