<?php
namespace App\Form;
use App\Entity\Usuario;
use App\Service\CpfValidator;
use App\Service\TelefoneValidator;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CountryType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\Callback;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\EmailValidator;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
class CadastroCandidatoType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$repository = $options['repository'];
$builder
->add('nome', TextType::class, [
'label' => 'Nome completo',
])
->add('nacionalidade', CountryType::class)
->add('cpf', TextType::class, [
'label' => 'CPF',
'constraints' => [
new Callback([
'callback' => function($value, ExecutionContextInterface $context) use ($repository){
if (empty($value)) return;
$cpf = new CpfValidator($value, true);
if (!$cpf->isValid()) {
$context->buildViolation('Este não é um CPF válido!')
->atPath('cpf')
->addViolation();
}
$user = $repository->findOneBy(['cpf' => $cpf]);
if ($user) {
$context->buildViolation("O CPF {$cpf} já está em uso por outro candidato. Se é seu CPF, faça o login.")
->atPath('cpf')
->addViolation();
}
$context->getRoot()->getData()->setCpf($cpf->getString());
}
]),
],
])
->add('passaporte', TextType::class, [
'label' => 'Passaporte',
'required' => false,
'constraints' => [
new Callback([
'callback' => function($value, ExecutionContextInterface $context) use ($repository){
if (empty($value)) return;
$nacionalidade = $context->getRoot()->getData()->getNacionalidade();
$passaporte = trim(strtoupper($value));
if (!preg_match('/^[A-Z0-9]{6,40}$/', $value)) {
$context->buildViolation("O Passaporte {$passaporte} ($nacionalidade) não é válido.")
->atPath('passaporte')
->addViolation();
}
$user = $repository->findOneBy(['passaporte' => $passaporte, 'nacionalidade' => $nacionalidade]);
if ($user) {
$context->buildViolation("O Passaporte {$passaporte} ($nacionalidade) já está em uso por outro candidato. Se é o seu passaporte, faça o login.")
->atPath('passaporte')
->addViolation();
}
$context->getRoot()->getData()->setPassaporte($passaporte);
}
]),
],
'help' => 'Estrangeiro: o seu Passaporte irá garantir o seu cadastro, mas você precisará apresentar um CPF válido para matrícula, no caso de aprovação.',
])
->add('telefone', TextType::class, [
'constraints' => [
new Callback([
'callback' => function($value, ExecutionContextInterface $context){
//if (empty($value)) return;
$nacionalidade = $context->getRoot()->getData()->getNacionalidade();
if ($nacionalidade == 'BR') {
$tel = new TelefoneValidator($value, null, true);
if (!$tel->isValid()) {
$context->buildViolation('Este não é um telefone válido!')
->atPath('telefone')
->addViolation();
}
$context->getRoot()->getData()->setTelefone($tel->getString());
}
else {
$tel = preg_replace('/[^\d]/', '', $value);
if (strlen($tel) < 8) {
$context->buildViolation('Este não parece ser telefone válido!')
->atPath('telefone')
->addViolation();
}
}
}
]),
],
])
->add('email', RepeatedType::class, [
'type' => EmailType::class,
'invalid_message' => 'Os emails devem ser iguais.',
'required' => true,
'first_options' => ['label' => 'E-mail', 'constraints' => [
new Email(['mode' => Email::VALIDATION_MODE_LOOSE]),
new Email(['mode' => Email::VALIDATION_MODE_STRICT])
]],
'second_options' => ['label' => 'Repita o e-mail'],
])
->add('plainPassword', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => 'As senhas devem ser iguais.',
'required' => true,
'first_options' => ['label' => 'Senha', 'constraints' => [
new Length([
'min' => 8,
'minMessage' => "Senha muito curta. Use pelo menos 8 caracteres entre minúsculas, maiúsculas, números e sinais. Por exemplo: ".Usuario::generatePassword(),
'allowEmptyString' => false
])
]],
'second_options' => ['label' => 'Repita a Senha']
])
->add('save', SubmitType::class, [
'label' => 'Cadastrar',
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Usuario::class,
'repository' => null,
]);
}
}