Skip to content

Commit

Permalink
EntityColumnRule - check backed Enum type against Column mapping type
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Jan 15, 2022
1 parent 820606a commit c056a39
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 2 deletions.
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
],
"require": {
"php": "^7.1 || ^8.0",
"phpstan/phpstan": "^1.3"
"phpstan/phpstan": "^1.4.1"
},
"conflict": {
"doctrine/collections": "<1.0",
Expand Down Expand Up @@ -46,7 +46,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
"dev-master": "1.1-dev"
},
"phpstan": {
"includes": [
Expand Down
22 changes: 22 additions & 0 deletions src/Rules/Doctrine/ORM/EntityColumnRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MissingPropertyFromReflectionException;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Rules\Rule;
use PHPStan\Type\ArrayType;
use PHPStan\Type\Doctrine\DescriptorNotRegisteredException;
Expand Down Expand Up @@ -35,6 +36,9 @@ class EntityColumnRule implements Rule
/** @var \PHPStan\Type\Doctrine\DescriptorRegistry */
private $descriptorRegistry;

/** @var ReflectionProvider */
private $reflectionProvider;

/** @var bool */
private $reportUnknownTypes;

Expand All @@ -44,12 +48,14 @@ class EntityColumnRule implements Rule
public function __construct(
ObjectMetadataResolver $objectMetadataResolver,
DescriptorRegistry $descriptorRegistry,
ReflectionProvider $reflectionProvider,
bool $reportUnknownTypes,
bool $allowNullablePropertyForRequiredField
)
{
$this->objectMetadataResolver = $objectMetadataResolver;
$this->descriptorRegistry = $descriptorRegistry;
$this->reflectionProvider = $reflectionProvider;
$this->reportUnknownTypes = $reportUnknownTypes;
$this->allowNullablePropertyForRequiredField = $allowNullablePropertyForRequiredField;
}
Expand Down Expand Up @@ -122,6 +128,22 @@ public function processNode(Node $node, Scope $scope): array

$enumTypeString = $fieldMapping['enumType'] ?? null;
if ($enumTypeString !== null) {
if ($this->reflectionProvider->hasClass($enumTypeString)) {
$enumReflection = $this->reflectionProvider->getClass($enumTypeString);
$backedEnumType = $enumReflection->getBackedEnumType();
if ($backedEnumType !== null) {
if (!$backedEnumType->equals($writableToDatabaseType) || !$backedEnumType->equals($writableToPropertyType)) {
$errors[] = sprintf(
'Property %s::$%s type mapping mismatch: backing type %s of enum %s does not match database type %s.',
$className,
$propertyName,
$backedEnumType->describe(VerbosityLevel::typeOnly()),
$enumReflection->getDisplayName(),
$writableToDatabaseType->describe(VerbosityLevel::typeOnly())
);
}
}
}
$enumType = new ObjectType($enumTypeString);
$writableToPropertyType = $enumType;
$writableToDatabaseType = $enumType;
Expand Down
5 changes: 5 additions & 0 deletions tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ protected function getRule(): Rule
new ReflectionDescriptor(CustomType::class, $this->createBroker()),
new ReflectionDescriptor(CustomNumericType::class, $this->createBroker()),
]),
$this->createReflectionProvider(),
true,
$this->allowNullablePropertyForRequiredField
);
Expand Down Expand Up @@ -291,6 +292,10 @@ public function testEnumType(): void
'Property PHPStan\Rules\Doctrine\ORMAttributes\Foo::$type2 type mapping mismatch: property can contain PHPStan\Rules\Doctrine\ORMAttributes\BarEnum but database expects PHPStan\Rules\Doctrine\ORMAttributes\FooEnum.',
35,
],
[
'Property PHPStan\Rules\Doctrine\ORMAttributes\Foo::$type3 type mapping mismatch: backing type string of enum PHPStan\Rules\Doctrine\ORMAttributes\FooEnum does not match database type int.',
38,
],
]);
}

Expand Down
3 changes: 3 additions & 0 deletions tests/Rules/Doctrine/ORM/data-attributes/enum-type.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,7 @@ class Foo
#[ORM\Column(type: "string", enumType: FooEnum::class)]
public BarEnum $type2;

#[ORM\Column(type: "integer", enumType: FooEnum::class)]
public FooEnum $type3;

}

0 comments on commit c056a39

Please sign in to comment.