Skip to content

Commit 634a58c

Browse files
committed
Merge 4.1
2 parents ecb3f6c + 04414e4 commit 634a58c

File tree

2 files changed

+15
-17
lines changed

2 files changed

+15
-17
lines changed

src/Serializer/ItemNormalizer.php

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
/**
3434
* Generic item normalizer.
3535
*
36+
* TODO: do not hardcode "id"
37+
*
3638
* @author Kévin Dunglas <[email protected]>
3739
*/
3840
class ItemNormalizer extends AbstractItemNormalizer
@@ -60,7 +62,9 @@ public function denormalize(mixed $data, string $class, ?string $format = null,
6062
}
6163

6264
if (isset($context['resource_class'])) {
63-
$this->updateObjectToPopulate($data, $context);
65+
if ($this->updateObjectToPopulate($data, $context)) {
66+
unset($data['id']);
67+
}
6468
} else {
6569
// See https://github.com/api-platform/core/pull/2326 to understand this message.
6670
$this->logger->warning('The "resource_class" key is missing from the context.', [
@@ -69,24 +73,15 @@ public function denormalize(mixed $data, string $class, ?string $format = null,
6973
}
7074
}
7175

72-
// See https://github.com/api-platform/core/pull/7270 - id may be an allowed attribute due to being added in the
73-
// overridden getAllowedAttributes below, in order to allow updating a nested item via ID. But in this case it
74-
// may not "really" be an allowed attribute, ie we don't want to actually use it in denormalization. In this
75-
// scenario it will not be present in parent::getAllowedAttributes
76-
if (isset($data['id'], $context['resource_class'])) {
77-
$parentAllowedAttributes = parent::getAllowedAttributes($class, $context, true);
78-
if (\is_array($parentAllowedAttributes) && !\in_array('id', $parentAllowedAttributes, true)) {
79-
unset($data['id']);
80-
}
81-
}
82-
8376
return parent::denormalize($data, $class, $format, $context);
8477
}
8578

86-
private function updateObjectToPopulate(array $data, array &$context): void
79+
private function updateObjectToPopulate(array $data, array &$context): bool
8780
{
8881
try {
8982
$context[self::OBJECT_TO_POPULATE] = $this->iriConverter->getResourceFromIri((string) $data['id'], $context + ['fetch_data' => true]);
83+
84+
return true;
9085
} catch (InvalidArgumentException) {
9186
$operation = $this->resourceMetadataCollectionFactory?->create($context['resource_class'])->getOperation();
9287
if (
@@ -103,6 +98,8 @@ private function updateObjectToPopulate(array $data, array &$context): void
10398

10499
$context[self::OBJECT_TO_POPULATE] = $this->iriConverter->getResourceFromIri($iri, $context + ['fetch_data' => true]);
105100
}
101+
102+
return false;
106103
}
107104

108105
private function getContextUriVariables(array $data, Operation $operation, array $context): array
@@ -125,8 +122,9 @@ private function getContextUriVariables(array $data, Operation $operation, array
125122
protected function getAllowedAttributes(string|object $classOrObject, array $context, bool $attributesAsString = false): array|bool
126123
{
127124
$allowedAttributes = parent::getAllowedAttributes($classOrObject, $context, $attributesAsString);
128-
if (\is_array($allowedAttributes) && ($context['api_denormalize'] ?? false)) {
129-
$allowedAttributes = array_merge($allowedAttributes, ['id']);
125+
// id is a special case handled above it causes issues not allowing it
126+
if (\is_array($allowedAttributes) && ($context['api_denormalize'] ?? false) && !\in_array('id', $allowedAttributes, true)) {
127+
$allowedAttributes[] = 'id';
130128
}
131129

132130
return $allowedAttributes;

src/Serializer/Tests/ItemNormalizerTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,14 +316,14 @@ public function testDenormalizeWithWrongId(): void
316316
$operation = new Get(uriVariables: ['id' => new Link(identifiers: ['id'], parameterName: 'id')]);
317317
$obj = new Dummy();
318318

319-
$propertyNameCollection = new PropertyNameCollection(['name']);
319+
$propertyNameCollection = new PropertyNameCollection(['id', 'name']);
320320
$propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
321321
$propertyNameCollectionFactoryProphecy->create(Dummy::class, [])->willReturn($propertyNameCollection)->shouldBeCalled();
322322

323323
$propertyMetadata = (new ApiProperty())->withReadable(true)->withWritable(true);
324324
$propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
325325
$propertyMetadataFactoryProphecy->create(Dummy::class, 'name', [])->willReturn($propertyMetadata)->shouldBeCalled();
326-
$propertyMetadataFactoryProphecy->create(Dummy::class, 'id', [])->willReturn($propertyMetadata)->shouldBeCalled();
326+
$propertyMetadataFactoryProphecy->create(Dummy::class, 'id', [])->willReturn((new ApiProperty())->withIdentifier(true))->shouldBeCalled();
327327

328328
$iriConverterProphecy = $this->prophesize(IriConverterInterface::class);
329329
$iriConverterProphecy->getResourceFromIri('fail', $context + ['fetch_data' => true])->willThrow(new InvalidArgumentException());

0 commit comments

Comments
 (0)