src/Controller/SecurityController.php line 48
<?phpnamespace App\Controller;use App\Balance\BalanceRefillAmountEnum;use App\Balance\BalanceService;use App\Donation\DonationLevelEnum;use App\Entity\User;use App\Form\RegistrationFormStepOneType;use App\Form\RegistrationFormStepTwoType;use App\Repository\UserRepository;use App\Security\LoginFormAuthenticator;use App\Util\Formatter;use App\Util\USA as USAUtil;use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;use Symfony\Bundle\SecurityBundle\Security;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpFoundation\RequestStack;use Symfony\Component\HttpFoundation\Response;use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;use Symfony\Component\Routing\Annotation\Route;use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;class SecurityController extends AbstractController{private const SESSION_KEY = 'registration_user_id';// todo make sure we don't start sessions for anon userspublic function __construct(private RequestStack $requestStack,private UserRepository $userRepository,){}#[Route('/app', name: 'app_default', methods: 'GET')]public function default(): Response{/*** This is the entry point for requests without valid cup tag, e.g. direct URL type ins*/return $this->render('home/default.html.twig', []);}#[Route('/login', name: 'app_login', methods: ['GET', 'POST'])]public function login(AuthenticationUtils $authenticationUtils): Response{if ($this->getUser()) {return $this->redirectToRoute('app_home');}// get the login error if there is one$error = $authenticationUtils->getLastAuthenticationError();// last username entered by the user$lastUsername = $authenticationUtils->getLastUsername();return $this->render('security/login.html.twig', ['last_username' => $lastUsername,'error' => $error,'states' => USAUtil::getUsStateDemocraticParties()]);}#[Route(path: '/logout', name: 'app_logout')]public function logout(): void{throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');}#[Route('/register', name: 'app_register_step_one', methods: ['GET', 'POST'])]public function registerStepOne(Request $request,UserPasswordHasherInterface $userPasswordHasher,): Response{$user = new User();$form = $this->createForm(RegistrationFormStepOneType::class, $user);$form->handleRequest($request);if ($form->isSubmitted() && $form->isValid()) {// encode the plain password$user->setPassword($userPasswordHasher->hashPassword($user,$form->get('plainPassword')->getData()));// keep uncompleted user in DB$this->userRepository->save($user, true);// pass user to next step$this->requestStack->getSession()->set(self::SESSION_KEY, $user->getId());return $this->redirectToRoute('app_register_step_two');}return $this->render('security/register_step_one.html.twig', ['form' => $form,]);}#[Route('/register/fill', name: 'app_register_step_two', methods: ['GET', 'POST'])]public function registerStepTwo(Request $request, BalanceService $balanceService): Response{$user = $this->getUserFromPreviousStep();if (empty($user)) {return $this->redirectToRoute('app_register_step_one');}$form = $this->createForm(RegistrationFormStepTwoType::class);$form->handleRequest($request);if ($form->isSubmitted() && $form->isValid()) {$refillAmount = BalanceRefillAmountEnum::tryFrom($form->get('refillAmount')->getData());$level = DonationLevelEnum::tryFrom($form->get('donationAmount')->getData());// todo steps below should be in one transaction// set default donation level, no flush needed yet since the user already in DB and has an ID$user->setTransactionDefaultAmount($level);// add points to balance$balanceService->addToBalanceForUser($refillAmount, $user);// activate user$user->activate();$this->userRepository->save($user);return $this->redirectToRoute('app_register_success');}return $this->render('security/register_step_two.html.twig', ['form' => $form,]);}private function getUserFromPreviousStep(): ?User{// get user id passed from the previous step$session = $this->requestStack->getSession();$userId = $session->get(self::SESSION_KEY);if (empty($userId) || !is_int($userId)) {$session->invalidate();return null;}// find previously saved user$user = $this->userRepository->find($userId);if (empty($user)) {$session->invalidate();return null;}return $user;}#[Route('/register/success', name: 'app_register_success', methods: 'GET')]public function registerSuccess(BalanceService $balanceService, Security $security): Response{$user = $this->getUserFromPreviousStep();if (empty($user)) {$this->redirectToRoute('app_register_step_one');}$security->login($user, LoginFormAuthenticator::class);$data = ['name' => $user->getFullName(),'email' => $user->getEmail(),'employer' => $user->getEmployer(),'occupation' => $user->getOccupation(),'level' => Formatter::formatMoney($user->getTransactionDefaultAmount()),'balance' => Formatter::formatMoney($balanceService->getBalanceForUser($user)),];return $this->render('security/register_success.html.twig', ['data' => $data,]);}}