1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
<?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\OrmFunctionalTestCase;
use InvalidArgumentException;
use PHPUnit\Framework\Attributes\Group;
use Stringable;
use function in_array;
class GH6141Test extends OrmFunctionalTestCase
{
protected function setUp(): void
{
parent::setUp();
Type::addType(GH6141PeopleType::NAME, GH6141PeopleType::class);
$this->createSchemaForModels(
GH6141Person::class,
GH6141Boss::class,
GH6141Employee::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 `GH6141Person`)
*/
#[Group('GH-6141')]
public function testEnumDiscriminatorsShouldBeConvertedToString(): void
{
$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
{
public const NAME = 'gh6141people';
/**
* {@inheritDoc}
*/
public function convertToDatabaseValue($value, AbstractPlatform $platform): string
{
if (! $value instanceof GH6141People) {
$value = GH6141People::get($value);
}
return (string) $value;
}
/**
* {@inheritDoc}
*/
public function convertToPHPValue($value, AbstractPlatform $platform): GH6141People
{
return GH6141People::get($value);
}
public function getName(): string
{
return self::NAME;
}
}
class GH6141People implements Stringable
{
public const BOSS = 'boss';
public const EMPLOYEE = 'employee';
/** @throws InvalidArgumentException */
public static function get(string $value): GH6141People
{
if (! self::isValid($value)) {
throw new InvalidArgumentException();
}
return new self($value);
}
private static function isValid(string $valid): bool
{
return in_array($valid, [self::BOSS, self::EMPLOYEE], true);
}
private function __construct(private string $value)
{
}
public function getValue(): string
{
return $this->value;
}
public function __toString(): string
{
return $this->value;
}
}
#[Entity]
#[InheritanceType('JOINED')]
#[DiscriminatorColumn(name: 'discr', type: 'gh6141people')]
#[DiscriminatorMap([GH6141People::BOSS => GH6141Boss::class, GH6141People::EMPLOYEE => GH6141Employee::class])]
abstract class GH6141Person
{
/** @var int */
#[Id]
#[Column(type: 'integer')]
#[GeneratedValue(strategy: 'AUTO')]
public $id;
public function __construct(
#[Column(type: 'string', length: 255)]
public string $name,
) {
}
}
#[Entity]
class GH6141Boss extends GH6141Person
{
}
#[Entity]
class GH6141Employee extends GH6141Person
{
}
|