From cf2039b95f4d81270b3a0b63440600faf12ad9fa Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Tue, 8 Sep 2020 14:49:01 +0100 Subject: [PATCH] Issue #3009003 by ilya.no, phenaproxima, b_sharpe, kirkkala, kekkis, alexpott, seanB, marcoscano, joshua.boltz, vood002: Expose oEmbed resource object to iframe template --- core/modules/media/media.module | 1 + .../src/Controller/OEmbedIframeController.php | 1 + .../media_test_oembed.module | 9 ++++ .../src/Kernel/OEmbedIframeControllerTest.php | 48 +++++++++++++++++++ 4 files changed, 59 insertions(+) diff --git a/core/modules/media/media.module b/core/modules/media/media.module index 49df4f3f79a..a1ebd0b5067 100644 --- a/core/modules/media/media.module +++ b/core/modules/media/media.module @@ -77,6 +77,7 @@ function media_theme() { ], 'media_oembed_iframe' => [ 'variables' => [ + 'resource' => NULL, 'media' => NULL, 'placeholder_token' => '', ], diff --git a/core/modules/media/src/Controller/OEmbedIframeController.php b/core/modules/media/src/Controller/OEmbedIframeController.php index d5a879186e3..2a6c0eb8fa5 100644 --- a/core/modules/media/src/Controller/OEmbedIframeController.php +++ b/core/modules/media/src/Controller/OEmbedIframeController.php @@ -146,6 +146,7 @@ class OEmbedIframeController implements ContainerInjectionInterface { // 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 diff --git a/core/modules/media/tests/modules/media_test_oembed/media_test_oembed.module b/core/modules/media/tests/modules/media_test_oembed/media_test_oembed.module index f3b283ca632..2e19d9faceb 100644 --- a/core/modules/media/tests/modules/media_test_oembed/media_test_oembed.module +++ b/core/modules/media/tests/modules/media_test_oembed/media_test_oembed.module @@ -7,6 +7,15 @@ use Drupal\media\OEmbed\Provider; +/** + * Implements hook_preprocess_media_oembed_iframe(). + */ +function media_test_oembed_preprocess_media_oembed_iframe(array &$variables) { + if ($variables['resource']->getProvider()->getName() === 'YouTube') { + $variables['media'] = str_replace('?feature=oembed', '?feature=oembed&pasta=rigatoni', (string) $variables['media']); + } +} + /** * Implements hook_oembed_resource_url_alter(). */ diff --git a/core/modules/media/tests/src/Kernel/OEmbedIframeControllerTest.php b/core/modules/media/tests/src/Kernel/OEmbedIframeControllerTest.php index 3dc099be20d..3b702a6ef74 100644 --- a/core/modules/media/tests/src/Kernel/OEmbedIframeControllerTest.php +++ b/core/modules/media/tests/src/Kernel/OEmbedIframeControllerTest.php @@ -2,6 +2,10 @@ namespace Drupal\Tests\media\Kernel; +use Drupal\media\Controller\OEmbedIframeController; +use Drupal\media\OEmbed\Provider; +use Drupal\media\OEmbed\Resource; +use Prophecy\Argument; use Symfony\Component\HttpFoundation\Request; /** @@ -11,6 +15,11 @@ use Symfony\Component\HttpFoundation\Request; */ class OEmbedIframeControllerTest extends MediaKernelTestBase { + /** + * {@inheritdoc} + */ + protected static $modules = ['media_test_oembed']; + /** * Data provider for testBadHashParameter(). * @@ -54,4 +63,43 @@ class OEmbedIframeControllerTest extends MediaKernelTestBase { $controller($request); } + /** + * Tests that resources can be used in media_oembed_iframe preprocess. + * + * @see media_test_oembed_preprocess_media_oembed_iframe() + * + * @covers ::render + */ + public function testResourcePassedToPreprocess() { + $hash = $this->container->get('media.oembed.iframe_url_helper') + ->getHash('', 0, 0); + + $url_resolver = $this->prophesize('\Drupal\media\OEmbed\UrlResolverInterface'); + $resource_fetcher = $this->prophesize('\Drupal\media\OEmbed\ResourceFetcherInterface'); + + $provider = new Provider('YouTube', 'https://youtube.com', [ + [ + 'url' => 'https://youtube.com/foo', + ], + ]); + $resource = Resource::rich('', 320, 240, $provider); + + $resource_fetcher->fetchResource(Argument::cetera())->willReturn($resource); + + $this->container->set('media.oembed.url_resolver', $url_resolver->reveal()); + $this->container->set('media.oembed.resource_fetcher', $resource_fetcher->reveal()); + + $request = new Request([ + 'url' => '', + 'hash' => $hash, + ]); + $content = OEmbedIframeController::create($this->container) + ->render($request) + ->getContent(); + + // This query parameter is added by + // media_test_oembed_preprocess_media_oembed_iframe() for YouTube videos. + $this->assertStringContainsString('&pasta=rigatoni', $content); + } + }