<?php
namespace App\Controller;
use App\Entity\Country;
use App\Entity\Customer;
use App\Entity\User;
use App\Service\Mailer;
use App\Service\StripeClient;
use Stripe\Exception\ApiErrorException;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
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\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
use Symfony\Component\Security\Csrf\TokenGenerator\UriSafeTokenGenerator;
use Symfony\Component\Validator\Constraints\Date;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\EqualTo;
use Symfony\Component\Validator\Constraints\IsTrue;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
class CustomerController extends AbstractController
{
/**
* @Route("/portal/registrierung", name="customer_registration")
*
* @param \Symfony\Component\HttpFoundation\Session\SessionInterface $session
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface $passwordEncoder
* @param \App\Service\Mailer $mailer
* @param \Symfony\Component\Security\Core\User\UserInterface|null $user
*
* @return \Symfony\Component\HttpFoundation\Response
* @throws \Twig_Error_Loader
* @throws \Twig_Error_Runtime
* @throws \Twig_Error_Syntax
*/
public function registration(
SessionInterface $session,
Request $request,
UserPasswordEncoderInterface $passwordEncoder,
Mailer $mailer,
UserInterface $user = null
) {
if ($request->get('utm_campaign') === 'rabattcode-register') {
$session->set('riser-discount', true);
}
if ($user !== null) {
if ($this->isGranted('ROLE_CUSTOMER')) {
return $this->redirectToRoute('portal');
}
if ($this->isGranted('ROLE_ADMIN')) {
return $this->redirectToRoute('dashboard');
}
}
$customer = new Customer();
/** @var \App\Repository\CountryRepository $countryRepo */
$countryRepo = $this->getDoctrine()->getRepository(Country::class);
$formBuilder = $this->createFormBuilder($customer);
$formBuilder
->add('gender', ChoiceType::class, [
'label' => 'Anrede',
'expanded' => true,
'choices' => [
'Herr' => 'm',
'Frau' => 'f',
'Keine Angabe' => 'u',
],
])
->add('firstName', TextType::class, ['label' => 'Vorname'])
->add('lastName', TextType::class, ['label' => 'Nachname'])
->add('company', TextType::class, ['label' => 'Firma', 'required' => false])
->add('street', TextType::class, ['label' => 'Straße / Hausnr.'])
->add('city', TextType::class, ['label' => 'Stadt'])
->add('zip', TextType::class, ['label' => 'PLZ'])
->add('country', EntityType::class, [
'class' => Country::class,
'choice_label' => 'name',
'label' => 'Land',
'choices' => $countryRepo->getChoices(),
'preferred_choices' => $countryRepo->getPreferredCountryChoices(),
])
->add('email', EmailType::class, [
'label' => 'E-Mail-Adresse',
'mapped' => false,
'constraints' => [
new NotBlank([
'message' => 'E-Mail-Adresse darf nicht leer sein',
]),
new Email([
'message' => 'Dies ist keine gültige E-Mail-Adresse',
]),
],
])
->add('confirmEmail', EmailType::class, [
'label' => 'E-Mail-Adresse bestätigen',
'mapped' => false,
'required' => false,
'constraints' => [
new Email([
'message' => 'Dies ist keine gültige E-Mail-Adresse',
]),
],
])
->add('phone', TextType::class, ['label' => 'Telefonnummer', 'required' => false])
->add('password', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => 'Die Passwörter stimmen nicht überein',
'first_options' => ['label' => 'Passwort wählen'],
'second_options' => ['label' => 'Passwort wiederholen'],
'mapped' => false,
'constraints' => [
new NotBlank([
'message' => 'Bitte geben Sie ein Passwort ein',
]),
new Length([
'min' => 6,
'minMessage' => 'Das Passwort muss mindestens {{ limit }} Zeichen lang sein',
'maxMessage' => 'Das Passwort überschreitet die zugelassene Länge von {{ limit }} Zeichen',
'max' => 4096,
]),
],
]);
if ($session->get('riser-discount') === true) {
$formBuilder->add('riserCode', TextType::class, [
'label' => 'Rabatt-Code',
'required' => false,
'mapped' => false,
'constraints' => [
new EqualTo([
'value' => getenv('PORTAL_RISER_CUSTOMER_CODE'),
'message' => 'Der eingegebene Rabatt-Code ist nicht gültig',
]),
],
]);
}
$form = $formBuilder
->add('terms', CheckboxType::class, [
'label' => 'Die Datenschutzerklärung und AGB habe ich zur Kenntnis genommen.',
'required' => true,
'mapped' => false,
'constraints' => [
new IsTrue([
'message' => 'Bitte bestätigen Sie die Datenschutzerklärung und AGB',
]),
],
])
->add('save', SubmitType::class, ['label' => 'Registrieren'])
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/* Honey-pot. Hopefully bots will fill out this field and get redirected to the success page without an actual registration */
$confirmEmail = $form->get('confirmEmail')->getData();
if (!empty($confirmEmail)) {
return $this->redirectToRoute('customer_registration_success');
}
$email = $form->get('email')->getData();
if (empty($this->getDoctrine()->getRepository(User::class)->findBy(['email' => $email]))) {
/** @var \App\Entity\Customer $customer */
$customer = $form->getData();
$customer->setCreationDate(new \DateTime());
$user = new User();
if ($form->has('riserCode') && ! empty($form->get('riserCode')->getData())) {
$customer->setIsRiserCustomer(true);
}
$user->setEmail($form->get('email')->getData());
$user->setRoles(['ROLE_CUSTOMER']);
$user->setPassword(
$passwordEncoder->encodePassword(
$user,
$form->get('password')->getData()
)
);
$user->setCustomer($customer);
// generate confirmation token
$tokenGenerator = new UriSafeTokenGenerator();
$user->setConfirmationKey($tokenGenerator->generateToken());
$user->setConfirmationType(User::CONFIRMATION_TYPE_REGISTRATION);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
// send confirmation mail
$mailer->sendPortalRegistrationEmail($user);
$session->remove('riser-discount');
return $this->redirectToRoute('customer_registration_success');
}
$form->get('email')->addError(new FormError('Die angegebene E-Mail-Adresse existiert bereits'));
}
return $this->render('portal/customer/registration.html.twig', [
'form' => $form->createView(),
'riserDiscount' => $session->get('riser-discount') === true,
]);
}
/**
* @Route("/portal/registrierung-erfolgreich", name="customer_registration_success")
*/
public function registrationSuccess()
{
return $this->render('portal/customer/registration_success.html.twig');
}
/**
* @Route("/portal/registrierung-abschliessen/{token}", name="customer_registration_confirmation")
*
* @param string $token
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function registrationConfirmation($token)
{
/** @var \App\Entity\User[] $users */
$users = $this->getDoctrine()->getRepository(User::class)->findBy(['confirmationKey' => $token, 'confirmationType' => User::CONFIRMATION_TYPE_REGISTRATION]);
if (empty($users)) {
$success = false;
$this->addFlash('error', 'Der Bestätigungscode ist ungültig oder wurde bereits verwendet');
} else {
$success = true;
$user = $users[0];
$user->setConfirmationKey(null)->setConfirmationType(null)->setIsActive(true);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
}
return $this->render('portal/customer/registration_confirmation.html.twig', [
'success' => $success,
]);
}
/**
* @Route("/portal/profil/", name="customer_profile")
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function profile()
{
return $this->render('portal/customer/profile/index.html.twig');
}
/**
* @Route("/portal/profil/persoenliche-daten/", name="customer_profile_data")
*
* @param \Symfony\Component\Security\Core\User\UserInterface $user
* @param \Symfony\Component\HttpFoundation\Request $request
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function profilePersonalData(UserInterface $user, Request $request)
{
/** @var User $user */
/** @var \App\Repository\CountryRepository $countryRepo */
$countryRepo = $this->getDoctrine()->getRepository(Country::class);
$formBuilder = $this->createFormBuilder($user->getCustomer());
$form = $formBuilder
->add('gender', ChoiceType::class, [
'label' => 'Anrede',
'expanded' => true,
'choices' => [
'Herr' => 'm',
'Frau' => 'f',
'Keine Angabe' => 'u',
],
])
->add('firstName', TextType::class, ['label' => 'Vorname'])
->add('lastName', TextType::class, ['label' => 'Nachname'])
->add('company', TextType::class, ['label' => 'Firma', 'required' => false])
->add('street', TextType::class, ['label' => 'Straße / Hausnr.'])
->add('city', TextType::class, ['label' => 'Stadt'])
->add('zip', TextType::class, ['label' => 'PLZ'])
->add('country', EntityType::class, [
'class' => Country::class,
'choice_label' => 'name',
'label' => 'Land',
'choices' => $countryRepo->getChoices(),
'preferred_choices' => $countryRepo->getPreferredCountryChoices(),
])
->add('phone', TextType::class, ['label' => 'Telefonnummer', 'required' => false])
->add('save', SubmitType::class, ['label' => 'Änderungen speichern'])
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$customer = $form->getData();
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($customer);
$entityManager->flush();
return $this->redirectToRoute('customer_profile');
}
return $this->render('portal/customer/profile/personal_data.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @Route("/portal/profil/zahldaten/", name="customer_profile_payment_data")
*
* @param \Symfony\Component\Security\Core\User\UserInterface $user
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \App\Service\StripeClient $stripeClient
*
* @return \Symfony\Component\HttpFoundation\Response
*
* @throws \Stripe\Exception\ApiErrorException
*/
public function profilePaymentData(UserInterface $user, Request $request, StripeClient $stripeClient)
{
/** @var User $user */
$stripeCustomerId = $user->getCustomer()->getStripeCustomer();
if ($stripeCustomerId !== null) {
// $stripeCustomer = $stripeClient->getCustomer($stripeCustomerId);
// $stripeCustomerSources = $stripeCustomer->sources->data;
$stripeCustomerSources = $stripeClient->getCardsByCustomer($stripeCustomerId);
} else {
// $stripeCustomer = null;
$stripeCustomerSources = [];
}
$formBuilder = $this->createFormBuilder();
$form = $formBuilder
->add('type', ChoiceType::class, [
'label' => 'Zahlungsart wählen',
'expanded' => true,
'choices' => [
'Kreditkarte' => 'card',
// 'Lastschrift' => 'sepa',
],
'choice_attr' => function ($choiceValue, $key, $value) {
return ['class' => 'payment_type_' . strtolower($key)];
},
])
// ->add('stripeSource', HiddenType::class)
->add('save', SubmitType::class, ['label' => 'Hinzufügen'])
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/*
$stripeSource = $form->get('stripeSource')->getData();
try {
$stripeClient->getSource($stripeSource);
} catch (\Exception $e) {
$this->addFlash('error', 'Ein Fehler ist aufgetreten.');
return $this->redirectToRoute('customer_profile_payment_data');
}
*/
if ($stripeCustomerId === null) {
$stripeCustomer = $stripeClient->createCustomer($user->getEmail());
$stripeCustomerId = $stripeCustomer->id;
$user->getCustomer()->setStripeCustomer($stripeCustomerId);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
}
$setupIntent = $stripeClient->createSetupIntent($stripeCustomerId);
/*
try {
$stripeCustomer->sources->create(['source' => $stripeSource]);
} catch (\Exception $e) {
if ($e->getMessage() === 'Your card\'s security code is incorrect.') {
$this->addFlash('error', 'Der Sicherheitscode ist nicht korrekt.');
} elseif ($e->getMessage() === 'Your card was declined.') {
$this->addFlash('error', 'Ihre Karte wurde abgelehnt.');
} else {
$this->addFlash('error', 'Ein Fehler ist aufgetreten. Bitte prüfen Sie Ihre Eingaben.');
}
}
*/
return $this->redirectToRoute('customer_profile_add_card', [
'setupIntentId' => $setupIntent->id,
]);
}
$sepaSources = array_filter($stripeCustomerSources, function ($el) {
return $el->type === 'sepa_debit';
});
$cardSources = array_filter($stripeCustomerSources, function ($el) {
return $el->type === 'card';
});
return $this->render('portal/customer/profile/payment_data.html.twig', [
'form' => $form->createView(),
'sepaSources' => $sepaSources,
'cardSources' => $cardSources,
]);
}
/**
* @Route("/portal/profil/zahldaten/kreditkarte-hinzufuegen/{setupIntentId}", name="customer_profile_add_card")
*
* @param \Symfony\Component\Security\Core\User\UserInterface $user
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \App\Service\StripeClient $stripeClient
*
* @param string $setupIntentId
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function addCard(UserInterface $user, Request $request, StripeClient $stripeClient, string $setupIntentId)
{
/** @var User $user */
if (empty($setupIntentId)) {
$this->addFlash('error', 'Ein Fehler ist aufgetreten.');
return $this->redirectToRoute('customer_profile_payment_data');
}
try {
$setupIntent = $stripeClient->getSetupIntent($setupIntentId);
} catch (ApiErrorException $e) {
$this->addFlash('error', 'Ein Fehler ist aufgetreten.');
return $this->redirectToRoute('customer_profile_payment_data');
}
return $this->render('portal/customer/profile/payment_data_add_card.html.twig', [
'clientSecret' => $setupIntent->client_secret,
]);
}
/**
* @Route("/portal/profil/zahldaten/{sourceId}/entfernen/", name="customer_profile_remove_payment_source")
*
* @param \Symfony\Component\Security\Core\User\UserInterface $user
* @param \App\Service\StripeClient $stripeClient
* @param string $sourceId
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
public function removePaymentSource(UserInterface $user, StripeClient $stripeClient, string $sourceId)
{
/** @var User $user */
$stripeCustomerId = $user->getCustomer()->getStripeCustomer();
if ($stripeCustomerId === null) {
$this->addFlash('error', 'Fehler: Zahlungsmethode nicht vorhanden');
return $this->redirectToRoute('customer_profile_payment_data');
}
try {
// $stripeCustomer = $stripeClient->getCustomer($stripeCustomerId);
// $stripeCustomer->sources->retrieve($sourceId)->detach();
$stripeClient->getPaymentMethod($sourceId)->detach();
$this->addFlash('notice', 'Zahlungsmethode erfolgreich entfernt');
} catch (ApiErrorException $e) {
$this->addFlash('error', 'Fehler: Zahlungsmethode nicht vorhanden');
}
return $this->redirectToRoute('customer_profile_payment_data');
}
/**
* @Route("/portal/profil/passwort/", name="customer_profile_password")
*
* @param \Symfony\Component\Security\Core\User\UserInterface $user
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface $passwordEncoder
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function profilePassword(
UserInterface $user,
Request $request,
UserPasswordEncoderInterface $passwordEncoder
) {
/** @var User $user */
$formBuilder = $this->createFormBuilder($user);
$form = $formBuilder
->add('old_password', PasswordType::class, [
'mapped' => false,
'label' => 'aktuelles Passwort',
'constraints' => [
new UserPassword([
'message' => 'Das Passwort ist nicht korrekt'
])
]
])
->add('password', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => 'Die Passwörter stimmen nicht überein',
'first_options' => ['label' => 'Neues Passwort wählen'],
'second_options' => ['label' => 'Neues Passwort wiederholen'],
'mapped' => false,
'constraints' => [
new NotBlank([
'message' => 'Bitte geben Sie ein Passwort ein',
]),
new Length([
'min' => 6,
'minMessage' => 'Das Passwort muss mindestens {{ limit }} Zeichen lang sein',
'maxMessage' => 'Das Passwort überschreitet die zugelassene Länge von {{ limit }} Zeichen',
'max' => 4096,
]),
],
])
->add('save', SubmitType::class, ['label' => 'Änderungen speichern'])
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user->setPassword(
$passwordEncoder->encodePassword(
$user,
$form->get('password')->getData()
)
);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
return $this->redirectToRoute('customer_profile');
}
return $this->render('portal/customer/profile/password.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @Route("/portal/passwort-vergessen/", name="customer_forgot_password")
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \Symfony\Component\HttpFoundation\Session\Session $session
* @param \App\Service\Mailer $mailer
*
* @return \Symfony\Component\HttpFoundation\Response
* @throws \Twig_Error_Loader
* @throws \Twig_Error_Runtime
* @throws \Twig_Error_Syntax
*/
public function forgotPassword(Request $request, \Symfony\Component\HttpFoundation\Session\Session $session, Mailer $mailer)
{
if ($this->isGranted('ROLE_CUSTOMER')) {
$session->getFlashBag()->clear();
return $this->redirectToRoute('portal');
}
if ($this->isGranted('ROLE_ADMIN')) {
$session->getFlashBag()->clear();
return $this->redirectToRoute('dashboard');
}
if (!empty($session->getFlashBag()->peekAll())) {
return $this->render('portal/customer/forgot-password.html.twig', [
'step' => 2,
]);
}
$formBuilder = $this->createFormBuilder();
$form = $formBuilder
->add('email', EmailType::class, [
'label' => 'Ihre E-Mail-Adresse',
'constraints' => [
new NotBlank([
'message' => 'E-Mail-Adresse darf nicht leer sein',
]),
new Email([
'message' => 'Dies ist keine gültige E-Mail-Adresse',
]),
],
])
->add('save', SubmitType::class, ['label' => 'Passwort zurücksetzen'])
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var User[] $result */$session->getFlashBag()->clear();
$result = $this->getDoctrine()->getRepository(User::class)->findBy(['email' => $form->get('email')->getData()]);
if ( ! empty($result)) {
$user = $result[0];
if ( ! $user->getIsActive()) {
$this->addFlash('error',
'Dieses Konto ist nicht aktiv. Fall Sie sich neu registriert haben, schauen Sie bitte in Ihrem E-Mail-Postfach nach einer Bestätigungsmail für Ihre Registrierung und klicken Sie auf den Bestätigungslink. Bei Fragen oder Problemen stehen wir Ihnen gerne per E-Mail zur Verfügung: <a href="mailto:support@adressermittlung.de">support@adressermittlung.de</a>');
} else {
if ($user->getConfirmationType() === null || $user->getConfirmationType() === User::CONFIRMATION_TYPE_PASSWORD_RESET) {
// generate confirmation token
$tokenGenerator = new UriSafeTokenGenerator();
$user->setConfirmationKey($tokenGenerator->generateToken());
$user->setConfirmationType(User::CONFIRMATION_TYPE_PASSWORD_RESET);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
$mailer->sendPortalResetPasswordEmail($user);
}
$this->addFlash('notice','Eine E-Mail mit Anweisungen zum Zurücksetzen Ihres Passworts wurde an die von Ihnen angegebene E-Mail-Adresse versandt. Bitte prüfen Sie Ihr Postfach.');
}
} else {
$this->addFlash('notice','Eine E-Mail mit Anweisungen zum Zurücksetzen Ihres Passworts wurde an die von Ihnen angegebene E-Mail-Adresse versandt. Bitte prüfen Sie Ihr Postfach.');
}
return $this->redirectToRoute('customer_forgot_password');
}
return $this->render('portal/customer/forgot-password.html.twig', [
'form' => $form->createView(),
'step' => 1,
]);
}
/**
* @Route("/portal/passwort-aendern/{token}", name="customer_reset_password")
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface $passwordEncoder
* @param string $token
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function resetPassword(Request $request, UserPasswordEncoderInterface $passwordEncoder, $token)
{
if ($this->isGranted('ROLE_CUSTOMER')) {
return $this->redirectToRoute('portal');
}
if ($this->isGranted('ROLE_ADMIN')) {
return $this->redirectToRoute('dashboard');
}
/** @var \App\Entity\User[] $users */
$users = $this->getDoctrine()->getRepository(User::class)->findBy(['confirmationKey' => $token, 'confirmationType' => User::CONFIRMATION_TYPE_PASSWORD_RESET]);
$viewParams = [];
if (empty($users)) {
$viewParams['success'] = false;
$this->addFlash('error', 'Der Sicherheitscode ist ungültig oder wurde bereits verwendet');
} else {
$viewParams['success'] = true;
$formBuilder = $this->createFormBuilder();
$form = $formBuilder->add('password', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => 'Die Passwörter stimmen nicht überein',
'first_options' => ['label' => 'Passwort wählen'],
'second_options' => ['label' => 'Passwort wiederholen'],
'constraints' => [
new NotBlank([
'message' => 'Bitte geben Sie ein Passwort ein',
]),
new Length([
'min' => 6,
'minMessage' => 'Das Passwort muss mindestens {{ limit }} Zeichen lang sein',
'maxMessage' => 'Das Passwort überschreitet die zugelassene Länge von {{ limit }} Zeichen',
'max' => 4096,
]),
],
])
->add('save', SubmitType::class, ['label' => 'Passwort ändern'])
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user = $users[0];
$user->setPassword(
$passwordEncoder->encodePassword(
$user,
$form->get('password')->getData()
)
);
$user->setConfirmationKey(null)->setConfirmationType(null)->setIsActive(true);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
$this->addFlash('notice', 'Ihr Passwort wurde erfolgreich geändert. Sie können sich nun mit Ihrem neuen Passwort einloggen.');
return $this->redirectToRoute('app_login');
}
$viewParams['form'] = $form->createView();
}
return $this->render('portal/customer/reset_password.html.twig', $viewParams);
}
}