<?php
namespace Nen\Bundle\KennisbankPlatformBundle\Form;
use App\Entity\User;
use Doctrine\ORM\EntityRepository;
use App\Entity\Company;
use Nen\Bundle\KennisbankPlatformBundle\Form\Constraint\StrongPasswordConstraint;
use Nen\Bundle\KennisbankPlatformBundle\Form\DataTransformer\RolesDataTransformer;
use Nen\Bundle\KennisbankPlatformBundle\Service\PlatformUserRolesProvider;
use Nen\Bundle\KennisbankPlatformBundle\Service\UserRolesProvider;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManager;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\NotCompromisedPassword;
class UserType extends AbstractType
{
private UserRolesProvider $userRolesProvider;
private Security $security;
private AccessDecisionManagerInterface $accessDecisionManager;
public function __construct(UserRolesProvider $userRolesProvider, Security $security, AccessDecisionManagerInterface $accessDecisionManager)
{
$this->userRolesProvider = $userRolesProvider;
$this->security = $security;
$this->accessDecisionManager = $accessDecisionManager;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(
'sex',
ChoiceType::class,
[
'label' => 'Aanhef',
'choices' => User::getSexes(),
'expanded' => true,
'multiple' => false,
'label_attr' => [
'class' => 'radio-inline',
],
]
)
->add(
'initials',
null,
[
'label' => 'Voorletters',
'attr' => [
'placeholder' => 'Voorletters',
],
]
)
->add(
'firstname',
null,
[
'label' => 'Voornaam',
'attr' => [
'placeholder' => 'Voornaam',
],
]
)
->add(
'lastnamePrefix',
null,
[
'label' => 'Tussenvoegsel',
'required' => false,
'attr' => [
'placeholder' => 'Tussenvoegsel',
],
]
)
->add(
'lastname',
null,
[
'label' => 'Achternaam',
'attr' => [
'placeholder' => 'Achternaam',
],
]
)
->add(
'username',
null,
[
'label' => 'E-mailadres',
'attr' => [
'placeholder' => 'E-mailadres',
],
]
)
->add(
'job',
null,
[
'label' => 'Functie',
'attr' => [
'placeholder' => 'Functie',
],
]
);
$type = $options['type'];
if ($type == 'register') {
$builder->add(
'hash',
RepeatedType::class,
[
// instead of being set onto the object directly,
// this is read and encoded in the controller
'type' => PasswordType::class,
'mapped' => false,
'first_options' => [
'label' => 'Wachtwoord',
'constraints' => [
new NotBlank(
[
'message' => 'Ontbrekende waarde.',
]
),
new StrongPasswordConstraint(),
new NotCompromisedPassword([
'message' => 'Het ingevulde wachtwoord is niet veilig genoeg. Deze voldoet niet aan de onderstaande voorwaarden of staat op de lijst van onveilige veelvoorkomende wachtwoorden.',
]),
],
],
'second_options' => [
'label' => 'Wachtwoord nogmaals',
'constraints' => [
new NotBlank(
[
'message' => 'Ontbrekende waarde.',
]
),
],
],
]
)
->add(
'license_code',
TextType::class,
[
'required' => true,
'mapped' => false,
]
);
}
if ($type !== 'profile') {
$roles = $this->userRolesProvider->getSelectableRolesForForm();
// When the form is in edit or registration mode check the roles of the current
// user and disable roles that cannot be set. Edit or registration mode is when
// the company manager is editing the users of their company.
if ($type === 'edit' || $type === 'registration' || $type === 'administration') {
if (!$this->security->isGranted(PlatformUserRolesProvider::ROLE_CUSTOMER_SERVICE)) {
$roles = array_filter($roles, static function ($role) {
return !in_array($role, [
PlatformUserRolesProvider::ROLE_ADMINISTRATOR,
PlatformUserRolesProvider::ROLE_CUSTOMER_SERVICE
], true);
});
}
if (!$this->security->isGranted(PlatformUserRolesProvider::ROLE_ADMINISTRATOR)) {
$roles = array_filter($roles, static function ($role) {
return !in_array($role, [
PlatformUserRolesProvider::ROLE_ADMINISTRATOR,
PlatformUserRolesProvider::ROLE_CUSTOMER_SERVICE
], true);
});
}
}
$userToken = $builder->getData() !== null ? new UsernamePasswordToken($builder->getData(), 'none', 'main', $builder->getData()->getRoles()) : null;
$builder->add(
'roles',
ChoiceType::class,
[
'label' => 'Rollen',
'choices' => $roles,
'disabled' => $userToken !== null && $this->accessDecisionManager->decide($userToken, [PlatformUserRolesProvider::ROLE_CUSTOMER_SERVICE]),
'expanded' => false,
'multiple' => true,
]
);
$builder->get('roles')->addModelTransformer(new RolesDataTransformer());
// $builder->add(
// 'role',
// ChoiceType::class,
// [
// 'label' => 'Rol',
// 'choices' => User::getUserRoles(),
// 'expanded' => false,
// 'multiple' => false,
// 'label_attr' => [
// 'class' => 'radio-inline',
// ],
// ]
// )
// ->add(
// 'manager',
// CheckboxType::class,
// [
// 'label' => 'Bedrijfsbeheerder',
// 'required' => false,
// ]
// );
}
if (in_array($type, ['registration', 'upgrade'])) {
$builder->add('company', CompanyType::class, ['license' => $options['license'], 'type' => $type]);
}
if ($type == 'administration') {
$builder->add(
'company',
EntityType::class,
[
// looks for choices from this entity
'class' => Company::class,
'label' => 'Organisatie',
'placeholder' => 'Kies een organisatie',
'query_builder' => function (EntityRepository $repository) {
return $repository
->createQueryBuilder('c')
->orderBy('c.name', 'ASC');
},
// uses the User.username property as the visible option string
'choice_label' => 'name',
]
)
->add(
'ips',
CollectionType::class,
[
'entry_type' => IpType::class,
'allow_add' => true,
'prototype' => true,
'by_reference' => false,
'label' => 'IP adressen',
]
);
}
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
[
'data_class' => User::class,
'license' => null,
'type' => 'registration',
]
);
}
}