diff --git a/src/Metadata/Resource/Factory/ExtractorResourceMetadataFactory.php b/src/Metadata/Resource/Factory/ExtractorResourceMetadataFactory.php
index 456fb9e5cc7..aa267b8d7e0 100644
--- a/src/Metadata/Resource/Factory/ExtractorResourceMetadataFactory.php
+++ b/src/Metadata/Resource/Factory/ExtractorResourceMetadataFactory.php
@@ -87,16 +87,23 @@ private function handleNotFound(?ResourceMetadata $parentPropertyMetadata, strin
}
/**
- * Creates a new instance of metadata if the property is not already set.
+ * Update resource metadata if new config is given.
*/
private function update(ResourceMetadata $resourceMetadata, array $metadata): ResourceMetadata
{
foreach (['shortName', 'description', 'iri', 'itemOperations', 'collectionOperations', 'subresourceOperations', 'graphql', 'attributes'] as $property) {
- if (null === $metadata[$property] || null !== $resourceMetadata->{'get'.ucfirst($property)}()) {
+ $propertyMetadata = $metadata[$property];
+ $parentPropertyMetadata = $resourceMetadata->{'get'.ucfirst($property)}();
+
+ if (null === $propertyMetadata) {
continue;
}
- $resourceMetadata = $resourceMetadata->{'with'.ucfirst($property)}($metadata[$property]);
+ if (\is_array($parentPropertyMetadata) && \is_array($propertyMetadata)) {
+ $propertyMetadata = array_merge($parentPropertyMetadata, $propertyMetadata);
+ }
+
+ $resourceMetadata = $resourceMetadata->{'with'.ucfirst($property)}($propertyMetadata);
}
return $resourceMetadata;
diff --git a/tests/Fixtures/FileConfigurations/resources.xml b/tests/Fixtures/FileConfigurations/resources.xml
index f12ed385eaa..872e6d4aae7 100644
--- a/tests/Fixtures/FileConfigurations/resources.xml
+++ b/tests/Fixtures/FileConfigurations/resources.xml
@@ -23,6 +23,7 @@
POST
the/collection/path
+ 201
diff --git a/tests/Fixtures/FileConfigurations/resources.yml b/tests/Fixtures/FileConfigurations/resources.yml
index b20ab46e982..514c760b6e0 100644
--- a/tests/Fixtures/FileConfigurations/resources.yml
+++ b/tests/Fixtures/FileConfigurations/resources.yml
@@ -12,6 +12,7 @@ resources:
my_collection_op:
method: 'POST'
path: 'the/collection/path'
+ status: '201'
subresourceOperations:
my_collection_subresource:
path: 'the/subresource/path'
diff --git a/tests/Fixtures/FileConfigurations/resourcesoverride.xml b/tests/Fixtures/FileConfigurations/resourcesoverride.xml
new file mode 100644
index 00000000000..63554a2e64e
--- /dev/null
+++ b/tests/Fixtures/FileConfigurations/resourcesoverride.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+ GET
+ the/path
+
+
+
+
+ POST
+ 200
+
+
+
+
diff --git a/tests/Fixtures/FileConfigurations/resourcesoverride.yml b/tests/Fixtures/FileConfigurations/resourcesoverride.yml
new file mode 100644
index 00000000000..36d021ab1d3
--- /dev/null
+++ b/tests/Fixtures/FileConfigurations/resourcesoverride.yml
@@ -0,0 +1,11 @@
+resources:
+ 'ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\FileConfigDummy':
+ description: New description
+ itemOperations:
+ my_op_name:
+ method: 'GET'
+ path: 'the/path'
+ collectionOperations:
+ my_collection_op:
+ method: 'POST'
+ status: '200'
diff --git a/tests/Fixtures/FileConfigurations/single_resource.yml b/tests/Fixtures/FileConfigurations/single_resource.yml
index c7c22563313..46bd3b184fc 100644
--- a/tests/Fixtures/FileConfigurations/single_resource.yml
+++ b/tests/Fixtures/FileConfigurations/single_resource.yml
@@ -10,6 +10,7 @@
my_collection_op:
method: 'POST'
path: 'the/collection/path'
+ status: '201'
subresourceOperations:
my_collection_subresource:
path: 'the/subresource/path'
diff --git a/tests/Metadata/Resource/Factory/ExtractorResourceMetadataFactoryTest.php b/tests/Metadata/Resource/Factory/ExtractorResourceMetadataFactoryTest.php
index 07f700a8d68..d2f20aeb9b4 100644
--- a/tests/Metadata/Resource/Factory/ExtractorResourceMetadataFactoryTest.php
+++ b/tests/Metadata/Resource/Factory/ExtractorResourceMetadataFactoryTest.php
@@ -163,6 +163,23 @@ public function testXmlExistingParentResourceMetadataFactory(ResourceMetadata $e
$this->assertEquals($expectedResourceMetadata, $resourceMetadata);
}
+ /**
+ * @dataProvider overrideOperationsResourceMetadataProvider
+ */
+ public function testXmlOverrideExistingParentResourceMetadataFactory(ResourceMetadata $expectedResourceMetadata)
+ {
+ $configPath = __DIR__.'/../../../Fixtures/FileConfigurations/resourcesoverride.xml';
+
+ $decorated = $this->prophesize(ResourceMetadataFactoryInterface::class);
+ $decorated->create(FileConfigDummy::class)->willReturn($this->resourceMetadataProvider()[0][0])->shouldBeCalled();
+
+ $resourceMetadataFactory = new ExtractorResourceMetadataFactory(new XmlExtractor([$configPath]), $decorated->reveal());
+
+ $resourceMetadata = $resourceMetadataFactory->create(FileConfigDummy::class);
+
+ $this->assertEquals($expectedResourceMetadata, $resourceMetadata);
+ }
+
/**
* @dataProvider resourceMetadataProvider
*/
@@ -251,6 +268,23 @@ public function testYamlExistingParentResourceMetadataFactory(ResourceMetadata $
$this->assertEquals($expectedResourceMetadata, $resourceMetadata);
}
+ /**
+ * @dataProvider overrideOperationsResourceMetadataProvider
+ */
+ public function testYamlOverrideExistingParentResourceMetadataFactory(ResourceMetadata $expectedResourceMetadata)
+ {
+ $configPath = __DIR__.'/../../../Fixtures/FileConfigurations/resourcesoverride.yml';
+
+ $decorated = $this->prophesize(ResourceMetadataFactoryInterface::class);
+ $decorated->create(FileConfigDummy::class)->willReturn($this->resourceMetadataProvider()[0][0])->shouldBeCalled();
+
+ $resourceMetadataFactory = new ExtractorResourceMetadataFactory(new YamlExtractor([$configPath]), $decorated->reveal());
+
+ $resourceMetadata = $resourceMetadataFactory->create(FileConfigDummy::class);
+
+ $this->assertEquals($expectedResourceMetadata, $resourceMetadata);
+ }
+
public function testCreateWithMalformedYaml()
{
$this->expectException(InvalidArgumentException::class);
diff --git a/tests/Metadata/Resource/Factory/FileConfigurationMetadataFactoryProvider.php b/tests/Metadata/Resource/Factory/FileConfigurationMetadataFactoryProvider.php
index 39c81511c39..e96f93f1024 100644
--- a/tests/Metadata/Resource/Factory/FileConfigurationMetadataFactoryProvider.php
+++ b/tests/Metadata/Resource/Factory/FileConfigurationMetadataFactoryProvider.php
@@ -36,7 +36,7 @@ public function resourceMetadataProvider()
'my_other_op_name' => ['method' => 'POST'],
],
'collectionOperations' => [
- 'my_collection_op' => ['method' => 'POST', 'path' => 'the/collection/path'],
+ 'my_collection_op' => ['method' => 'POST', 'path' => 'the/collection/path', 'status' => '201'],
],
'subresourceOperations' => [
'my_collection_subresource' => ['path' => 'the/subresource/path'],
@@ -111,4 +111,22 @@ public function legacyOperationsResourceMetadataProvider()
return [[$resourceMetadata]];
}
+
+ public function overrideOperationsResourceMetadataProvider()
+ {
+ $resourceMetadata = $this->resourceMetadataProvider()[0][0];
+
+ $resourceMetadata = $resourceMetadata->withDescription('New description');
+
+ $resourceMetadata = $resourceMetadata->withItemOperations([
+ 'my_op_name' => ['method' => 'GET', 'path' => 'the/path'],
+ 'my_other_op_name' => ['method' => 'POST'],
+ ]);
+
+ $resourceMetadata = $resourceMetadata->withCollectionOperations([
+ 'my_collection_op' => ['method' => 'POST', 'status' => '200'],
+ ]);
+
+ return [[$resourceMetadata]];
+ }
}