src/Form/RegisterAccountForm.php line 33

Open in your IDE?
  1. <?php
  2. namespace App\Form;
  3. use App\Entity\Location\City;
  4. use App\Entity\User;
  5. use App\Repository\CityRepository;
  6. use App\Repository\UserRepository;
  7. use App\Service\DefaultCityProvider;
  8. use App\Service\Features;
  9. use App\Validator\Constraints\EmailNotBlack;
  10. use EWZ\Bundle\RecaptchaBundle\Form\Type\EWZRecaptchaType;
  11. use EWZ\Bundle\RecaptchaBundle\Validator\Constraints\IsTrue;
  12. use Symfony\Bridge\Doctrine\Form\Type\EntityType;
  13. use Symfony\Component\Form\AbstractType;
  14. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  15. use Symfony\Component\Form\Extension\Core\Type\EmailType;
  16. use Symfony\Component\Form\Extension\Core\Type\HiddenType;
  17. use Symfony\Component\Form\Extension\Core\Type\PasswordType;
  18. use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
  19. use Symfony\Component\Form\Extension\Core\Type\TextType;
  20. use Symfony\Component\Form\FormBuilderInterface;
  21. use Symfony\Component\Form\FormEvent;
  22. use Symfony\Component\Form\FormEvents;
  23. use Symfony\Component\Intl\Countries;
  24. use Symfony\Component\OptionsResolver\OptionsResolver;
  25. use Symfony\Component\Validator\Constraints\Callback;
  26. use Symfony\Component\Validator\Constraints\Email;
  27. use Symfony\Component\Validator\Constraints\Length;
  28. use Symfony\Component\Validator\Constraints\NotBlank;
  29. use Symfony\Component\Validator\Context\ExecutionContextInterface;
  30. class RegisterAccountForm extends AbstractType
  31. {
  32.     public function __construct(
  33.         private Features $features,
  34.         private CityRepository $cityRepository,
  35.         private UserRepository $userRepository,
  36.         private DefaultCityProvider $defaultCityProvider,
  37.     ) {}
  38.     public function buildForm(FormBuilderInterface $builder, array $options): void
  39.     {
  40.         $builder
  41.             ->add('accountType'HiddenType::class, [
  42.                 'mapped' => false,
  43.             ]);
  44.         $builder
  45.             ->add('nickName'TextType::class)
  46.             ->add('plainPassword'RepeatedType::class, [
  47.                 'type' => PasswordType::class,
  48.             ])
  49.             ->add('email'EmailType::class, [
  50.                 'constraints' => [
  51.                     new NotBlank(),
  52.                     new Length(['min' => 5]),
  53.                     new Email(),
  54.                     new EmailNotBlack(),
  55.                     new Callback(function($objectExecutionContextInterface $context$payload): void {
  56.                         if(!empty($object) && null != $this->userRepository->findOneBy(['email' => $object])) {
  57.                             $context->buildViolation('Email already in use')
  58.                                 ->atPath('email')
  59.                                 ->addViolation()
  60.                             ;
  61.                         }
  62.                     }),
  63.                 ],
  64.             ])
  65.         ;
  66.         if ($this->features->multiple_cities()) {
  67.             $cityCountries $this->cityRepository->cityCountries();
  68.             if (count($cityCountries) > 1) {
  69.                 $builder
  70.                     ->add('country'ChoiceType::class, [
  71.                         'placeholder'  => 'Выберите страну',
  72.                         'choices'      => $cityCountries,
  73.                         'choice_label' => function ($choice): string {
  74.                             return Countries::getName($choice);
  75.                         },
  76.                         'required' => true,
  77.                     ]);
  78.             }
  79.             $builder
  80.                 ->add('city'EntityType::class, [
  81.                     'class'        => City::class,
  82.                     'placeholder'  => 'Выберите',
  83.                     'choice_label' => 'name',
  84.                     'choice_attr'  => function (City $city): array {
  85.                         return ['data-country' => $city->getCountryCode()];
  86.                     },
  87.                     'required' => true,
  88.                     'constraints' => [
  89.                         new NotBlank(),
  90.                     ],
  91.                 ]);
  92.         }
  93.         if (true === $options['use_captcha']) {
  94.             $builder->add($options['captcha_field_name'], EWZRecaptchaType::class, [
  95.                 'mapped' => false,
  96.                 'constraints' => [
  97.                     new IsTrue(),
  98.                 ],
  99.             ]);
  100.         }
  101.         $builder->addEventListener(FormEvents::POST_SUBMIT, [$this'onSubmit']);
  102.     }
  103.     public function configureOptions(OptionsResolver $resolver): void
  104.     {
  105.         $resolver->setDefaults([
  106.             'data_class' => User::class,
  107.             'validation_groups' => ['Default''Registration'],
  108.             'use_captcha' => false,
  109.             'captcha_field_name' => 'captcha',
  110.         ]);
  111.         $resolver->setAllowedTypes('use_captcha''boolean');
  112.         $resolver->setAllowedTypes('captcha_field_name''string');
  113.     }
  114.     public function onSubmit(FormEvent $event): void
  115.     {
  116.         $user $event->getData();
  117.         if(null === $user) {
  118.             return;
  119.         }
  120.         /** @var User $user */
  121.         if(null === $user->getCity()) {
  122.             $user->setCity($this->defaultCityProvider->getDefaultCity());
  123.         }
  124.     }
  125. }