Enum Support in Workflows

Tugdual Saunier Grégoire Pineau
Contributed by Tugdual Saunier and Grégoire Pineau in #60114 and #60204

Symfony has added support for PHP enums in many parts of the framework. In Symfony 7.4, we are adding support for backed enums in the Workflow component. Consider the following enum that defines the possible states of a blog post in your application:

1
2
3
4
5
6
7
8
9
10
// src/Enumeration/BlogPostStatus.php
namespace App\Enumeration;

enum BlogPostStatus: string
{
    case Draft = 'draft';
    case Reviewed = 'reviewed';
    case Published = 'published';
    case Rejected = 'rejected';
}

You can now use these values as places, initial markings, and transitions of any workflow. For example, when using the YAML configuration format:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# config/packages/workflow.yaml
framework:
    workflows:
        blog_publishing:
            type: 'workflow'
            marking_store:
                type: 'method'
                property: 'status'
            supports:
                - App\Entity\BlogPost
            initial_marking: !php/enum App\Enumeration\BlogPostStatus::Draft
            places: !php/enum App\Enumeration\BlogPostStatus
            transitions:
                to_review:
                    from: !php/enum App\Enumeration\BlogPostStatus::Draft
                    to:   !php/enum App\Enumeration\BlogPostStatus::Reviewed
                publish:
                    from: !php/enum App\Enumeration\BlogPostStatus::Reviewed
                    to:   !php/enum App\Enumeration\BlogPostStatus::Published
                reject:
                    from: !php/enum App\Enumeration\BlogPostStatus::Reviewed
                    to:   !php/enum App\Enumeration\BlogPostStatus::Rejected

Symfony will now transparently cast the enum to its backing value when needed and back to the enum when working with your objects.

CDATA Wrapping Per Field

Maximilian Ruta
Contributed by Maximilian Ruta in #60355

The Serializer component provides an option called CDATA_WRAPPING_PATTERN to wrap field content in CDATA if it matches the given regex. However, in some scenarios (legacy systems, XML consumers, or strict XSD schemas) certain fields are expected to always use CDATA sections.

In Symfony 7.4, we added a new option called CDATA_WRAPPING_NAME_PATTERN, where you can define a regular expression that is matched against field names, not their contents:

1
2
3
$this->encoder->encode($data, 'xml', [
    XmlEncoder::CDATA_WRAPPING_NAME_PATTERN => '(firstname|lastname)'
]);

DynamoDB Lock Store

Nathan Page
Contributed by Nathan Page in #60138

DynamoDB is a fully managed, serverless NoSQL database service from AWS (Amazon Web Services). In Symfony 7.4, we added support for it in the Lock component. Install the symfony/amazon-dynamo-db-lock package, configure a DSN, and you can store your locks in a DynamoDB database:

1
2
3
4
use Symfony\Component\Lock\Bridge\DynamoDb\Store\DynamoDbStore;

$dynamoDbClientOrDSN = 'dynamodb://default/lock';
$store = new DynamoDbStore($dynamoDbClientOrDSN);

DayPointType and TimePointType Doctrine Types

Wojciech Kania
Contributed by Wojciech Kania in #60237 and #60315

In Symfony 7.4, we are introducing two new Doctrine types: DayPointType and TimePointType. These new types allow you to use the DatePoint class from the Clock component for date-only and time-only fields instead of datetime fields:

1
2
3
4
5
6
7
8
#[ORM\Column(type: 'date_point')]
public DatePoint $createdAt;

#[ORM\Column(type: 'day_point')]
public DatePoint $birthday;

#[ORM\Column(type: 'time_point')]
public DatePoint $openAt;

We also added support for using date_point as the value of the input option in the Symfony form types related to dates.

Explicit Query Parameters

Benjamin Morel
Contributed by Benjamin Morel in #60508

Consider a route definition like https://{siteCode}.{domain}/admin/stats. If you pass a parameter called {siteCode} when generating the URL, this value will always be used as a subdomain. As a result, you cannot generate URLs like https://fr.example.com/admin/stats?siteCode=us.

In Symfony 7.4, we are introducing a special _query key in the route parameters so you can define values that must always be included in the query string, regardless of the route definition. You can now generate the previously impossible URL like this:

1
2
3
4
5
6
7
$urlGenerator->generate('admin_stats', [
    'siteCode' => 'fr',
    'domain' => 'example.com',
    '_query' => [
        'siteCode' => 'us',
    ]
]);
Published in #Living on the edge