Unverified Commit 5b2ffba9 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3230772 by larowlan, phenaproxima: OembedMediaController doesn't...

Issue #3230772 by larowlan, phenaproxima: OembedMediaController doesn't properly bubble cacheability metadata/attachments

(cherry picked from commit 0cbd31db)
parent d4e4f7c1
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Render\HtmlResponse;
use Drupal\Core\Render\RenderContext;
use Drupal\Core\Render\RendererInterface;
@@ -167,7 +168,8 @@ public function render(Request $request) {
        ],
        '#placeholder_token' => $placeholder_token,
      ];
      $content = $this->renderer->executeInRenderContext(new RenderContext(), function () use ($resource, $element) {
      $context = new RenderContext();
      $content = $this->renderer->executeInRenderContext($context, function () use ($resource, $element) {
        return $this->renderer->render($element);
      });
      $response
@@ -175,6 +177,18 @@ public function render(Request $request) {
        ->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.
+5 −0
Original line number Diff line number Diff line
/**
 * This is an empty file by design.
 * @see \Drupal\Tests\media\Kernel\OEmbedIframeControllerTest::testResourcePassedToPreprocess()
 * @see media_test_oembed_preprocess_media_oembed_iframe()
 */
+5 −0
Original line number Diff line number Diff line
frame:
  version: VERSION
  css:
    component:
      css/test.css: { preprocess: false, minified: true }
+3 −0
Original line number Diff line number Diff line
@@ -14,6 +14,9 @@ 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']);
  }
  // @see \Drupal\Tests\media\Kernel\OEmbedIframeControllerTest
  $variables['#attached']['library'][] = 'media_test_oembed/frame';
  $variables['#cache']['tags'][] = 'yo_there';
}

/**
+8 −3
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@

namespace Drupal\Tests\media\Kernel;

use Drupal\Core\Render\HtmlResponse;
use Drupal\media\Controller\OEmbedIframeController;
use Drupal\media\OEmbed\Provider;
use Drupal\media\OEmbed\Resource;
@@ -93,13 +94,17 @@ public function testResourcePassedToPreprocess() {
      'url' => '',
      'hash' => $hash,
    ]);
    $content = OEmbedIframeController::create($this->container)
      ->render($request)
      ->getContent();
    $response = $this->container->get('html_response.attachments_processor')
      ->processAttachments(OEmbedIframeController::create($this->container)
        ->render($request));
    assert($response instanceof HtmlResponse);
    $content = $response->getContent();

    // This query parameter is added by
    // media_test_oembed_preprocess_media_oembed_iframe() for YouTube videos.
    $this->assertStringContainsString('&pasta=rigatoni', $content);
    $this->assertStringContainsString('test.css', $content);
    $this->assertContains('yo_there', $response->getCacheableMetadata()->getCacheTags());
  }

}