Skip to content

Commit

Permalink
Add support for PHP 8.1 enums in embedded classes (#9419)
Browse files Browse the repository at this point in the history
  • Loading branch information
HypeMC authored Jan 23, 2022
1 parent 5f01dd8 commit 6d5da83
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 3 deletions.
12 changes: 11 additions & 1 deletion lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -1056,9 +1056,19 @@ public function wakeupReflection($reflService)

foreach ($this->fieldMappings as $field => $mapping) {
if (isset($mapping['declaredField']) && isset($parentReflFields[$mapping['declaredField']])) {
$childProperty = $this->getAccessibleProperty($reflService, $mapping['originalClass'], $mapping['originalField']);
assert($childProperty !== null);

if (isset($mapping['enumType'])) {
$childProperty = new ReflectionEnumProperty(
$childProperty,
$mapping['enumType']
);
}

$this->reflFields[$field] = new ReflectionEmbeddedProperty(
$parentReflFields[$mapping['declaredField']],
$this->getAccessibleProperty($reflService, $mapping['originalClass'], $mapping['originalField']),
$childProperty,
$mapping['originalClass']
);
continue;
Expand Down
2 changes: 2 additions & 0 deletions phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,11 @@
<rule ref="Generic.WhiteSpace.ScopeIndent.Incorrect">
<!-- see https://github.com/squizlabs/PHP_CodeSniffer/issues/3474 -->
<exclude-pattern>tests/Doctrine/Tests/Models/Enums/Suit.php</exclude-pattern>
<exclude-pattern>tests/Doctrine/Tests/Models/Enums/Unit.php</exclude-pattern>
</rule>
<rule ref="Generic.WhiteSpace.ScopeIndent.IncorrectExact">
<!-- see https://github.com/squizlabs/PHP_CodeSniffer/issues/3474 -->
<exclude-pattern>tests/Doctrine/Tests/Models/Enums/Suit.php</exclude-pattern>
<exclude-pattern>tests/Doctrine/Tests/Models/Enums/Unit.php</exclude-pattern>
</rule>
</ruleset>
3 changes: 1 addition & 2 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,7 @@
<code>$fieldName</code>
<code>$fieldName</code>
</ParamNameMismatch>
<PossiblyNullArgument occurrences="9">
<PossiblyNullArgument occurrences="8">
<code>$class</code>
<code>$className</code>
<code>$entityResult['entityClass']</code>
Expand All @@ -772,7 +772,6 @@
<code>$parentReflFields[$embeddedClass['declaredField']]</code>
<code>$parentReflFields[$mapping['declaredField']]</code>
<code>$queryMapping['resultClass']</code>
<code>$this-&gt;getAccessibleProperty($reflService, $mapping['originalClass'], $mapping['originalField'])</code>
</PossiblyNullArgument>
<PossiblyNullPropertyFetch occurrences="2">
<code>$embeddable-&gt;reflClass-&gt;name</code>
Expand Down
21 changes: 21 additions & 0 deletions tests/Doctrine/Tests/Models/Enums/Product.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Doctrine\Tests\Models\Enums;

use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Embedded;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Id;

#[Entity]
class Product
{
#[Id, GeneratedValue, Column(type: 'integer')]
public int $id;

#[Embedded(class: Quantity::class)]
public Quantity $quantity;
}
18 changes: 18 additions & 0 deletions tests/Doctrine/Tests/Models/Enums/Quantity.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Doctrine\Tests\Models\Enums;

use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Embeddable;

#[Embeddable]
class Quantity
{
#[Column(type: 'integer')]
public int $value;

#[Column(type: 'string', enumType: Unit::class)]
public Unit $unit;
}
11 changes: 11 additions & 0 deletions tests/Doctrine/Tests/Models/Enums/Unit.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace Doctrine\Tests\Models\Enums;

enum Unit: string
{
case Gram = 'g';
case Meter = 'm';
}
22 changes: 22 additions & 0 deletions tests/Doctrine/Tests/ORM/Functional/EnumTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@
use Doctrine\ORM\Mapping\MappingException;
use Doctrine\ORM\Tools\SchemaTool;
use Doctrine\Tests\Models\Enums\Card;
use Doctrine\Tests\Models\Enums\Product;
use Doctrine\Tests\Models\Enums\Quantity;
use Doctrine\Tests\Models\Enums\Suit;
use Doctrine\Tests\Models\Enums\TypedCard;
use Doctrine\Tests\Models\Enums\Unit;
use Doctrine\Tests\OrmFunctionalTestCase;

use function dirname;
Expand Down Expand Up @@ -113,4 +116,23 @@ public function testItAllowsReadingAttributes(): void
$this->assertCount(1, $attributes);
$this->assertEquals(Column::class, $attributes[0]->getName());
}

public function testEnumMappingWithEmbeddable(): void
{
$this->setUpEntitySchema([Product::class]);

$product = new Product();
$product->quantity = new Quantity();
$product->quantity->value = 10;
$product->quantity->unit = Unit::Gram;

$this->_em->persist($product);
$this->_em->flush();
$this->_em->clear();

$fetchedProduct = $this->_em->find(Product::class, $product->id);

$this->assertInstanceOf(Unit::class, $fetchedProduct->quantity->unit);
$this->assertEquals(Unit::Gram, $fetchedProduct->quantity->unit);
}
}

0 comments on commit 6d5da83

Please sign in to comment.