class ResourceObjectNormalizationCacher in Drupal 9
Same name and namespace in other branches
- 8 core/modules/jsonapi/src/EventSubscriber/ResourceObjectNormalizationCacher.php \Drupal\jsonapi\EventSubscriber\ResourceObjectNormalizationCacher
Caches entity normalizations after the response has been sent.
@internal @todo Refactor once https://www.drupal.org/node/2551419 lands.
Hierarchy
- class \Drupal\jsonapi\EventSubscriber\ResourceObjectNormalizationCacher implements \Symfony\Component\EventDispatcher\EventSubscriberInterface
Expanded class hierarchy of ResourceObjectNormalizationCacher
See also
\Drupal\jsonapi\Normalizer\ResourceObjectNormalizer::getNormalization()
2 files declare their use of ResourceObjectNormalizationCacher
- ResourceObjectNormalizer.php in core/
modules/ jsonapi/ src/ Normalizer/ ResourceObjectNormalizer.php - ResourceObjectNormalizerCacherTest.php in core/
modules/ jsonapi/ tests/ src/ Kernel/ EventSubscriber/ ResourceObjectNormalizerCacherTest.php
1 string reference to 'ResourceObjectNormalizationCacher'
- jsonapi.services.yml in core/
modules/ jsonapi/ jsonapi.services.yml - core/modules/jsonapi/jsonapi.services.yml
1 service uses ResourceObjectNormalizationCacher
File
- core/
modules/ jsonapi/ src/ EventSubscriber/ ResourceObjectNormalizationCacher.php, line 19
Namespace
Drupal\jsonapi\EventSubscriberView source
class ResourceObjectNormalizationCacher implements EventSubscriberInterface {
/**
* Key for the base subset.
*
* The base subset contains the parts of the normalization that are always
* present. The presence or absence of these are not affected by the requested
* sparse field sets. This typically includes the resource type name, and the
* resource ID.
*/
const RESOURCE_CACHE_SUBSET_BASE = 'base';
/**
* Key for the fields subset.
*
* The fields subset contains the parts of the normalization that can appear
* in a normalization based on the selected field set. This subset is
* incrementally built across different requests for the same resource object.
* A given field is normalized and put into the cache whenever there is a
* cache miss for that field.
*/
const RESOURCE_CACHE_SUBSET_FIELDS = 'fields';
/**
* The render cache.
*
* @var \Drupal\Core\Render\RenderCacheInterface
*/
protected $renderCache;
/**
* The things to cache after the response has been sent.
*
* @var array
*/
protected $toCache = [];
/**
* Sets the render cache service.
*
* @param \Drupal\Core\Render\RenderCacheInterface $render_cache
* The render cache.
*/
public function setRenderCache(RenderCacheInterface $render_cache) {
$this->renderCache = $render_cache;
}
/**
* Reads an entity normalization from cache.
*
* The returned normalization may only be a partial normalization because it
* was previously normalized with a sparse fieldset.
*
* @param \Drupal\jsonapi\JsonApiResource\ResourceObject $object
* The resource object for which to generate a cache item.
*
* @return array|false
* The cached normalization parts, or FALSE if not yet cached.
*
* @see \Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber::renderArrayToResponse()
*/
public function get(ResourceObject $object) {
$cached = $this->renderCache
->get(static::generateLookupRenderArray($object));
return $cached ? $cached['#data'] : FALSE;
}
/**
* Adds a normalization to be cached after the response has been sent.
*
* @param \Drupal\jsonapi\JsonApiResource\ResourceObject $object
* The resource object for which to generate a cache item.
* @param array $normalization_parts
* The normalization parts to cache.
*/
public function saveOnTerminate(ResourceObject $object, array $normalization_parts) {
assert(array_keys($normalization_parts) === [
static::RESOURCE_CACHE_SUBSET_BASE,
static::RESOURCE_CACHE_SUBSET_FIELDS,
]);
$resource_type = $object
->getResourceType();
$key = $resource_type
->getTypeName() . ':' . $object
->getId();
$this->toCache[$key] = [
$object,
$normalization_parts,
];
}
/**
* Writes normalizations of entities to cache, if any were created.
*
* @param \Symfony\Component\HttpKernel\Event\TerminateEvent $event
* The Event to process.
*/
public function onTerminate(TerminateEvent $event) {
foreach ($this->toCache as $value) {
list($object, $normalization_parts) = $value;
$this
->set($object, $normalization_parts);
}
}
/**
* Writes a normalization to cache.
*
* @param \Drupal\jsonapi\JsonApiResource\ResourceObject $object
* The resource object for which to generate a cache item.
* @param array $normalization_parts
* The normalization parts to cache.
*
* @see \Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber::responseToRenderArray()
* @todo Refactor/remove once https://www.drupal.org/node/2551419 lands.
*/
protected function set(ResourceObject $object, array $normalization_parts) {
$base = static::generateLookupRenderArray($object);
$data_as_render_array = $base + [
// The data we actually care about.
'#data' => $normalization_parts,
// Tell RenderCache to cache the #data property: the data we actually care
// about.
'#cache_properties' => [
'#data',
],
// These exist only to fulfill the requirements of the RenderCache, which
// is designed to work with render arrays only. We don't care about these.
'#markup' => '',
'#attached' => '',
];
// Merge the entity's cacheability metadata with that of the normalization
// parts, so that RenderCache can take care of cache redirects for us.
CacheableMetadata::createFromObject($object)
->merge(static::mergeCacheableDependencies($normalization_parts[static::RESOURCE_CACHE_SUBSET_BASE]))
->merge(static::mergeCacheableDependencies($normalization_parts[static::RESOURCE_CACHE_SUBSET_FIELDS]))
->applyTo($data_as_render_array);
$this->renderCache
->set($data_as_render_array, $base);
}
/**
* Generates a lookup render array for a normalization.
*
* @param \Drupal\jsonapi\JsonApiResource\ResourceObject $object
* The resource object for which to generate a cache item.
*
* @return array
* A render array for use with the RenderCache service.
*
* @see \Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber::$dynamicPageCacheRedirectRenderArray
*/
protected static function generateLookupRenderArray(ResourceObject $object) {
return [
'#cache' => [
'keys' => [
$object
->getResourceType()
->getTypeName(),
$object
->getId(),
],
'bin' => 'jsonapi_normalizations',
],
];
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
$events[KernelEvents::TERMINATE][] = [
'onTerminate',
];
return $events;
}
/**
* Determines the joint cacheability of all provided dependencies.
*
* @param \Drupal\Core\Cache\CacheableDependencyInterface|object[] $dependencies
* The dependencies.
*
* @return \Drupal\Core\Cache\CacheableMetadata
* The cacheability of all dependencies.
*
* @see \Drupal\Core\Cache\RefinableCacheableDependencyInterface::addCacheableDependency()
*/
protected static function mergeCacheableDependencies(array $dependencies) {
$merged_cacheability = new CacheableMetadata();
array_walk($dependencies, function ($dependency) use ($merged_cacheability) {
$merged_cacheability
->addCacheableDependency($dependency);
});
return $merged_cacheability;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
ResourceObjectNormalizationCacher:: |
protected | property | The render cache. | |
ResourceObjectNormalizationCacher:: |
protected | property | The things to cache after the response has been sent. | |
ResourceObjectNormalizationCacher:: |
protected static | function | Generates a lookup render array for a normalization. | |
ResourceObjectNormalizationCacher:: |
public | function | Reads an entity normalization from cache. | |
ResourceObjectNormalizationCacher:: |
public static | function | ||
ResourceObjectNormalizationCacher:: |
protected static | function | Determines the joint cacheability of all provided dependencies. | |
ResourceObjectNormalizationCacher:: |
public | function | Writes normalizations of entities to cache, if any were created. | |
ResourceObjectNormalizationCacher:: |
constant | Key for the base subset. | ||
ResourceObjectNormalizationCacher:: |
constant | Key for the fields subset. | ||
ResourceObjectNormalizationCacher:: |
public | function | Adds a normalization to be cached after the response has been sent. | |
ResourceObjectNormalizationCacher:: |
protected | function | Writes a normalization to cache. | |
ResourceObjectNormalizationCacher:: |
public | function | Sets the render cache service. |