Issue 1:
Having a layer of validation on the browser is great, but most of the time the guesser gets it all wrong!

Take this example: If you create a boolean field on an entity and let the guesser do its work, it sets the field as a required checkbox.

How can one choose the false option then?

The same happen with text fields.

If the column is not nullable but I'm not validating it's content, an empty value is just saved as an empty string on the db…

… unless you have HTML5 validation enabled on your browser. Why don't the type guesser don't follow what the rest of the application is doing?

Maybe the guesser should set the "required" atribute only when the field is explicitly validated with NotBlank or NotNull.

Issue 2:
Build a form from a form type class:

public function buildForm( FormBuilder $builder, array $options )
{
$builder
->add( 'text', 'text', array(
'label' => 'search.form.text.label'
) )
->add( 'date', 'date', array(
'widget' => 'single_text',
'format' => 'dd.MM.yyyy',
'label' => 'search.form.date.label'
) );
}

Add basic validation rules where none of the fields are required:

Me\MyBundle\Form\Model\TextSearch:
properties:
date:
- Type: \DateTime

Render the form:

<form method="post" {{ form_enctype( form ) }}>
{{ form_widget( form ) }}
<input type="submit" value="Search" />
</form>

All the fields get a required attribute:

<label for="text_search_text" class=" required">Text</label>
<input type="text" id="text_search_text" name="text_search[text]" required="required" value="" />

This is incorrect, since the validation rules state that they are not required.

Under Forms (2.0) – Form Validation, the documentation states:

HTML5 Validation

As of HTML5, many browsers can natively enforce certain validation constraints on the client side. The most common validation is activated by rendering a required attribute on fields that are required. […]

Generated forms take full advantage of this new feature by adding sensible HTML attributes that trigger the validation.

This is clearly not the case: all the fields get the required attribute.

Also, under Built-in Field Types – Field Type Options (i.e. not under Form Validation), one can read:

The required option

The most common option is the required option, which can be applied to any field. By default, the required option is set to true, meaning that HTML5-ready browsers will apply client-side validation if the field is left blank.

In other words, Symfony is artificially introducing a discrepancy between the client- and the server-side validation criteria, and this by default.

Moreover, there is a conflict between the two cited paragraphs of the documentation. The first one states that the required attribute is rendered on fields that are required, which is confirmed by the following paragraph under Field Type Guessing – Field Type Options Guessing:

required: The required option can be guessed based off of the validation rules (i.e. is the field NotBlank or NotNull) or the Doctrine metadata (i.e. is the field nullable). This is very useful, as your client-side validation will automatically match your validation rules.

However, the second paragraph states that the required option is set to true by default.

Resolution

The documentation should be corrected for consistency: under Built-in Field Types – Field Type Options:

By default, the required option is set to true on the fields that are guessed to be required based on the validation rules, meaning that HTML5-ready browsers will apply client-side validation if the field is left blank.

Symfony’s behaviour should be changed to match the documentation: the required option should be set based on the guessed value and not to true by default.