Set password hidden in FOS UserBundle - php

I wanted to set the password field in registration form hidden since I don't need the password in my first step registration. The field is right now not showing since I have overridden the form, But still I could not submit the form because it says password should not be blank.
So I have tried this and its not working
class RegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('firstname')
->add('lastname')
->add('username')
->add('plainPassword',HiddenType::class)
->add('sex')
->add('email')
->add('city')
->add('zip_code')
->add('age');
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class'=>'AppBundle\Entity\User'
]);
}
public function getBlockPrefix()
{
return 'app_bundle_registration_type';
}
}
Any help would be appreciated.
Thanks.

$builder
->add('password', HiddenType::class, [
'required' => false,
'validation_groups' => false
]);
You have a third parameter to provide options, you can use this to make it optional.

To modify the NotBlank constraint you could override the FOSUserBundle/Resources/config/validation.xml. Copy it to MyBundle/Resources/config/validation.xml and make changes you want.

So however managed to solve this for now with the help of OlivierC!
So I used life cycle callbacks to persist the data in the entity.
http://symfony.com/doc/current/doctrine/lifecycle_callbacks.html
Entity:
/**
* #ORM\Entity
* #ORM\HasLifecycleCallbacks()
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* #ORM\PrePersist()
*/
public function setPassword($password)
{
$this->password = 'abcdef';
}}
Now it doesn't show as blank and for registration with password, I would need to update this field.

Related

Symfony form common fields inheritance/composition

I have 2 entities A and B that share common fields, I used a trait to setup those common fields based on (Doctrine inheritance for entities common fields) because I don't want to use a MappedSuperClass.
Setting up a restful post route for entity B, I instantiate a FormBType which data_class maps to B::class, that extends FormCType (contains common fields and 'data_class' maps to nothing).
I tried to use the inherit_data approach with https://symfony.com/doc/current/form/inherit_data_option.html but I don't want that extra key/nested layer in my form (I want a flattened one).
My problem is that validation for the common fields which are in the trait using Assert aren't taken into account and form passes validation with empty strings.
class B {
use CTrait;
}
//trait that has the common fields with ORM mapping and Assert
trait CTrait {
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string")
* #ORM\Assert\Length(min="2")
*/
private $name;
}
//Common fields formType
class CType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name');
}
}
//Form using the common fields formType
class BType extends CType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => B::class,
'csrf_protection' => false,
]);
}
}
After further checking on Length I realized empty strings are considered valid values and it was still passing through validation using name: "" even though I had Assert\Length(min=2), after adding NotBlank the validation worked.

Symfony3 FOSuserbundle register form one to one entity

i neeed in my symfony base aplication 4 types of user,one of them is super user and can be just typical fosuserbundle user, but need to admin can add 3 different type of user. So i do a new Client class for one type of user which has 1:1 entity with my base user class
class Client{
my client class fields
...
/**
* #ORM\OneToOne(targetEntity="AppBundle\Entity\User")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
...
}
And my User class
class User extends BaseUser
{......}
The Question is how to do a register form for this ? Please help me
Now i have this UserType form
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => User::class,
));
}
public function getParent()
{
return 'FOS\UserBundle\Form\Type\RegistrationFormType';
}
public function getBlockPrefix()
{
return 'app_user_registration';
}
}
And my clientForm class
class ClientForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TextType::class)
->add('address', TextareaType::class)
->add('phone', TextType::class)
->add('deliveryAddress', TextareaType::class)
->add('user', UserType::class);
}
public function getParent()
{
return 'FOS\UserBundle\Form\Type\RegistrationFormType';
}
public function getBlockPrefix()
{
return 'app_user_registration';
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Client::class,
]);
}
}
But this give me a error
Neither the property "email" nor one of the methods "getEmail()", "email()", "isEmail()", "hasEmail()", "__get()" exist and have public access in class "AppBundle\Entity\Client".
Oki, becuse earlier i've try a lot of different way to do this, i just delete getParent and getBlockPrefix from my ClientForm class and all look fine :)

Symfony2 Embedded forms How to assign values of certain form fields to child form field

I have entity User and entity Company.
Relations are Company (one) to User (many).
When I signup as a company I need both these objects to be created.
Both objects have same properties: $phone, $firstName, $lastName;
(for company those fields mean main contact person).
My registration form consists of 2 forms: user form and embedded company form.
Problem: Now when I render signup form I have duplicated fields:
phone, firstName, lastName rendered for each object.
Is there a way to combine them somehow and ask for those values from user only once but still to save them into database for both entities?
I've managed to solve this problem using event listeners on PRE_SUBMIT event:
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
/**
* Class CompanyRegFormType
* #package AppBundle\Form
*/
class UserFormType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('firstName', 'text')
->add('lastName', 'text')
->add('phone', 'text')
->add('company', new CompanyFormType())
->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event){
$data = $event->getData();
$data['company']['phone'] = $data['phone'];
$data['company']['firstName'] = $data['firstName'];
$data['company']['lastName'] = $data['lastName'];
$event->setData($data);
}
);
}
/**
* #return string
*/
public function getName()
{
return 'app_user_registration';
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => 'AppBundle\Entity\User',
]);
}
}

Symfony2 UniqueEntity constraint SQL error instead of message

I'm stuck with creating a user registration form with Symfony2.
I'm trying to define an Unique constraint on the email attribute of my User class.
Acme\APPBundle\Entity\User.php
namespace Acme\APPBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* #ORM\Entity
* #ORM\Entity(repositoryClass="Acme\APPBundle\Entity\UserRepository")
* #ORM\Table("users")
* #UniqueEntity(
* fields={"email"},
* message="email already used"
* )
*/
class User implements UserInterface, \Serializable
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=255, unique=true)
* #Assert\NotBlank()
* #Assert\Email()
*/
protected $email;
[...]
}
Acme\APPBundle\Form\Type\UserType.php
namespace Acme\APPBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('email', 'email');
$builder->add('password', 'repeated', array(
'first_name' => 'password',
'second_name' => 'confirm',
'type' => 'password',
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\APPBundle\Entity\User',
'cascade_validation' => true,
));
}
public function getName()
{
return 'user';
}
}
I've added the constraint following the documentation but I still get an exception like :
An exception occured while executing 'INSERT INTO users ( ... )'
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry
It looks like my message value defined in annotations is ignored and the form validation is bypassed since it should fail before attempting to insert row in database.
Can you tell me what am I doing wrong ?
EDIT :
Following Matteo 'Ingannatore' G.'s advice I've noticed that my form is not properly validated.
I forgot to mention that I use a registration class that extends the user form. I've written my code after what is explained in the Symfony Cookbook.
Thus I have :
Acme\APPBundle\Form\Model\Registration.php
namespace Acme\APPBundle\Form\Model;
use Symfony\Component\Validator\Constraints as Assert;
use Acme\APPBundle\Entity\User;
class Registration
{
/**
* #Assert\Type(type="Acme\APPBundle\Entity\User")
*/
protected $user;
/**
* #Assert\NotBlank()
* #Assert\True()
*/
protected $termsAccepted;
public function setUser(User $user)
{
$this->user = $user;
}
public function getUser()
{
return $this->user;
}
public function getTermsAccepted()
{
return $this->termsAccepted;
}
public function setTermsAccepted($termsAccepted)
{
$this->termsAccepted = (Boolean) $termsAccepted;
}
}
Acme\APPBundle\Form\Type\RegistrationType.php
namespace Acme\APPBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class RegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('user', new UserType());
$builder->add('terms', 'checkbox', array('property_path' => 'termsAccepted'));
}
public function getName()
{
return 'registration';
}
}
Acme\APPBundle\Controller\AccountController.php
namespace Acme\APPBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Acme\AccountBundle\Form\Type\RegistrationType;
use Acme\AccountBundle\Form\Model\Registration;
class AccountController extends Controller
{
public function registerAction()
{
$form = $this->createForm(new RegistrationType(), new Registration());
return $this->render('AcmeAPPBundle:Account:register.html.twig', array('form' => $form->createView()));
}
public function createAction()
{
$em = $this->getDoctrine()->getEntityManager();
$form = $this->createForm(new RegistrationType(), new Registration());
$form->handleRequest($this->getRequest());
if ($form->isValid()) { // FIXME !!
$registration = $form->getData();
$em->persist($registration->getUser());
$em->flush();
return $this->redirect($this->generateUrl('home'));
}
return $this->render('AcmeAPPBundle:Account:register.html.twig', array('form' => $form->createView()));
}
}
I guess the error I get might be caused by the fact that the Registration Form is validated, but the User Form within isn't submitted to validation. Am I wrong ?
How can I simply change that behaviour ? I saw there is a cascade_validation option but it seems to be useless here.
I think it's strange that Symfony Cookbook provides both guides to create a user provider and create a registration form but does not explain how to get those work along.
I finally found what the acutal problem was.
The validation was processed only on the RegistrationType instance but not on the UserType within.
To make sure that the validation also checks the constraints for the user I added the following code to my RegistrationType class :
public function setDefaultOptions(Options ResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\APPBundle\Form\Model\Registration',
'cascade_validation' => true,
));
}
What changes everything is the cascade_validation option that must be set to true for this class while this option is set on the UserType class in the CookBook example.
Also, don't forget to :
use Symfony\Component\OptionResolver\OptionsResolverInterface
in the file where you define the setDefaultOptions.

PreSubmit event created for register action interrupt with login action in UserController

I have the following UserType.php file,
<?php
namespace Acme\UserBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Acme\UserBundle\Controller\UserController;
class UserType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('UserName')
->add('description')
->add('email')
->add('password')
;
$builder->addEventListener(FormEvents::PRE_SUBMIT, array($this, 'onPreSubmit'));
}
public function onPreSubmit(FormEvent $event)
{
$User = $event->getData();
$email = $User['email'];
$UserObj = new UserController();
$unique_id = $UserObj->idUnique($email);
$User['userName'] = $unique_id;
$event->setData($User);
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\UserBundle\Entity\User'
));
}
/**
* #return string
*/
public function getName()
{
return 'acme_userbundle_user';
}
}
When user first registers in the site, I want to process his email to create unique id. For this, I get form data using events. Because, in symfony, you cannot modify form data after user pressing submit button. Hence, I use PreSubmit event to manipulate user's form data. It works well.
<?php
public function loginAction(Request $request)
{
$request = $this->getRequest();
// here program control goes directly to preSubmit event created for registration.
}
Now, when the user log in to the system, I am using same UserController.php (specified in code above) and a method called "login". But, this time when the user presses submit button, he is taken directly to the onPreSubmit event created for the purpose of form data manipulation for registration. How should I change the login controller method so that onPreSubmit should not interrupt while program control goes to login method?

Categories