<?php
namespace App\Form;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Boab\CmsBundle\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CountryType;
use Boab\CmsBundle\Repository\UserRepositoryInterface;
use Boab\CmsBundle\Security\RandomGeneratorInterface;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Validator\Constraints\IsTrue;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
class SignupType extends AbstractType
{
protected $userRepository;
protected $authorizationChecker;
private $passwordHasher;
private $randomStringGenerator;
public function __construct(
UserRepositoryInterface $userRepository,
AuthorizationCheckerInterface $authorizationChecker,
UserPasswordHasherInterface $passwordHasher,
RandomGeneratorInterface $randomStringGenerator)
{
$this->userRepository = $userRepository;
$this->authorizationChecker = $authorizationChecker;
$this->passwordHasher = $passwordHasher;
$this->randomStringGenerator = $randomStringGenerator;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('firstname', TextType::class, [
'attr' => [
'class'=>'form-control',
'placeholder'=>'First Name',
],
'constraints' => [
new NotBlank()
],
]
)
->add('lastname', TextType::class, [
'attr' => [
'class'=>'form-control',
'placeholder'=>'Last Name',
],
'constraints' => [
new NotBlank()
],
]
)
->add('email', EmailType::class, [
'attr' => [
'class'=> 'form-control',
'placeholder'=>'Email Address',
],
'constraints' => [
new NotBlank(array('message' => 'This field is require')),
new Email(['message' => 'Invalid email address.'])
],
]
)
->add('agreeTerms', CheckboxType::class, [
'mapped' => false,
'attr' => [
'class' => 'custom-control-input'
],
'constraints' => [
new IsTrue([
'message' => 'You should agree to our terms.',
]),
],
])
->add('plainPassword', PasswordType::class, [
// instead of being set onto the object directly,
// this is read and encoded in the controller
'mapped' => false,
'attr' => [
'autocomplete' => 'new-password',
'class' => 'form-control',
'placeholder'=>'Password',
],
'constraints' => [
new NotBlank([
'message' => 'Please enter a password',
]),
new Length([
'min' => 6,
'minMessage' => 'Your password should be at least {{ limit }} characters',
// max length allowed by Symfony for security reasons
'max' => 4096,
]),
],
])
;
$builder->addEventListener(FormEvents::SUBMIT, function(FormEvent $event){
$form = $event->getForm();
$customer = $event->getData();
$username = $this->randomStringGenerator->generate(6);
if(!$customer->getId()){
$passwordEncoded = $this->passwordHasher->hashPassword($customer, $form->get('plainPassword')->getData());
$customer->setPassword($passwordEncoded);
$customer->setUsername(strtolower($username));
$customer->setIsActivated(false);
$customer->setCreatedAt(new \DateTime('now'));
}
});
$builder->get('email')->addEventListener(FormEvents::PRE_SUBMIT, function(FormEvent $event)use($options){
$email = $event->getData();
$user = $this->userRepository->findOneBy(['email'=>$email]);
if($user){
$event->getForm()->addError(new FormError('A user with this email already exists'));
}
});
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
'user'=>null,
]);
}
}