Skip to content

Commit

Permalink
Allow JsonType to store any json-compatible type
Browse files Browse the repository at this point in the history
  • Loading branch information
simPod committed Jul 1, 2021
1 parent c35261f commit 5532790
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 2 deletions.
29 changes: 27 additions & 2 deletions src/Type/Doctrine/Descriptors/JsonType.php
Expand Up @@ -2,25 +2,50 @@

namespace PHPStan\Type\Doctrine\Descriptors;

use JsonSerializable;
use PHPStan\Type\ArrayType;
use PHPStan\Type\BooleanType;
use PHPStan\Type\FloatType;
use PHPStan\Type\IntegerType;
use PHPStan\Type\MixedType;
use PHPStan\Type\NullType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\StringType;
use PHPStan\Type\Type;
use stdClass;

class JsonType implements DoctrineTypeDescriptor
{

private static function getJsonType(): \PHPStan\Type\UnionType
{
$mixedType = new MixedType();

return new \PHPStan\Type\UnionType([
new ArrayType($mixedType, $mixedType),
new BooleanType(),
new FloatType(),
new IntegerType(),
new NullType(),
new ObjectType(JsonSerializable::class),
new ObjectType(stdClass::class),
new StringType(),
]);
}

public function getType(): string
{
return \Doctrine\DBAL\Types\JsonType::class;
}

public function getWritableToPropertyType(): Type
{
return new \PHPStan\Type\ArrayType(new MixedType(), new MixedType());
return self::getJsonType();
}

public function getWritableToDatabaseType(): Type
{
return new \PHPStan\Type\ArrayType(new MixedType(), new MixedType());
return self::getJsonType();
}

}
10 changes: 10 additions & 0 deletions tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php
Expand Up @@ -17,6 +17,7 @@
use PHPStan\Type\Doctrine\Descriptors\DateType;
use PHPStan\Type\Doctrine\Descriptors\DecimalType;
use PHPStan\Type\Doctrine\Descriptors\IntegerType;
use PHPStan\Type\Doctrine\Descriptors\JsonType;
use PHPStan\Type\Doctrine\Descriptors\Ramsey\UuidTypeDescriptor;
use PHPStan\Type\Doctrine\Descriptors\ReflectionDescriptor;
use PHPStan\Type\Doctrine\Descriptors\StringType;
Expand Down Expand Up @@ -57,6 +58,7 @@ protected function getRule(): Rule
new DateTimeType(),
new DateType(),
new DecimalType(),
new JsonType(),
new IntegerType(),
new StringType(),
new UuidTypeDescriptor(UuidType::class),
Expand Down Expand Up @@ -124,6 +126,14 @@ public function testRule(): void
'Property PHPStan\Rules\Doctrine\ORM\MyBrokenEntity::$invalidCarbonImmutable type mapping mismatch: database can contain Carbon\CarbonImmutable but property expects Carbon\Carbon.',
138,
],
[
'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.',
156,
],
[
'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.',
156,
],
]);
}

Expand Down
6 changes: 6 additions & 0 deletions tests/Rules/Doctrine/ORM/data/MyBrokenEntity.php
Expand Up @@ -148,4 +148,10 @@ class MyBrokenEntity extends MyBrokenSuperclass
* @var \Carbon\CarbonImmutable
*/
private $validCarbonImmutable;

/**
* @ORM\Column(type="json")
* @var EmptyObject
*/
private $incompatibleJsonValueObject;
}
42 changes: 42 additions & 0 deletions tests/Rules/Doctrine/ORM/data/MyEntity.php
Expand Up @@ -3,6 +3,7 @@
namespace PHPStan\Rules\Doctrine\ORM;

use Doctrine\ORM\Mapping as ORM;
use stdClass;

/**
* @ORM\Entity()
Expand Down Expand Up @@ -35,4 +36,45 @@ class MyEntity
*/
private $parent;

/**
* @var array
* @ORM\Column(type="json")
*/
private $jsonArray;

/**
* @var bool|null
* @ORM\Column(type="json")
*/
private $jsonBoolOrNull;

/**
* @var float
* @ORM\Column(type="json")
*/
private $jsonFloat;

/**
* @var int
* @ORM\Column(type="json")
*/
private $jsonInt;

/**
* @var JsonSerializableObject
* @ORM\Column(type="json")
*/
private $jsonSerializable;

/**
* @var stdClass
* @ORM\Column(type="json")
*/
private $jsonStdClass;

/**
* @var string
* @ORM\Column(type="json")
*/
private $jsonString;
}
17 changes: 17 additions & 0 deletions tests/Rules/Doctrine/ORM/data/objects.php
@@ -0,0 +1,17 @@
<?php declare(strict_types = 1);

namespace PHPStan\Rules\Doctrine\ORM;

use JsonSerializable;

final class JsonSerializableObject implements JsonSerializable
{
public function jsonSerialize()
{
return null;
}
}

final class EmptyObject
{
}

0 comments on commit 5532790

Please sign in to comment.