diff --git a/src/Bridge/Symfony/Routing/ApiLoader.php b/src/Bridge/Symfony/Routing/ApiLoader.php index 8f5e7bdffa0..aa9a85ae13c 100644 --- a/src/Bridge/Symfony/Routing/ApiLoader.php +++ b/src/Bridge/Symfony/Routing/ApiLoader.php @@ -111,6 +111,8 @@ public function load($data, $type = null): RouteCollection 'property' => $operation['property'], 'identifiers' => $operation['identifiers'], 'collection' => $operation['collection'], + 'parent_resource_class' => $resourceClass, + 'parent_operation_name' => $operation['operation_name'], 'operationId' => $operationId, ], ] + $operation['defaults'] ?? [], diff --git a/src/Serializer/SerializerContextBuilder.php b/src/Serializer/SerializerContextBuilder.php index ccf76e61952..776122a7428 100644 --- a/src/Serializer/SerializerContextBuilder.php +++ b/src/Serializer/SerializerContextBuilder.php @@ -42,36 +42,43 @@ public function createFromRequest(Request $request, bool $normalization, array $ throw new RuntimeException('Request attributes are not valid.'); } - $resourceMetadata = $this->resourceMetadataFactory->create($attributes['resource_class']); $key = $normalization ? 'normalization_context' : 'denormalization_context'; - $operationKey = null; - $operationType = null; - if (isset($attributes['collection_operation_name'])) { - $operationKey = 'collection_operation_name'; - $operationType = OperationType::COLLECTION; - } elseif (isset($attributes['subresource_operation_name'])) { - $operationKey = 'subresource_operation_name'; - $operationType = OperationType::SUBRESOURCE; - } + $attribute = $attributes['collection_operation_name']; + $resourceClass = $attributes['resource_class']; - if (null !== $operationKey) { - $attribute = $attributes[$operationKey]; + $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass); $context = $resourceMetadata->getCollectionOperationAttribute($attribute, $key, [], true); - $context[$operationKey] = $attribute; + + $context['collection_operation_name'] = $attribute; + $context['resource_class'] = $resourceClass; + $context['operation_type'] = OperationType::COLLECTION; + } elseif (isset($attributes['subresource_operation_name'])) { + $attribute = $attributes['subresource_operation_name']; + $resourceClass = $attributes['resource_class']; + $parentClass = $attributes['subresource_context']['parent_resource_class']; + $parentOperationName = $attributes['subresource_context']['parent_operation_name']; + + $parentMetadata = $this->resourceMetadataFactory->create($parentClass); + $context = $parentMetadata->getSubresourceOperationAttribute($parentOperationName, $key, [], true); + + $context['subresource_operation_name'] = $attribute; + $context['resource_class'] = $resourceClass; + $context['operation_type'] = OperationType::SUBRESOURCE; } else { + $resourceClass = $attributes['resource_class']; + $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass); $context = $resourceMetadata->getItemOperationAttribute($attributes['item_operation_name'], $key, [], true); $context['item_operation_name'] = $attributes['item_operation_name']; + $context['resource_class'] = $attributes['resource_class']; + $context['operation_type'] = OperationType::ITEM; } - $context['operation_type'] = $operationType ?: OperationType::ITEM; - if (!$normalization && !isset($context['api_allow_update'])) { $context['api_allow_update'] = Request::METHOD_PUT === $request->getMethod(); } - $context['resource_class'] = $attributes['resource_class']; $context['request_uri'] = $request->getRequestUri(); if (isset($attributes['subresource_context'])) { diff --git a/src/Util/RequestAttributesExtractor.php b/src/Util/RequestAttributesExtractor.php index 77d60e91119..954adf6bf53 100644 --- a/src/Util/RequestAttributesExtractor.php +++ b/src/Util/RequestAttributesExtractor.php @@ -41,14 +41,14 @@ public static function extractAttributes(Request $request) { $result = ['resource_class' => $request->attributes->get('_api_resource_class')]; - if ($subresourceContext = $request->attributes->get('_api_subresource_context')) { - $result['subresource_context'] = $subresourceContext; - } - if (null === $result['resource_class']) { return []; } + if ($subresourceContext = $request->attributes->get('_api_subresource_context')) { + $result['subresource_context'] = $subresourceContext; + } + $hasRequestAttributeKey = false; foreach (OperationType::TYPES as $operationType) { $attribute = "_api_{$operationType}_operation_name";