From 55baa6006a6df12c989d4608750f347ab789bf7c Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Fri, 21 Feb 2020 17:23:44 +0100 Subject: [PATCH] [DoctrineBridge] Use new Types::* constants and support new json type --- .../Doctrine/Form/DoctrineOrmTypeGuesser.php | 34 ++++----- .../PropertyInfo/DoctrineExtractor.php | 55 ++++++++------- .../RememberMe/DoctrineTokenProvider.php | 7 +- .../PropertyInfo/DoctrineExtractorTest.php | 69 ++++++++++++------- .../PropertyInfo/Fixtures/DoctrineDummy.php | 2 +- .../Fixtures/DoctrineDummy210.php | 30 ++++++++ 6 files changed, 127 insertions(+), 70 deletions(-) create mode 100644 src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy210.php diff --git a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php index ff4b54d24bdcc..9de0d88198662 100644 --- a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php +++ b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php @@ -15,6 +15,7 @@ use Doctrine\Common\Persistence\Mapping\MappingException as LegacyCommonMappingException; use Doctrine\Common\Util\ClassUtils; use Doctrine\DBAL\Types\Type; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping\ClassMetadataInfo; use Doctrine\ORM\Mapping\MappingException as LegacyMappingException; use Doctrine\Persistence\ManagerRegistry; @@ -56,31 +57,32 @@ public function guessType($class, $property) return new TypeGuess('Symfony\Bridge\Doctrine\Form\Type\EntityType', ['em' => $name, 'class' => $mapping['targetEntity'], 'multiple' => $multiple], Guess::HIGH_CONFIDENCE); } + $useDeprecatedConstants = !class_exists(Types::class); switch ($metadata->getTypeOfField($property)) { - case Type::TARRAY: + case $useDeprecatedConstants ? Type::TARRAY : Types::ARRAY: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\CollectionType', [], Guess::MEDIUM_CONFIDENCE); - case Type::BOOLEAN: + case $useDeprecatedConstants ? Type::BOOLEAN : Types::BOOLEAN: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\CheckboxType', [], Guess::HIGH_CONFIDENCE); - case Type::DATETIME: - case Type::DATETIMETZ: + case $useDeprecatedConstants ? Type::DATETIME : Types::DATETIME_MUTABLE: + case $useDeprecatedConstants ? Type::DATETIMETZ : Types::DATETIMETZ_MUTABLE: case 'vardatetime': return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateTimeType', [], Guess::HIGH_CONFIDENCE); case 'dateinterval': return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateIntervalType', [], Guess::HIGH_CONFIDENCE); - case Type::DATE: + case $useDeprecatedConstants ? Type::DATE : Types::DATE_MUTABLE: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateType', [], Guess::HIGH_CONFIDENCE); - case Type::TIME: + case $useDeprecatedConstants ? Type::TIME : Types::TIME_MUTABLE: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TimeType', [], Guess::HIGH_CONFIDENCE); - case Type::DECIMAL: - case Type::FLOAT: + case $useDeprecatedConstants ? Type::DECIMAL : Types::DECIMAL: + case $useDeprecatedConstants ? Type::FLOAT : Types::FLOAT: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\NumberType', [], Guess::MEDIUM_CONFIDENCE); - case Type::INTEGER: - case Type::BIGINT: - case Type::SMALLINT: + case $useDeprecatedConstants ? Type::INTEGER : Types::INTEGER: + case $useDeprecatedConstants ? Type::BIGINT : Types::BIGINT: + case $useDeprecatedConstants ? Type::SMALLINT : Types::SMALLINT: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\IntegerType', [], Guess::MEDIUM_CONFIDENCE); - case Type::STRING: + case $useDeprecatedConstants ? Type::STRING : Types::STRING: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TextType', [], Guess::MEDIUM_CONFIDENCE); - case Type::TEXT: + case $useDeprecatedConstants ? Type::TEXT : Types::TEXT: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TextareaType', [], Guess::MEDIUM_CONFIDENCE); default: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TextType', [], Guess::LOW_CONFIDENCE); @@ -103,7 +105,7 @@ public function guessRequired($class, $property) // Check whether the field exists and is nullable or not if (isset($classMetadata->fieldMappings[$property])) { - if (!$classMetadata->isNullable($property) && Type::BOOLEAN !== $classMetadata->getTypeOfField($property)) { + if (!$classMetadata->isNullable($property) && (!class_exists(Types::class) ? Type::BOOLEAN : Types::BOOLEAN) !== $classMetadata->getTypeOfField($property)) { return new ValueGuess(true, Guess::HIGH_CONFIDENCE); } @@ -140,7 +142,7 @@ public function guessMaxLength($class, $property) return new ValueGuess($mapping['length'], Guess::HIGH_CONFIDENCE); } - if (\in_array($ret[0]->getTypeOfField($property), [Type::DECIMAL, Type::FLOAT])) { + if (\in_array($ret[0]->getTypeOfField($property), !class_exists(Types::class) ? [Type::DECIMAL, Type::FLOAT] : [Types::DECIMAL, Types::FLOAT])) { return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE); } } @@ -155,7 +157,7 @@ public function guessPattern($class, $property) { $ret = $this->getMetadata($class); if ($ret && isset($ret[0]->fieldMappings[$property]) && !$ret[0]->hasAssociation($property)) { - if (\in_array($ret[0]->getTypeOfField($property), [Type::DECIMAL, Type::FLOAT])) { + if (\in_array($ret[0]->getTypeOfField($property), !class_exists(Types::class) ? [Type::DECIMAL, Type::FLOAT] : [Types::DECIMAL, Types::FLOAT])) { return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE); } } diff --git a/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php b/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php index ea96b59f45043..bc3ce34613945 100644 --- a/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php +++ b/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php @@ -14,6 +14,7 @@ use Doctrine\Common\Persistence\Mapping\ClassMetadataFactory as LegacyClassMetadataFactory; use Doctrine\Common\Persistence\Mapping\MappingException as LegacyMappingException; use Doctrine\DBAL\Types\Type as DBALType; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping\ClassMetadataInfo; use Doctrine\ORM\Mapping\MappingException as OrmMappingException; use Doctrine\Persistence\Mapping\ClassMetadataFactory; @@ -146,14 +147,15 @@ public function getTypes($class, $property, array $context = []) $nullable = $metadata instanceof ClassMetadataInfo && $metadata->isNullable($property); + $useDeprecatedConstants = !class_exists(Types::class); switch ($builtinType) { case Type::BUILTIN_TYPE_OBJECT: switch ($typeOfField) { - case DBALType::DATE: - case DBALType::DATETIME: - case DBALType::DATETIMETZ: + case $useDeprecatedConstants ? DBALType::DATE : Types::DATE_MUTABLE: + case $useDeprecatedConstants ? DBALType::DATETIME : Types::DATETIME_MUTABLE: + case $useDeprecatedConstants ? DBALType::DATETIMETZ : Types::DATETIMETZ_MUTABLE: case 'vardatetime': - case DBALType::TIME: + case $useDeprecatedConstants ? DBALType::TIME : Types::TIME_MUTABLE: return [new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, 'DateTime')]; case 'date_immutable': @@ -169,11 +171,12 @@ public function getTypes($class, $property, array $context = []) break; case Type::BUILTIN_TYPE_ARRAY: switch ($typeOfField) { - case DBALType::TARRAY: - case DBALType::JSON_ARRAY: + case $useDeprecatedConstants ? DBALType::TARRAY : Types::ARRAY: + case 'json_array': + case $useDeprecatedConstants ? false : Types::JSON: return [new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true)]; - case DBALType::SIMPLE_ARRAY: + case $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))]; } } @@ -220,34 +223,35 @@ private function isAssociationNullable(array $associationMapping) */ private function getPhpType($doctrineType) { + $useDeprecatedConstants = !class_exists(Types::class); switch ($doctrineType) { - case DBALType::SMALLINT: - case DBALType::INTEGER: + case $useDeprecatedConstants ? DBALType::SMALLINT : Types::SMALLINT: + case $useDeprecatedConstants ? DBALType::INTEGER : Types::INTEGER: return Type::BUILTIN_TYPE_INT; - case DBALType::FLOAT: + case $useDeprecatedConstants ? DBALType::FLOAT : Types::FLOAT: return Type::BUILTIN_TYPE_FLOAT; - case DBALType::BIGINT: - case DBALType::STRING: - case DBALType::TEXT: - case DBALType::GUID: - case DBALType::DECIMAL: + case $useDeprecatedConstants ? DBALType::BIGINT : Types::BIGINT: + case $useDeprecatedConstants ? DBALType::STRING : Types::STRING: + case $useDeprecatedConstants ? DBALType::TEXT : Types::TEXT: + case $useDeprecatedConstants ? DBALType::GUID : Types::GUID: + case $useDeprecatedConstants ? DBALType::DECIMAL : Types::DECIMAL: return Type::BUILTIN_TYPE_STRING; - case DBALType::BOOLEAN: + case $useDeprecatedConstants ? DBALType::BOOLEAN : Types::BOOLEAN: return Type::BUILTIN_TYPE_BOOL; - case DBALType::BLOB: + case $useDeprecatedConstants ? DBALType::BLOB : Types::BLOB: case 'binary': return Type::BUILTIN_TYPE_RESOURCE; - case DBALType::OBJECT: - case DBALType::DATE: - case DBALType::DATETIME: - case DBALType::DATETIMETZ: + case $useDeprecatedConstants ? DBALType::OBJECT : Types::OBJECT: + case $useDeprecatedConstants ? DBALType::DATE : Types::DATE_MUTABLE: + case $useDeprecatedConstants ? DBALType::DATETIME : Types::DATETIME_MUTABLE: + case $useDeprecatedConstants ? DBALType::DATETIMETZ : Types::DATETIMETZ_MUTABLE: case 'vardatetime': - case DBALType::TIME: + case $useDeprecatedConstants ? DBALType::TIME : Types::TIME_MUTABLE: case 'date_immutable': case 'datetime_immutable': case 'datetimetz_immutable': @@ -255,9 +259,10 @@ private function getPhpType($doctrineType) case 'dateinterval': return Type::BUILTIN_TYPE_OBJECT; - case DBALType::TARRAY: - case DBALType::SIMPLE_ARRAY: - case DBALType::JSON_ARRAY: + case $useDeprecatedConstants ? DBALType::TARRAY : Types::ARRAY: + case $useDeprecatedConstants ? DBALType::SIMPLE_ARRAY : Types::SIMPLE_ARRAY: + case 'json_array': + case $useDeprecatedConstants ? false : Types::JSON: return Type::BUILTIN_TYPE_ARRAY; } diff --git a/src/Symfony/Bridge/Doctrine/Security/RememberMe/DoctrineTokenProvider.php b/src/Symfony/Bridge/Doctrine/Security/RememberMe/DoctrineTokenProvider.php index 64515fac71840..671c2d517f312 100644 --- a/src/Symfony/Bridge/Doctrine/Security/RememberMe/DoctrineTokenProvider.php +++ b/src/Symfony/Bridge/Doctrine/Security/RememberMe/DoctrineTokenProvider.php @@ -12,7 +12,8 @@ namespace Symfony\Bridge\Doctrine\Security\RememberMe; use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Types\Type as DoctrineType; +use Doctrine\DBAL\Types\Type; +use Doctrine\DBAL\Types\Types; use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken; use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentTokenInterface; use Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface; @@ -90,7 +91,7 @@ public function updateToken($series, $tokenValue, \DateTime $lastUsed) ]; $paramTypes = [ 'value' => \PDO::PARAM_STR, - 'lastUsed' => DoctrineType::DATETIME, + 'lastUsed' => !class_exists(Types::class) ? Type::DATETIME : Types::DATETIME_MUTABLE, 'series' => \PDO::PARAM_STR, ]; $updated = $this->conn->executeUpdate($sql, $paramValues, $paramTypes); @@ -119,7 +120,7 @@ public function createNewToken(PersistentTokenInterface $token) 'username' => \PDO::PARAM_STR, 'series' => \PDO::PARAM_STR, 'value' => \PDO::PARAM_STR, - 'lastUsed' => DoctrineType::DATETIME, + 'lastUsed' => !class_exists(Types::class) ? Type::DATETIME : Types::DATETIME_MUTABLE, ]; $this->conn->executeUpdate($sql, $paramValues, $paramTypes); } diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php index 9c658a324613c..c4efb6c936106 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php @@ -13,10 +13,12 @@ use Doctrine\Common\Collections\Collection; use Doctrine\DBAL\Types\Type as DBALType; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManager; use Doctrine\ORM\Tools\Setup; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Doctrine\PropertyInfo\DoctrineExtractor; +use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineDummy210; use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation; use Symfony\Component\PropertyInfo\Type; @@ -45,29 +47,40 @@ protected function setUp() public function testGetProperties() { + // Fields + $expected = [ + 'id', + 'guid', + 'time', + 'timeImmutable', + 'dateInterval', + 'jsonArray', + 'simpleArray', + 'float', + 'decimal', + 'bool', + 'binary', + 'customFoo', + 'bigint', + ]; + + if (class_exists(Types::class)) { + $expected[] = 'json'; + } + + // Associations + $expected = array_merge($expected, [ + 'foo', + 'bar', + 'indexedBar', + 'indexedFoo', + 'indexedByDt', + 'indexedByCustomType', + ]); + $this->assertEquals( - [ - 'id', - 'guid', - 'time', - 'timeImmutable', - 'dateInterval', - 'json', - 'simpleArray', - 'float', - 'decimal', - 'bool', - 'binary', - 'customFoo', - 'bigint', - 'foo', - 'bar', - 'indexedBar', - 'indexedFoo', - 'indexedByDt', - 'indexedByCustomType', - ], - $this->extractor->getProperties('Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineDummy') + $expected, + $this->extractor->getProperties(!class_exists(Types::class) ? 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineDummy' : DoctrineDummy210::class) ); } @@ -91,7 +104,7 @@ public function testGetPropertiesWithEmbedded() */ public function testExtract($property, array $type = null) { - $this->assertEquals($type, $this->extractor->getTypes('Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineDummy', $property, [])); + $this->assertEquals($type, $this->extractor->getTypes(!class_exists(Types::class) ? 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineDummy' : DoctrineDummy210::class, $property, [])); } public function testExtractWithEmbedded() @@ -117,7 +130,7 @@ public function testExtractWithEmbedded() public function typesProvider() { - return [ + $provider = [ ['id', [new Type(Type::BUILTIN_TYPE_INT)]], ['guid', [new Type(Type::BUILTIN_TYPE_STRING)]], ['bigint', [new Type(Type::BUILTIN_TYPE_STRING)]], @@ -128,7 +141,7 @@ public function typesProvider() ['decimal', [new Type(Type::BUILTIN_TYPE_STRING)]], ['bool', [new Type(Type::BUILTIN_TYPE_BOOL)]], ['binary', [new Type(Type::BUILTIN_TYPE_RESOURCE)]], - ['json', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true)]], + ['jsonArray', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true)]], ['foo', [new Type(Type::BUILTIN_TYPE_OBJECT, true, 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation')]], ['bar', [new Type( Type::BUILTIN_TYPE_OBJECT, @@ -167,6 +180,12 @@ public function typesProvider() )]], ['indexedByCustomType', null], ]; + + if (class_exists(Types::class)) { + $provider[] = ['json', [new Type(Type::BUILTIN_TYPE_ARRAY, true, null, true)]]; + } + + return $provider; } public function testGetPropertiesCatchException() diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php index c8bd04e4ec5f4..81264fad27c5f 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php +++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php @@ -74,7 +74,7 @@ class DoctrineDummy /** * @Column(type="json_array") */ - private $json; + private $jsonArray; /** * @Column(type="simple_array") diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy210.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy210.php new file mode 100644 index 0000000000000..d3916143deab7 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy210.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures; + +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\ManyToMany; +use Doctrine\ORM\Mapping\ManyToOne; +use Doctrine\ORM\Mapping\OneToMany; + +/** + * @Entity + */ +final class DoctrineDummy210 extends DoctrineDummy +{ + /** + * @Column(type="json", nullable=true) + */ + private $json; +}