New in Symfony 6.3: Enum Improvements


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

Contributed by Alexandre Daubois
in #48669.

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

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

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:

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 Nadim AL ABDOU
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:

// 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
{
// ...
}
}

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:

// 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);

// ...
}
}

Sponsor the Symfony project.