Symfony 5.4 introduced support for Enums in forms November 2021. Later, in Symfony 6.2, we improved enums support to allow using them in YAML files, env vars, etc. In Symfony 6.3 we're improving enums support again.

Enums in Expressions

Alexandre Daubois
Contributed by Alexandre Daubois in #48669

The ExpressionLanguage component now includes a function called enum() to get the case of an enumeration inside expressions:

1
2
3
4
5
6
7
8
9
10
11
12
namespace App\Config\Order;

enum OrderStatus
{
    case Paid = 'paid';
    case Pending = 'pending';
    case Refunded = 'refunded';
    case Deleted = 'deleted';
}

// inside expressions, namespace separators must be escaped with 3 backslashes
$expressionLanguage->evaluate('order.status == enum("App\\\Config\\\Order\\\OrderStatus::Paid")')

Enums Support in EnumNode Config

Thomas Calvet
Contributed by Thomas Calvet in #49098

When using the Config component, you can now use enum values as part of the allowed values of enum nodes defined with the enumNode() method:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
enum OrderDelivery: string
{
    case Standard = 'standard';
    case Expedited = 'expedited';
    case Priority = 'priority';
}

$rootNode
    ->children()
        ->enumNode('delivery')
            // You can provide all values of the enum...
            ->values(OrderDelivery::cases())

            // ... or you can pass only some values next to other scalar values
            ->values([OrderDelivery::Priority, OrderDelivery::Standard, 'other', false])
        ->end()
    ->end()
;

Enums as Default Values of Route Parameters

Contributed by in #50031

In Symfony 6.2 we added support for using the value of backed enums as route arguments so Symfony would transform them automatically into their associated enum case. In Symfony 6.3 we're improving this feature by allowing to use enum cases as the default value of route arguments:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// src/Controller/OrderController.php
namespace App\Controller;

use App\Config\Order\OrderStatus;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class OrderController extends AbstractController
{
    #[Route('/orders/list/{status}', name: 'list_orders_by_status')]
    public function list(OrderStatus $status = OrderStatus::Paid): Response
    {
        // ...
    }
}
Nicolas Philippe
Contributed by Nicolas Philippe in #48820

Related to this, we've also improved the parameter bag used to get values from the Request to add a getEnum() method. This converts e.g. the values from a query string into backed enum cases:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// src/Controller/OrderController.php
namespace App\Controller;

// ...
use Symfony\Component\HttpFoundation\Request;

class OrderController extends AbstractController
{
    #[Route('/orders/list/', name: 'list_orders')]
    public function list(Request $request): Response
    {
        // the second argument is the FQCN of the backed enum to use when transforming the value
        $status = $request->query->getEnum('status', OrderStatus::class);

        // ...
    }
}
Published in #Living on the edge