feat: require all personal data fields for registration

This commit is contained in:
Björn Fromme
2026-01-27 18:25:38 +01:00
parent e9548d9f38
commit dc91660488
5 changed files with 88 additions and 45 deletions
+1 -8
View File
@@ -90,14 +90,7 @@ class ApiClient
'key' => $this->createKey($this->config['bpn_username'], $this->config['bpn_password'], static::TYPE_CUSTOMER_DATA), 'key' => $this->createKey($this->config['bpn_username'], $this->config['bpn_password'], static::TYPE_CUSTOMER_DATA),
'satz' => ['@typ' => static::TYPE_CUSTOMER_DATA], 'satz' => ['@typ' => static::TYPE_CUSTOMER_DATA],
'art' => 'Adresse_Neu', 'art' => 'Adresse_Neu',
'adressdaten' => [ 'adressdaten' => $registrationData->toPayload(),
'geschlecht' => $registrationData->gender,
'vorname' => $registrationData->firstName,
'name' => $registrationData->name,
'kommunikation' => [
'email' => $registrationData->email,
],
],
]; ];
return $this->sendRequest(static::TYPE_CUSTOMER_DATA, $data); return $this->sendRequest(static::TYPE_CUSTOMER_DATA, $data);
+2 -2
View File
@@ -41,12 +41,12 @@ class RegistrationController extends AbstractController
$this->addFlash('success', 'Du erhältst in Kürze eine E-Mail mit einem Link zum (Zurück)setzen deines Passworts.'); $this->addFlash('success', 'Du erhältst in Kürze eine E-Mail mit einem Link zum (Zurück)setzen deines Passworts.');
} }
$this->logger->info('Initiated registration', [ $this->logger->info('Initiated registration', [
'email' => $registrationData->email, 'email' => $registrationData->communication->email,
]); ]);
} catch (ApiClientException $e) { } catch (ApiClientException $e) {
$this->addFlash('error', $e->getMessage()); $this->addFlash('error', $e->getMessage());
$this->logger->error('Error initiating registration', [ $this->logger->error('Error initiating registration', [
'email' => $registrationData->email, 'email' => $registrationData->communication->email,
'error' => $e->getMessage(), 'error' => $e->getMessage(),
]); ]);
} }
+39 -3
View File
@@ -1,7 +1,11 @@
<?php <?php
declare(strict_types=1);
namespace App\Form\Model; namespace App\Form\Model;
use App\BusProNet\Model\Address;
use App\BusProNet\Model\Communication;
use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Constraints as Assert;
class RegistrationDto class RegistrationDto
@@ -13,10 +17,42 @@ class RegistrationDto
public ?string $name = null; public ?string $name = null;
#[Assert\NotBlank(message: 'Bitte angeben')] #[Assert\NotBlank(message: 'Bitte angeben')]
#[Assert\Choice(choices: ['M', 'W', 'd'])] #[Assert\Choice(choices: ['M', 'W', 'D'], message: 'Bitte gib einen gültigen Wert an')]
public ?string $gender = null; public ?string $gender = null;
#[Assert\NotBlank(message: 'Bitte angeben')] #[Assert\NotBlank(message: 'Bitte angeben')]
#[Assert\Email(message: 'Bitte eine gültige E-Mail Adresse angeben', mode: 'strict')] public ?\DateTimeImmutable $dateOfBirth = null;
public ?string $email = null;
#[Assert\NotBlank(message: 'Bitte angeben')]
public ?string $nationality = null;
#[Assert\Valid]
public Address $address;
#[Assert\Valid]
public Communication $communication;
public function __construct()
{
$this->address = new Address();
$this->communication = new Communication();
}
/**
* Converts the registration data to API payload format.
*
* @return array<string, mixed>
*/
public function toPayload(): array
{
return [
'geschlecht' => $this->gender,
'vorname' => $this->firstName,
'name' => $this->name,
'nationalitaet' => $this->nationality,
'geburtsdatum' => $this->dateOfBirth?->format('d.m.Y'),
'anschrift' => $this->address->toPayload(),
'kommunikation' => $this->communication->toPayload(),
];
}
} }
+7 -13
View File
@@ -1,11 +1,11 @@
<?php <?php
declare(strict_types=1);
namespace App\Form; namespace App\Form;
use App\Form\Model\RegistrationDto; use App\Form\Model\RegistrationDto;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
@@ -15,24 +15,17 @@ class RegistrationType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options): void public function buildForm(FormBuilderInterface $builder, array $options): void
{ {
$builder $builder
->add('gender', ChoiceType::class, [
'label' => 'Gender',
'choices' => [
'männlich' => 'M',
'weiblich' => 'W',
'divers' => 'D',
],
])
->add('firstName', TextType::class, [ ->add('firstName', TextType::class, [
'label' => 'Name', 'label' => 'Vorname',
'sanitize_html' => true, 'sanitize_html' => true,
]) ])
->add('name', TextType::class, [ ->add('name', TextType::class, [
'label' => 'Nachname', 'label' => 'Nachname',
'sanitize_html' => true, 'sanitize_html' => true,
]) ])
->add('email', EmailType::class, [ ->add('personalData', PersonalDataType::class, [
'label' => 'E-Mail', 'label' => false,
'inherit_data' => true,
]) ])
; ;
} }
@@ -41,6 +34,7 @@ class RegistrationType extends AbstractType
{ {
$resolver->setDefaults([ $resolver->setDefaults([
'data_class' => RegistrationDto::class, 'data_class' => RegistrationDto::class,
'validation_groups' => ['Default', 'personal_data'],
]); ]);
} }
} }
+39 -19
View File
@@ -1,30 +1,50 @@
{% extends 'layout.html.twig' %} {% extends 'layout.html.twig' %}
{% block content %} {% block content %}
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 px-4 lg:px-8 py-8 lg:py-16"> <div class="px-4 lg:px-8 py-8 lg:py-16">
<div> <h1 class="text-white uppercase pb-4 mb-8 border-b border-primary-bg/40">
<h1 class="text-white uppercase pb-4 mb-8 border-b border-primary-bg/40"> Registrierung
Registrierung <br>
<br> MyE&amp;P
MyE&amp;P </h1>
</h1> {% include '_partials/_flashes.html.twig' %}
{% include '_partials/_flashes.html.twig' %} {{ form_start(form) }}
<div class="pb-4"> <div class="grid md:grid-cols-2 gap-x-8 gap-y-4 pb-4">
{{ form_start(form) }} <div>
<h3 class="text-white">
Persönliches
</h3>
{{ form_row(form.personalData.gender, { 'label_attr': { 'class': 'text-white' } }) }}
{{ form_row(form.firstName, { 'label_attr': { 'class': 'text-white' } }) }} {{ form_row(form.firstName, { 'label_attr': { 'class': 'text-white' } }) }}
{{ form_row(form.name, { 'label_attr': { 'class': 'text-white' } }) }} {{ form_row(form.name, { 'label_attr': { 'class': 'text-white' } }) }}
{{ form_row(form.email, { 'label_attr': { 'class': 'text-white' } }) }} {{ form_row(form.personalData.dateOfBirth, { 'label_attr': { 'class': 'text-white' } }) }}
{{ form_row(form.gender, { 'label_attr': { 'class': 'text-white' } }) }} {{ form_row(form.personalData.nationality, { 'label_attr': { 'class': 'text-white' } }) }}
<button type="submit" class="button button--primary"> <h3 class="text-white">
Jetzt registrieren Kontakt
</button> </h3>
{{ form_rest(form) }} {{ form_row(form.personalData.email, { 'label_attr': { 'class': 'text-white' } }) }}
{{ form_end(form) }} {{ form_row(form.personalData.mobile, { 'label_attr': { 'class': 'text-white' } }) }}
{{ form_row(form.personalData.phone, { 'label_attr': { 'class': 'text-white' } }) }}
</div> </div>
<a href="{{ path('app_login') }}" <div>
class="text-white underline"> <h3 class="text-white">
Anschrift
</h3>
{{ form_row(form.personalData.street, { 'label_attr': { 'class': 'text-white' } }) }}
{{ form_row(form.personalData.postCode, { 'label_attr': { 'class': 'text-white' } }) }}
{{ form_row(form.personalData.city, { 'label_attr': { 'class': 'text-white' } }) }}
{{ form_row(form.personalData.country, { 'label_attr': { 'class': 'text-white' } }) }}
</div>
</div>
<div class="flex justify-between">
<a href="{{ path('app_login') }}" class="button button--secondary">
Zum Login Zum Login
</a> </a>
<button type="submit" class="button button--primary">
Jetzt registrieren
</button>
</div> </div>
{{ form_rest(form) }}
{{ form_end(form) }}
</div> </div>
{% endblock %} {% endblock %}