Skip to content

Commit 5532790

Browse files
authored
Allow JsonType to store any json-compatible type
1 parent c35261f commit 5532790

File tree

5 files changed

+102
-2
lines changed

5 files changed

+102
-2
lines changed

src/Type/Doctrine/Descriptors/JsonType.php

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,50 @@
22

33
namespace PHPStan\Type\Doctrine\Descriptors;
44

5+
use JsonSerializable;
6+
use PHPStan\Type\ArrayType;
7+
use PHPStan\Type\BooleanType;
8+
use PHPStan\Type\FloatType;
9+
use PHPStan\Type\IntegerType;
510
use PHPStan\Type\MixedType;
11+
use PHPStan\Type\NullType;
12+
use PHPStan\Type\ObjectType;
13+
use PHPStan\Type\StringType;
614
use PHPStan\Type\Type;
15+
use stdClass;
716

817
class JsonType implements DoctrineTypeDescriptor
918
{
1019

20+
private static function getJsonType(): \PHPStan\Type\UnionType
21+
{
22+
$mixedType = new MixedType();
23+
24+
return new \PHPStan\Type\UnionType([
25+
new ArrayType($mixedType, $mixedType),
26+
new BooleanType(),
27+
new FloatType(),
28+
new IntegerType(),
29+
new NullType(),
30+
new ObjectType(JsonSerializable::class),
31+
new ObjectType(stdClass::class),
32+
new StringType(),
33+
]);
34+
}
35+
1136
public function getType(): string
1237
{
1338
return \Doctrine\DBAL\Types\JsonType::class;
1439
}
1540

1641
public function getWritableToPropertyType(): Type
1742
{
18-
return new \PHPStan\Type\ArrayType(new MixedType(), new MixedType());
43+
return self::getJsonType();
1944
}
2045

2146
public function getWritableToDatabaseType(): Type
2247
{
23-
return new \PHPStan\Type\ArrayType(new MixedType(), new MixedType());
48+
return self::getJsonType();
2449
}
2550

2651
}

tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use PHPStan\Type\Doctrine\Descriptors\DateType;
1818
use PHPStan\Type\Doctrine\Descriptors\DecimalType;
1919
use PHPStan\Type\Doctrine\Descriptors\IntegerType;
20+
use PHPStan\Type\Doctrine\Descriptors\JsonType;
2021
use PHPStan\Type\Doctrine\Descriptors\Ramsey\UuidTypeDescriptor;
2122
use PHPStan\Type\Doctrine\Descriptors\ReflectionDescriptor;
2223
use PHPStan\Type\Doctrine\Descriptors\StringType;
@@ -57,6 +58,7 @@ protected function getRule(): Rule
5758
new DateTimeType(),
5859
new DateType(),
5960
new DecimalType(),
61+
new JsonType(),
6062
new IntegerType(),
6163
new StringType(),
6264
new UuidTypeDescriptor(UuidType::class),
@@ -124,6 +126,14 @@ public function testRule(): void
124126
'Property PHPStan\Rules\Doctrine\ORM\MyBrokenEntity::$invalidCarbonImmutable type mapping mismatch: database can contain Carbon\CarbonImmutable but property expects Carbon\Carbon.',
125127
138,
126128
],
129+
[
130+
'Property PHPStan\Rules\Doctrine\ORM\MyBrokenEntity::$incompatibleJsonValueObject type mapping mismatch: database can contain array|bool|float|int|JsonSerializable|stdClass|string|null but property expects PHPStan\Rules\Doctrine\ORM\EmptyObject.',
131+
156,
132+
],
133+
[
134+
'Property PHPStan\Rules\Doctrine\ORM\MyBrokenEntity::$incompatibleJsonValueObject type mapping mismatch: property can contain PHPStan\Rules\Doctrine\ORM\EmptyObject but database expects array|bool|float|int|JsonSerializable|stdClass|string|null.',
135+
156,
136+
],
127137
]);
128138
}
129139

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,10 @@ class MyBrokenEntity extends MyBrokenSuperclass
148148
* @var \Carbon\CarbonImmutable
149149
*/
150150
private $validCarbonImmutable;
151+
152+
/**
153+
* @ORM\Column(type="json")
154+
* @var EmptyObject
155+
*/
156+
private $incompatibleJsonValueObject;
151157
}

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\Rules\Doctrine\ORM;
44

55
use Doctrine\ORM\Mapping as ORM;
6+
use stdClass;
67

78
/**
89
* @ORM\Entity()
@@ -35,4 +36,45 @@ class MyEntity
3536
*/
3637
private $parent;
3738

39+
/**
40+
* @var array
41+
* @ORM\Column(type="json")
42+
*/
43+
private $jsonArray;
44+
45+
/**
46+
* @var bool|null
47+
* @ORM\Column(type="json")
48+
*/
49+
private $jsonBoolOrNull;
50+
51+
/**
52+
* @var float
53+
* @ORM\Column(type="json")
54+
*/
55+
private $jsonFloat;
56+
57+
/**
58+
* @var int
59+
* @ORM\Column(type="json")
60+
*/
61+
private $jsonInt;
62+
63+
/**
64+
* @var JsonSerializableObject
65+
* @ORM\Column(type="json")
66+
*/
67+
private $jsonSerializable;
68+
69+
/**
70+
* @var stdClass
71+
* @ORM\Column(type="json")
72+
*/
73+
private $jsonStdClass;
74+
75+
/**
76+
* @var string
77+
* @ORM\Column(type="json")
78+
*/
79+
private $jsonString;
3880
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Doctrine\ORM;
4+
5+
use JsonSerializable;
6+
7+
final class JsonSerializableObject implements JsonSerializable
8+
{
9+
public function jsonSerialize()
10+
{
11+
return null;
12+
}
13+
}
14+
15+
final class EmptyObject
16+
{
17+
}

0 commit comments

Comments
 (0)