Skip to content

Commit 0cb27d7

Browse files
lookymanondrejmirtes
authored andcommitted
Added ReflectionDescriptor for properly annotated custom types
1 parent 0cd4856 commit 0cb27d7

File tree

4 files changed

+123
-0
lines changed

4 files changed

+123
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Type\Doctrine\Descriptors;
4+
5+
use PHPStan\Broker\Broker;
6+
use PHPStan\Reflection\ParametersAcceptorSelector;
7+
use PHPStan\Type\Type;
8+
9+
class ReflectionDescriptor implements DoctrineTypeDescriptor
10+
{
11+
12+
/** @var string */
13+
private $type;
14+
15+
/** @var \PHPStan\Broker\Broker */
16+
private $broker;
17+
18+
public function __construct(string $type, Broker $broker)
19+
{
20+
$this->type = $type;
21+
$this->broker = $broker;
22+
}
23+
24+
public function getType(): string
25+
{
26+
return $this->type;
27+
}
28+
29+
public function getWritableToPropertyType(): Type
30+
{
31+
return ParametersAcceptorSelector::selectSingle($this->broker->getClass((['Doctrine\DBAL\Types\Type', 'getTypesMap'])()[$this->type])->getNativeMethod('convertToPHPValue')->getVariants())->getReturnType();
32+
}
33+
34+
public function getWritableToDatabaseType(): Type
35+
{
36+
return ParametersAcceptorSelector::selectSingle($this->broker->getClass((['Doctrine\DBAL\Types\Type', 'getTypesMap'])()[$this->type])->getNativeMethod('convertToDatabaseValue')->getVariants())->getParameters()[0]->getType();
37+
}
38+
39+
}

tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php

+21
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Rules\Doctrine\ORM;
44

5+
use Doctrine\DBAL\Types\Type;
56
use Iterator;
67
use PHPStan\Rules\Rule;
78
use PHPStan\Testing\RuleTestCase;
@@ -10,6 +11,7 @@
1011
use PHPStan\Type\Doctrine\Descriptors\BinaryType;
1112
use PHPStan\Type\Doctrine\Descriptors\DateTimeImmutableType;
1213
use PHPStan\Type\Doctrine\Descriptors\DateTimeType;
14+
use PHPStan\Type\Doctrine\Descriptors\ReflectionDescriptor;
1315
use PHPStan\Type\Doctrine\Descriptors\StringType;
1416
use PHPStan\Type\Doctrine\ObjectMetadataResolver;
1517

@@ -18,6 +20,10 @@ class EntityColumnRuleTest extends RuleTestCase
1820

1921
protected function getRule(): Rule
2022
{
23+
if (!Type::hasType(CustomType::NAME)) {
24+
Type::addType(CustomType::NAME, CustomType::class);
25+
}
26+
2127
return new EntityColumnRule(
2228
new ObjectMetadataResolver(__DIR__ . '/entity-manager.php', null),
2329
new DescriptorRegistry([
@@ -26,6 +32,7 @@ protected function getRule(): Rule
2632
new DateTimeType(),
2733
new DateTimeImmutableType(),
2834
new BinaryType(),
35+
new ReflectionDescriptor(CustomType::NAME, $this->createBroker()),
2936
])
3037
);
3138
}
@@ -94,4 +101,18 @@ public function generatedIdsProvider(): Iterator
94101
yield 'nullable both' => [__DIR__ . '/data/GeneratedIdEntity4.php', []];
95102
}
96103

104+
public function testCustomType(): void
105+
{
106+
$this->analyse([__DIR__ . '/data/EntityWithCustomType.php'], [
107+
[
108+
'Property PHPStan\Rules\Doctrine\ORM\EntityWithCustomType::$foo type mapping mismatch: database can contain DateTimeInterface but property expects int.',
109+
24,
110+
],
111+
[
112+
'Property PHPStan\Rules\Doctrine\ORM\EntityWithCustomType::$foo type mapping mismatch: property can contain int but database expects array.',
113+
24,
114+
],
115+
]);
116+
}
117+
97118
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Doctrine\ORM;
4+
5+
use DateTimeImmutable;
6+
use DateTimeInterface;
7+
use Doctrine\DBAL\Platforms\AbstractPlatform;
8+
use Doctrine\DBAL\Types\Type;
9+
10+
class CustomType extends Type
11+
{
12+
13+
public const NAME = 'custom';
14+
15+
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string
16+
{
17+
return '';
18+
}
19+
20+
public function getName(): string
21+
{
22+
return self::NAME;
23+
}
24+
25+
public function convertToPHPValue($value, AbstractPlatform $abstractPlatform): DateTimeInterface
26+
{
27+
return new DateTimeImmutable();
28+
}
29+
30+
/**
31+
* @param array $value
32+
*/
33+
public function convertToDatabaseValue($value, AbstractPlatform $abstractPlatform): string
34+
{
35+
return '';
36+
}
37+
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Doctrine\ORM;
4+
5+
use Doctrine\ORM\Mapping as ORM;
6+
7+
/**
8+
* @ORM\Entity()
9+
*/
10+
class EntityWithCustomType
11+
{
12+
13+
/**
14+
* @ORM\Id()
15+
* @ORM\Column(type="int")
16+
* @var int
17+
*/
18+
private $id;
19+
20+
/**
21+
* @ORM\Column(type="custom")
22+
* @var int
23+
*/
24+
private $foo;
25+
}

0 commit comments

Comments
 (0)