Repository: doctrine/orm (php)

Issue:
can not set default value to enum case
### Bug Report

|    Q        |   A
|------------ | ------
| BC Break    | no
| Version     | 2.11.0

#### Summary

We dumbly tried to put a default value to a property set to a enum's case and
it does not work when generating the migration
which means we can not set default value based on enum case
(we can hardcode it but we are not happy with this solution)

#### Current behavior
given an enum:
```
enum Suit: string {
    case Hearts = 'hearts';
    case Diamonds = 'diamonds'; 
}
```

trying

```
    /**
     * @ORM\Column(
     *      type="string",
     *      length=255,
     *      enumType="App\Enum\Suit",
     *      options={"default": App\Enum\Suit::Hearts}
     * )
     */
    private Suit $suit = Suit::Hearts;
```

give us after a bin/console make:migration

```
In AbstractPlatform.php line 3913:
                                                                                                                      
  str_replace(): Argument #3 ($subject) must be of type array|string, App\Enum\Suit given 
```
trying

```
    /**
     * @ORM\Column(
     *      type="string",
     *      length=255,
     *      enumType="App\Enum\Suit",
     *      options={"default": "App\Enum\Suit::Hearts"}
     * )
     */
    private Suit $suit = Suit::Hearts;
```

give us a migration like

```
    public function up(Schema $schema): void
    {
        // this up() migration is auto-generated, please modify it to your needs
        $this->addSql('ALTER TABLE entity ALTER suit SET DEFAULT \'App\\Enum\\Suit::Hearts\'');
    }
```

which is the string "App\\Enum\\Suit::Hearts\" and not the value of the enum case

#### How to reproduce

create an enum:

```
enum Suit: string {
    case Hearts = 'hearts';
    case Diamonds = 'diamonds'; 
}
```

set a property in an entity linking to this enum
with a default value set to one of the enum case

```
    /**
     * @ORM\Column(
     *      type="string",
     *      length=255,
     *      enumType="App\Enum\Suit",
     *      options={"default": App\Enum\Suit::Hearts}
     * )
     */
    private Suit $suit = Suit::Hearts;
```
make a migration
(in sf5): `bin/console make:migration`

#### Expected behavior

trying

```
    /**
     * @ORM\Column(
     *      type="string",
     *      length=255,
     *      enumType="App\Enum\Suit",
     *      options={"default": App\Enum\Suit::Hearts}
     * )
     */
    private Suit $suit = Suit::Hearts;
```

give us a migration like

```
    public function up(Schema $schema): void
    {
        // this up() migration is auto-generated, please modify it to your needs
        $this->addSql('ALTER TABLE entity ALTER suit SET DEFAULT \'hearts\''');
    }
```



Pull request:
Support enums as default values
Fixes #9375, closes doctrine/dbal#5336

Patch:
diff --git a/lib/Doctrine/ORM/Tools/SchemaTool.php b/lib/Doctrine/ORM/Tools/SchemaTool.php
index b92a6be58..87653f846 100644
--- a/lib/Doctrine/ORM/Tools/SchemaTool.php
+++ b/lib/Doctrine/ORM/Tools/SchemaTool.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace Doctrine\ORM\Tools;
 
+use BackedEnum;
 use Doctrine\DBAL\Connection;
 use Doctrine\DBAL\Platforms\AbstractPlatform;
 use Doctrine\DBAL\Schema\AbstractAsset;
@@ -787,6 +788,10 @@ class SchemaTool
             $mappingOptions['enumType'] = $mapping['enumType'];
         }
 
+        if (($mappingOptions['default'] ?? null) instanceof BackedEnum) {
+            $mappingOptions['default'] = $mappingOptions['default']->value;
+        }
+
         if (empty($mappingOptions)) {
             return [];
         }


Test patch:
diff --git a/tests/Doctrine/Tests/Models/Enums/CardWithDefault.php b/tests/Doctrine/Tests/Models/Enums/CardWithDefault.php
new file mode 100644
index 000000000..c4763ee7e
--- /dev/null
+++ b/tests/Doctrine/Tests/Models/Enums/CardWithDefault.php
@@ -0,0 +1,19 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Doctrine\Tests\Models\Enums;
+
+use Doctrine\ORM\Mapping\Column;
+use Doctrine\ORM\Mapping\Entity;
+use Doctrine\ORM\Mapping\Id;
+
+#[Entity]
+class CardWithDefault
+{
+    #[Id, Column]
+    public string $id;
+
+    #[Column(options: ['default' => Suit::Hearts])]
+    public Suit $suit;
+}
diff --git a/tests/Doctrine/Tests/ORM/Functional/EnumTest.php b/tests/Doctrine/Tests/ORM/Functional/EnumTest.php
index 9fe1f7b8d..2170da900 100644
--- a/tests/Doctrine/Tests/ORM/Functional/EnumTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/EnumTest.php
@@ -9,6 +9,7 @@ use Doctrine\ORM\Mapping\Driver\AttributeDriver;
 use Doctrine\ORM\Mapping\MappingException;
 use Doctrine\ORM\Tools\SchemaTool;
 use Doctrine\Tests\Models\Enums\Card;
+use Doctrine\Tests\Models\Enums\CardWithDefault;
 use Doctrine\Tests\Models\Enums\Product;
 use Doctrine\Tests\Models\Enums\Quantity;
 use Doctrine\Tests\Models\Enums\Suit;
@@ -18,6 +19,7 @@ use Doctrine\Tests\OrmFunctionalTestCase;
 
 use function dirname;
 use function sprintf;
+use function uniqid;
 
 /**
  * @requires PHP 8.1
@@ -159,4 +161,17 @@ EXCEPTION
         $this->assertInstanceOf(Unit::class, $fetchedProduct->quantity->unit);
         $this->assertEquals(Unit::Gram, $fetchedProduct->quantity->unit);
     }
+
+    public function testEnumWithDefault(): void
+    {
+        $this->setUpEntitySchema([CardWithDefault::class]);
+
+        $table  = $this->_em->getClassMetadata(CardWithDefault::class)->getTableName();
+        $cardId = uniqid('', true);
+
+        $this->_em->getConnection()->insert($table, ['id' => $cardId]);
+        $card = $this->_em->find(CardWithDefault::class, $cardId);
+
+        self::assertSame(Suit::Hearts, $card->suit);
+    }
 }