Skip to content

Commit f63a9c8

Browse files
committed
fix(resource model): allow meta data reading from relationship
1 parent 4777e60 commit f63a9c8

File tree

3 files changed

+40
-21
lines changed

3 files changed

+40
-21
lines changed

src/Model/Resource/FlatResource.php

+26-4
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222
*/
2323
class FlatResource
2424
{
25-
/** @var ResourceInterface */
26-
private $resource;
25+
/** @var array<string,array> */
26+
private array $relationshipMetas;
2727

28-
public function __construct(ResourceInterface $resource)
28+
public function __construct(private ResourceInterface $resource)
2929
{
30-
$this->resource = $resource;
30+
$this->relationshipMetas = [];
3131
}
3232

3333
/**
@@ -62,6 +62,7 @@ public function getRelationships(): array
6262

6363
/** @var RelationshipInterface $relationship */
6464
foreach ($this->resource->getRelationships() as $relationship) {
65+
$this->buildRelationshipMeta($relationship);
6566
$relationshipData = $relationship->getData();
6667

6768
if (null === $relationshipData) {
@@ -79,6 +80,7 @@ public function getRelationships(): array
7980
if ($relationshipData instanceof ToOneRelationshipDataInterface && false === $relationshipData->isEmpty()) {
8081
/** @var ResourceIdentifierInterface $data */
8182
$data = $relationshipData->getData();
83+
8284
$flatRelationships[$relationship->getName()] = $data->getId();
8385

8486
continue;
@@ -129,4 +131,24 @@ public function getIndexedRelationshipObjects(): array
129131

130132
return $flatRelationships;
131133
}
134+
135+
/** @return array<string,array<mixed,mixed>> */
136+
public function getRelationshipMetas(): array
137+
{
138+
if (true === empty($this->relationshipMetas)) {
139+
/** @var RelationshipInterface $relationship */
140+
foreach ($this->resource->getRelationships() as $relationship) {
141+
$this->buildRelationshipMeta($relationship);
142+
}
143+
}
144+
145+
return $this->relationshipMetas;
146+
}
147+
148+
private function buildRelationshipMeta(RelationshipInterface $relationship): void
149+
{
150+
$this->relationshipMetas[$relationship->getName() . 'Meta'] = null === $relationship->getMeta()
151+
? []
152+
: $relationship->getMeta()->getData();
153+
}
132154
}

src/Service/Resource/Denormalizer/ResourceDenormalizer.php

+6-11
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,10 @@
1818

1919
class ResourceDenormalizer
2020
{
21-
/** @var ResourceMetadataFactoryInterface */
22-
private $metadataFactory;
23-
24-
/** @var DenormalizerInterface */
25-
private $denormalizer;
26-
27-
public function __construct(ResourceMetadataFactoryInterface $metadataFactory, DenormalizerInterface $denormalizer)
28-
{
29-
$this->metadataFactory = $metadataFactory;
30-
$this->denormalizer = $denormalizer;
21+
public function __construct(
22+
private ResourceMetadataFactoryInterface $metadataFactory,
23+
private DenormalizerInterface $denormalizer
24+
) {
3125
}
3226

3327
/**
@@ -50,7 +44,7 @@ public function denormalize(ResourceInterface $resource, string $class): ApiMode
5044
try {
5145
/** @var ApiModel $result */
5246
$result = $this->denormalizer->denormalize($data, $class, null, [
53-
AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
47+
AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => true,
5448
]);
5549
} catch (MissingConstructorArgumentsException $e) {
5650
throw new MissingDataValueResourceDenormalizationException(
@@ -85,6 +79,7 @@ private function prepareData(ResourceInterface $resource, string $class): array
8579
];
8680
$data = array_merge($data, $flatResource->getAttributes());
8781
$data = array_merge($data, $flatResource->getRelationships());
82+
$data = array_merge($data, $flatResource->getRelationshipMetas());
8883

8984
/*
9085
* Resource has attribute and relationship names that can be different from the property name in the class.

tests/Integration/Resource/Denormalizer/ResourceWithAliasesDenormalizerTest.php

+8-6
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ public function testDenormalizationOfInvalidResourceResultsWithException(): void
158158
$this->serializer->denormalize($resource, AliasedResourceDto::class);
159159
}
160160

161-
public function testDenormalizationOfResourceWithExtraAttributeResultsWithException(): void
161+
public function testDenormalizeWillReturnCorrectApiModelWithExtraAttributesIgnored(): void
162162
{
163163
$resource = new Resource(
164164
'1',
@@ -174,11 +174,12 @@ public function testDenormalizationOfResourceWithExtraAttributeResultsWithExcept
174174
->get()
175175
);
176176

177-
$this->expectException(ResourceDenormalizationException::class);
178-
$this->serializer->denormalize($resource, AliasedResourceDto::class);
177+
$model = $this->serializer->denormalize($resource, AliasedResourceDto::class);
178+
static::assertInstanceOf(AliasedResourceDto::class, $model);
179+
static::assertObjectNotHasAttribute('extra', $model);
179180
}
180181

181-
public function testDenormalizationOfResourceWithExtraRelationshipResultsWithException(): void
182+
public function testDenormalizeWillReturnCorrectApiModelWithExtraRelationshipsIgnored(): void
182183
{
183184
$resource = new Resource(
184185
'1',
@@ -194,8 +195,9 @@ public function testDenormalizationOfResourceWithExtraRelationshipResultsWithExc
194195
->get()
195196
);
196197

197-
$this->expectException(ResourceDenormalizationException::class);
198-
$this->serializer->denormalize($resource, AliasedResourceDto::class);
198+
$model = $this->serializer->denormalize($resource, AliasedResourceDto::class);
199+
static::assertInstanceOf(AliasedResourceDto::class, $model);
200+
static::assertObjectNotHasAttribute('extras', $model);
199201
}
200202

201203
public function testResourceWithAliasedOptionalToOneRelationshipCanBeDenormalized(): void

0 commit comments

Comments
 (0)