-
-
Notifications
You must be signed in to change notification settings - Fork 900
fix(serializer): use data if no uri_variables provided #5743
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ | |
use ApiPlatform\Exception\ItemNotFoundException; | ||
use ApiPlatform\Metadata\ApiProperty; | ||
use ApiPlatform\Metadata\CollectionOperationInterface; | ||
use ApiPlatform\Metadata\Exception\OperationNotFoundException; | ||
use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface; | ||
use ApiPlatform\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface; | ||
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface; | ||
|
@@ -512,12 +513,7 @@ protected function denormalizeCollection(string $attribute, ApiProperty $propert | |
|
||
$collectionKeyType = $type->getCollectionKeyTypes()[0] ?? null; | ||
$collectionKeyBuiltinType = $collectionKeyType?->getBuiltinType(); | ||
$childContext = $this->createChildContext(['resource_class' => $className] + $context, $attribute, $format); | ||
unset($childContext['uri_variables']); | ||
if ($this->resourceMetadataCollectionFactory) { | ||
$childContext['operation'] = $this->resourceMetadataCollectionFactory->create($className)->getOperation(); | ||
} | ||
|
||
$childContext = $this->createChildContext($this->createOperationContext($context, $className), $attribute, $format); | ||
$values = []; | ||
foreach ($value as $index => $obj) { | ||
if (null !== $collectionKeyBuiltinType && !\call_user_func('is_'.$collectionKeyBuiltinType, $index)) { | ||
|
@@ -637,8 +633,7 @@ protected function getAttributeValue(object $object, string $attribute, string $ | |
} | ||
|
||
$resourceClass = $this->resourceClassResolver->getResourceClass($attributeValue, $className); | ||
$childContext = $this->createChildContext($context, $attribute, $format); | ||
unset($childContext['iri'], $childContext['uri_variables'], $childContext['resource_class'], $childContext['operation']); | ||
$childContext = $this->createChildContext($this->createOperationContext($context, $resourceClass), $attribute, $format); | ||
|
||
return $this->normalizeCollectionOfRelations($propertyMetadata, $attributeValue, $resourceClass, $format, $childContext); | ||
} | ||
|
@@ -653,12 +648,7 @@ protected function getAttributeValue(object $object, string $attribute, string $ | |
} | ||
|
||
$resourceClass = $this->resourceClassResolver->getResourceClass($attributeValue, $className); | ||
$childContext = $this->createChildContext($context, $attribute, $format); | ||
$childContext['resource_class'] = $resourceClass; | ||
if ($this->resourceMetadataCollectionFactory) { | ||
$childContext['operation'] = $this->resourceMetadataCollectionFactory->create($resourceClass)->getOperation(); | ||
} | ||
unset($childContext['iri'], $childContext['uri_variables']); | ||
$childContext = $this->createChildContext($this->createOperationContext($context, $resourceClass), $attribute, $format); | ||
|
||
return $this->normalizeRelation($propertyMetadata, $attributeValue, $resourceClass, $format, $childContext); | ||
} | ||
|
@@ -670,17 +660,16 @@ protected function getAttributeValue(object $object, string $attribute, string $ | |
unset($context['resource_class']); | ||
unset($context['force_resource_class']); | ||
|
||
// Anonymous resources | ||
if ($type && $type->getClassName()) { | ||
$childContext = $this->createChildContext($context, $attribute, $format); | ||
unset($childContext['iri'], $childContext['uri_variables']); | ||
$childContext['output']['gen_id'] = $propertyMetadata->getGenId() ?? true; | ||
|
||
return $this->serializer->normalize($attributeValue, $format, $childContext); | ||
} | ||
|
||
if ($type && 'array' === $type->getBuiltinType()) { | ||
$childContext = $this->createChildContext($context, $attribute, $format); | ||
unset($childContext['iri'], $childContext['uri_variables']); | ||
|
||
return $this->serializer->normalize($attributeValue, $format, $childContext); | ||
} | ||
|
@@ -804,12 +793,7 @@ private function createAndValidateAttributeValue(string $attribute, mixed $value | |
&& $this->resourceClassResolver->isResourceClass($className) | ||
) { | ||
$resourceClass = $this->resourceClassResolver->getResourceClass(null, $className); | ||
$childContext = $this->createChildContext($context, $attribute, $format); | ||
$childContext['resource_class'] = $resourceClass; | ||
unset($childContext['uri_variables']); | ||
if ($this->resourceMetadataCollectionFactory) { | ||
$childContext['operation'] = $this->resourceMetadataCollectionFactory->create($resourceClass)->getOperation(); | ||
} | ||
$childContext = $this->createChildContext($this->createOperationContext($context, $resourceClass), $attribute, $format); | ||
|
||
return $this->denormalizeRelation($attribute, $propertyMetadata, $resourceClass, $value, $format, $childContext); | ||
} | ||
|
@@ -899,4 +883,29 @@ private function setValue(object $object, string $attributeName, mixed $value): | |
// Properties not found are ignored | ||
} | ||
} | ||
|
||
private function createOperationContext(array $context, string $resourceClass = null): array | ||
{ | ||
if (isset($context['operation']) && !isset($context['root_operation'])) { | ||
$context['root_operation'] = $context['operation']; | ||
$context['root_operation_name'] = $context['operation_name']; | ||
} | ||
|
||
unset($context['iri'], $context['uri_variables']); | ||
if (!$resourceClass) { | ||
return $context; | ||
} | ||
|
||
unset($context['operation'], $context['operation_name']); | ||
$context['resource_class'] = $resourceClass; | ||
if ($this->resourceMetadataCollectionFactory) { | ||
try { | ||
$context['operation'] = $this->resourceMetadataCollectionFactory->create($resourceClass)->getOperation(); | ||
$context['operation_name'] = $context['operation']->getName(); | ||
} catch (OperationNotFoundException) { | ||
} | ||
} | ||
|
||
return $context; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jonag can you try this and use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updating to API Platform v3.1.14 and changing my custom normalizer to use the root_operation instead of the operation fixes all my tests! |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -86,11 +86,7 @@ private function updateObjectToPopulate(array $data, array &$context): void | |
|
||
private function getContextUriVariables(array $data, $operation, array $context): array | ||
{ | ||
if (!isset($context['uri_variables'])) { | ||
return ['id' => $data['id']]; | ||
} | ||
|
||
$uriVariables = $context['uri_variables']; | ||
$uriVariables = $context['uri_variables'] ?? $data; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Aerendir can you try this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @soyuka , I've tried the fix, but it doesn't work... In I'm going to reproduce in tests what's going on... |
||
|
||
/** @var Link $uriVariable */ | ||
foreach ($operation->getUriVariables() as $uriVariable) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the API Platform project. | ||
* | ||
* (c) Kévin Dunglas <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue5736; | ||
|
||
use ApiPlatform\Metadata\ApiProperty; | ||
use ApiPlatform\Metadata\Get; | ||
use ApiPlatform\Metadata\Operation; | ||
|
||
#[Get( | ||
provider: [Alpha::class, 'provide'], | ||
)] | ||
final class Alpha | ||
{ | ||
public function __construct(#[ApiProperty(identifier: true)] public int $alphaId) | ||
{ | ||
} | ||
|
||
public static function provide(Operation $operation, array $uriVariables = []): self | ||
{ | ||
return new self(alphaId: $uriVariables['alphaId']); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the API Platform project. | ||
* | ||
* (c) Kévin Dunglas <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue5736; | ||
|
||
use ApiPlatform\Metadata\ApiProperty; | ||
use ApiPlatform\Metadata\Operation; | ||
use ApiPlatform\Metadata\Patch; | ||
|
||
#[Patch( | ||
processor: [Beta::class, 'process'], | ||
provider: [Beta::class, 'provide'], | ||
)] | ||
final class Beta | ||
{ | ||
public function __construct(#[ApiProperty(identifier: true)] public int $betaId, public ?Alpha $alpha = null) | ||
{ | ||
} | ||
|
||
public static function provide(Operation $operation, array $uriVariables = []): self | ||
{ | ||
return new self(betaId: $uriVariables['betaId']); | ||
} | ||
|
||
public static function process($body) | ||
{ | ||
return $body; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Aerendir this works right now so I'm not sure what the issue is, are you using merge-patch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@soyuka , no, I'm using
PUT
s... I'm going to reproduce the scenario...