Skip to content

Commit d9fd95a

Browse files
authored
Merge pull request #16 from 21TORR/doctrine-deprecation
Avoid using deprecated doctrine helpers for resolving classes
2 parents a788b8a + 977c6bd commit d9fd95a

5 files changed

Lines changed: 158 additions & 25 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
1.4.1
2+
=====
3+
4+
* (improvement) Avoid using deprecated Doctrine internals when resolving class names.
5+
6+
17
1.4.0
28
=====
39

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"require-dev": {
2020
"21torr/janus": "^1.5.1",
2121
"bamarni/composer-bin-plugin": "^1.8.2",
22-
"doctrine/common": "^3.5",
22+
"doctrine/orm": "^3.0",
2323
"phpunit/phpunit": "^12.2.5",
2424
"roave/security-advisories": "dev-latest"
2525
},

src/Normalizer/SimpleNormalizer.php

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
namespace Torr\SimpleNormalizer\Normalizer;
44

5-
use Doctrine\Common\Util\ClassUtils;
5+
use Doctrine\ORM\EntityManagerInterface;
6+
use Doctrine\ORM\Mapping\ClassMetadataFactory;
67
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
78
use Symfony\Component\DependencyInjection\ServiceLocator;
89
use Torr\SimpleNormalizer\Exception\ObjectTypeNotSupportedException;
@@ -23,14 +24,20 @@
2324
*/
2425
class SimpleNormalizer
2526
{
27+
private readonly ?ClassMetadataFactory $doctrineMetadata;
28+
2629
/**
2730
* @param ServiceLocator<SimpleObjectNormalizerInterface> $objectNormalizers
2831
*/
2932
public function __construct (
3033
private readonly ServiceLocator $objectNormalizers,
3134
private readonly bool $isDebug = false,
3235
private readonly ?ValidJsonVerifier $validJsonVerifier = null,
33-
) {}
36+
?EntityManagerInterface $entityManager = null,
37+
)
38+
{
39+
$this->doctrineMetadata = $entityManager?->getMetadataFactory();
40+
}
3441

3542
/**
3643
*/
@@ -104,12 +111,7 @@ private function recursiveNormalize (mixed $value, array $context = []) : mixed
104111

105112
try
106113
{
107-
$className = $value::class;
108-
109-
if (class_exists(ClassUtils::class))
110-
{
111-
$className = ClassUtils::getRealClass($className);
112-
}
114+
$className = $this->normalizeClassName($value::class);
113115

114116
$normalizer = $this->objectNormalizers->get($className);
115117
\assert($normalizer instanceof SimpleObjectNormalizerInterface);
@@ -131,6 +133,26 @@ private function recursiveNormalize (mixed $value, array $context = []) : mixed
131133
));
132134
}
133135

136+
/**
137+
* Normalizes the class name
138+
*
139+
* @param class-string $className
140+
*
141+
* @return class-string
142+
*/
143+
private function normalizeClassName (string $className) : string
144+
{
145+
// if there is no doctrine, just return
146+
if (null === $this->doctrineMetadata)
147+
{
148+
return $className;
149+
}
150+
151+
return $this->doctrineMetadata->hasMetadataFor($className)
152+
? $this->doctrineMetadata->getMetadataFor($className)->getName()
153+
: $className;
154+
}
155+
134156
/**
135157
* The actual customized normalization logic for arrays, that recursively normalizes the value.
136158
* It must never call one of the public methods above and just normalizes the value.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Tests\Torr\SimpleNormalizer\Fixture;
4+
5+
use Torr\SimpleNormalizer\Normalizer\SimpleNormalizer;
6+
use Torr\SimpleNormalizer\Normalizer\SimpleObjectNormalizerInterface;
7+
8+
/**
9+
* @final
10+
*/
11+
readonly class DummyVONormalizer implements SimpleObjectNormalizerInterface
12+
{
13+
public function __construct (
14+
private mixed $returnValue = null,
15+
) {}
16+
17+
public function normalize (object $value, array $context, SimpleNormalizer $normalizer) : mixed
18+
{
19+
return $this->returnValue;
20+
}
21+
22+
public static function getNormalizedType () : string
23+
{
24+
return DummyVO::class;
25+
}
26+
}

tests/Normalizer/SimpleNormalizerTest.php

Lines changed: 95 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22

33
namespace Tests\Torr\SimpleNormalizer\Normalizer;
44

5+
use Doctrine\ORM\EntityManagerInterface;
6+
use Doctrine\ORM\Mapping\ClassMetadata;
7+
use Doctrine\ORM\Mapping\ClassMetadataFactory;
58
use PHPUnit\Framework\Attributes\DataProvider;
69
use PHPUnit\Framework\TestCase;
710
use Symfony\Component\DependencyInjection\ServiceLocator;
811
use Tests\Torr\SimpleNormalizer\Fixture\DummyVO;
12+
use Tests\Torr\SimpleNormalizer\Fixture\DummyVONormalizer;
913
use Torr\SimpleNormalizer\Exception\IncompleteNormalizationException;
1014
use Torr\SimpleNormalizer\Normalizer\SimpleNormalizer;
11-
use Torr\SimpleNormalizer\Normalizer\SimpleObjectNormalizerInterface;
1215
use Torr\SimpleNormalizer\Normalizer\Validator\ValidJsonVerifier;
1316

1417
/**
@@ -124,27 +127,103 @@ public function testInvalidNestedNormalizer () : void
124127
]);
125128
}
126129

130+
/**
131+
*/
132+
public function testWithoutEntityManager () : void
133+
{
134+
$locator = $this->createMock(ServiceLocator::class);
135+
136+
$locator->expects(self::once())
137+
->method("get")
138+
->with(DummyVO::class)
139+
->willReturn(new DummyVONormalizer(5));
140+
141+
$normalizer = new SimpleNormalizer(
142+
objectNormalizers: $locator,
143+
isDebug: true,
144+
validJsonVerifier: new ValidJsonVerifier(),
145+
);
146+
147+
$normalizer->normalize(new DummyVO(5));
148+
}
149+
150+
/**
151+
*/
152+
public function testWithEntityManagerButNoMapping () : void
153+
{
154+
$metadataFactory = $this->createMock(ClassMetadataFactory::class);
155+
$metadataFactory
156+
->expects(self::once())
157+
->method("hasMetadataFor")
158+
->with(DummyVO::class)
159+
->willReturn(false);
160+
161+
$entityManager = $this->createMock(EntityManagerInterface::class);
162+
$entityManager->method("getMetadataFactory")->willReturn($metadataFactory);
163+
164+
$locator = $this->createMock(ServiceLocator::class);
165+
166+
$locator->expects(self::once())
167+
->method("get")
168+
->with(DummyVO::class)
169+
->willReturn(new DummyVONormalizer(5));
170+
171+
$normalizer = new SimpleNormalizer(
172+
objectNormalizers: $locator,
173+
isDebug: true,
174+
validJsonVerifier: new ValidJsonVerifier(),
175+
entityManager: $entityManager,
176+
);
177+
178+
$normalizer->normalize(new DummyVO(5));
179+
}
180+
181+
/**
182+
*/
183+
public function testWithEntityManagerWithMapping () : void
184+
{
185+
$classMetaData = new ClassMetadata("SomeClass");
186+
187+
$metadataFactory = $this->createMock(ClassMetadataFactory::class);
188+
$metadataFactory
189+
->expects(self::once())
190+
->method("hasMetadataFor")
191+
->with(DummyVO::class)
192+
->willReturn(true);
193+
194+
$metadataFactory
195+
->expects(self::once())
196+
->method("getMetadataFor")
197+
->with(DummyVO::class)
198+
->willReturn($classMetaData);
199+
200+
$entityManager = $this->createMock(EntityManagerInterface::class);
201+
$entityManager->method("getMetadataFactory")->willReturn($metadataFactory);
202+
203+
$locator = $this->createMock(ServiceLocator::class);
204+
205+
$locator->expects(self::once())
206+
->method("get")
207+
->with("SomeClass")
208+
->willReturn(new DummyVONormalizer(5));
209+
210+
$normalizer = new SimpleNormalizer(
211+
objectNormalizers: $locator,
212+
isDebug: true,
213+
validJsonVerifier: new ValidJsonVerifier(),
214+
entityManager: $entityManager,
215+
);
216+
217+
$normalizer->normalize(new DummyVO(5));
218+
}
219+
127220
/**
128221
* @return ServiceLocator<mixed>
129222
*/
130223
private function createNormalizerObjectNormalizers (mixed $returnValue) : ServiceLocator
131224
{
132225
return new ServiceLocator([
133-
DummyVO::class => static fn () => new readonly class($returnValue) implements SimpleObjectNormalizerInterface {
134-
public function __construct (
135-
private mixed $returnValue,
136-
) {}
137-
138-
public function normalize (object $value, array $context, SimpleNormalizer $normalizer) : mixed
139-
{
140-
return $this->returnValue;
141-
}
142-
143-
public static function getNormalizedType () : string
144-
{
145-
return DummyVO::class;
146-
}
147-
},
226+
DummyVO::class => static fn () => new DummyVONormalizer($returnValue),
148227
]);
149228
}
150229
}

0 commit comments

Comments
 (0)