Duplicate Preferred Choices

Arnaud De Abreu
Contributed by Arnaud De Abreu in #50934

The preferred_choices option of the ChoiceType field allows you to display certain choices at the top of your list with a visual separator between them and the complete list of options.

Originally, those preferred choices were included only once at the top of the list. In Symfony 4.4, to avoid confusion from some people, we changed this and the choices are now rendered both at the top of the list and their original location.

This new behavior is also confusing for some people, so we've added a new config option so you can fully control if they should be rendered twice or not:

1
2
3
4
5
6
7
8
9
10
11
12
13
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...

$builder->add('language', ChoiceType::class, [
    'choices' => [
        'PHP' => 'php',
        'JavaScript' => 'js',
        'Twig' => 'twig',
        // ...
    ],
    'preferred_choices' => ['php', 'twig'],
    'duplicate_preferred_choices' => true,
]);
syl20b
Contributed by syl20b in #48841

The BrowserKit component simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically. In Symfony 6.4 we've improved the click() and clickLink() methods to allow setting custom server parameters that are added as request headers when clicking on the link:

1
2
3
4
5
6
7
$client = new Client();
$client->request('GET', '/product/123');

$crawler = $client->clickLink('Proceed to Checkout', ['X-Custom-Header' => 'Some data']);

$link = $crawler->selectLink('Proceed to Checkout')->link();
$client->click($link, ['X-Custom-Header' => 'Some data']);

Default Crawler Attributes

Rastishka
Contributed by Rastishka in #51368

The DomCrawler component eases the DOM navigation for HTML and XML documents. The methods text() and html(), which extract the text/HTML contents of the given node allow to define a default value. This is useful because trying to access the text/HTML of a node that doesn't exist will throw an exception:

1
2
3
4
5
// if the node does not exist, calling to text() will result in an exception
$message = $crawler->filterXPath('//body/p')->text();

// avoid the exception passing an argument that text() returns when node does not exist
$message = $crawler->filterXPath('//body/p')->text('Default text content');

In Symfony 6.4, we've improved the attr() method to also support a default value for the same reasons, to avoid exceptions when the node doesn't exist:

1
2
3
4
5
6
7
8
9
// instead of this...
try {
    $value = $dom->filter('a.someclass')->attr('href');
} catch (\InvalidArgumentException $e) {
    $value = '';
}

// ...do this
$value = $dom->filter('a.someclass')->attr('href', '');

Maximum Retries in HTTP Client

Daniel Burger
Contributed by Daniel Burger in #50240

By default, when requests fail because of network issues or temporary server errors, the HttpClient component retries failed requests up to 3 times, with an exponential delay between retries. In Symfony 6.4 we're improving this feature to allow you to set the exact number of max retries to attempt:

1
2
3
4
// ...
$client->request('GET', '/foo-bar', [
    'max_retries' => 1,  // 0 disables retrying
]);

Defined Env Var Processor

Gary PEGEOT
Contributed by Gary PEGEOT in #50791

The environment variable processors transform the original contents of a given environment variable (which is always a string) to turn it into other data types or to change its contents.

In Symfony 6.4 we're adding a new processor called defined which returns false if the env var doesn't exist or if it's null or the empty string. It returns true otherwise:

1
2
3
parameters:
    # ...
    is_captcha_enabled: '%env(defined:CLOUDFLARE_TURNSTILE_SITE_KEY)%'
Published in #Living on the edge