Skip to content

Commit 2d665c4

Browse files
committed
feat: add a second hook for resource to entity or document transformation
1 parent 8a22893 commit 2d665c4

File tree

8 files changed

+116
-68
lines changed

8 files changed

+116
-68
lines changed

src/Doctrine/Common/State/ModelTransformerLocatorTrait.php

Lines changed: 0 additions & 43 deletions
This file was deleted.

src/Doctrine/Common/State/Options.php

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@ class Options implements OptionsInterface
1919
{
2020
/**
2121
* @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
23+
* @param mixed $fromResourceTransformer experimental callable, typed mixed as we may want a service name in the future
2224
*/
2325
public function __construct(
2426
protected mixed $handleLinks = null,
25-
protected mixed $transformModel = null,
27+
protected mixed $toResourceTransformer = null,
28+
protected mixed $fromResourceTransformer = null,
2629
) {
2730
}
2831

@@ -39,15 +42,28 @@ public function withHandleLinks(mixed $handleLinks): self
3942
return $self;
4043
}
4144

42-
public function getTransformModel(): mixed
45+
public function getToResourceTransformer(): mixed
4346
{
44-
return $this->transformModel;
47+
return $this->toResourceTransformer;
4548
}
4649

47-
public function withTransformModel(mixed $transformModel): self
50+
public function withToResourceTransformer(mixed $toResourceTransformer): self
4851
{
4952
$self = clone $this;
50-
$self->transformModel = $transformModel;
53+
$self->toResourceTransformer = $toResourceTransformer;
54+
55+
return $self;
56+
}
57+
58+
public function getFromResourceTransformer(): mixed
59+
{
60+
return $this->fromResourceTransformer;
61+
}
62+
63+
public function withFromResourceTransformer(mixed $fromResourceTransformer): self
64+
{
65+
$self = clone $this;
66+
$self->fromResourceTransformer = $fromResourceTransformer;
5167

5268
return $self;
5369
}

src/Doctrine/Common/State/PersistProcessor.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ final class PersistProcessor implements ProcessorInterface
2424
{
2525
use ClassInfoTrait;
2626
use LinksHandlerTrait;
27+
use ResourceTransformerLocatorTrait;
2728

2829
public function __construct(private readonly ManagerRegistry $managerRegistry)
2930
{
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <dunglas@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Doctrine\Common\State;
15+
16+
use ApiPlatform\Metadata\Operation;
17+
use Psr\Container\ContainerInterface;
18+
19+
/**
20+
* Maybe merge this and LinksHandlerLocatorTrait into a OptionsHooksLocatorTrait or something similar?
21+
*/
22+
trait ResourceTransformerLocatorTrait
23+
{
24+
private ?ContainerInterface $resourceTransformerLocator;
25+
26+
protected function getToResourceTransformer(Operation $operation): ?callable
27+
{
28+
if (!($options = $operation->getStateOptions()) || !$options instanceof Options) {
29+
return null;
30+
}
31+
32+
$transformer = $options->getToResourceTransformer();
33+
if (\is_callable($transformer)) {
34+
return $transformer;
35+
}
36+
37+
if ($this->resourceTransformerLocator && \is_string($transformer) && $this->resourceTransformerLocator->has($transformer)) {
38+
return [$this->resourceTransformerLocator->get($transformer), 'toResource'];
39+
}
40+
41+
return null;
42+
}
43+
44+
protected function getFromResourceTransformer(Operation $operation): ?callable
45+
{
46+
if (!($options = $operation->getStateOptions()) || !$options instanceof Options) {
47+
return null;
48+
}
49+
50+
$transformer = $options->getFromResourceTransformer();
51+
if (\is_callable($transformer)) {
52+
return $transformer;
53+
}
54+
55+
if ($this->resourceTransformerLocator && \is_string($transformer) && $this->resourceTransformerLocator->has($transformer)) {
56+
return [$this->resourceTransformerLocator->get($transformer), 'fromResource'];
57+
}
58+
59+
return null;
60+
}
61+
}

src/Doctrine/Odm/State/Options.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,16 @@ class Options extends CommonOptions implements OptionsInterface
2020
{
2121
/**
2222
* @param mixed $handleLinks experimental callable, typed mixed as we may want a service name in the future
23-
* @param mixed $transformDocument experimental callable, typed mixed as we may want a service name in the future
23+
* @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 $transformDocument = null,
29+
mixed $handleLinks = null,
30+
mixed $transformFromDocument = null,
3131
) {
32-
parent::__construct(handleLinks: $handleLinks, transformModel: $transformDocument);
32+
parent::__construct(handleLinks: $handleLinks, toResourceTransformer: $transformFromDocument);
3333
}
3434

3535
public function getDocumentClass(): ?string
@@ -47,13 +47,13 @@ public function withDocumentClass(?string $documentClass): self
4747

4848
public function getTransformDocument(): mixed
4949
{
50-
return $this->getTransformModel();
50+
return $this->getToResourceTransformer();
5151
}
5252

5353
public function withTransformDocument(mixed $transformDocument): self
5454
{
5555
$self = clone $this;
56-
$self->transformModel = $transformDocument;
56+
$self->toResourceTransformer = $transformDocument;
5757

5858
return $self;
5959
}

src/Doctrine/Orm/State/Options.php

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,17 @@ class Options extends CommonOptions implements OptionsInterface
2020
{
2121
/**
2222
* @param string|callable $handleLinks experimental callable, typed mixed as we may want a service name in the future
23-
* @param string|callable $transformEntity experimental callable, typed mixed as we may want a service name in the future
23+
* @param string|callable $transformFromEntity 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 $entityClass = null,
29-
mixed $handleLinks = null,
30-
mixed $transformEntity = null,
29+
mixed $handleLinks = null,
30+
mixed $transformFromEntity = null,
31+
mixed $transformToEntity = null,
3132
) {
32-
parent::__construct(handleLinks: $handleLinks, transformModel: $transformEntity);
33+
parent::__construct(handleLinks: $handleLinks, toResourceTransformer: $transformFromEntity, fromResourceTransformer: $transformToEntity);
3334
}
3435

3536
public function getEntityClass(): ?string
@@ -45,16 +46,30 @@ public function withEntityClass(?string $entityClass): self
4546
return $self;
4647
}
4748

48-
public function getTransformDocument(): mixed
49+
public function getTransformFromEntity(): mixed
4950
{
50-
return $this->getTransformModel();
51+
return $this->getToResourceTransformer();
5152
}
5253

53-
public function withTransformDocument(mixed $transformEntity): self
54+
public function withTransformFromEntity(mixed $transformFromEntity): self
5455
{
5556
$self = clone $this;
56-
$self->transformModel = $transformEntity;
57+
$self->toResourceTransformer = $transformFromEntity;
5758

5859
return $self;
5960
}
61+
62+
public function getTransformToEntity(): mixed
63+
{
64+
return $this->getFromResourceTransformer();
65+
}
66+
67+
public function withTransformToEntity(mixed $transformToEntity): self
68+
{
69+
$self = clone $this;
70+
$self->fromResourceTransformer = $transformToEntity;
71+
72+
return $self;
73+
}
74+
6075
}

tests/Fixtures/TestBundle/ApiResource/TransformedDummyDocumentRessource.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
use ApiPlatform\Metadata\Get;
1818
use ApiPlatform\Metadata\GetCollection;
1919
use ApiPlatform\Tests\Fixtures\TestBundle\Document\TransformedDummyDocument;
20-
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\TransformedDummyEntity;
2120

2221
#[ApiResource(
2322
operations : [
@@ -26,7 +25,7 @@
2625
],
2726
stateOptions: new \ApiPlatform\Doctrine\Odm\State\Options(
2827
documentClass: TransformedDummyDocument::class,
29-
transformDocument: [self::class, 'transformModel'],
28+
transformFromDocument: [self::class, 'transformToResource'],
3029
)
3130
)]
3231
class TransformedDummyDocumentRessource
@@ -35,7 +34,7 @@ class TransformedDummyDocumentRessource
3534

3635
public ?int $year = null;
3736

38-
public static function transformModel(TransformedDummyEntity|TransformedDummyDocument $model): self
37+
public static function transformToResource(TransformedDummyDocument $model): self
3938
{
4039
$resource = new self();
4140
$resource->id = $model->getId();

tests/Fixtures/TestBundle/ApiResource/TransformedDummyEntityRessource.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
use ApiPlatform\Metadata\ApiResource;
1818
use ApiPlatform\Metadata\Get;
1919
use ApiPlatform\Metadata\GetCollection;
20-
use ApiPlatform\Tests\Fixtures\TestBundle\Document\TransformedDummyDocument;
2120
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\TransformedDummyEntity;
2221

2322
#[ApiResource(
@@ -27,7 +26,7 @@
2726
],
2827
stateOptions: new Options(
2928
entityClass: TransformedDummyEntity::class,
30-
transformEntity: [self::class, 'transformModel'],
29+
transformFromEntity: [self::class, 'transformToResource'],
3130
)
3231
)]
3332
class TransformedDummyEntityRessource
@@ -36,7 +35,7 @@ class TransformedDummyEntityRessource
3635

3736
public ?int $year = null;
3837

39-
public static function transformModel(TransformedDummyEntity|TransformedDummyDocument $model): self
38+
public static function transformToResource(TransformedDummyEntity $model): self
4039
{
4140
$resource = new self();
4241
$resource->id = $model->getId();

0 commit comments

Comments
 (0)