2011-03-18 15:34:54 +00:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Component\Form ;
2011-03-19 13:31:25 +00:00
use Symfony\Component\Form\Exception\FormException ;
2011-03-19 18:20:55 +00:00
use Symfony\Component\Form\Exception\UnexpectedTypeException ;
2011-03-18 15:34:54 +00:00
use Symfony\Component\EventDispatcher\EventDispatcherInterface ;
2012-04-13 15:42:01 +01:00
/**
2012-05-16 18:25:27 +01:00
* A builder for creating { @ link Form } instances .
*
2012-04-13 15:42:01 +01:00
* @ author Bernhard Schussek < bschussek @ gmail . com >
*/
2012-07-28 09:59:23 +01:00
class FormBuilder extends FormConfigBuilder implements \IteratorAggregate , FormBuilderInterface
2011-03-18 15:34:54 +00:00
{
2011-05-10 13:24:23 +01:00
/**
2012-05-16 18:25:27 +01:00
* The children of the form builder .
*
2011-05-10 13:24:23 +01:00
* @ var array
*/
2011-03-25 01:12:01 +00:00
private $children = array ();
2011-03-18 15:34:54 +00:00
2011-05-10 13:24:23 +01:00
/**
2012-05-16 18:25:27 +01:00
* The data of children who haven ' t been converted to form builders yet .
*
* @ var array
2011-05-10 13:24:23 +01:00
*/
2012-05-16 18:25:27 +01:00
private $unresolvedChildren = array ();
2011-03-27 14:12:35 +01:00
2011-12-14 14:01:09 +00:00
/**
2012-08-26 07:28:19 +01:00
* The parent of this builder .
*
2011-12-14 14:01:09 +00:00
* @ var FormBuilder
*/
private $parent ;
2011-05-10 13:24:23 +01:00
/**
2012-05-17 15:09:13 +01:00
* Creates a new form builder .
2011-05-10 13:24:23 +01:00
*
2012-05-18 18:41:48 +01:00
* @ param string $name
* @ param string $dataClass
2012-05-17 15:09:13 +01:00
* @ param EventDispatcherInterface $dispatcher
* @ param FormFactoryInterface $factory
2012-07-28 09:59:23 +01:00
* @ param array $options
2011-05-10 13:24:23 +01:00
*/
2012-05-23 17:47:14 +01:00
public function __construct ( $name , $dataClass , EventDispatcherInterface $dispatcher , FormFactoryInterface $factory , array $options = array ())
2011-03-20 12:35:19 +00:00
{
2012-05-23 17:47:14 +01:00
parent :: __construct ( $name , $dataClass , $dispatcher , $options );
2012-01-16 23:02:58 +00:00
2012-12-14 15:05:05 +00:00
$this -> setFormFactory ( $factory );
2011-03-20 12:35:19 +00:00
}
2011-03-18 15:34:54 +00:00
/**
2012-05-23 18:34:41 +01:00
* { @ inheritdoc }
2011-03-18 15:34:54 +00:00
*/
2011-04-24 09:54:50 +01:00
public function add ( $child , $type = null , array $options = array ())
2011-03-18 15:34:54 +00:00
{
2012-07-28 09:59:23 +01:00
if ( $this -> locked ) {
throw new FormException ( 'The form builder cannot be modified anymore.' );
}
2011-04-24 09:54:50 +01:00
if ( $child instanceof self ) {
2011-12-14 14:01:09 +00:00
$child -> setParent ( $this );
2011-04-24 09:54:50 +01:00
$this -> children [ $child -> getName ()] = $child ;
2012-05-16 18:25:27 +01:00
// In case an unresolved child with the same name exists
unset ( $this -> unresolvedChildren [ $child -> getName ()]);
2011-04-24 09:54:50 +01:00
return $this ;
}
2012-12-14 18:27:28 +00:00
if ( ! is_string ( $child ) && ! is_int ( $child )) {
throw new UnexpectedTypeException ( $child , 'string, integer or Symfony\Component\Form\FormBuilder' );
2011-03-18 15:34:54 +00:00
}
2011-03-27 13:05:06 +01:00
if ( null !== $type && ! is_string ( $type ) && ! $type instanceof FormTypeInterface ) {
2011-04-22 16:41:21 +01:00
throw new UnexpectedTypeException ( $type , 'string or Symfony\Component\Form\FormTypeInterface' );
2011-03-19 18:42:16 +00:00
}
2012-07-06 16:32:57 +01:00
// Add to "children" to maintain order
$this -> children [ $child ] = null ;
2012-05-16 18:25:27 +01:00
$this -> unresolvedChildren [ $child ] = array (
'type' => $type ,
'options' => $options ,
2011-03-19 18:42:16 +00:00
);
return $this ;
}
2011-05-30 14:17:05 +01:00
/**
2012-05-23 18:34:41 +01:00
* { @ inheritdoc }
2011-05-30 14:17:05 +01:00
*/
2011-04-24 09:54:50 +01:00
public function create ( $name , $type = null , array $options = array ())
2011-03-19 18:42:16 +00:00
{
2012-07-28 09:59:23 +01:00
if ( $this -> locked ) {
throw new FormException ( 'The form builder cannot be modified anymore.' );
}
2012-05-17 15:09:13 +01:00
if ( null === $type && null === $this -> getDataClass ()) {
2011-06-09 10:37:06 +01:00
$type = 'text' ;
}
2011-03-19 18:20:55 +00:00
if ( null !== $type ) {
2012-12-14 15:05:05 +00:00
return $this -> getFormFactory () -> createNamedBuilder ( $name , $type , null , $options , $this );
2011-03-18 15:34:54 +00:00
}
2012-12-14 15:05:05 +00:00
return $this -> getFormFactory () -> createBuilderForProperty ( $this -> getDataClass (), $name , null , $options , $this );
2011-03-18 15:34:54 +00:00
}
2011-05-30 14:17:05 +01:00
/**
2012-05-23 18:34:41 +01:00
* { @ inheritdoc }
2011-05-30 14:17:05 +01:00
*/
2011-03-18 15:34:54 +00:00
public function get ( $name )
{
2012-05-16 18:25:27 +01:00
if ( isset ( $this -> unresolvedChildren [ $name ])) {
return $this -> resolveChild ( $name );
2011-03-18 15:34:54 +00:00
}
2012-05-16 18:25:27 +01:00
if ( isset ( $this -> children [ $name ])) {
return $this -> children [ $name ];
2011-03-18 15:34:54 +00:00
}
2012-05-16 18:25:27 +01:00
throw new FormException ( sprintf ( 'The child with the name "%s" does not exist.' , $name ));
2011-03-18 15:34:54 +00:00
}
/**
2012-05-23 18:34:41 +01:00
* { @ inheritdoc }
2011-03-18 15:34:54 +00:00
*/
public function remove ( $name )
{
2012-07-28 09:59:23 +01:00
if ( $this -> locked ) {
throw new FormException ( 'The form builder cannot be modified anymore.' );
}
2012-05-20 10:18:31 +01:00
unset ( $this -> unresolvedChildren [ $name ]);
2012-05-16 18:25:27 +01:00
2012-07-10 07:48:09 +01:00
if ( array_key_exists ( $name , $this -> children )) {
2011-12-14 14:01:09 +00:00
if ( $this -> children [ $name ] instanceof self ) {
$this -> children [ $name ] -> setParent ( null );
}
2011-03-25 01:12:01 +00:00
unset ( $this -> children [ $name ]);
2011-03-19 21:03:49 +00:00
}
2011-05-10 13:26:38 +01:00
return $this ;
2011-03-18 15:34:54 +00:00
}
/**
2012-05-23 18:34:41 +01:00
* { @ inheritdoc }
2011-03-18 15:34:54 +00:00
*/
public function has ( $name )
{
2012-05-16 18:25:27 +01:00
if ( isset ( $this -> unresolvedChildren [ $name ])) {
return true ;
}
if ( isset ( $this -> children [ $name ])) {
return true ;
}
return false ;
2011-03-18 15:34:54 +00:00
}
2011-05-10 13:24:23 +01:00
/**
2012-05-23 18:34:41 +01:00
* { @ inheritdoc }
2012-04-11 18:07:08 +01:00
*/
public function all ()
{
2012-05-16 18:25:27 +01:00
$this -> resolveChildren ();
2012-04-11 18:07:08 +01:00
return $this -> children ;
}
2012-05-24 13:24:28 +01:00
/**
* { @ inheritdoc }
*/
public function count ()
{
return count ( $this -> children );
}
2012-04-11 18:07:08 +01:00
/**
2012-05-23 18:34:41 +01:00
* { @ inheritdoc }
2011-05-10 13:24:23 +01:00
*/
2011-03-20 14:16:53 +00:00
public function getForm ()
2011-03-18 15:34:54 +00:00
{
2012-05-16 18:25:27 +01:00
$this -> resolveChildren ();
2011-03-18 15:34:54 +00:00
2012-07-28 09:59:23 +01:00
$form = new Form ( $this -> getFormConfig ());
2011-03-18 15:34:54 +00:00
2012-05-16 18:25:27 +01:00
foreach ( $this -> children as $child ) {
$form -> add ( $child -> getForm ());
2011-03-18 15:34:54 +00:00
}
2012-05-16 18:25:27 +01:00
return $form ;
2011-03-18 15:34:54 +00:00
}
2011-05-10 13:24:23 +01:00
2011-12-14 14:01:09 +00:00
/**
2012-05-23 18:34:41 +01:00
* { @ inheritdoc }
2011-12-14 14:01:09 +00:00
*/
public function getParent ()
{
return $this -> parent ;
}
/**
2012-05-23 18:34:41 +01:00
* { @ inheritdoc }
2011-12-14 14:01:09 +00:00
*/
2012-05-23 18:34:41 +01:00
public function setParent ( FormBuilderInterface $parent = null )
2011-12-14 14:01:09 +00:00
{
2012-07-28 09:59:23 +01:00
if ( $this -> locked ) {
throw new FormException ( 'The form builder cannot be modified anymore.' );
}
2011-12-14 14:01:09 +00:00
$this -> parent = $parent ;
return $this ;
}
2012-05-24 13:24:28 +01:00
/**
* { @ inheritdoc }
*/
public function hasParent ()
{
return null !== $this -> parent ;
}
2011-05-10 13:24:23 +01:00
/**
2012-05-16 18:25:27 +01:00
* Converts an unresolved child into a { @ link FormBuilder } instance .
2011-05-10 13:24:23 +01:00
*
2012-05-16 18:25:27 +01:00
* @ param string $name The name of the unresolved child .
*
* @ return FormBuilder The created instance .
2011-05-10 13:24:23 +01:00
*/
2012-05-16 18:25:27 +01:00
private function resolveChild ( $name )
2011-05-10 13:24:23 +01:00
{
2012-05-16 18:25:27 +01:00
$info = $this -> unresolvedChildren [ $name ];
$child = $this -> create ( $name , $info [ 'type' ], $info [ 'options' ]);
$this -> children [ $name ] = $child ;
unset ( $this -> unresolvedChildren [ $name ]);
return $child ;
2011-05-10 13:24:23 +01:00
}
/**
2012-05-16 18:25:27 +01:00
* Converts all unresolved children into { @ link FormBuilder } instances .
2011-05-10 13:24:23 +01:00
*/
2012-05-16 18:25:27 +01:00
private function resolveChildren ()
2011-05-10 13:24:23 +01:00
{
2012-05-16 18:25:27 +01:00
foreach ( $this -> unresolvedChildren as $name => $info ) {
$this -> children [ $name ] = $this -> create ( $name , $info [ 'type' ], $info [ 'options' ]);
2011-05-10 13:24:23 +01:00
}
2012-05-16 18:25:27 +01:00
$this -> unresolvedChildren = array ();
2011-05-10 13:24:23 +01:00
}
2012-05-24 13:24:28 +01:00
/**
* { @ inheritdoc }
*/
public function getIterator ()
{
return new \ArrayIterator ( $this -> children );
}
2012-07-12 18:17:14 +01:00
/**
* Returns the types used by this builder .
*
2012-11-01 15:08:59 +00:00
* @ return FormTypeInterface [] An array of FormTypeInterface
2012-07-12 18:17:14 +01:00
*
* @ deprecated Deprecated since version 2.1 , to be removed in 2.3 . Use
* { @ link FormConfigInterface :: getType ()} instead .
*/
public function getTypes ()
{
2012-12-12 16:43:13 +00:00
trigger_error ( 'getTypes() is deprecated since version 2.1 and will be removed in 2.3. Use getConfig() and FormConfigInterface::getType() instead.' , E_USER_DEPRECATED );
2012-07-12 18:17:14 +01:00
$types = array ();
for ( $type = $this -> getType (); null !== $type ; $type = $type -> getParent ()) {
array_unshift ( $types , $type -> getInnerType ());
}
return $types ;
}
2011-06-08 11:16:48 +01:00
}