I use FOSUserBundle with a custom registration form that extends the one provided by the bundle. I want to override the validation so it doesn't check for a username (I generate it). I have read that this can be achieved thru the usage of validation groups.
These are the relevant parts of my form:
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
...
$builder->remove('username');
...
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Ysu\Bundle\SiteBundle\Entity\User',
'validation_groups' => array('my-registration-group'),
'cascade_validation' => true
));
}
...
However the username is still validated with the validation files provided by the bundle. I found out that $options (array) contains an array validation_groupswhich in its turn contains the 'Registration' group, so that is why the field is still validated. However, I don't know how to remove it. If I unset it from $optionsbefore passing it to parent::buildFormit will still contain the Registration group.
Does anyone know how to solve this?
Turns out you can configure the validation groups for the FOSUserBundle's forms in config.yml:
fos_user:
....
registration:
form:
validation_groups: [default, registration_mod]
....
Related
I am attempting to upload a file via an API endpoint controller I have created:
/**
* #Route("/upload", methods="POST")
*/
public function upload(Request $request)
{
$form = $this->createForm(UserFileType::class);
$form->handleRequest($request);
if (!$form->isSubmitted()) {
dd($request->files->get('file'));
}
...
The dd($request->files->get('file')) is showing my file as expected so I am unclear why isSubmitted() is returning false when the method is receiving multipart/form-data POST request with data. I am submitting the POST request via Postman. Why is the form not submitted?
UserFileType:
class UserFileType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('file', FileType::class, [
'mapped' => false,
'required' => true,
'constraints' => [
new File([
'maxSize' => '2M',
'mimeTypes' => [
'application/pdf',
'application/x-pdf',
],
'maxSizeMessage' => 'The file size must not exceed {{ limit }} {{ suffix }}.',
'mimeTypesMessage' => 'The file type {{ type }} is not valid',
])
],
]);
}
For form classes derived from AbstractType, the form is named using fqcnToBlockPrefix when it's built through FormFactory.
You can confirm this by dumping $form->getName().
Now, $form->handleRequest method as implemented performs a number of checks through the request handler before submitting the form.
Checks the method matches that of the form
Checks the name of the form is present in the request if the form has a name
Checks that at least one of the form fields are filled if the form has no name
Your form is not submitting through the request handler handleRequest method because fields in the request are not properly mapped together with your form name.
You have to map the form name in your HTTP POST request in following way:
[ "user_file" => [ "file" => <uploaded file> ] ]
This may prove to not be straight forward in Postman.
Therefore I recommend to implement your form as a nameless form instead by overriding getBlockPrefix to return an empty string.
class UserFileType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
//...
}
public function getBlockPrefix()
{
return '';
}
}
Since this is the first SO thread that comes up for the keywords handlerequest issubmitted false, I thought I would share what worked for my team on an adjacent issue.
We were getting a false response when doing a PATCH request. We eventually realized that we were neglecting to pass Request::METHOD_PATCH in the method option when creatin the form. Putting in a ternary statement that set that value was enough to solve our problem.
I hope this helps someone.
I have a Symfony project with FOSUserBundle, i extended the FormType in my personal Bundle following this guide "http://symfony.com/doc/master/bundles/FOSUserBundle/overriding_forms.html"
I created a Person entity with first name, last name, adresse ..., created its FormType like this :
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('firstName', TextType::class)
->add('lastName', TextType::class)
->add('adress', TextType::class)
->add('account', AccountType::class) ;
}
The Account entity is the user class for FOSUserBundle
Then i generated the CRUD for Person, the newAction() looks like this :
public function newAction(Request $request)
{
$person = new Person();
$form = $this->createForm('AppBundle\Form\PersonType', $person);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$person->getAccount()->setEnabled(1); //i'm doing this because it's not automatic
$em->persist($person->getAccount());
$em->persist($person);
$em->flush($person);
return $this->redirectToRoute('fos_user_security_login'); // redirecting to the login page because it's not done automatically
}
return $this->render('person/new.html.twig', array(
'person' => $person,
'form' => $form->createView(),
));
}
The two entitys have a OneToOne relationship, with this code they are both persisted in the data base and i can use the username and password to log in normally
Here is my FOSUerBundle configuration :
fos_user:
db_driver: orm
firewall_name: main
user_class: AppBundle\Entity\Account
from_email:
address: "%mailer_user%"
sender_name: "%mailer_user%"
registration:
form:
type: AppBundle\Form\AccountType
I want to the user to log in automatically after registration like it happens when using the default FOSUserBundle registration, anyone got an idea how to do so ?
I tried a lot of stuff but no success
Thanks for your answers
I was able to login from my controller using the $person->getAccount() object:
All i have to do is dispatch the REGISTRATION_COMPLETED event like in the default Controller : https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Controller/RegistrationController.php#L78
Just copied some code to my controller
This will trigger the authentication : https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/EventListener/AuthenticationListener.php
I want to set CSRF error bubbling to false in symfony, on a form, using form builder.
I thought this would do it
$builder->get('_token')->setErrorBubbling(false);
but it gives me
The child with the name "_token" does not exist.
The csrf_field_name is set to '_token'. So, does the token get generated after my form building or something? Any ideas how I can do this?
many thanks
Dave
If you want to disable the CSRF token you have two options:
When creating the form on the controller pass an option:
$form = $this->createForm(new AcmeForm(), $acme, array(
'csrf_protection' => false
));
Or as default option on your form class:
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'csrf_protection' => false
}
I have a form like this made with Symfony2:
class UsuarioRegistroType extends AbstractType {
public function BuildForm(FormBuilderInterface $builder, array $options) {
$builder->add('email', 'email', array('label' => 'E-mail', 'required' => true))
....
Forms works fine, but if I write something like Email: asdf (not email address), I never get the error assosiated with this issue. Also, if I don't write anything, I don't get any error for required constraint.
Any idea with this issue?
Thanks :)
Required true don't validate anything. It just add a class required on the field on the form view. It's the html5 which validate that.
Try to add that on UsuarioRegistroType class :
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$collectionConstraint = new Collection(array(
'email' => array(
new NotBlank(array('message' => 'Email should not be blank.')),
new Email(array('message' => 'Invalid email address.'))
)
));
$resolver->setDefaults(array(
'constraints' => $collectionConstraint
));
}
don't forget the use statements :
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Collection;
You have just used HTML5 validation, many barowser do not support this. With this old version of different famous browser also not support HTML5 validation.
I think you should use annotation for validation from serverside. I think you know about annotation , which you can use in your Entity class. In your enity class property you may defined your required validation rules using annotaion in symfony2.
Example:
use Symfony\Component\Validator\Constraints as Assert;
class Author
{
/**
* #Assert\Email(
* message = "The email '{{ value }}' is not a valid email.",
* checkMX = true
* )
*/
protected $email;
}
Helpful link from Symfony2 official documentation: Symfony2 Validation
I am attempting to override the RegistrationFormType in the Symfony2 FOSUserBundle. I am following the documentation and believe i've covered everything. I've created a bundle to contain my overrides to the FOSUserBundle and the following code is from this bundle as well as the application config.
Has anyone experienced this when overriding FOSUserBundle, or see anything in my code that would help explain why I keep getting this error.
I'm on symfony v2.0.4
RegistrationFormType.php
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Thrive\SaasBundle\Form\Type;
use Symfony\Component\Form\FormBuilder;
use FOS\UserBundle\Form\Type\RegistrationFormType as BaseType;
class RegistrationFormType extends BaseType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('firstname', null, array('error_bubbling' => true))
->add('lastname', null, array('error_bubbling' => true))
->add('company', null, array('error_bubbling' => true))
->add('email', 'email', array('error_bubbling' => true))
->add('username', null, array('error_bubbling' => true))
->add('plainPassword', 'repeated', array('type' => 'password', 'error_bubbling' => true))
;
}
public function getName()
{
return 'thrive_user_registration';
}
}
Services.yml
services:
thrive_saas_registration.form.type:
class: Thrive\SaasBundle\Form\Type\RegistrationFormType
arguments: [%fos_user.model.user.class%]
tags:
- { name: form.type, alias: thrive_user_registration}
Application's Config File
fos_user:
...
registration:
form:
type: thrive_user_registration
Turns out my services.yml file wasn't being loaded via dependency injection. After digging around i realized my extension.php file for this bundle was named incorrectly. Early on I had renamed the bundle and made a typo when renaming the extension.php file inside the DependencyInjection folder. After correcting the mispelling everything works again.
Did you tried to just add one new field and look if it works?
public function buildForm(FormBuilder $builder, array $options)
{
parent::buildForm($builder, $options);
// add your custom field
$builder->add('name');
}
Also remember to clear your prod cache if you're testing from there...