This is mainly intended for complex configurations to ease the work you
have with normalizing different configuration formats (YAML, XML, and PHP).
First, you have to set-up a config tree:
$treeBuilder = new TreeBuilder();
$tree = $treeBuilder
->root('security_config', 'array')
->node('access_denied_url', 'scalar')->end()
->normalize('encoder')
->node('encoders', 'array')
->key('class')
->prototype('array')
->before()->ifString()->then(function($v) { return array('algorithm' => $v); })->end()
->node('algorithm', 'scalar')->end()
->node('encode_as_base64', 'scalar')->end()
->node('iterations', 'scalar')->end()
->end()
->end()
->end()
->buildTree()
;
This tree and the metadata attached to the different nodes is then used
to intelligently transform the passed config array:
$normalizedConfig = $tree->normalize($config);
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.