Skip to content

Commit

Permalink
bug #35794 [DoctrineBridge][DoctrineExtractor] Fix indexBy with custo…
Browse files Browse the repository at this point in the history
…m and some core types (fancyweb)

This PR was merged into the 3.4 branch.

Discussion
----------

[DoctrineBridge][DoctrineExtractor] Fix indexBy with custom and some core types

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | #35542 and #35604
| License       | MIT
| Doc PR        | -

For #35604:
To guess the collection key type, the `getPhpType()` method is called. But it does not handle most objects and arrays core types. This is why an indexBy datetime does not work.

For #35542:
When the php type cannot be guessed, null is returned. In this case, we cannot pass a valid builtin type to PropertyInfo Type, so we should return null.

Commits
-------

018ec1a [DoctrineBridge][DoctrineExtractor] Fix indexBy with custom and some core types
  • Loading branch information
fabpot committed Feb 21, 2020
2 parents 8197d9a + 018ec1a commit 643f34f
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 28 deletions.
80 changes: 52 additions & 28 deletions src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php
Expand Up @@ -117,7 +117,9 @@ public function getTypes($class, $property, array $context = [])
$typeOfField = $subMetadata->getTypeOfField($indexProperty);
}

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

Expand All @@ -137,39 +139,46 @@ public function getTypes($class, $property, array $context = [])

if ($metadata->hasField($property)) {
$typeOfField = $metadata->getTypeOfField($property);
$nullable = $metadata instanceof ClassMetadataInfo && $metadata->isNullable($property);

switch ($typeOfField) {
case DBALType::DATE:
case DBALType::DATETIME:
case DBALType::DATETIMETZ:
case 'vardatetime':
case DBALType::TIME:
return [new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, 'DateTime')];

case 'date_immutable':
case 'datetime_immutable':
case 'datetimetz_immutable':
case 'time_immutable':
return [new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, 'DateTimeImmutable')];

case 'dateinterval':
return [new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, 'DateInterval')];

case DBALType::TARRAY:
return [new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true)];
if (!$builtinType = $this->getPhpType($typeOfField)) {
return null;
}

case DBALType::SIMPLE_ARRAY:
return [new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))];
$nullable = $metadata instanceof ClassMetadataInfo && $metadata->isNullable($property);

case DBALType::JSON_ARRAY:
return [new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true)];
switch ($builtinType) {
case Type::BUILTIN_TYPE_OBJECT:
switch ($typeOfField) {
case DBALType::DATE:
case DBALType::DATETIME:
case DBALType::DATETIMETZ:
case 'vardatetime':
case DBALType::TIME:
return [new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, 'DateTime')];

case 'date_immutable':
case 'datetime_immutable':
case 'datetimetz_immutable':
case 'time_immutable':
return [new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, 'DateTimeImmutable')];

case 'dateinterval':
return [new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, 'DateInterval')];
}

default:
$builtinType = $this->getPhpType($typeOfField);
break;
case Type::BUILTIN_TYPE_ARRAY:
switch ($typeOfField) {
case DBALType::TARRAY:
case DBALType::JSON_ARRAY:
return [new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true)];

return $builtinType ? [new Type($builtinType, $nullable)] : null;
case DBALType::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($builtinType, $nullable)];
}

return null;
Expand Down Expand Up @@ -234,7 +243,22 @@ private function getPhpType($doctrineType)
return Type::BUILTIN_TYPE_RESOURCE;

case DBALType::OBJECT:
case DBALType::DATE:
case DBALType::DATETIME:
case DBALType::DATETIMETZ:
case 'vardatetime':
case DBALType::TIME:
case 'date_immutable':
case 'datetime_immutable':
case 'datetimetz_immutable':
case 'time_immutable':
case 'dateinterval':
return Type::BUILTIN_TYPE_OBJECT;

case DBALType::TARRAY:
case DBALType::SIMPLE_ARRAY:
case DBALType::JSON_ARRAY:
return Type::BUILTIN_TYPE_ARRAY;
}

return null;
Expand Down
Expand Up @@ -11,11 +11,13 @@

namespace Symfony\Bridge\Doctrine\Tests\PropertyInfo;

use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Type as DBALType;
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\DoctrineRelation;
use Symfony\Component\PropertyInfo\Type;

/**
Expand Down Expand Up @@ -62,6 +64,8 @@ public function testGetProperties()
'bar',
'indexedBar',
'indexedFoo',
'indexedByDt',
'indexedByCustomType',
],
$this->extractor->getProperties('Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineDummy')
);
Expand Down Expand Up @@ -153,6 +157,15 @@ public function typesProvider()
['simpleArray', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))]],
['customFoo', null],
['notMapped', null],
['indexedByDt', [new Type(
Type::BUILTIN_TYPE_OBJECT,
false,
Collection::class,
true,
new Type(Type::BUILTIN_TYPE_OBJECT),
new Type(Type::BUILTIN_TYPE_OBJECT, false, DoctrineRelation::class)
)]],
['indexedByCustomType', null],
];
}

Expand Down
Expand Up @@ -112,4 +112,14 @@ class DoctrineDummy
private $bigint;

public $notMapped;

/**
* @OneToMany(targetEntity="DoctrineRelation", mappedBy="dt", indexBy="dt")
*/
protected $indexedByDt;

/**
* @OneToMany(targetEntity="DoctrineRelation", mappedBy="customType", indexBy="customType")
*/
private $indexedByCustomType;
}
Expand Up @@ -39,4 +39,14 @@ class DoctrineRelation
* @ManyToOne(targetEntity="DoctrineDummy", inversedBy="indexedFoo")
*/
protected $foo;

/**
* @Column(type="datetime")
*/
private $dt;

/**
* @Column(type="foo")
*/
private $customType;
}

0 comments on commit 643f34f

Please sign in to comment.