Skip to content

Commit 0621ee1

Browse files
mhujerondrejmirtes
authored andcommitted
Ramsey UUID TypeDescriptor
1 parent 586f708 commit 0621ee1

File tree

5 files changed

+101
-0
lines changed

5 files changed

+101
-0
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"phpstan/phpstan-phpunit": "^0.12",
3030
"phpstan/phpstan-strict-rules": "^0.12",
3131
"phpunit/phpunit": "^7.0",
32+
"ramsey/uuid-doctrine": "^1.5.0",
3233
"slevomat/coding-standard": "^4.5.2",
3334
"doctrine/common": "^2.7",
3435
"doctrine/orm": "^2.5",

extension.neon

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,3 +255,20 @@ services:
255255
-
256256
class: PHPStan\Type\Doctrine\Descriptors\TimeType
257257
tags: [phpstan.doctrine.typeDescriptor]
258+
259+
# 3rd party Type descriptors
260+
-
261+
class: PHPStan\Type\Doctrine\Descriptors\Ramsey\UuidTypeDescriptor
262+
tags: [phpstan.doctrine.typeDescriptor]
263+
arguments:
264+
uuidTypeName: Ramsey\Uuid\Doctrine\UuidType
265+
-
266+
class: PHPStan\Type\Doctrine\Descriptors\Ramsey\UuidTypeDescriptor
267+
tags: [phpstan.doctrine.typeDescriptor]
268+
arguments:
269+
uuidTypeName: Ramsey\Uuid\Doctrine\UuidBinaryType
270+
-
271+
class: PHPStan\Type\Doctrine\Descriptors\Ramsey\UuidTypeDescriptor
272+
tags: [phpstan.doctrine.typeDescriptor]
273+
arguments:
274+
uuidTypeName: Ramsey\Uuid\Doctrine\UuidBinaryOrderedTimeType
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Type\Doctrine\Descriptors\Ramsey;
4+
5+
use PHPStan\Type\Doctrine\Descriptors\DoctrineTypeDescriptor;
6+
use PHPStan\Type\Type;
7+
use PHPStan\Type\TypeCombinator;
8+
use Ramsey\Uuid\UuidInterface;
9+
10+
class UuidTypeDescriptor implements DoctrineTypeDescriptor
11+
{
12+
13+
private const SUPPORTED_UUID_TYPES = [
14+
\Ramsey\Uuid\Doctrine\UuidType::class,
15+
\Ramsey\Uuid\Doctrine\UuidBinaryType::class,
16+
\Ramsey\Uuid\Doctrine\UuidBinaryOrderedTimeType::class,
17+
];
18+
19+
/**
20+
* @phpstan-var class-string<\Doctrine\DBAL\Types\Type>
21+
* @var string
22+
*/
23+
private $uuidTypeName;
24+
25+
public function __construct(
26+
string $uuidTypeName
27+
)
28+
{
29+
if (!in_array($uuidTypeName, self::SUPPORTED_UUID_TYPES, true)) {
30+
throw new \PHPStan\ShouldNotHappenException(sprintf(
31+
'Unexpected UUID column type "%s" provided',
32+
$uuidTypeName
33+
));
34+
}
35+
36+
$this->uuidTypeName = $uuidTypeName;
37+
}
38+
39+
public function getType(): string
40+
{
41+
return $this->uuidTypeName;
42+
}
43+
44+
public function getWritableToPropertyType(): Type
45+
{
46+
return new \PHPStan\Type\ObjectType(UuidInterface::class);
47+
}
48+
49+
public function getWritableToDatabaseType(): Type
50+
{
51+
return TypeCombinator::union(
52+
new \PHPStan\Type\StringType(),
53+
new \PHPStan\Type\ObjectType(UuidInterface::class)
54+
);
55+
}
56+
57+
}

tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
use PHPStan\Type\Doctrine\Descriptors\DateTimeType;
1414
use PHPStan\Type\Doctrine\Descriptors\DateType;
1515
use PHPStan\Type\Doctrine\Descriptors\IntegerType;
16+
use PHPStan\Type\Doctrine\Descriptors\Ramsey\UuidTypeDescriptor;
1617
use PHPStan\Type\Doctrine\Descriptors\ReflectionDescriptor;
1718
use PHPStan\Type\Doctrine\Descriptors\StringType;
1819
use PHPStan\Type\Doctrine\ObjectMetadataResolver;
20+
use Ramsey\Uuid\Doctrine\UuidType;
1921

2022
/**
2123
* @extends RuleTestCase<EntityColumnRule>
@@ -28,6 +30,9 @@ protected function getRule(): Rule
2830
if (!Type::hasType(CustomType::NAME)) {
2931
Type::addType(CustomType::NAME, CustomType::class);
3032
}
33+
if (!Type::hasType(UuidType::NAME)) {
34+
Type::addType(UuidType::NAME, UuidType::class);
35+
}
3136

3237
return new EntityColumnRule(
3338
new ObjectMetadataResolver(__DIR__ . '/entity-manager.php', null),
@@ -40,6 +45,7 @@ protected function getRule(): Rule
4045
new IntegerType(),
4146
new ReflectionDescriptor(CustomType::class, $this->createBroker()),
4247
new DateType(),
48+
new UuidTypeDescriptor(UuidType::class),
4349
]),
4450
true
4551
);
@@ -72,6 +78,14 @@ public function testRule(): void
7278
'Property PHPStan\Rules\Doctrine\ORM\MyBrokenEntity::$four type mapping mismatch: property can contain DateTime but database expects DateTimeImmutable.',
7379
43,
7480
],
81+
[
82+
'Property PHPStan\Rules\Doctrine\ORM\MyBrokenEntity::$uuidInvalidType type mapping mismatch: database can contain Ramsey\Uuid\UuidInterface but property expects int.',
83+
72,
84+
],
85+
[
86+
'Property PHPStan\Rules\Doctrine\ORM\MyBrokenEntity::$uuidInvalidType type mapping mismatch: property can contain int but database expects Ramsey\Uuid\UuidInterface|string.',
87+
72,
88+
],
7589
]);
7690
}
7791

tests/Rules/Doctrine/ORM/data/MyBrokenEntity.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,16 @@ class MyBrokenEntity extends MyBrokenSuperclass
5959
*/
6060
private $never;
6161

62+
/**
63+
* @ORM\Column(type="uuid")
64+
* @var \Ramsey\Uuid\UuidInterface
65+
*/
66+
private $uuid;
67+
68+
/**
69+
* @ORM\Column(type="uuid")
70+
* @var int
71+
*/
72+
private $uuidInvalidType;
73+
6274
}

0 commit comments

Comments
 (0)