diff --git a/src/State/Provider/ObjectMapperProvider.php b/src/State/Provider/ObjectMapperProvider.php index 9986f43954f..8eef0c15f30 100644 --- a/src/State/Provider/ObjectMapperProvider.php +++ b/src/State/Provider/ObjectMapperProvider.php @@ -41,7 +41,7 @@ public function __construct( public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null { $data = $this->decorated->provide($operation, $uriVariables, $context); - $class = $operation->getOutput()['class'] ?? $operation->getClass(); + $class = $operation->getInput()['class'] ?? $operation->getOutput()['class'] ?? $operation->getClass(); if (!$this->objectMapper || !$operation->canMap()) { return $data; diff --git a/tests/State/Provider/ObjectMapperProviderTest.php b/tests/State/Provider/ObjectMapperProviderTest.php index 5917c82474d..1cf360040ef 100644 --- a/tests/State/Provider/ObjectMapperProviderTest.php +++ b/tests/State/Provider/ObjectMapperProviderTest.php @@ -14,6 +14,7 @@ namespace ApiPlatform\Tests\State\Provider; use ApiPlatform\Metadata\Get; +use ApiPlatform\Metadata\Patch; use ApiPlatform\State\Pagination\ArrayPaginator; use ApiPlatform\State\Pagination\MappedObjectPaginator; use ApiPlatform\State\Provider\ObjectMapperProvider; @@ -168,6 +169,42 @@ public function testProvideMapsPaginator(): void $this->assertSame($targetResource2, $items[1]); } + public function testProvideMapsToInputClassWhenInputIsSet(): void + { + $sourceEntity = new SourceEntity(); + $inputResource = new InputResource(); + $operation = new Patch(class: TargetResource::class, input: ['class' => InputResource::class], output: ['class' => OutputResource::class], map: true); + $objectMapper = $this->createMock(ObjectMapperInterface::class); + $objectMapper->expects($this->once()) + ->method('map') + ->with($sourceEntity, InputResource::class) + ->willReturn($inputResource); + $decorated = $this->createStub(ProviderInterface::class); + $decorated->method('provide')->willReturn($sourceEntity); + $provider = new ObjectMapperProvider($objectMapper, $decorated); + + $result = $provider->provide($operation); + $this->assertSame($inputResource, $result); + } + + public function testProvideMapsToOutputClassWhenNoInput(): void + { + $sourceEntity = new SourceEntity(); + $outputResource = new OutputResource(); + $operation = new Get(class: TargetResource::class, output: ['class' => OutputResource::class], map: true); + $objectMapper = $this->createMock(ObjectMapperInterface::class); + $objectMapper->expects($this->once()) + ->method('map') + ->with($sourceEntity, OutputResource::class) + ->willReturn($outputResource); + $decorated = $this->createStub(ProviderInterface::class); + $decorated->method('provide')->willReturn($sourceEntity); + $provider = new ObjectMapperProvider($objectMapper, $decorated); + + $result = $provider->provide($operation); + $this->assertSame($outputResource, $result); + } + public function testProvideMapsEmptyArray(): void { $operation = new Get(class: TargetResource::class, map: true); @@ -207,3 +244,13 @@ class TargetResource { public string $name = 'target'; } + +class InputResource +{ + public string $name = 'input'; +} + +class OutputResource +{ + public string $name = 'output'; +}