-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
In all hydrators, discriminator columns are for all purposes converted to string using explicit (string) conversion. This is not allowed with PHP enums. Therefore, I added code which checks whether the variable is a BackedEnum instance and if so, instead its ->value is used (which can be cast to string without issues as it's a scalar)
- Loading branch information
Showing
5 changed files
with
196 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Doctrine\Tests\Models\GH10288; | ||
|
||
enum GH10288People: string | ||
{ | ||
case BOSS = 'boss'; | ||
case EMPLOYEE = 'employee'; | ||
} |
152 changes: 152 additions & 0 deletions
152
tests/Doctrine/Tests/ORM/Functional/Ticket/GH10288Test.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Doctrine\Tests\ORM\Functional\Ticket; | ||
|
||
use Doctrine\DBAL\Platforms\AbstractPlatform; | ||
use Doctrine\DBAL\Types\StringType; | ||
use Doctrine\DBAL\Types\Type; | ||
use Doctrine\ORM\AbstractQuery; | ||
use Doctrine\ORM\Mapping\Column; | ||
use Doctrine\ORM\Mapping\DiscriminatorColumn; | ||
use Doctrine\ORM\Mapping\DiscriminatorMap; | ||
use Doctrine\ORM\Mapping\Entity; | ||
use Doctrine\ORM\Mapping\GeneratedValue; | ||
use Doctrine\ORM\Mapping\Id; | ||
use Doctrine\ORM\Mapping\InheritanceType; | ||
use Doctrine\Tests\Models\GH10288\GH10288People; | ||
use Doctrine\Tests\OrmFunctionalTestCase; | ||
|
||
/** | ||
* @requires PHP 8.1 | ||
*/ | ||
class GH10288Test extends OrmFunctionalTestCase | ||
{ | ||
protected function setUp(): void | ||
{ | ||
parent::setUp(); | ||
|
||
Type::addType(GH10288PeopleType::NAME, GH10288PeopleType::class); | ||
|
||
$this->createSchemaForModels( | ||
GH10288Person::class, | ||
GH10288Boss::class, | ||
GH10288Employee::class | ||
); | ||
} | ||
|
||
/** | ||
* The intent of this test is to ensure that the ORM is capable | ||
* of using objects as discriminators (which makes things a bit | ||
* more dynamic as you can see on the mapping of `GH10288Person`) | ||
* | ||
* @group GH-6141 | ||
*/ | ||
public function testEnumDiscriminatorsShouldBeConvertedToString(): void | ||
{ | ||
$boss = new GH10288Boss('John'); | ||
$employee = new GH10288Employee('Bob'); | ||
|
||
$this->_em->persist($boss); | ||
$this->_em->persist($employee); | ||
$this->_em->flush(); | ||
$this->_em->clear(); | ||
|
||
// Using DQL here to make sure that we'll use ObjectHydrator instead of SimpleObjectHydrator | ||
$query = $this->_em->createQueryBuilder() | ||
->select('person') | ||
->from(GH10288Person::class, 'person') | ||
->where('person.name = :name') | ||
->setMaxResults(1) | ||
->getQuery(); | ||
|
||
$query->setParameter('name', 'John'); | ||
self::assertEquals($boss, $query->getOneOrNullResult(AbstractQuery::HYDRATE_OBJECT)); | ||
self::assertEquals( | ||
GH10288People::BOSS, | ||
$query->getOneOrNullResult(AbstractQuery::HYDRATE_ARRAY)['discr'] | ||
); | ||
|
||
$query->setParameter('name', 'Bob'); | ||
self::assertEquals($employee, $query->getOneOrNullResult(AbstractQuery::HYDRATE_OBJECT)); | ||
self::assertEquals( | ||
GH10288People::EMPLOYEE, | ||
$query->getOneOrNullResult(AbstractQuery::HYDRATE_ARRAY)['discr'] | ||
); | ||
} | ||
} | ||
|
||
class GH10288PeopleType extends StringType | ||
{ | ||
public const NAME = 'GH10288people'; | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function convertToDatabaseValue($value, AbstractPlatform $platform) | ||
{ | ||
if (! $value instanceof GH10288People) { | ||
$value = GH10288People::from($value); | ||
} | ||
|
||
return $value->value; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function convertToPHPValue($value, AbstractPlatform $platform) | ||
{ | ||
return GH10288People::from($value); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getName() | ||
{ | ||
return self::NAME; | ||
} | ||
} | ||
|
||
/** | ||
* @Entity | ||
* @InheritanceType("JOINED") | ||
* @DiscriminatorColumn(name="discr", type="GH10288people") | ||
* @DiscriminatorMap({ | ||
* "boss" = GH10288Boss::class, | ||
* "employee" = GH10288Employee::class | ||
* }) | ||
*/ | ||
abstract class GH10288Person | ||
{ | ||
/** | ||
* @var int | ||
* @Id | ||
* @Column(type="integer") | ||
* @GeneratedValue(strategy="AUTO") | ||
*/ | ||
public $id; | ||
|
||
/** | ||
* @var string | ||
* @Column(type="string", length=255) | ||
*/ | ||
public $name; | ||
|
||
public function __construct(string $name) | ||
{ | ||
$this->name = $name; | ||
} | ||
} | ||
|
||
/** @Entity */ | ||
class GH10288Boss extends GH10288Person | ||
{ | ||
} | ||
|
||
/** @Entity */ | ||
class GH10288Employee extends GH10288Person | ||
{ | ||
} |