getCacheableMetadata example


  protected function shouldCacheResponse(CacheableResponseInterface $response) {
    $conditions = $this->rendererConfig['auto_placeholder_conditions'];

    $cacheability = $response->getCacheableMetadata();

    // Response's max-age is at or below the configured threshold.     if ($cacheability->getCacheMaxAge() !== Cache::PERMANENT && $cacheability->getCacheMaxAge() <= $conditions['max-age']) {
      return FALSE;
    }

    // Response has a high-cardinality cache context.     if (array_intersect($cacheability->getCacheContexts()$conditions['contexts'])) {
      return FALSE;
    }

    
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);
    }
  }

  /** * Registers the methods in this class that should be listeners. * * @return array * An array of event listener definitions. */
 $response_data;
        }
        else {
          $response_resources = static::isResourceIdentifier($response_data)
            ? [$response_data]
            : $response_data;
          foreach ($response_resources as $response_resource) {
            $merged_document['data'][] = $response_resource;
          }
        }
      }
      $merged_cacheability->addCacheableDependency($response->getCacheableMetadata());
    }
    $merged_document['jsonapi'] = [
      'meta' => [
        'links' => [
          'self' => ['href' => 'http://jsonapi.org/format/1.0/'],
        ],
      ],
      'version' => '1.0',
    ];
    // Until we can reasonably know what caused an error, we shouldn't include     // 'self' links in error documents. For example, a 404 shouldn't have a
/** * Sets extra headers on any responses, also subrequest ones. * * @param \Symfony\Component\HttpKernel\Event\ResponseEvent $event * The event to process. */
  public function onAllResponds(ResponseEvent $event) {
    $response = $event->getResponse();
    // Always add the 'http_response' cache tag to be able to invalidate every     // response, for example after rebuilding routes.     if ($response instanceof CacheableResponseInterface) {
      $response->getCacheableMetadata()->addCacheTags(['http_response']);
    }
  }

  /** * Sets extra headers on successful responses. * * @param \Symfony\Component\HttpKernel\Event\ResponseEvent $event * The event to process. */
  public function onRespond(ResponseEvent $event) {
    if (!$event->isMainRequest()) {
      
        $overrides = $this->loadOverrides([$name]);
        if (isset($overrides[$name])) {
          $config->setModuleOverride($overrides[$name]);
        }
        // Apply any settings.php overrides.         if (isset($GLOBALS['config'][$name])) {
          $config->setSettingsOverride($GLOBALS['config'][$name]);
        }
      }

      foreach ($this->configFactoryOverrides as $override) {
        $config->addCacheableDependency($override->getCacheableMetadata($name));
      }

      return $config;
    }
  }

  /** * {@inheritdoc} */
  public function loadMultiple(array $names) {
    return $this->doLoadMultiple($names);
  }
$meta = [];
    if ($resource_type->includeCount()) {
      $link_context['total_count'] = $meta['count'] = $primary_data->getTotalCount();
    }
    $collection_links = self::getPagerLinks($request$page_param$link_context);
    $response = $this->buildWrappedResponse($primary_data$request$includes, 200, []$collection_links$meta);

    // When a new change to any entity in the resource happens, we cannot ensure     // the validity of this cached list. Add the list tag to deal with that.     $list_tag = $this->entityTypeManager->getDefinition($resource_type->getEntityTypeId())
      ->getListCacheTags();
    $response->getCacheableMetadata()->addCacheTags($list_tag);
    foreach ($primary_data as $entity) {
      $response->addCacheableDependency($entity);
    }
    return $response;
  }

  /** * Takes a field from the origin entity and puts it to the destination entity. * * @param \Drupal\jsonapi\ResourceType\ResourceType $resource_type * The JSON:API resource type of the entity to be updated. * @param \Drupal\Core\Entity\EntityInterface $origin * The entity that contains the field values. * @param \Drupal\Core\Entity\EntityInterface $destination * The entity that needs to be updated. * @param string $field_name * The name of the field to extract and update. * * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException * Thrown when the serialized and destination entities are of different * types. */

  protected function flattenResponse(ResourceResponseInterface $response) {
    $final_response = ($response instanceof CacheableResponseInterface) ? new CacheableResponse() : new Response();
    $final_response->setContent($response->getContent());
    $final_response->setStatusCode($response->getStatusCode());
    $final_response->setProtocolVersion($response->getProtocolVersion());
    if ($response->getCharset()) {
      $final_response->setCharset($response->getCharset());
    }
    $final_response->headers = clone $response->headers;
    if ($final_response instanceof CacheableResponseInterface) {
      $final_response->addCacheableDependency($response->getCacheableMetadata());
    }
    return $final_response;
  }

  /** * {@inheritdoc} */
  public static function getSubscribedEvents(): array {
    // Run before \Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber     // (priority 100), so that Dynamic Page Cache can cache flattened responses.     $events[KernelEvents::RESPONSE][] = ['onResponse', 128];
    
/** * Populates this BigPipeResponse object based on the original HTML response. */
  protected function populateBasedOnOriginalHtmlResponse() {
    // Clone the HtmlResponse's data into the new BigPipeResponse.     $this->headers = clone $this->originalHtmlResponse->headers;
    $this
      ->setStatusCode($this->originalHtmlResponse->getStatusCode())
      ->setContent($this->originalHtmlResponse->getContent())
      ->setAttachments($this->originalHtmlResponse->getAttachments())
      ->addCacheableDependency($this->originalHtmlResponse->getCacheableMetadata());

    // A BigPipe response can never be cached, because it is intended for a     // single user.     // @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1     $this->setPrivate();

    // Inform surrogates how they should handle BigPipe responses:     // - "no-store" specifies that the response should not be stored in cache;     // it is only to be used for the original request     // - "content" identifies what processing surrogates should perform on the     // response before forwarding it. We send, "BigPipe/1.0", which surrogates
$entity_collection = $this->getData();
    assert(count($entity_collection) > 1, 'A collection must have more that one entity in it.');

    $collection_url = Url::fromRoute(sprintf('jsonapi.%s.collection', static::$resourceTypeName))->setAbsolute(TRUE);
    $request_options = [];
    $request_options[RequestOptions::HEADERS]['Accept'] = 'application/vnd.api+json';
    $request_options = NestedArray::mergeDeep($request_options$this->getAuthenticationRequestOptions());

    // This asserts that collections will work without a sort, added by default     // below, without actually asserting the content of the response.     $expected_response = $this->getExpectedCollectionResponse($entity_collection$collection_url->toString()$request_options);
    $expected_cacheability = $expected_response->getCacheableMetadata();
    $response = $this->request('HEAD', $collection_url$request_options);
    // MISS or UNCACHEABLE depends on the collection data. It must not be HIT.     $dynamic_cache = $expected_cacheability->getCacheMaxAge() === 0 ? 'UNCACHEABLE' : 'MISS';
    $this->assertResourceResponse(200, NULL, $response$expected_cacheability->getCacheTags()$expected_cacheability->getCacheContexts(), FALSE, $dynamic_cache);

    // Different databases have different sort orders, so a sort is required so     // test expectations do not need to vary per database.     $default_sort = ['sort' => 'drupal_internal__' . $this->entity->getEntityType()->getKey('id')];
    $collection_url->setOption('query', $default_sort);

    // 200 for collections, even when all entities are inaccessible. Access is
// Get the response.     $resource_type = $this->container->get('jsonapi.resource_type.repository')->get('node', 'article');
    $response = $entity_resource->getCollection($resource_type$request);

    // Assertions.     $this->assertInstanceOf(CacheableResourceResponse::class$response);
    $this->assertInstanceOf(JsonApiDocumentTopLevel::class$response->getResponseData());
    $this->assertInstanceOf(Data::class$response->getResponseData()->getData());
    $data = $response->getResponseData()->getData();
    $this->assertCount(1, $data);
    $this->assertEquals($this->node2->uuid()$data->toArray()[0]->getId());
    $this->assertEqualsCanonicalizing(['node:2', 'node_list']$response->getCacheableMetadata()->getCacheTags());
  }

  /** * @covers ::getCollection */
  public function testGetEmptyCollection() {
    $request = Request::create('/jsonapi/node/article');
    $request->query = new InputBag(['filter' => ['id' => 'invalid']]);

    // Get the response.     $resource_type = new ResourceType('node', 'article', NULL);
    

  public function toRenderArray(array $contexts = []$in_preview = FALSE) {
    $event = new SectionComponentBuildRenderArrayEvent($this$contexts$in_preview);
    $this->eventDispatcher()->dispatch($event, LayoutBuilderEvents::SECTION_COMPONENT_BUILD_RENDER_ARRAY);
    $output = $event->getBuild();
    $event->getCacheableMetadata()->applyTo($output);
    return $output;
  }

  /** * Gets any arbitrary property for the component. * * @param string $property * The property to retrieve. * * @return mixed * The value for that property, or NULL if the property does not exist. */
// The getExpires method could return NULL if Expires header is not set, so     // the returned value needs to be checked before calling getTimestamp.     elseif ($expires = $response->getExpires()) {
      $date = $expires->getTimestamp();
      $expire = ($date > $request_time) ? $date : Cache::PERMANENT;
    }
    else {
      $expire = Cache::PERMANENT;
    }

    if ($expire === Cache::PERMANENT || $expire > $request_time) {
      $tags = $response->getCacheableMetadata()->getCacheTags();
      $this->set($request$response$expire$tags);
    }

    return TRUE;
  }

  /** * Returns a response object from the page cache. * * @param \Symfony\Component\HttpFoundation\Request $request * A request object. * @param bool $allow_invalid * (optional) If TRUE, a cache item may be returned even if it is expired or * has been invalidated. Such items may sometimes be preferred, if the * alternative is recalculating the value stored in the cache, especially * if another concurrent request is already recalculating the same value. * The "valid" property of the returned object indicates whether the item is * valid or not. Defaults to FALSE. * * @return \Symfony\Component\HttpFoundation\Response|false * The cached response or FALSE on failure. */
$html_response = new HtmlResponse();
      $html_response->setContent([
        '#markup' => BigPipeMarkup::create($js_bottom_placeholder),
        '#attached' => [
          'drupalSettings' => $cumulative_assets->getSettings(),
          'library' => $cumulative_assets->getAlreadyLoadedLibraries(),
          'html_response_attachment_placeholders' => [
            'scripts_bottom' => $js_bottom_placeholder,
          ],
        ],
      ]);
      $html_response->getCacheableMetadata()->setCacheMaxAge(0);

      // Push a fake request with the asset libraries loaded so far and dispatch       // KernelEvents::RESPONSE event. This results in the attachments for the       // HTML response being processed by HtmlResponseAttachmentsProcessor and       // hence the HTML to load the bottom JavaScript can be rendered.       $fake_request = $this->requestStack->getMainRequest()->duplicate();
      $html_response = $this->filterEmbeddedResponse($fake_request$html_response);
      $scripts_bottom = $html_response->getContent();
    }

    $this->sendChunk($scripts_bottom);
  }

  protected static function flattenResponse(ResourceResponse $response, Request $request) {
    $final_response = ($response instanceof CacheableResponseInterface && $request->isMethodCacheable()) ? new CacheableResponse() : new Response();
    $final_response->setContent($response->getContent());
    $final_response->setStatusCode($response->getStatusCode());
    $final_response->setProtocolVersion($response->getProtocolVersion());
    if ($charset = $response->getCharset()) {
      $final_response->setCharset($charset);
    }
    $final_response->headers = clone $response->headers;
    if ($final_response instanceof CacheableResponseInterface) {
      $final_response->addCacheableDependency($response->getCacheableMetadata());
    }
    return $final_response;
  }

}

abstract class CacheableSecuredRedirectResponse extends SecuredRedirectResponse implements CacheableResponseInterface {

  use CacheableResponseTrait;

  /** * {@inheritdoc} */
  protected function fromResponse(RedirectResponse $response) {
    parent::fromResponse($response);

    $metadata = $this->getCacheableMetadata();
    if ($response instanceof CacheableResponseInterface) {
      $metadata->addCacheableDependency($response->getCacheableMetadata());
    }
    else {
      $metadata->setCacheMaxAge(0);
    }
  }

}
Home | Imprint | This part of the site doesn't use cookies.