Merge pull request #6141 from lcobucci/object-as-discriminators
Allow using objects as discriminators
This commit is contained in:
commit
7789df39c5
@ -251,12 +251,13 @@ class ObjectHydrator extends AbstractHydrator
|
||||
}
|
||||
|
||||
$discrMap = $this->_metadataCache[$className]->discriminatorMap;
|
||||
$discriminatorValue = (string) $data[$discrColumn];
|
||||
|
||||
if ( ! isset($discrMap[$data[$discrColumn]])) {
|
||||
throw HydrationException::invalidDiscriminatorValue($data[$discrColumn], array_keys($discrMap));
|
||||
if ( ! isset($discrMap[$discriminatorValue])) {
|
||||
throw HydrationException::invalidDiscriminatorValue($discriminatorValue, array_keys($discrMap));
|
||||
}
|
||||
|
||||
$className = $discrMap[$data[$discrColumn]];
|
||||
$className = $discrMap[$discriminatorValue];
|
||||
|
||||
unset($data[$discrColumn]);
|
||||
}
|
||||
|
195
tests/Doctrine/Tests/ORM/Functional/Ticket/GH6141Test.php
Normal file
195
tests/Doctrine/Tests/ORM/Functional/Ticket/GH6141Test.php
Normal file
@ -0,0 +1,195 @@
|
||||
<?php
|
||||
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\Tests\OrmFunctionalTestCase;
|
||||
|
||||
class GH6141Test extends OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
Type::addType(GH6141PeopleType::NAME, GH6141PeopleType::class);
|
||||
|
||||
$this->_schemaTool->createSchema(
|
||||
[
|
||||
$this->_em->getClassMetadata(GH6141Person::class),
|
||||
$this->_em->getClassMetadata(GH6141Boss::class),
|
||||
$this->_em->getClassMetadata(GH6141Employee::class),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function testEnumDiscriminatorsShouldBeConvertedToString()
|
||||
{
|
||||
$boss = new GH6141Boss('John');
|
||||
$employee = new GH6141Employee('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(GH6141Person::class, 'person')
|
||||
->where('person.name = :name')
|
||||
->setMaxResults(1)
|
||||
->getQuery();
|
||||
|
||||
$query->setParameter('name', 'John');
|
||||
self::assertEquals($boss, $query->getOneOrNullResult(AbstractQuery::HYDRATE_OBJECT));
|
||||
self::assertEquals(
|
||||
GH6141People::get(GH6141People::BOSS),
|
||||
$query->getOneOrNullResult(AbstractQuery::HYDRATE_ARRAY)['discr']
|
||||
);
|
||||
|
||||
$query->setParameter('name', 'Bob');
|
||||
self::assertEquals($employee, $query->getOneOrNullResult(AbstractQuery::HYDRATE_OBJECT));
|
||||
self::assertEquals(
|
||||
GH6141People::get(GH6141People::EMPLOYEE),
|
||||
$query->getOneOrNullResult(AbstractQuery::HYDRATE_ARRAY)['discr']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class GH6141PeopleType extends StringType
|
||||
{
|
||||
const NAME = 'gh6141people';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function convertToDatabaseValue($value, AbstractPlatform $platform)
|
||||
{
|
||||
if (!$value instanceof GH6141People) {
|
||||
$value = GH6141People::get($value);
|
||||
}
|
||||
|
||||
return (string) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function convertToPhpValue($value, AbstractPlatform $platform)
|
||||
{
|
||||
return GH6141People::get($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return self::NAME;
|
||||
}
|
||||
}
|
||||
|
||||
class GH6141People
|
||||
{
|
||||
const BOSS = 'boss';
|
||||
const EMPLOYEE = 'employee';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return GH6141People
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function get($value)
|
||||
{
|
||||
if (!self::isValid($value)) {
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
|
||||
return new self($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $valid
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function isValid($valid)
|
||||
{
|
||||
return in_array($valid, [self::BOSS, self::EMPLOYEE]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
private function __construct($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @InheritanceType("JOINED")
|
||||
* @DiscriminatorColumn(name="discr", type="gh6141people")
|
||||
* @DiscriminatorMap({
|
||||
* "boss" = GH6141Boss::class,
|
||||
* "employee" = GH6141Employee::class
|
||||
* })
|
||||
*/
|
||||
abstract class GH6141Person
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @Column(type="integer")
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @Column(type="string")
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
}
|
||||
|
||||
/** @Entity */
|
||||
class GH6141Boss extends GH6141Person
|
||||
{
|
||||
}
|
||||
|
||||
/** @Entity */
|
||||
class GH6141Employee extends GH6141Person
|
||||
{
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user