This commit removes CollectionToStringTransformer. Transformers should never change the state of the outside world, otherwise hard-to-track bugs might creap in.
This functionality needs to be implemented as a custom FieldType (see EntityChoiceField).
The implication is that set<Reference>() in the object of the parent form will not be called (and thus not has to be implemented/public).
If you want to suppress this behaviour, manually set "by_reference" to false.
Separated validation of data and form had serious drawbacks. When a form had nested form whose data was not connected to the data of the root form, this data would not be validated.
The new implementation validates the whole object graph at once. Class Form has a new method validateData(), that manually passes the data to the GraphWalker of the Validator and overrides the Default group with the groups set in the form.
With the form factory there was no reasonable way to implement instantiation of custom form classes. So the implementation was changed to let the classes instantiate themselves. A FormContext instance with default settings has to be passed to the creation method. This context is by default configured in the DI container.
$context = $this->get('form.context');
// or
$context = FormContext::buildDefault();
$form = MyFormClass::create($context, 'author');
If you want to circumvent this process, you can also create a form manually. Remember that the services stored in the default context won't be available then unless you pass them explicitely.
$form = new MyFormClass('author');
A form now always has to be bound, independent of whether the request is a POST request or not. The bind() method detects itself whether the request was a post request or not and reads its data accordingly. The "old" bind()/isBound() methods were renamed to submit()/isSubmitted().
$form = new Form('author');
$form->bind($request, $author);
if ($form->isValid()) {
// isValid() implies isSubmitted(), non-submitted forms can
// never be valid
// do something with author now
}
Alternatively, you can only bind global variables, if you don't have a request object.
$form->bindGlobals($author);
Note that the $author object is in both cases optional. You can also pass no object at all and read the data using $form->getData(), but then no validation will occur. You can also prefill the form with an object during instantiation.
$form = new Form('author', array('data' => $author));
$form->bind($request);
// etc.
* Added empty_value option on CountryField, LanguageField, LocaleField, TimezoneField
* Added missing date_pattern to DateTimeField
* Made the currency option on MoneyField required.