Form before handleRequest: no global errors.
Form {#1852 ▼
-config: FormBuilder {#1851 ▶}
-parent: null
-children: OrderedHashMap {#1836 ▶}
-errors: []
-submitted: false
-clickedButton: null
-modelData: User {#2096 ▶}
-normData: User {#2096 ▶}
-viewData: User {#2096 ▶}
-extraData: []
-synchronized: true
-defaultDataSet: true
-lockSetData: false
}
Request: 'firstname' field is passed.
Request {#3 ▼
+attributes: ParameterBag {#6 ▶}
+request: ParameterBag {#4 ▼
#parameters: array:1 [▼
"registration" => array:6 [▼
"firstname" => "foo"
"lastname" => "bar"
"email" => "[email protected]"
"accountType" => "bbbbbb"
"school_info" => array:4 [▶]
"_token" => "1a55e2d7474183267374a0007e15b92e6114158d"
]
]
}
...
}
Form after handleRequest: global error with error message from 'firstname' field, but no error in the field itself.
Form {#1852 ▼
-config: FormBuilder {#1851 ▶}
-parent: null
-children: OrderedHashMap {#1836 ▼
-elements: array:5 [▼
"firstname" => Form {#1835 ▼
-config: FormBuilder {#1854 ▶}
-parent: Form {#1852}
-children: OrderedHashMap {#1853 ▶}
-errors: []
-submitted: true
-clickedButton: null
-modelData: "poipoi"
-normData: "poipoi"
-viewData: "poipoi"
-extraData: []
-synchronized: true
-defaultDataSet: true
-lockSetData: false
}
"email" => Form {#1858 ▶}
"lastname" => Form {#1861 ▶}
"accountType" => Form {#1864 ▶}
"school_info" => Form {#1867 ▶}
]
-orderedKeys: array:5 [▶]
-managedCursors: []
}
-errors: array:3 [▼
0 => FormError {#728 ▼
-message: "missing email"
#messageTemplate: "missing email"
#messageParameters: array:1 [▶]
#messagePluralization: null
}
1 => FormError {#733 ▼
-message: "missing firstname"
#messageTemplate: "missing firstname"
#messageParameters: array:1 [▶]
#messagePluralization: null
}
2 => FormError {#738 ▼
-message: "missing lastname"
#messageTemplate: "missing lastname"
#messageParameters: array:1 [▶]
#messagePluralization: null
}
]
-submitted: true
-clickedButton: null
-modelData: User {#2096 ▶}
-normData: User {#2096 ▶}
-viewData: User {#2096 ▶}
-extraData: []
-synchronized: true
-defaultDataSet: true
-lockSetData: false
}
Same issue for 'firstname', 'lastname' and 'email'. Notice how the errors are global to the form, and there is no error in the fields themselves. Also, error bubbling does not affect the issue.
Form Type:
<?php
namespace Acme\SiteBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Acme\SiteBundle\Entity\User;
/**
*
*/
class RegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('firstname', null, array('label' => 'firstname'))
->add('lastname', null, array('label' => 'lastname'))
->add('email', 'email', array('label' => 'form.email'))
->add('accountType', 'choice'));
$builder->add('school_info', 'school_info', array(
'label' => 'School',
'cascade_validation' => false,
'mapped' => false,
'required' => false,
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\\SiteBundle\\Entity\\User',
'intention' => 'registration',
'validation_groups' => function (FormInterface $form) {
$data = $form->getData();
if ($this->isPro($data)) {
return array('HKCustomRegistration', 'account_type_pro');
} else {
return array('HKCustomRegistration', 'account_type');
}
},
'cascade_validation' => true,
));
}
public function getName()
{
return 'registration';
}
}
Embedded Form (school_info) Form Type.
Key point : The issue only happens when the school_info form is added as a field in the registration form and shool input is filled in (if not filled in, bug does not happen).
<?php
namespace Acme\SiteBundle\Form\Type;
use Acme\SiteBundle\Service\SiteProvider;
use Acme\SiteBundle\Entity\School;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Doctrine\ORM\EntityRepository;
class SchoolInfoType extends AbstractType
{
private $site;
public function __construct(SiteProvider $siteProvider)
{
$this->site = $siteProvider->getCurrentSiteDB();
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$site = $this->site;
$builder
->add('school', 'entity', array(
'empty_value' => '------------',
'class' => 'AcmeSiteBundle:School',
'query_builder' => function (EntityRepository $er) use ($site) {
return $er->createQueryBuilder('sc')
->where('sc.site = :site')
->setParameter('site', $site)
->addOrderBy('sc.name', 'ASC');
},
'mapped' => true, // mapped but not persisted
'label' => 'school',
));
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\SiteBundle\Entity\User',
'site' => null,
));
}
public function getName()
{
return 'school_info';
}
Validation constraints in the Entity:
/**
* @var string
*
* @ORM\Column(name="firstname", type="string", length=100, nullable=true)
* @Assert\NotBlank(groups={"HKCustomRegistration", "HKCustomProfile", "Default", "sylius"}, message="missing firstname")
*/
private $firstname;