|
3 | 3 | namespace PHPStan\Type\Doctrine\Descriptors;
|
4 | 4 |
|
5 | 5 | use Doctrine\DBAL\Platforms\AbstractPlatform;
|
| 6 | +use Doctrine\DBAL\Types\Type as DbalType; |
| 7 | +use PHPStan\DependencyInjection\Container; |
6 | 8 | use PHPStan\Reflection\ParametersAcceptorSelector;
|
7 | 9 | use PHPStan\Reflection\ReflectionProvider;
|
| 10 | +use PHPStan\Type\Doctrine\DefaultDescriptorRegistry; |
| 11 | +use PHPStan\Type\Doctrine\DescriptorNotRegisteredException; |
8 | 12 | use PHPStan\Type\MixedType;
|
9 | 13 | use PHPStan\Type\ObjectType;
|
10 | 14 | use PHPStan\Type\Type;
|
|
13 | 17 | class ReflectionDescriptor implements DoctrineTypeDescriptor
|
14 | 18 | {
|
15 | 19 |
|
16 |
| - /** @var class-string<\Doctrine\DBAL\Types\Type> */ |
| 20 | + /** @var class-string<DbalType> */ |
17 | 21 | private $type;
|
18 | 22 |
|
19 | 23 | /** @var ReflectionProvider */
|
20 | 24 | private $reflectionProvider;
|
21 | 25 |
|
| 26 | + /** @var Container */ |
| 27 | + private $container; |
| 28 | + |
22 | 29 | /**
|
23 |
| - * @param class-string<\Doctrine\DBAL\Types\Type> $type |
| 30 | + * @param class-string<DbalType> $type |
24 | 31 | */
|
25 |
| - public function __construct(string $type, ReflectionProvider $reflectionProvider) |
| 32 | + public function __construct( |
| 33 | + string $type, |
| 34 | + ReflectionProvider $reflectionProvider, |
| 35 | + Container $container |
| 36 | + ) |
26 | 37 | {
|
27 | 38 | $this->type = $type;
|
28 | 39 | $this->reflectionProvider = $reflectionProvider;
|
| 40 | + $this->container = $container; |
29 | 41 | }
|
30 | 42 |
|
31 | 43 | public function getType(): string
|
@@ -57,6 +69,24 @@ public function getWritableToDatabaseType(): Type
|
57 | 69 |
|
58 | 70 | public function getDatabaseInternalType(): Type
|
59 | 71 | {
|
| 72 | + if (!$this->reflectionProvider->hasClass($this->type)) { |
| 73 | + return new MixedType(); |
| 74 | + } |
| 75 | + |
| 76 | + $registry = $this->container->getByType(DefaultDescriptorRegistry::class); |
| 77 | + $parents = $this->reflectionProvider->getClass($this->type)->getParentClassesNames(); |
| 78 | + |
| 79 | + foreach ($parents as $dbalTypeParentClass) { |
| 80 | + try { |
| 81 | + // this assumes that if somebody inherits from DecimalType, |
| 82 | + // the real database type remains decimal and we can reuse its descriptor |
| 83 | + return $registry->getByClassName($dbalTypeParentClass)->getDatabaseInternalType(); |
| 84 | + |
| 85 | + } catch (DescriptorNotRegisteredException $e) { |
| 86 | + continue; |
| 87 | + } |
| 88 | + } |
| 89 | + |
60 | 90 | return new MixedType();
|
61 | 91 | }
|
62 | 92 |
|
|
0 commit comments