/**
  * Adds in the current user as a context.
  *
  * @param \Drupal\page_manager\Event\PageManagerContextEvent $event
  *   The page entity context event.
  */
 public function onPageContext(PageManagerContextEvent $event)
 {
     $request = $this->requestStack->getCurrentRequest();
     $page = $event->getPage();
     $routes = $this->routeProvider->getRoutesByPattern($page->getPath())->all();
     $route = reset($routes);
     if ($route && ($route_contexts = $route->getOption('parameters'))) {
         foreach ($route_contexts as $route_context_name => $route_context) {
             // Skip this parameter.
             if ($route_context_name == 'page_manager_page_variant' || $route_context_name == 'page_manager_page') {
                 continue;
             }
             $context_name = $this->t('{@name} from route', ['@name' => $route_context_name]);
             if ($request->attributes->has($route_context_name)) {
                 $value = $request->attributes->get($route_context_name);
             } else {
                 // @todo Find a way to add in a fake value for configuration.
                 $value = NULL;
             }
             $cacheability = new CacheableMetadata();
             $cacheability->setCacheContexts(['route']);
             $context = new Context(new ContextDefinition($route_context['type'], $context_name, FALSE), $value);
             $context->addCacheableDependency($cacheability);
             $page->addContext($route_context_name, $context);
         }
     }
 }
 /**
  * Prints a page listing various types of help.
  *
  * The page has sections defined by \Drupal\help\HelpSectionPluginInterface
  * plugins.
  *
  * @return array
  *   A render array for the help page.
  */
 public function helpMain()
 {
     $output = [];
     // We are checking permissions, so add the user.permissions cache context.
     $cacheability = new CacheableMetadata();
     $cacheability->addCacheContexts(['user.permissions']);
     $plugins = $this->helpManager->getDefinitions();
     $cacheability->addCacheableDependency($this->helpManager);
     foreach ($plugins as $plugin_id => $plugin_definition) {
         // Check the provided permission.
         if (!empty($plugin_definition['permission']) && !$this->currentuser()->hasPermission($plugin_definition['permission'])) {
             continue;
         }
         // Add the section to the page.
         /** @var \Drupal\help\HelpSectionPluginInterface $plugin */
         $plugin = $this->helpManager->createInstance($plugin_id);
         $this_output = ['#theme' => 'help_section', '#title' => $plugin->getTitle(), '#description' => $plugin->getDescription(), '#empty' => $this->t('There is currently nothing in this section.'), '#links' => []];
         $links = $plugin->listTopics();
         if (is_array($links) && count($links)) {
             $this_output['#links'] = $links;
         }
         $cacheability->addCacheableDependency($plugin);
         $output[$plugin_id] = $this_output;
     }
     $cacheability->applyTo($output);
     return $output;
 }
Exemplo n.º 3
0
 /**
  * {@inheritdoc}
  */
 public function getRuntimeContexts(array $unqualified_context_ids)
 {
     // Add a context for each language type.
     $language_types = $this->languageManager->getLanguageTypes();
     $info = $this->languageManager->getDefinedLanguageTypesInfo();
     if ($unqualified_context_ids) {
         foreach ($unqualified_context_ids as $unqualified_context_id) {
             if (array_search($unqualified_context_id, $language_types) === FALSE) {
                 unset($language_types[$unqualified_context_id]);
             }
         }
     }
     $result = [];
     foreach ($language_types as $type_key) {
         if (isset($info[$type_key]['name'])) {
             $context = new Context(new ContextDefinition('language', $info[$type_key]['name']));
             $context->setContextValue($this->languageManager->getCurrentLanguage($type_key));
             $cacheability = new CacheableMetadata();
             $cacheability->setCacheContexts(['languages:' . $type_key]);
             $context->addCacheableDependency($cacheability);
             $result[$type_key] = $context;
         }
     }
     return $result;
 }
 /**
  * Adds a cache tag if the 'user.permissions' cache context is present.
  *
  * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
  *   The event to process.
  */
 public function onRespond(FilterResponseEvent $event)
 {
     if (!$event->isMasterRequest()) {
         return;
     }
     if (!$this->currentUser->isAnonymous()) {
         return;
     }
     $response = $event->getResponse();
     if (!$response instanceof CacheableResponseInterface) {
         return;
     }
     // The 'user.permissions' cache context ensures that if the permissions for
     // a role are modified, users are not served stale render cache content.
     // But, when entire responses are cached in reverse proxies, the value for
     // the cache context is never calculated, causing the stale response to not
     // be invalidated. Therefore, when varying by permissions and the current
     // user is the anonymous user, also add the cache tag for the 'anonymous'
     // role.
     if (in_array('user.permissions', $response->getCacheableMetadata()->getCacheContexts())) {
         $per_permissions_response_for_anon = new CacheableMetadata();
         $per_permissions_response_for_anon->setCacheTags(['config:user.role.anonymous']);
         $response->addCacheableDependency($per_permissions_response_for_anon);
     }
 }
 /**
  * {@inheritdoc}
  */
 public function processOutbound($route_name, Route $route, array &$parameters, CacheableMetadata $cacheable_metadata = NULL)
 {
     if ($route_name === '<current>') {
         if ($current_route = $this->routeMatch->getRouteObject()) {
             $requirements = $current_route->getRequirements();
             // Setting _method and _schema is deprecated since 2.7. Using
             // setMethods() and setSchemes() are now the recommended ways.
             unset($requirements['_method']);
             unset($requirements['_schema']);
             $route->setRequirements($requirements);
             $route->setPath($current_route->getPath());
             $route->setSchemes($current_route->getSchemes());
             $route->setMethods($current_route->getMethods());
             $route->setOptions($current_route->getOptions());
             $route->setDefaults($current_route->getDefaults());
             $parameters = array_merge($parameters, $this->routeMatch->getRawParameters()->all());
             if ($cacheable_metadata) {
                 $cacheable_metadata->addCacheContexts(['route']);
             }
         } else {
             // If we have no current route match available, point to the frontpage.
             $route->setPath('/');
         }
     }
 }
 /**
  * {@inheritdoc}
  */
 public function getCacheableMetadata($menu_name = NULL)
 {
     if (!$menu_name) {
         throw new \LogicException('No menu name provided for menu.active_trails cache context.');
     }
     $cacheable_metadata = new CacheableMetadata();
     return $cacheable_metadata->setCacheTags(["config:system.menu.{$menu_name}"]);
 }
 /**
  * {@inheritdoc}
  */
 public function getCacheableMetadata()
 {
     // Since this depends on State this can change at any time and is not
     // cacheable.
     $metadata = new CacheableMetadata();
     $metadata->setCacheMaxAge(0);
     return $metadata;
 }
 /**
  * {@inheritdoc}
  */
 public function getCacheableMetadata($name)
 {
     $metadata = new CacheableMetadata();
     if ($name === 'block.block.config_override_test') {
         $metadata->setCacheContexts(['config_override_integration_test'])->setCacheTags(['config_override_integration_test_tag']);
     }
     return $metadata;
 }
Exemplo n.º 9
0
 /**
  * {@inheritdoc}
  */
 public function process($text, $langcode)
 {
     $result = new FilterProcessResult($text);
     $metadata = new CacheableMetadata();
     $metadata->addCacheTags(['merge:tag']);
     $metadata->addCacheContexts(['user.permissions']);
     $result = $result->merge($metadata);
     return $result;
 }
 /**
  * {@inheritdoc}
  */
 public function getCacheableMetadata()
 {
     $cacheable_metadata = new CacheableMetadata();
     $tags = [];
     foreach ($this->user->getRoles() as $rid) {
         $tags[] = "config:user.role.{$rid}";
     }
     return $cacheable_metadata->setCacheTags($tags);
 }
Exemplo n.º 11
0
 /**
  * {@inheritdoc}
  */
 public function addCacheableDependency($dependency)
 {
     // A trait doesn't have a constructor, so initialize the cacheability
     // metadata if that hasn't happened yet.
     if (!isset($this->cacheabilityMetadata)) {
         $this->cacheabilityMetadata = new CacheableMetadata();
     }
     $this->cacheabilityMetadata = $this->cacheabilityMetadata->merge(CacheableMetadata::createFromObject($dependency));
     return $this;
 }
Exemplo n.º 12
0
 /**
  * {@inheritdoc}
  */
 public function getRuntimeContexts(array $unqualified_context_ids)
 {
     $current_user = $this->userStorage->load($this->account->id());
     $context = new Context(new ContextDefinition('entity:user', $this->t('Current user')), $current_user);
     $cacheability = new CacheableMetadata();
     $cacheability->setCacheContexts(['user']);
     $context->addCacheableDependency($cacheability);
     $result = ['current_user' => $context];
     return $result;
 }
 /**
  * Adds in the current user as a context.
  *
  * @param \Drupal\page_manager\Event\PageManagerContextEvent $event
  *   The page entity context event.
  */
 public function onPageContext(PageManagerContextEvent $event)
 {
     $id = $this->account->id();
     $current_user = $this->userStorage->load($id);
     $context = new Context(new ContextDefinition('entity:user', $this->t('Current user')), $current_user);
     $cacheability = new CacheableMetadata();
     $cacheability->setCacheContexts(['user']);
     $context->addCacheableDependency($cacheability);
     $event->getPage()->addContext('current_user', $context);
 }
Exemplo n.º 14
0
 /**
  * {@inheritdoc}
  */
 public function getRuntimeContexts(array $unqualified_context_ids)
 {
     $current_user = $this->userStorage->load($this->account->id());
     $context1 = new Context(new ContextDefinition('entity:user', 'User 1'), $current_user);
     $context2 = new Context(new ContextDefinition('entity:user', 'User 2'), $current_user);
     $cacheability = new CacheableMetadata();
     $cacheability->setCacheContexts(['user']);
     $context1->addCacheableDependency($cacheability);
     $context2->addCacheableDependency($cacheability);
     return ['user1' => $context1, 'user2' => $context2];
 }
 /**
  * {@inheritdoc}
  */
 public function getCacheableMetadata()
 {
     $cacheable_metadata = new CacheableMetadata();
     // The permissions hash changes when:
     // - a user is updated to have different roles;
     $tags = ['user:' . $this->user->id()];
     // - a role is updated to have different permissions.
     foreach ($this->user->getRoles() as $rid) {
         $tags[] = "config:user.role.{$rid}";
     }
     return $cacheable_metadata->setCacheTags($tags);
 }
Exemplo n.º 16
0
 /**
  * {@inheritdoc}
  */
 public function getRuntimeContexts(array $unqualified_context_ids)
 {
     // Load the current domain.
     $current_domain = $this->negotiator->getActiveDomain();
     // Set the context.
     $context = new Context(new ContextDefinition('entity:domain', $this->t('Active domain')), $current_domain);
     // Allow caching.
     $cacheability = new CacheableMetadata();
     $cacheability->setCacheContexts(['url.site']);
     $context->addCacheableDependency($cacheability);
     // Prepare the result.
     $result = ['current_domain' => $context];
     return $result;
 }
 /**
  * {@inheritdoc}
  */
 public function getCacheableMetadata($operation = NULL)
 {
     $cacheable_metadata = new CacheableMetadata();
     if (!\Drupal::moduleHandler()->getImplementations('node_grants')) {
         return $cacheable_metadata;
     }
     // The node grants may change if the user is updated. (The max-age is set to
     // zero below, but sites may override this cache context, and change it to a
     // non-zero value. In such cases, this cache tag is needed for correctness.)
     $cacheable_metadata->setCacheTags(['user:' . $this->user->id()]);
     // If the site is using node grants, this cache context can not be
     // optimized.
     return $cacheable_metadata->setCacheMaxAge(0);
 }
 /**
  * Sets the '4xx-response' cache tag on 4xx responses.
  *
  * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
  *   The event to process.
  */
 public function onRespond(FilterResponseEvent $event)
 {
     if (!$event->isMasterRequest()) {
         return;
     }
     $response = $event->getResponse();
     if (!$response instanceof CacheableResponseInterface) {
         return;
     }
     if ($response->isClientError()) {
         $http_4xx_response_cacheability = new CacheableMetadata();
         $http_4xx_response_cacheability->setCacheTags(['4xx-response']);
         $response->addCacheableDependency($http_4xx_response_cacheability);
     }
 }
Exemplo n.º 19
0
 /**
  * Handles a page request for our forced login route.
  */
 public function forceLogin()
 {
     // TODO: What if CAS is not configured? need to handle that case.
     $query_params = $this->requestStack->getCurrentRequest()->query->all();
     $cas_login_url = $this->casHelper->getServerLoginUrl($query_params);
     $this->casHelper->log("Cas forced login route, redirecting to: {$cas_login_url}");
     // This response is OK to cache, but since the redirect URL is dependent on
     // the configured server settings, we need to add some cache metadata tied
     // to the settings.
     $cacheable_metadata = new CacheableMetadata();
     $cacheable_metadata->addCacheTags(array('config:cas.settings'));
     $response = TrustedRedirectResponse::create($cas_login_url, 302);
     $response->addCacheableDependency($cacheable_metadata);
     return $response;
 }
Exemplo n.º 20
0
 /**
  * Creates a bubbleable metadata object with values taken from a render array.
  *
  * @param array $build
  *   A render array.
  *
  * @return static
  */
 public static function createFromRenderArray(array $build)
 {
     $meta = parent::createFromRenderArray($build);
     $meta->attached = isset($build['#attached']) ? $build['#attached'] : [];
     $meta->postRenderCache = isset($build['#post_render_cache']) ? $build['#post_render_cache'] : [];
     return $meta;
 }
Exemplo n.º 21
0
 /**
  * {@inheritdoc}
  */
 public function getVisibleBlocksPerRegion(array &$cacheable_metadata = [])
 {
     $active_theme = $this->themeManager->getActiveTheme();
     // Build an array of the region names in the right order.
     $empty = array_fill_keys($active_theme->getRegions(), array());
     $full = array();
     foreach ($this->blockStorage->loadByProperties(array('theme' => $active_theme->getName())) as $block_id => $block) {
         /** @var \Drupal\block\BlockInterface $block */
         $access = $block->access('view', NULL, TRUE);
         $region = $block->getRegion();
         if (!isset($cacheable_metadata[$region])) {
             $cacheable_metadata[$region] = CacheableMetadata::createFromObject($access);
         } else {
             $cacheable_metadata[$region] = $cacheable_metadata[$region]->merge(CacheableMetadata::createFromObject($access));
         }
         // Set the contexts on the block before checking access.
         if ($access->isAllowed()) {
             $full[$region][$block_id] = $block;
         }
     }
     // Merge it with the actual values to maintain the region ordering.
     $assignments = array_intersect_key(array_merge($empty, $full), $empty);
     foreach ($assignments as &$assignment) {
         // Suppress errors because PHPUnit will indirectly modify the contents,
         // triggering https://bugs.php.net/bug.php?id=50688.
         @uasort($assignment, 'Drupal\\block\\Entity\\Block::sort');
     }
     return $assignments;
 }
Exemplo n.º 22
0
 /**
  * {@inheritdoc}
  *
  * @see ::prepareView()
  * @see ::getEntitiestoView()
  */
 public function view(FieldItemListInterface $items, $langcode = NULL)
 {
     $elements = parent::view($items, $langcode);
     $field_level_access_cacheability = new CacheableMetadata();
     // Try to map the cacheability of the access result that was set at
     // _accessCacheability in getEntitiesToView() to the corresponding render
     // subtree. If no such subtree is found, then merge it with the field-level
     // access cacheability.
     foreach ($items as $delta => $item) {
         // Ignore items for which access cacheability could not be determined in
         // prepareView().
         if (!empty($item->_accessCacheability)) {
             if (isset($elements[$delta])) {
                 CacheableMetadata::createFromRenderArray($elements[$delta])->merge($item->_accessCacheability)->applyTo($elements[$delta]);
             } else {
                 $field_level_access_cacheability = $field_level_access_cacheability->merge($item->_accessCacheability);
             }
         }
     }
     // Apply the cacheability metadata for the inaccessible entities and the
     // entities for which the corresponding render subtree could not be found.
     // This causes the field to be rendered (and cached) according to the cache
     // contexts by which the access results vary, to ensure only users with
     // access to this field can view it. It also tags this field with the cache
     // tags on which the access results depend, to ensure users that cannot view
     // this field at the moment will gain access once any of those cache tags
     // are invalidated.
     $field_level_access_cacheability->applyTo($elements);
     return $elements;
 }
Exemplo n.º 23
0
 /**
  * {@inheritdoc}
  */
 public function getCacheableMetadata()
 {
     // The book active trail depends on the node and data attached to it.
     // That information is however not stored as part of the node.
     $cacheable_metadata = new CacheableMetadata();
     if ($node = $this->requestStack->getCurrentRequest()->get('node')) {
         // If the node is part of a book then we can use the cache tag for that
         // book. If not, then it can't be optimized away.
         if (!empty($node->book['bid'])) {
             $cacheable_metadata->addCacheTags(['bid:' . $node->book['bid']]);
         } else {
             $cacheable_metadata->setCacheMaxAge(0);
         }
     }
     return $cacheable_metadata;
 }
Exemplo n.º 24
0
 /**
  * Test the forcedLogin redirect.
  *
  * @covers ::forceLogin
  * @covers ::__construct
  */
 public function testForceLogin()
 {
     $request = $this->getMock('\\Symfony\\Component\\HttpFoundation\\Request');
     $query = $this->getMock('\\Symfony\\Component\\HttpFoundation\\ParameterBag');
     $request->query = $query;
     $this->requestStack->expects($this->once())->method('getCurrentRequest')->will($this->returnValue($request));
     $parameters = array('returnto' => 'node/1', 'foo' => 'bar');
     $query->expects($this->once())->method('all')->will($this->returnValue($parameters));
     $this->casHelper->expects($this->once())->method('getServerLoginUrl')->with($this->equalTo($parameters))->will($this->returnValue('https://example.com'));
     $cacheableMetadata = new CacheableMetadata();
     $cacheableMetadata->addCacheTags(array('config:cas.settings'));
     $expected_response = new TrustedRedirectResponse('https://example.com', 302);
     $expected_response->addCacheableDependency($cacheableMetadata);
     $force_login_controller = new ForceLoginController($this->casHelper, $this->requestStack);
     $response = $force_login_controller->forceLogin();
     $this->assertEquals($expected_response, $response);
 }
Exemplo n.º 25
0
 /**
  * {@inheritdoc}
  */
 public function getRuntimeContexts(array $unqualified_context_ids)
 {
     $result = [];
     $context = new Context(new ContextDefinition('entity:node', NULL, FALSE));
     if (($route_object = $this->routeMatch->getRouteObject()) && ($route_contexts = $route_object->getOption('parameters')) && isset($route_contexts['node'])) {
         if ($node = $this->routeMatch->getParameter('node')) {
             $context->setContextValue($node);
         }
     } elseif ($this->routeMatch->getRouteName() == 'node.add') {
         $node_type = $this->routeMatch->getParameter('node_type');
         $context->setContextValue(Node::create(array('type' => $node_type->id())));
     }
     $cacheability = new CacheableMetadata();
     $cacheability->setCacheContexts(['route']);
     $context->addCacheableDependency($cacheability);
     $result['node'] = $context;
     return $result;
 }
Exemplo n.º 26
0
 /**
  * {@inheritdoc}
  */
 public function processOutbound($route_name, Route $route, array &$parameters, CacheableMetadata $cacheable_metadata = NULL)
 {
     if ($route_name === '<current>') {
         if ($current_route = $this->routeMatch->getRouteObject()) {
             $route->setPath($current_route->getPath());
             $route->setRequirements($current_route->getRequirements());
             $route->setOptions($current_route->getOptions());
             $route->setDefaults($current_route->getDefaults());
             $parameters = array_merge($parameters, $this->routeMatch->getRawParameters()->all());
             if ($cacheable_metadata) {
                 $cacheable_metadata->addCacheContexts(['route']);
             }
         } else {
             // If we have no current route match available, point to the frontpage.
             $route->setPath('/');
         }
     }
 }
Exemplo n.º 27
0
 /**
  * {@inheritdoc}
  */
 public function processOutbound($route_name, Route $route, array &$parameters, CacheableMetadata $cacheable_metadata = NULL)
 {
     if ($route->hasRequirement('_csrf_token')) {
         $path = ltrim($route->getPath(), '/');
         // Replace the path parameters with values from the parameters array.
         foreach ($parameters as $param => $value) {
             $path = str_replace("{{$param}}", $value, $path);
         }
         // Adding this to the parameters means it will get merged into the query
         // string when the route is compiled.
         $parameters['token'] = $this->csrfToken->get($path);
         if ($cacheable_metadata) {
             // Tokens are per user and per session, so not cacheable.
             // @todo Improve in https://www.drupal.org/node/2351015.
             $cacheable_metadata->setCacheMaxAge(0);
         }
     }
 }
 /**
  * Implements Drupal\Core\PathProcessor\OutboundPathProcessorInterface::processOutbound().
  */
 public function processOutbound($path, &$options = array(), Request $request = NULL, CacheableMetadata $cacheable_metadata = NULL)
 {
     // Rewrite user/uid to user/username.
     if (preg_match('!^/user/([0-9]+)(/.*)?!', $path, $matches)) {
         if ($account = User::load($matches[1])) {
             $matches += array(2 => '');
             $path = '/user/' . $account->getUsername() . $matches[2];
             if ($cacheable_metadata) {
                 $cacheable_metadata->addCacheTags($account->getCacheTags());
             }
         }
     }
     // Rewrite forum/ to community/.
     if ($path == '/forum' || strpos($path, '/forum/') === 0) {
         $path = '/community' . substr($path, 5);
     }
     return $path;
 }
 /**
  * {@inheritdoc}
  */
 public function getCacheableMetadata($operation = NULL)
 {
     $cacheable_metadata = new CacheableMetadata();
     if (!\Drupal::moduleHandler()->getImplementations('node_grants')) {
         return $cacheable_metadata;
     }
     // If the site is using node grants, this cache context can not be
     // optimized.
     return $cacheable_metadata->setCacheMaxAge(0);
 }
 /**
  * {@inheritdoc}
  */
 public function getRuntimeContexts(array $unqualified_context_ids)
 {
     $result = [];
     $context_definition = new ContextDefinition('entity:rdf_entity:asset_release', NULL, FALSE);
     $value = NULL;
     if (($route_object = $this->routeMatch->getRouteObject()) && ($route_contexts = $route_object->getOption('parameters')) && isset($route_contexts['rdf_entity'])) {
         /** @var \Drupal\rdf_entity\RdfInterface $asset_release */
         if ($asset_release = $this->routeMatch->getParameter('rdf_entity')) {
             if ($asset_release->bundle() == 'asset_release') {
                 $value = $asset_release;
             }
         }
     }
     $cacheability = new CacheableMetadata();
     $cacheability->setCacheContexts(['route']);
     $context = new Context($context_definition, $value);
     $context->addCacheableDependency($cacheability);
     $result['asset_release'] = $context;
     return $result;
 }