Skip to content

Commit b118556

Browse files
committed
fix some tests
1 parent 330d2ba commit b118556

File tree

5 files changed

+138
-9
lines changed

5 files changed

+138
-9
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@
165165
"symfony/cache": "^6.4 || ^7.0",
166166
"symfony/config": "^6.4 || ^7.0",
167167
"symfony/console": "^6.4 || ^7.0",
168-
"symfony/object-mapper": "^7.3",
169168
"symfony/css-selector": "^6.4 || ^7.0",
170169
"symfony/dependency-injection": "^6.4 || ^7.0",
171170
"symfony/doctrine-bridge": "^6.4.2 || ^7.1",
@@ -181,6 +180,7 @@
181180
"symfony/maker-bundle": "^1.24",
182181
"symfony/mercure-bundle": "*",
183182
"symfony/messenger": "^6.4 || ^7.0",
183+
"symfony/object-mapper": "^7.3",
184184
"symfony/routing": "^6.4 || ^7.0",
185185
"symfony/security-bundle": "^6.4 || ^7.0",
186186
"symfony/security-core": "^6.4 || ^7.0",

src/State/Provider/ObjectMapperProvider.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use ApiPlatform\Doctrine\Odm\State\Options as OdmOptions;
1717
use ApiPlatform\Doctrine\Orm\State\Options;
1818
use ApiPlatform\Metadata\Operation;
19+
use ApiPlatform\Metadata\Util\CloneTrait;
1920
use ApiPlatform\State\Pagination\ArrayPaginator;
2021
use ApiPlatform\State\Pagination\PaginatorInterface;
2122
use ApiPlatform\State\ProviderInterface;
@@ -27,6 +28,8 @@
2728
*/
2829
final class ObjectMapperProvider implements ProviderInterface
2930
{
31+
use CloneTrait;
32+
3033
/**
3134
* @param ProviderInterface<mixed> $decorated
3235
*/
@@ -40,7 +43,7 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
4043
{
4144
$data = $this->decorated->provide($operation, $uriVariables, $context);
4245

43-
if (!\is_object($data)) {
46+
if (!\is_object($data) || !($request = $context['request'] ?? null)) {
4447
return $data;
4548
}
4649

@@ -53,14 +56,21 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
5356
$entityClass = $options->getDocumentClass();
5457
}
5558

56-
if (!$entityClass || !(new \ReflectionClass($entityClass))->getAttributes(Map::class)) {
59+
$entityClass ??= $data::class;
60+
61+
if (!(new \ReflectionClass($entityClass))->getAttributes(Map::class)) {
5762
return $data;
5863
}
5964

6065
if ($data instanceof PaginatorInterface) {
61-
return new ArrayPaginator(array_map(fn ($v) => $this->objectMapper->map($v), iterator_to_array($data)), 0, \count($data));
66+
$data = new ArrayPaginator(array_map(fn ($v) => $this->objectMapper->map($v), iterator_to_array($data)), 0, \count($data));
67+
} else {
68+
$data = $this->objectMapper->map($data);
6269
}
6370

64-
return $this->objectMapper->map($data);
71+
$request?->attributes->set('data', $data);
72+
$request?->attributes->set('previous_data', $this->clone($data));
73+
74+
return $data;
6575
}
6676
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
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\Tests\Fixtures\TestBundle\ApiResource;
15+
16+
use ApiPlatform\Doctrine\Odm\State\Options;
17+
use ApiPlatform\JsonLd\ContextBuilder;
18+
use ApiPlatform\Metadata\ApiResource;
19+
use ApiPlatform\Tests\Fixtures\TestBundle\Document\MappedDocument;
20+
use Symfony\Component\ObjectMapper\Attribute\Map;
21+
22+
#[ApiResource(
23+
stateOptions: new Options(documentClass: MappedDocument::class),
24+
normalizationContext: [ContextBuilder::HYDRA_CONTEXT_HAS_PREFIX => false],
25+
)]
26+
#[Map(target: MappedDocument::class)]
27+
final class MappedResourceOdm
28+
{
29+
#[Map(if: false)]
30+
public ?string $id = null;
31+
32+
#[Map(target: 'firstName', transform: [self::class, 'toFirstName'])]
33+
#[Map(target: 'lastName', transform: [self::class, 'toLastName'])]
34+
public string $username;
35+
36+
public static function toFirstName(string $v): string
37+
{
38+
return explode(' ', $v)[0] ?? null;
39+
}
40+
41+
public static function toLastName(string $v): string
42+
{
43+
return explode(' ', $v)[1] ?? null;
44+
}
45+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
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\Tests\Fixtures\TestBundle\Document;
15+
16+
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\MappedResource;
17+
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
18+
use Symfony\Component\ObjectMapper\Attribute\Map;
19+
20+
/**
21+
* MappedEntity to MappedResource.
22+
*/
23+
#[ODM\Document]
24+
#[Map(target: MappedResource::class)]
25+
class MappedDocument
26+
{
27+
#[ODM\Id(strategy: 'INCREMENT', type: 'int')]
28+
private ?int $id = null;
29+
30+
#[ODM\Field]
31+
#[Map(if: false)]
32+
private string $firstName;
33+
34+
#[Map(target: 'username', transform: [self::class, 'toUsername'])]
35+
#[ODM\Field]
36+
private string $lastName;
37+
38+
public static function toUsername($value, $object): string
39+
{
40+
return $object->getFirstName().' '.$object->getLastName();
41+
}
42+
43+
public function getId(): ?int
44+
{
45+
return $this->id;
46+
}
47+
48+
public function setLastName(string $name): void
49+
{
50+
$this->lastName = $name;
51+
}
52+
53+
public function getLastName(): string
54+
{
55+
return $this->lastName;
56+
}
57+
58+
public function setFirstName(string $name): void
59+
{
60+
$this->firstName = $name;
61+
}
62+
63+
public function getFirstName(): string
64+
{
65+
return $this->firstName;
66+
}
67+
}

tests/Functional/MappingTest.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,12 @@
1515

1616
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
1717
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\MappedResource;
18+
use ApiPlatform\Tests\Fixtures\TestBundle\Document\MappedDocument;
1819
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\MappedEntity;
1920
use ApiPlatform\Tests\RecreateSchemaTrait;
2021
use ApiPlatform\Tests\SetupClassResourcesTrait;
22+
use Doctrine\ODM\MongoDB\DocumentManager;
23+
use Symfony\Component\ObjectMapper\ObjectMapper;
2124

2225
final class MappingTest extends ApiTestCase
2326
{
@@ -35,20 +38,24 @@ public static function getResources(): array
3538

3639
public function testShouldMapBetweenResourceAndEntity(): void
3740
{
41+
if (!class_exists(ObjectMapper::class)) {
42+
$this->markTestSkipped('ObjectMapper not installed');
43+
}
44+
3845
$this->recreateSchema([MappedEntity::class]);
3946
$this->loadFixtures();
40-
self::createClient()->request('GET', 'mapped_resources');
47+
self::createClient()->request('GET', $this->isMongoDB() ? 'mapped_resources_odm' : 'mapped_resources');
4148
$this->assertJsonContains(['member' => [
4249
['username' => 'B0 A0'],
4350
['username' => 'B1 A1'],
4451
['username' => 'B2 A2'],
4552
]]);
4653

47-
$r = self::createClient()->request('POST', 'mapped_resources', ['json' => ['username' => 'so yuka']]);
54+
$r = self::createClient()->request('POST', $this->isMongoDB() ? 'mapped_resources_odm' : 'mapped_resources', ['json' => ['username' => 'so yuka']]);
4855
$this->assertJsonContains(['username' => 'so yuka']);
4956

5057
$manager = $this->getManager();
51-
$repo = $manager->getRepository(MappedEntity::class);
58+
$repo = $manager->getRepository($this->isMongoDB() ? MappedDocument::class : MappedEntity::class);
5259
$persisted = $repo->findOneBy(['id' => $r->toArray()['id']]);
5360
$this->assertSame('so', $persisted->getFirstName());
5461
$this->assertSame('yuka', $persisted->getLastName());
@@ -66,7 +73,7 @@ private function loadFixtures(): void
6673
$manager = $this->getManager();
6774

6875
for ($i = 0; $i < 10; ++$i) {
69-
$e = new MappedEntity();
76+
$e = $manager instanceof DocumentManager ? new MappedDocument() : new MappedEntity();
7077
$e->setLastName('A'.$i);
7178
$e->setFirstName('B'.$i);
7279
$manager->persist($e);

0 commit comments

Comments
 (0)