Issue 1:
Q
A

Bug report?
yes

Feature request?
no

BC Break report?
no

RFC?
no

Symfony version
3.2.7

If you have a configuration node with a non-string type, e.g. IntegerNode, and pass an env variable, even though the env variable will be resolved in an integer, the value won't pass the validation and throw an error when booting.

e.g.:

parameters:
int_val_param: '%env(INT_ENV_VAL)%'

app:
int_val: '%int_val_param%'

or:

app:
int_val: '%env(INT_ENV_VAL)%'

with:

// Configuration file

public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();

$treeBuilder->root('app')
->children()
->integerNode('int_val')
->isRequired()
->end()
->end()
;

return $treeBuilder;
}

will throw:

[Symfony\Component\DependencyInjection\Exception\EnvParameterException]
Incompatible use of dynamic environment variables "INT_ENV_VAL" found in parameters.

[Symfony\Component\Config\Definition\Exception\InvalidTypeException]
Invalid type for path "app.int_val". Expected int, but got 'string'.

Issue reproduced on the repo: https://github.com/theofidry/symfony-22594

Issue 2:
Depends on: #3879, #3968 (OptionsParser::replaceDefaults is required)

I want to add three options to the ChoiceType that abstract functionality of EntityType for use in all choice fields. See also #3479.

The new options are:

"choice_labels"

If given, the "choices" option is interpreted as storing the choices in the values instead of the keys. This way, choices can be created that select between values that are not allowed to be passed as array keys (any non-integer or non-string value).

"choice_labels" can be:

an array with a label for each choice

a callable that is executed for each choice and returns the label

a property path string, if the choices are objects

<?php
// The following two are equivalent
$builder->add('foo', 'choice', array(
'choices' => array(0 => 'no', 1 => 'yes'),
));
$builder->add('foo', 'choice', array(
'choices' => array(0, 1),
'choice_labels' => array('no', 'yes'),
));

// The following ones cannot be expressed without the new option
$builder->add('foo', 'choice', array(
'choices' => array(null, false, true),
'choice_labels' => array('maybe', 'no', 'yes'),
));
$builder->add('foo', 'choice', array(
'choices' => array($obj1, $obj2),
'choice_labels' => 'name',
));
$builder->add('foo', 'choice', array(
'choices' => array($obj1, $obj2),
'choice_labels' => function ($obj) {
return 'Label for ' . $obj->name;
},
));

"choice_values"

Like "choice_labels", but stores/generates the values that are stored in the "value" attributes of the generated HTML. Values must be strings and unique (i.e. no two choices must have the same value).

By default, the choices are used as values, if possible. If not possible, integer values are generated.

Like "choice_labels", this option can be an array, a callable or a string (if choices are objects).

<?php
$builder->add('foo', 'choice', array(
'choices' => array($obj1, $obj2),
'choice_labels' => 'name',
'choice_values' => 'id',
));

"choice_attr"

Like choice_values.

"group_by"

The "group_by" option stores a callable that returns the choice group for each choice or a property path if the choices are objects.

<?php
$builder->add('favNumber', 'choice', array(
'choices' => range(0, 100),
'choice_labels' => range(0, 100),
'group_by' => function ($choice) {
return $choice % 2 == 0 ? 'Even' : 'Odd',
}
));

"preferred_choices"

The "preferred_choices" option allows to pass the values of the preferred choices as array, a callable or a property path if the choices are objects.

$builder->add('foo', 'choice', array(
'choices' => array(null, false, true),
'choice_labels' => array('maybe', 'no', 'yes'),
'preferred_choices' => array(true, false),
));
$builder->add('foo', 'choice', array(
'choices' => array($obj1, $obj2),
'preferred_choices' => 'preferred', // i.e. isPreferred()
));
$builder->add('foo', 'choice', array(
'choices' => array($obj1, $obj2),
'preferred_choices' => function ($obj) {
return $obj instanceof PreferredSomething;
},
));

Poll

If the "choices" option is given as hierarchical array sorting each choice into a choice group, there are two possible ways for associating choices with their labels/values. Which one do you prefer?

A. Duplicate the hierarchy

<?php
$builder->add('favNumber', 'choice', array(
'choices' => array(
'Even' => array($obj0, $obj2, $obj4),
'Odd' => array($obj1, $obj3, $obj5),
),
'choice_labels' => array(
'Even' => array('Zero', 'Two', 'Four'),
'Odd' => array('One', 'Three', 'Five'),
),
'choice_values' => array(
'Even' => array(0, 2, 4),
'Odd' => array(1, 3, 5),
),
));

B. Array-index based

<?php
$builder->add('favNumber', 'choice', array(
'choices' => array(
'Even' => array(0 => $obj0, 2 => $obj2, 4 => $obj4),
'Odd' => array(1 => $obj1, 3 => $obj3, 5 => $obj5),
),
'choice_labels' => array(
array(0 => 'Zero', 1 => 'One', 2 => 'Two', 3 => 'Three', 4 => 'Four', 5 => 'Five'),
),
'choice_values' => array(
array(0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5),
),
));

Please name your preferred option in the comments.