/**
  * @covers ::optimizeTokens
  *
  * @dataProvider providerTestOptimizeTokens
  */
 public function testOptimizeTokens(array $context_tokens, array $optimized_context_tokens)
 {
     $container = $this->getMockBuilder('Drupal\\Core\\DependencyInjection\\Container')->disableOriginalConstructor()->getMock();
     $container->expects($this->any())->method('get')->will($this->returnValueMap([['a', Container::EXCEPTION_ON_INVALID_REFERENCE, new FooCacheContext()], ['a.b', Container::EXCEPTION_ON_INVALID_REFERENCE, new FooCacheContext()], ['a.b.c', Container::EXCEPTION_ON_INVALID_REFERENCE, new BazCacheContext()], ['x', Container::EXCEPTION_ON_INVALID_REFERENCE, new BazCacheContext()]]));
     $cache_contexts = new CacheContexts($container, $this->getContextsFixture());
     $this->assertSame($optimized_context_tokens, $cache_contexts->optimizeTokens($context_tokens));
 }
Esempio n. 2
0
 /**
  * {@inheritdoc}
  *
  * The entire HTML: takes a #type 'page' and wraps it in a #type 'html'.
  */
 public function renderResponse(array $main_content, Request $request, RouteMatchInterface $route_match)
 {
     list($page, $title) = $this->prepare($main_content, $request, $route_match);
     if (!isset($page['#type']) || $page['#type'] !== 'page') {
         throw new \LogicException('Must be #type page');
     }
     $page['#title'] = $title;
     // Now render the rendered page.html.twig template inside the html.html.twig
     // template, and use the bubbled #attached metadata from $page to ensure we
     // load all attached assets.
     $html = ['#type' => 'html', 'page' => $page];
     $html += element_info('html');
     // The special page regions will appear directly in html.html.twig, not in
     // page.html.twig, hence add them here, just before rendering html.html.twig.
     $this->buildPageTopAndBottom($html);
     // The three parts of rendered markup in html.html.twig (page_top, page and
     // page_bottom) must be rendered with drupal_render_root(), so that their
     // #post_render_cache callbacks are executed (which may attach additional
     // assets).
     // html.html.twig must be able to render the final list of attached assets,
     // and hence may not execute any #post_render_cache_callbacks (because they
     // might add yet more assets to be attached), and therefore it must be
     // rendered with drupal_render(), not drupal_render_root().
     $this->renderer->render($html['page'], TRUE);
     if (isset($html['page_top'])) {
         $this->renderer->render($html['page_top'], TRUE);
     }
     if (isset($html['page_bottom'])) {
         $this->renderer->render($html['page_bottom'], TRUE);
     }
     $content = $this->renderer->render($html);
     // Expose the cache contexts and cache tags associated with this page in a
     // X-Drupal-Cache-Contexts and X-Drupal-Cache-Tags header respectively. Also
     // associate the "rendered" cache tag. This allows us to invalidate the
     // entire render cache, regardless of the cache bin.
     $cache_contexts = [];
     $cache_tags = ['rendered'];
     $cache_max_age = Cache::PERMANENT;
     foreach (['page_top', 'page', 'page_bottom'] as $region) {
         if (isset($html[$region])) {
             $cache_contexts = Cache::mergeContexts($cache_contexts, $html[$region]['#cache']['contexts']);
             $cache_tags = Cache::mergeTags($cache_tags, $html[$region]['#cache']['tags']);
             $cache_max_age = Cache::mergeMaxAges($cache_max_age, $html[$region]['#cache']['max-age']);
         }
     }
     // Set the generator in the HTTP header.
     list($version) = explode('.', \Drupal::VERSION, 2);
     $response = new Response($content, 200, ['X-Drupal-Cache-Tags' => implode(' ', $cache_tags), 'X-Drupal-Cache-Contexts' => implode(' ', $this->cacheContexts->optimizeTokens($cache_contexts)), 'X-Generator' => 'Drupal ' . $version . ' (https://www.drupal.org)']);
     // If an explicit non-infinite max-age is specified by a part of the page,
     // respect that by applying it to the response's headers.
     if ($cache_max_age !== Cache::PERMANENT) {
         $response->setMaxAge($cache_max_age);
     }
     return $response;
 }