<?php
namespace App\Form;
use App\Entity\Enum\RoleEnum;
use App\Entity\RoleManagement;
use App\Entity\User;
use App\Form\Type\ImageFieldType;
use App\Service\Settings\RoleService;
use Doctrine\ORM\EntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\TelType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Validator\Constraints\IsTrue;
use Symfony\Component\Validator\Constraints\Regex;
use Symfony\Contracts\Translation\TranslatorInterface;
class RegistrationFormType extends AbstractType
{
public function __construct(
private TranslatorInterface $translator,
private Security $security,
private ManagerRegistry $registry,
private RoleService $roleService,
private ParameterBagInterface $parameterBag
) {}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$selectedRole = $this->getSelectedRole($options['roleId']);
/** @var User $user */
$user = $this->security->getUser();
$builder
->add('firstName', TextType::class, [
'required' => false,
'label' => 'register.firstName'
])
->add('lastName', TextType::class, [
'required' => false,
'label' => 'register.lastName'
])
->add('email', EmailType::class, [
'label' => 'login.email'
])
->add('phoneCountryCode', HiddenType::class, [
'required' => false,
'attr' => [
'class' => 'codeInput'
]
])
->add('phoneNo', TelType::class, [
'required' => false,
'label' => 'register.phoneNo',
'attr' => [
'class' => 'phoneInput'
]
])
->add('jobPosition', TextType::class, [
'required' => false,
'label' => 'register.position'
])
->add('plainPassword', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => $this->translator->trans('register.repeatPasswordMessage', [], 'security'),
'required' => true,
'mapped' => false,
'first_options' => [
'label' => 'login.password',
'constraints' => [
new Regex([
'message' => $this->translator->trans('register.passwordRegex', [], 'security'),
'htmlPattern' => '/^(?=.*?[0-9])(?=.*[A-Z]).{6,}$/',
'pattern' => '/^(?=.*?[0-9])(?=.*[A-Z]).{6,}$/'
])
],
],
'second_options' => [
'label' => 'register.repeatPasswordLabel'
],
])
->add('privacyPolicy', CheckboxType::class, [
'required' => false,
'constraints' => [
new IsTrue([
'message' => $this->translator->trans('register.required', [], 'security'),
])
]
])
->add('termsConditions', CheckboxType::class, [
'required' => false,
'constraints' => [
new IsTrue([
'message' => $this->translator->trans('register.required', [], 'security'),
])
]
])
->add('newsletterSubscription', CheckboxType::class, [
'label' => 'register.newsletterLabel',
'required' => false,
])
;
if ($options['edit'] === true) {
if ($this->canEditImage($options['userId'])) {
$builder
->add('profileImage', ImageFieldType::class, [
'required' => false,
'path' => $this->parameterBag->get('users_directory')
]);
}
if ($this->roleService->isSuperAdmin() || $this->roleService->isRegularAdmin() && $user->getId() !== $options['userId']) {
$builder
->add('isActive', CheckboxType::class, [
'required' => false
])
->add('isVerified', CheckboxType::class, [
'required' => false
])
;
}
if ($this->roleService->isSuperAdmin()) {
$builder
->add('userRole', EntityType::class, [
'class' => RoleManagement::class,
'choice_label' => 'roleName',
'label' => 'register.userRole',
'attr' => ['class' => 'select2'],
'mapped' => false,
'data' => $selectedRole,
'placeholder' => $this->translator->trans('admin.select', [], 'admin')
]);
}
if ($this->roleService->isRegularAdmin() && $user->getId() !== $options['userId']) {
$builder
->add('userRole', EntityType::class, [
'class' => RoleManagement::class,
'choice_label' => 'roleName',
'label' => 'register.userRole',
'attr' => ['class' => 'select2'],
'mapped' => false,
'data' => $selectedRole,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->andWhere('u.roleName != :superAdmin')
->setParameter('superAdmin', RoleEnum::SUPER_ADMIN->value)
;
},
'placeholder' => $this->translator->trans('admin.select', [], 'admin')
]);
}
if ($user->getId() === $options['userId']) {
$builder
->add('oldPassword', PasswordType::class, [
'required' => false,
'mapped' => false,
'label' => 'admin.oldPassword',
'attr' => [
'data-message' => $this->translator->trans('register.passwordRegex', [], 'security'),
'data-repeat' => $this->translator->trans('register.repeatPasswordMessage', [], 'security'),
],
'constraints' => [
new Regex([
'message' => $this->translator->trans('register.passwordRegex', [], 'security'),
'htmlPattern' => '/^(?=.*?[0-9])(?=.*[A-Z]).{6,}$/',
'pattern' => '/^(?=.*?[0-9])(?=.*[A-Z]).{6,}$/'
])
],
])
->add('plainPassword', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => $this->translator->trans('register.repeatPasswordMessage', [], 'security'),
'required' => false,
'mapped' => false,
'first_options' => [
'label' => 'admin.newPassword',
'constraints' => [
new Regex([
'message' => $this->translator->trans('register.passwordRegex', [], 'security'),
'htmlPattern' => '/^(?=.*?[0-9])(?=.*[A-Z]).{6,}$/',
'pattern' => '/^(?=.*?[0-9])(?=.*[A-Z]).{6,}$/'
])
],
],
'second_options' => [
'label' => 'admin.repeatNewPassword'
],
]);
}
} else {
if ($user) {
if ($this->roleService->isSuperAdmin()) {
$builder
->add('userRole', EntityType::class, [
'class' => RoleManagement::class,
'choice_label' => 'roleName',
'label' => 'register.userRole',
'attr' => ['class' => 'select2'],
'mapped' => false,
'placeholder' => $this->translator->trans('admin.select', [], 'admin')
]);
}
if ($this->roleService->isRegularAdmin()) {
$builder
->add('userRole', EntityType::class, [
'class' => RoleManagement::class,
'choice_label' => 'roleName',
'label' => 'register.userRole',
'attr' => ['class' => 'select2'],
'mapped' => false,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->andWhere('u.roleName != :superAdmin')
->setParameter('superAdmin', RoleEnum::SUPER_ADMIN->value)
;
},
'placeholder' => $this->translator->trans('admin.select', [], 'admin')
]);
}
}
}
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => User::class,
'translation_domain' => 'security',
'create' => false,
'edit' => false,
'roleId' => null,
'userId' => null,
]);
}
private function getSelectedRole(?int $roleId): null|RoleManagement
{
if (!$roleId) return null;
return $this->registry->getRepository(RoleManagement::class)->find($roleId);
}
private function canEditImage(int $userId): bool
{
/** @var User $user */
$user = $this->security->getUser();
if ($this->roleService->isSuperAdmin()) return true;
return $userId === $user->getId();
}
}