Skip to content

Commit

Permalink
bug #46676 [DoctrineBridge] Extend type guessing on enum fields (Gigi…
Browse files Browse the repository at this point in the history
…no Chianese)

This PR was merged into the 4.4 branch.

Discussion
----------

[DoctrineBridge] Extend type guessing on enum fields

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | -
| License       | MIT
| Doc PR        | -

Doctrine supports enumType on array values, while the current implementation always assumes the value to be an enum object, if enumType is set.

If $typeOfField is `json_array` the collectionKeyType will still be null, while collectionValueType will be filled. That's because we have no way to determine from doctrine metadata, if the key is string or int. Yet I don't know if that's a valid thing to do, otherwise we should return null in that case.

Commits
-------

79239fe CS fix
a9b0f43 [DoctrineBridge] Extend type guessing on enum fields
  • Loading branch information
nicolas-grekas committed Jun 19, 2022
2 parents fa4a7a4 + 79239fe commit af45ea5
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 43 deletions.
5 changes: 0 additions & 5 deletions src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php
Expand Up @@ -60,15 +60,12 @@ public function guessType($class, $property)

switch ($metadata->getTypeOfField($property)) {
case self::$useDeprecatedConstants ? Type::TARRAY : Types::ARRAY:
// no break
case self::$useDeprecatedConstants ? Type::SIMPLE_ARRAY : Types::SIMPLE_ARRAY:
return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\CollectionType', [], Guess::MEDIUM_CONFIDENCE);
case self::$useDeprecatedConstants ? Type::BOOLEAN : Types::BOOLEAN:
return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\CheckboxType', [], Guess::HIGH_CONFIDENCE);
case self::$useDeprecatedConstants ? Type::DATETIME : Types::DATETIME_MUTABLE:
// no break
case self::$useDeprecatedConstants ? Type::DATETIMETZ : Types::DATETIMETZ_MUTABLE:
// no break
case 'vardatetime':
return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateTimeType', [], Guess::HIGH_CONFIDENCE);
case 'datetime_immutable':
Expand All @@ -89,9 +86,7 @@ public function guessType($class, $property)
case self::$useDeprecatedConstants ? Type::FLOAT : Types::FLOAT:
return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\NumberType', [], Guess::MEDIUM_CONFIDENCE);
case self::$useDeprecatedConstants ? Type::INTEGER : Types::INTEGER:
// no break
case self::$useDeprecatedConstants ? Type::BIGINT : Types::BIGINT:
// no break
case self::$useDeprecatedConstants ? Type::SMALLINT : Types::SMALLINT:
return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\IntegerType', [], Guess::MEDIUM_CONFIDENCE);
case self::$useDeprecatedConstants ? Type::STRING : Types::STRING:
Expand Down
41 changes: 18 additions & 23 deletions src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php
Expand Up @@ -152,26 +152,24 @@ public function getTypes($class, $property, array $context = [])
}

if ($metadata->hasField($property)) {
$nullable = $metadata instanceof ClassMetadataInfo && $metadata->isNullable($property);
if (null !== $enumClass = $metadata->getFieldMapping($property)['enumType'] ?? null) {
return [new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $enumClass)];
}

$typeOfField = $metadata->getTypeOfField($property);

if (!$builtinType = $this->getPhpType($typeOfField)) {
return null;
}

$nullable = $metadata instanceof ClassMetadataInfo && $metadata->isNullable($property);
$enumType = null;
if (null !== $enumClass = $metadata->getFieldMapping($property)['enumType'] ?? null) {
$enumType = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $enumClass);
}

switch ($builtinType) {
case Type::BUILTIN_TYPE_OBJECT:
switch ($typeOfField) {
case self::$useDeprecatedConstants ? DBALType::DATE : Types::DATE_MUTABLE:
// no break
case self::$useDeprecatedConstants ? DBALType::DATETIME : Types::DATETIME_MUTABLE:
// no break
case self::$useDeprecatedConstants ? DBALType::DATETIMETZ : Types::DATETIMETZ_MUTABLE:
// no break
case 'vardatetime':
case self::$useDeprecatedConstants ? DBALType::TIME : Types::TIME_MUTABLE:
return [new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, 'DateTime')];
Expand All @@ -190,13 +188,23 @@ public function getTypes($class, $property, array $context = [])
case Type::BUILTIN_TYPE_ARRAY:
switch ($typeOfField) {
case self::$useDeprecatedConstants ? DBALType::TARRAY : Types::ARRAY:
// no break
case 'json_array':
// return null if $enumType is set, because we can't determine if collectionKeyType is string or int
if ($enumType) {
return null;
}

return [new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true)];

case self::$useDeprecatedConstants ? DBALType::SIMPLE_ARRAY : Types::SIMPLE_ARRAY:
return [new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))];
return [new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true, new Type(Type::BUILTIN_TYPE_INT), $enumType ?? new Type(Type::BUILTIN_TYPE_STRING))];
}
case Type::BUILTIN_TYPE_INT:
case Type::BUILTIN_TYPE_STRING:
if ($enumType !== null) {
return [$enumType];
}
break;
}

return [new Type($builtinType, $nullable)];
Expand Down Expand Up @@ -270,43 +278,32 @@ private function getPhpType(string $doctrineType): ?string
{
switch ($doctrineType) {
case self::$useDeprecatedConstants ? DBALType::SMALLINT : Types::SMALLINT:
// no break
case self::$useDeprecatedConstants ? DBALType::INTEGER : Types::INTEGER:
return Type::BUILTIN_TYPE_INT;

case self::$useDeprecatedConstants ? DBALType::FLOAT : Types::FLOAT:
return Type::BUILTIN_TYPE_FLOAT;

case self::$useDeprecatedConstants ? DBALType::BIGINT : Types::BIGINT:
// no break
case self::$useDeprecatedConstants ? DBALType::STRING : Types::STRING:
// no break
case self::$useDeprecatedConstants ? DBALType::TEXT : Types::TEXT:
// no break
case self::$useDeprecatedConstants ? DBALType::GUID : Types::GUID:
// no break
case self::$useDeprecatedConstants ? DBALType::DECIMAL : Types::DECIMAL:
return Type::BUILTIN_TYPE_STRING;

case self::$useDeprecatedConstants ? DBALType::BOOLEAN : Types::BOOLEAN:
return Type::BUILTIN_TYPE_BOOL;

case self::$useDeprecatedConstants ? DBALType::BLOB : Types::BLOB:
// no break
case 'binary':
return Type::BUILTIN_TYPE_RESOURCE;

case self::$useDeprecatedConstants ? DBALType::OBJECT : Types::OBJECT:
// no break
case self::$useDeprecatedConstants ? DBALType::DATE : Types::DATE_MUTABLE:
// no break
case self::$useDeprecatedConstants ? DBALType::DATETIME : Types::DATETIME_MUTABLE:
// no break
case self::$useDeprecatedConstants ? DBALType::DATETIMETZ : Types::DATETIMETZ_MUTABLE:
// no break
case 'vardatetime':
case self::$useDeprecatedConstants ? DBALType::TIME : Types::TIME_MUTABLE:
// no break
case 'date_immutable':
case 'datetime_immutable':
case 'datetimetz_immutable':
Expand All @@ -315,9 +312,7 @@ private function getPhpType(string $doctrineType): ?string
return Type::BUILTIN_TYPE_OBJECT;

case self::$useDeprecatedConstants ? DBALType::TARRAY : Types::ARRAY:
// no break
case self::$useDeprecatedConstants ? DBALType::SIMPLE_ARRAY : Types::SIMPLE_ARRAY:
// no break
case 'json_array':
return Type::BUILTIN_TYPE_ARRAY;
}
Expand Down
Expand Up @@ -185,6 +185,9 @@ public function testExtractEnum()
}
$this->assertEquals([new Type(Type::BUILTIN_TYPE_OBJECT, false, EnumString::class)], $this->createExtractor()->getTypes(DoctrineEnum::class, 'enumString', []));
$this->assertEquals([new Type(Type::BUILTIN_TYPE_OBJECT, false, EnumInt::class)], $this->createExtractor()->getTypes(DoctrineEnum::class, 'enumInt', []));
$this->assertEquals(null, $this->createExtractor()->getTypes(DoctrineEnum::class, 'enumStringArray', []));
$this->assertEquals([new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, EnumInt::class))], $this->createExtractor()->getTypes(DoctrineEnum::class, 'enumIntArray', []));
$this->assertEquals(null, $this->createExtractor()->getTypes(DoctrineEnum::class, 'enumCustom', []));
}

public function typesProvider()
Expand Down
Expand Up @@ -35,4 +35,19 @@ class DoctrineEnum
* @Column(type="integer", enumType="Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumInt")
*/
protected $enumInt;

/**
* @Column(type="array", enumType="Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumString")
*/
protected $enumStringArray;

/**
* @Column(type="simple_array", enumType="Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumInt")
*/
protected $enumIntArray;

/**
* @Column(type="custom_foo", enumType="Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumInt")
*/
protected $enumCustom;
}
3 changes: 0 additions & 3 deletions src/Symfony/Component/Form/Extension/Core/Type/FileType.php
Expand Up @@ -200,11 +200,8 @@ private static function getMaxFilesize()

switch (substr($iniMax, -1)) {
case 't': $max *= 1024;
// no break
case 'g': $max *= 1024;
// no break
case 'm': $max *= 1024;
// no break
case 'k': $max *= 1024;
}

Expand Down
3 changes: 0 additions & 3 deletions src/Symfony/Component/Form/Util/ServerParams.php
Expand Up @@ -62,11 +62,8 @@ public function getPostMaxSize()

switch (substr($iniMax, -1)) {
case 't': $max *= 1024;
// no break
case 'g': $max *= 1024;
// no break
case 'm': $max *= 1024;
// no break
case 'k': $max *= 1024;
}

Expand Down
3 changes: 0 additions & 3 deletions src/Symfony/Component/HttpFoundation/File/UploadedFile.php
Expand Up @@ -273,11 +273,8 @@ private static function parseFilesize(string $size)

switch (substr($size, -1)) {
case 't': $max *= 1024;
// no break
case 'g': $max *= 1024;
// no break
case 'm': $max *= 1024;
// no break
case 'k': $max *= 1024;
}

Expand Down
Expand Up @@ -114,11 +114,8 @@ private function convertToBytes(string $memoryLimit)

switch (substr($memoryLimit, -1)) {
case 't': $max *= 1024;
// no break
case 'g': $max *= 1024;
// no break
case 'm': $max *= 1024;
// no break
case 'k': $max *= 1024;
}

Expand Down
Expand Up @@ -219,11 +219,8 @@ private function convertToBytes(string $memoryLimit): int

switch (substr(rtrim($memoryLimit, 'b'), -1)) {
case 't': $max *= 1024;
// no break
case 'g': $max *= 1024;
// no break
case 'm': $max *= 1024;
// no break
case 'k': $max *= 1024;
}

Expand Down

0 comments on commit af45ea5

Please sign in to comment.