New in Symfony 6.3: DX Improvements (Part 3)


Allow to Exclude Properties in Cascade Constraint

Contributed by Alexandre Daubois
in #49596.

The Cascade constraint is used to validate a whole class, including all the
objects that might be stored in its properties. In Symfony 6.3 we're improving
it so you can exclude one or more properties from that validation:

// src/Model/BookCollection.php
namespace App\Model;

use App\Model\Author;
use App\Model\BookMetadata;
use Symfony\Component\Validator\Constraints as Assert;

#[Assert\Cascade(exclude: ['metadata', 'author'])]
class BookCollection
{
#[Assert\NotBlank]
protected $name = '';

public BookMetadata $metadata;

public Author $author;

// ...
}

Allow to Trim XML Parameters

Contributed by Alexandre Daubois
in #49412.

When using XML to configure the service container, you can't define parameters
like this:

<parameter key="app.admin_email">
something@example.com
parameter>

Symfony doesn't trim the XML contents, so the app.admin_email value would be
'\n something@example.com\n'. In Symfony 6.3 we've added a new trim
option for XML configuration:

<parameter key="app.admin_email" trim="true">
something@example.com
parameter>

The value of the app.admin_email option will now be 'something@example.com'.

Allow Setting Private Services in Testing Container

Contributed by Nicolas Grekas
in #48938.

A well-known technique when testing services in Symfony applications is to
mock a dependency of some service being tested. In order to make this work, you
need to set those services as public in the test container:

# config/services_test.yaml
services:
# redefine the alias as it should be while making it public
App\Contracts\Repository\NewsRepositoryInterface:
alias: App\Repository\NewsRepository
public: true

In Symfony 6.3 we're improving this feature so you can set private services
directly in the service container, without having to make any service public.
For example, in your tests, you can use code like this to set the mock service
directly:

static::getContainer()->set('example.client', new MockHttpClient(...));

DomCrawler Updates of innerText() Method

Contributed by otsch
in #48940.

The DomCrawler component defines an innerText() method to return the
text that is a direct descendant of the current node, excluding text from child
nodes. In Symfony 6.3 we've improved it in some ways:

// if content is 'Foo Bar Baz' innerText() now
// returns only the first text node 'Foo' instead of 'Foo Baz'
$text = $crawler->filterXPath('//body/p')->innerText();

// innerText() trims whitespace characters by default, but you can get
// the unchanged text by passing FALSE as argument
$text = $crawler->filterXPath('//body/p')->innerText(false);

Exit Code Management while Handling Console Signals

Contributed by Grégoire Pineau
in #49529.

In Symfony 6.3 we've made some changes in the logic that handles signals. First,
we only exit by default (to mimic PHP behavior) in SIGINT and SIGTERM.
Second, you can now tell via the console event to exit with a custom code (thanks
to the new $event->setExitCode($code); method).
Finally, inside a console event you can prevent the command to exit:

use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleSignalEvent;

$dispatcher->addListener(ConsoleEvents::SIGNAL, function (ConsoleSignalEvent $event) {
// ...

$event->abortExit();
});

Sponsor the Symfony project.