From 713fc5da232e9dccb92cf9a45bd4e33cf921c418 Mon Sep 17 00:00:00 2001 From: bradjones1 <bradjones1@405824.no-reply.drupal.org> Date: Fri, 29 Oct 2021 14:23:35 +0000 Subject: [PATCH] Issue #3071310 by bradjones1, ndobromirov, bbrala, e0ipso: Field enhancers need to support cacheability metadata bubbling --- src/Normalizer/FieldItemNormalizer.php | 19 +++++++++++++++---- .../ResourceIdentifierNormalizer.php | 19 +++++++++++++++---- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/Normalizer/FieldItemNormalizer.php b/src/Normalizer/FieldItemNormalizer.php index 50f458c..598c457 100644 --- a/src/Normalizer/FieldItemNormalizer.php +++ b/src/Normalizer/FieldItemNormalizer.php @@ -7,6 +7,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\jsonapi\Normalizer\FieldItemNormalizer as JsonapiFieldItemNormalizer; use Drupal\jsonapi\Normalizer\Value\CacheableNormalization; use Drupal\jsonapi_extras\Plugin\ResourceFieldEnhancerManager; +use Drupal\serialization\Normalizer\CacheableNormalizerInterface; use Shaper\Util\Context; /** @@ -57,12 +58,22 @@ class FieldItemNormalizer extends JsonApiNormalizerDecoratorBase { if (!$enhancer) { return $normalized_output; } - // Apply any enhancements necessary. - $context['field_item_object'] = $object; - $processed = $enhancer->undoTransform($normalized_output->getNormalization(), new Context($context)); $cacheability = CacheableMetadata::createFromObject($normalized_output) ->addCacheTags(['config:jsonapi_resource_config_list']); - $normalized_output = new CacheableNormalization($cacheability, $processed); + // Apply any enhancements necessary. + $context = new Context([ + 'field_item_object' => $object, + CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY => $cacheability, + ]); + $processed = $enhancer->undoTransform( + $normalized_output->getNormalization(), + $context + ); + $normalized_output = new CacheableNormalization( + // This was passed by reference but often, merging creates a new object. + $context->offsetGet(CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY), + $processed + ); return $normalized_output; } diff --git a/src/Normalizer/ResourceIdentifierNormalizer.php b/src/Normalizer/ResourceIdentifierNormalizer.php index a903e7a..e112004 100644 --- a/src/Normalizer/ResourceIdentifierNormalizer.php +++ b/src/Normalizer/ResourceIdentifierNormalizer.php @@ -2,6 +2,7 @@ namespace Drupal\jsonapi_extras\Normalizer; +use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Field\EntityReferenceFieldItemListInterface; use Drupal\jsonapi\JsonApiResource\ResourceIdentifier; @@ -9,6 +10,7 @@ use Drupal\jsonapi\JsonApiResource\ResourceObject; use Drupal\jsonapi\Normalizer\Value\CacheableNormalization; use Drupal\jsonapi\ResourceType\ResourceTypeRepositoryInterface; use Drupal\jsonapi_extras\ResourceType\ConfigurableResourceType; +use Drupal\serialization\Normalizer\CacheableNormalizerInterface; use Shaper\Util\Context; /** @@ -60,12 +62,21 @@ class ResourceIdentifierNormalizer extends JsonApiNormalizerDecoratorBase { if (!$enhancer) { return $normalized_output; } + $cacheability = CacheableMetadata::createFromObject($normalized_output) + ->addCacheTags(['config:jsonapi_resource_config_list']); // Apply any enhancements necessary. - $context['field_resource_identifier'] = $field; - $transformed = $enhancer->undoTransform($normalized_output->getNormalization(), new Context($context)); - // @todo Enhancers should utilize CacheableNormalization to infer additional cacheability from the enhancer. + $context = new Context([ + 'field_resource_identifier' => $field, + CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY => $cacheability, + ]); + $transformed = $enhancer->undoTransform( + $normalized_output->getNormalization(), + $context + ); + return new CacheableNormalization( - $normalized_output, + // This was passed by reference but often, merging creates a new object. + $context->offsetGet(CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY), array_intersect_key($transformed, array_flip(['id', 'type', 'meta'])) ); } -- GitLab