File: GH6141Test.php

package info (click to toggle)
doctrine 3.5.2%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,556 kB
  • sloc: php: 108,620; xml: 1,340; makefile: 35; sh: 14
file content (172 lines) | stat: -rw-r--r-- 4,473 bytes parent folder | download | duplicates (2)
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
{
}