Skip to content

Commit f2173c3

Browse files
committed
feat: use fromResourceTransformer in PersistProcessor
1 parent 2d665c4 commit f2173c3

File tree

12 files changed

+87
-31
lines changed

12 files changed

+87
-31
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@
135135
"friends-of-behat/mink-browserkit-driver": "^1.3.1",
136136
"friends-of-behat/mink-extension": "^2.2",
137137
"friends-of-behat/symfony-extension": "^2.1",
138+
"friendsofphp/php-cs-fixer": "^3.84",
138139
"guzzlehttp/guzzle": "^6.0 || ^7.0",
139140
"illuminate/config": "^11.0 || ^12.0",
140141
"illuminate/contracts": "^11.0 || ^12.0",

features/doctrine/transform_model.feature

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,49 @@ Feature: Use an entity or document transformer to return the correct ressource
22

33
@createSchema
44
@!mongodb
5-
Scenario: Get collection from entities
5+
Scenario: Get transformed collection from entities
66
Given there is a TransformedDummy for date '2025-01-01'
77
When I send a "GET" request to "/transformed_dummy_entity_ressources"
88
Then the response status code should be 200
99
And the response should be in JSON
1010
And the JSON node "hydra:totalItems" should be equal to 1
1111

1212
@!mongodb
13-
Scenario: Get item from entity
13+
Scenario: Get transform item from entity
1414
Given there is a TransformedDummy for date '2025-01-01'
1515
When I send a "GET" request to "/transformed_dummy_entity_ressources/1"
1616
Then the response status code should be 200
1717
And the response should be in JSON
1818
And the JSON node "year" should exist
1919
And the JSON node year should be equal to "2025"
2020

21+
@!mongodb
22+
Scenario: Post new entity from transformed resource
23+
Given I add "Content-type" header equal to "application/ld+json"
24+
When I send a "POST" request to "/transformed_dummy_entity_ressources" with body:
25+
"""
26+
{
27+
"year" : 2020
28+
}
29+
"""
30+
Then the response status code should be 201
31+
And the response should be in JSON
32+
And the JSON node "year" should be equal to "2020"
33+
34+
@!mongodb
35+
Scenario: Patch entity from transformed resource
36+
Given there is a TransformedDummy for date '2025-01-01'
37+
And I add "Content-type" header equal to "application/merge-patch+json"
38+
When I send a "PATCH" request to "/transformed_dummy_entity_ressources/1" with body:
39+
"""
40+
{
41+
"year" : 2020
42+
}
43+
"""
44+
Then the response status code should be 200
45+
And the response should be in JSON
46+
And the JSON node "year" should be equal to "2020"
47+
2148
@createSchema
2249
@mongodb
2350
Scenario: Get collection from documents

features/hydra/error.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Feature: Error handling
1616
And the header "Content-Type" should be equal to "application/problem+json; charset=utf-8"
1717
And the header "Link" should contain '<http://www.w3.org/ns/hydra/error>; rel="http://www.w3.org/ns/json-ld#error"'
1818
And the JSON node "type" should exist
19-
And the JSON node "title" should not exists
19+
And the JSON node "title" should not exist
2020
And the JSON node "hydra:title" should be equal to "An error occurred"
2121
And the JSON node "detail" should exist
2222
And the JSON node "description" should not exist

src/Doctrine/Common/State/Options.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
class Options implements OptionsInterface
1919
{
2020
/**
21-
* @param mixed $handleLinks experimental callable, typed mixed as we may want a service name in the future
22-
* @param mixed $toResourceTransformer experimental callable, typed mixed as we may want a service name in the future
21+
* @param mixed $handleLinks experimental callable, typed mixed as we may want a service name in the future
22+
* @param mixed $toResourceTransformer experimental callable, typed mixed as we may want a service name in the future
2323
* @param mixed $fromResourceTransformer experimental callable, typed mixed as we may want a service name in the future
2424
*/
2525
public function __construct(

src/Doctrine/Common/State/PersistProcessor.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,17 @@
1919
use ApiPlatform\State\ProcessorInterface;
2020
use Doctrine\Persistence\ManagerRegistry;
2121
use Doctrine\Persistence\ObjectManager as DoctrineObjectManager;
22+
use Psr\Container\ContainerInterface;
2223

2324
final class PersistProcessor implements ProcessorInterface
2425
{
2526
use ClassInfoTrait;
2627
use LinksHandlerTrait;
2728
use ResourceTransformerLocatorTrait;
2829

29-
public function __construct(private readonly ManagerRegistry $managerRegistry)
30+
public function __construct(private readonly ManagerRegistry $managerRegistry, ?ContainerInterface $handleLinksLocator = null)
3031
{
32+
$this->resourceTransformerLocator = $handleLinksLocator;
3133
}
3234

3335
/**
@@ -39,6 +41,12 @@ public function __construct(private readonly ManagerRegistry $managerRegistry)
3941
*/
4042
public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): mixed
4143
{
44+
// if a transformer is defined, start with that
45+
$data = match ($transformer = $this->getFromResourceTransformer($operation)) {
46+
null => $data,
47+
default => $transformer($data),
48+
};
49+
4250
if (
4351
!\is_object($data)
4452
|| !$manager = $this->managerRegistry->getManagerForClass($class = $this->getObjectClass($data))
@@ -105,7 +113,10 @@ public function process(mixed $data, Operation $operation, array $uriVariables =
105113
$manager->flush();
106114
$manager->refresh($data);
107115

108-
return $data;
116+
return match ($transformer = $this->getToResourceTransformer($operation)) {
117+
null => $data,
118+
default => $transformer($data, $operation, $uriVariables, $context),
119+
};
109120
}
110121

111122
/**

src/Doctrine/Odm/State/CollectionProvider.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
namespace ApiPlatform\Doctrine\Odm\State;
1515

1616
use ApiPlatform\Doctrine\Common\State\LinksHandlerLocatorTrait;
17-
use ApiPlatform\Doctrine\Common\State\ModelTransformerLocatorTrait;
17+
use ApiPlatform\Doctrine\Common\State\ResourceTransformerLocatorTrait;
1818
use ApiPlatform\Doctrine\Odm\Extension\AggregationCollectionExtensionInterface;
1919
use ApiPlatform\Doctrine\Odm\Extension\AggregationResultCollectionExtensionInterface;
2020
use ApiPlatform\Metadata\Exception\RuntimeException;
@@ -34,7 +34,7 @@ final class CollectionProvider implements ProviderInterface
3434
{
3535
use LinksHandlerLocatorTrait;
3636
use LinksHandlerTrait;
37-
use ModelTransformerLocatorTrait;
37+
use ResourceTransformerLocatorTrait;
3838
use StateOptionsTrait;
3939

4040
/**
@@ -44,7 +44,7 @@ public function __construct(ResourceMetadataCollectionFactoryInterface $resource
4444
{
4545
$this->resourceMetadataCollectionFactory = $resourceMetadataCollectionFactory;
4646
$this->handleLinksLocator = $handleLinksLocator;
47-
$this->transformEntityLocator = $handleLinksLocator;
47+
$this->resourceTransformerLocator = $handleLinksLocator;
4848
$this->managerRegistry = $managerRegistry;
4949
}
5050

@@ -82,7 +82,7 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
8282

8383
$result = $result ?? $aggregationBuilder->hydrate($documentClass)->getAggregation($executeOptions)->getIterator();
8484

85-
return match ($transformer = $this->getEntityTransformer($operation)) {
85+
return match ($transformer = $this->getToResourceTransformer($operation)) {
8686
null => $result,
8787
default => array_map($transformer, iterator_to_array($result)),
8888
};

src/Doctrine/Odm/State/ItemProvider.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
namespace ApiPlatform\Doctrine\Odm\State;
1515

1616
use ApiPlatform\Doctrine\Common\State\LinksHandlerLocatorTrait;
17-
use ApiPlatform\Doctrine\Common\State\ModelTransformerLocatorTrait;
17+
use ApiPlatform\Doctrine\Common\State\ResourceTransformerLocatorTrait;
1818
use ApiPlatform\Doctrine\Odm\Extension\AggregationItemExtensionInterface;
1919
use ApiPlatform\Doctrine\Odm\Extension\AggregationResultItemExtensionInterface;
2020
use ApiPlatform\Metadata\Exception\RuntimeException;
@@ -37,8 +37,8 @@ final class ItemProvider implements ProviderInterface
3737
{
3838
use LinksHandlerLocatorTrait;
3939
use LinksHandlerTrait;
40+
use ResourceTransformerLocatorTrait;
4041
use StateOptionsTrait;
41-
use ModelTransformerLocatorTrait;
4242

4343
/**
4444
* @param AggregationItemExtensionInterface[] $itemExtensions
@@ -47,7 +47,7 @@ public function __construct(ResourceMetadataCollectionFactoryInterface $resource
4747
{
4848
$this->resourceMetadataCollectionFactory = $resourceMetadataCollectionFactory;
4949
$this->handleLinksLocator = $handleLinksLocator;
50-
$this->transformEntityLocator = $handleLinksLocator;
50+
$this->resourceTransformerLocator = $handleLinksLocator;
5151
$this->managerRegistry = $managerRegistry;
5252
}
5353

@@ -89,7 +89,7 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
8989

9090
$result = $result ?? ($aggregationBuilder->hydrate($documentClass)->getAggregation($executeOptions)->getIterator()->current() ?: null);
9191

92-
return match ($transformer = $this->getEntityTransformer($operation)) {
92+
return match ($transformer = $this->getToResourceTransformer($operation)) {
9393
null => $result,
9494
default => (null !== $result) ? $transformer($result) : null,
9595
};

src/Doctrine/Odm/State/Options.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@
1919
class Options extends CommonOptions implements OptionsInterface
2020
{
2121
/**
22-
* @param mixed $handleLinks experimental callable, typed mixed as we may want a service name in the future
22+
* @param mixed $handleLinks experimental callable, typed mixed as we may want a service name in the future
2323
* @param mixed $transformFromDocument experimental callable, typed mixed as we may want a service name in the future
2424
*
2525
* @see LinksHandlerInterface
2626
*/
2727
public function __construct(
2828
protected ?string $documentClass = null,
29-
mixed $handleLinks = null,
30-
mixed $transformFromDocument = null,
29+
mixed $handleLinks = null,
30+
mixed $transformFromDocument = null,
3131
) {
3232
parent::__construct(handleLinks: $handleLinks, toResourceTransformer: $transformFromDocument);
3333
}

src/Doctrine/Orm/State/CollectionProvider.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
namespace ApiPlatform\Doctrine\Orm\State;
1515

1616
use ApiPlatform\Doctrine\Common\State\LinksHandlerLocatorTrait;
17-
use ApiPlatform\Doctrine\Common\State\ModelTransformerLocatorTrait;
17+
use ApiPlatform\Doctrine\Common\State\ResourceTransformerLocatorTrait;
1818
use ApiPlatform\Doctrine\Orm\Extension\QueryCollectionExtensionInterface;
1919
use ApiPlatform\Doctrine\Orm\Extension\QueryResultCollectionExtensionInterface;
2020
use ApiPlatform\Doctrine\Orm\Util\QueryNameGenerator;
@@ -37,7 +37,7 @@ final class CollectionProvider implements ProviderInterface
3737
{
3838
use LinksHandlerLocatorTrait;
3939
use LinksHandlerTrait;
40-
use ModelTransformerLocatorTrait;
40+
use ResourceTransformerLocatorTrait;
4141
use StateOptionsTrait;
4242

4343
/**
@@ -47,7 +47,7 @@ public function __construct(ResourceMetadataCollectionFactoryInterface $resource
4747
{
4848
$this->resourceMetadataCollectionFactory = $resourceMetadataCollectionFactory;
4949
$this->handleLinksLocator = $handleLinksLocator;
50-
$this->transformEntityLocator = $handleLinksLocator;
50+
$this->resourceTransformerLocator = $handleLinksLocator;
5151
$this->managerRegistry = $managerRegistry;
5252
}
5353

@@ -83,7 +83,7 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
8383

8484
$result = $result ?? $queryBuilder->getQuery()->getResult();
8585

86-
return match ($transformer = $this->getEntityTransformer($operation)) {
86+
return match ($transformer = $this->getToResourceTransformer($operation)) {
8787
null => $result,
8888
default => array_map($transformer, iterator_to_array($result)),
8989
};

src/Doctrine/Orm/State/ItemProvider.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
namespace ApiPlatform\Doctrine\Orm\State;
1515

1616
use ApiPlatform\Doctrine\Common\State\LinksHandlerLocatorTrait;
17-
use ApiPlatform\Doctrine\Common\State\ModelTransformerLocatorTrait;
17+
use ApiPlatform\Doctrine\Common\State\ResourceTransformerLocatorTrait;
1818
use ApiPlatform\Doctrine\Orm\Extension\QueryItemExtensionInterface;
1919
use ApiPlatform\Doctrine\Orm\Extension\QueryResultItemExtensionInterface;
2020
use ApiPlatform\Doctrine\Orm\Util\QueryNameGenerator;
@@ -37,8 +37,8 @@ final class ItemProvider implements ProviderInterface
3737
{
3838
use LinksHandlerLocatorTrait;
3939
use LinksHandlerTrait;
40+
use ResourceTransformerLocatorTrait;
4041
use StateOptionsTrait;
41-
use ModelTransformerLocatorTrait;
4242

4343
/**
4444
* @param QueryItemExtensionInterface[] $itemExtensions
@@ -47,7 +47,7 @@ public function __construct(ResourceMetadataCollectionFactoryInterface $resource
4747
{
4848
$this->resourceMetadataCollectionFactory = $resourceMetadataCollectionFactory;
4949
$this->handleLinksLocator = $handleLinksLocator;
50-
$this->transformEntityLocator = $handleLinksLocator;
50+
$this->resourceTransformerLocator = $handleLinksLocator;
5151
$this->managerRegistry = $managerRegistry;
5252
}
5353

@@ -92,7 +92,7 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
9292

9393
$result = $result ?? $queryBuilder->getQuery()->getOneOrNullResult();
9494

95-
return match ($transformer = $this->getEntityTransformer($operation)) {
95+
return match ($transformer = $this->getToResourceTransformer($operation)) {
9696
null => $result,
9797
default => $transformer($result),
9898
};

0 commit comments

Comments
 (0)