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),
'satz' => ['@typ' => static::TYPE_CUSTOMER_DATA],
'art' => 'Adresse_Neu',
'adressdaten' => [
'geschlecht' => $registrationData->gender,
'vorname' => $registrationData->firstName,
'name' => $registrationData->name,
'kommunikation' => [
'email' => $registrationData->email,
],
],
'adressdaten' => $registrationData->toPayload(),
];
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->logger->info('Initiated registration', [
'email' => $registrationData->email,
'email' => $registrationData->communication->email,
]);
} catch (ApiClientException $e) {
$this->addFlash('error', $e->getMessage());
$this->logger->error('Error initiating registration', [
'email' => $registrationData->email,
'email' => $registrationData->communication->email,
'error' => $e->getMessage(),
]);
}
+39 -3
View File
@@ -1,7 +1,11 @@
<?php
declare(strict_types=1);
namespace App\Form\Model;
use App\BusProNet\Model\Address;
use App\BusProNet\Model\Communication;
use Symfony\Component\Validator\Constraints as Assert;
class RegistrationDto
@@ -13,10 +17,42 @@ class RegistrationDto
public ?string $name = null;
#[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;
#[Assert\NotBlank(message: 'Bitte angeben')]
#[Assert\Email(message: 'Bitte eine gültige E-Mail Adresse angeben', mode: 'strict')]
public ?string $email = null;
public ?\DateTimeImmutable $dateOfBirth = 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
declare(strict_types=1);
namespace App\Form;
use App\Form\Model\RegistrationDto;
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\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
@@ -15,24 +15,17 @@ class RegistrationType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('gender', ChoiceType::class, [
'label' => 'Gender',
'choices' => [
'männlich' => 'M',
'weiblich' => 'W',
'divers' => 'D',
],
])
->add('firstName', TextType::class, [
'label' => 'Name',
'label' => 'Vorname',
'sanitize_html' => true,
])
->add('name', TextType::class, [
'label' => 'Nachname',
'sanitize_html' => true,
])
->add('email', EmailType::class, [
'label' => 'E-Mail',
->add('personalData', PersonalDataType::class, [
'label' => false,
'inherit_data' => true,
])
;
}
@@ -41,6 +34,7 @@ class RegistrationType extends AbstractType
{
$resolver->setDefaults([
'data_class' => RegistrationDto::class,
'validation_groups' => ['Default', 'personal_data'],
]);
}
}
+31 -11
View File
@@ -1,30 +1,50 @@
{% extends 'layout.html.twig' %}
{% 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>
<div class="px-4 lg:px-8 py-8 lg:py-16">
<h1 class="text-white uppercase pb-4 mb-8 border-b border-primary-bg/40">
Registrierung
<br>
MyE&amp;P
</h1>
{% include '_partials/_flashes.html.twig' %}
<div class="pb-4">
{{ form_start(form) }}
<div class="grid md:grid-cols-2 gap-x-8 gap-y-4 pb-4">
<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.name, { 'label_attr': { 'class': 'text-white' } }) }}
{{ form_row(form.email, { 'label_attr': { 'class': 'text-white' } }) }}
{{ form_row(form.gender, { 'label_attr': { 'class': 'text-white' } }) }}
{{ form_row(form.personalData.dateOfBirth, { 'label_attr': { 'class': 'text-white' } }) }}
{{ form_row(form.personalData.nationality, { 'label_attr': { 'class': 'text-white' } }) }}
<h3 class="text-white">
Kontakt
</h3>
{{ form_row(form.personalData.email, { 'label_attr': { 'class': 'text-white' } }) }}
{{ form_row(form.personalData.mobile, { 'label_attr': { 'class': 'text-white' } }) }}
{{ form_row(form.personalData.phone, { 'label_attr': { 'class': 'text-white' } }) }}
</div>
<div>
<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
</a>
<button type="submit" class="button button--primary">
Jetzt registrieren
</button>
</div>
{{ form_rest(form) }}
{{ form_end(form) }}
</div>
<a href="{{ path('app_login') }}"
class="text-white underline">
Zum Login
</a>
</div>
</div>
{% endblock %}