Skip to content
Snippets Groups Projects
Select Git revision
  • 3cce29f2af0ae0c822beb6539f198a54c28fb53f
  • main default protected
2 results

WikiAbstract-SolarSystem-22.stog.amr.dot

Blame
  • RegistrationController.php 6.66 KiB
    <?php
    
    namespace App\Controller;
    
    use App\Builder\UserBuilder;
    use App\Entity\Capsule;
    use App\Entity\PendingEditorInvitation;
    use App\Entity\User;
    use App\Form\RegistrationFormType;
    use App\Repository\CapsuleRepository;
    use App\Repository\PendingEditorInvitationRepository;
    use App\Repository\UserRepository;
    use App\Security\EmailVerifier;
    use Doctrine\ORM\EntityManagerInterface;
    use Symfony\Bridge\Twig\Mime\TemplatedEmail;
    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
    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\Contracts\Translation\TranslatorInterface;
    use SymfonyCasts\Bundle\VerifyEmail\Exception\VerifyEmailExceptionInterface;
    
    class RegistrationController extends AbstractController
    {
        private EmailVerifier $emailVerifier;
        private RequestStack $requestStack;
        private EntityManagerInterface $entity_manager;
    
        public function __construct(
            EmailVerifier $emailVerifier,
            RequestStack $requestStack,
            EntityManagerInterface $entity_manager
        ) {
            $this->emailVerifier = $emailVerifier;
            $this->requestStack = $requestStack;
            $this->entity_manager = $entity_manager;
        }
    
        /**
         * @Route("/register", name="app_register")
         */
        public function register(
            Request $request,
            UserPasswordHasherInterface $userPasswordHasher
        ): Response {
            if ($this->getUser()) {
                return $this->redirectToRoute('capsule_list');
            }
    
            $user = new User();
            $form = $this->createForm(RegistrationFormType::class, $user);
            $form->handleRequest($request);
    
            if ($form->isSubmitted() && $form->isValid()) {
                $userBuilder = new UserBuilder($userPasswordHasher, $user);
    
                // Ugly fix because I don't understand why those values aren't set correctly
                $userBuilder->withAcceptGeneralConditions($form->get('acceptGeneralConditions')->getData());
                $userBuilder->withNewsLetterSubscription(false);
    
                $userBuilder
                    ->withPassword(
                        random_bytes(100),
                        $form->get('plainPassword')->getData()
                    );
    
                $this->entity_manager->persist($userBuilder->createUser());
                $this->entity_manager->flush();
    
                // generate a signed url and email it to the user
                $this->emailVerifier->sendEmailConfirmation(
                    'app_verify_email',
                    $user->getId(),
                    $user->getEmail(),
                    (new TemplatedEmail())
                        ->to($user->getEmail())
                        ->subject('Please Confirm your Email')
                        ->htmlTemplate('registration/confirmation_email.html.twig')
                );
    
                $this->requestStack->getSession()->set('userid', $user->getId());
                return $this->redirectToRoute('app_register_mail_sent');
            }
    
            return $this->render('registration/register.html.twig', [
                'registrationForm' => $form->createView(),
            ]);
        }
    
        /**
         * @Route("/verify/email", name="app_verify_email")
         */
        public function verifyUserEmail(
            Request $request,
            UserRepository $userRepository,
            PendingEditorInvitationRepository $pending_editor_invitation_repository,
            CapsuleRepository $capsule_repository,
            TranslatorInterface $translator
        ): Response {
            $id = $request->get('id');
    
            if (null === $id) {
                return $this->redirectToRoute('app_register');
            }
    
            $user = $userRepository->find($id);
    
            if (null === $user) {
                return $this->redirectToRoute('app_register');
            }
    
            // validate email confirmation link, sets User::isVerified=true and persists
            try {
                $this->emailVerifier->handleEmailConfirmation($request, $user);
            } catch (VerifyEmailExceptionInterface $exception) {
                $this->addFlash('verify_email_error', $exception->getReason());
    
                return $this->redirectToRoute('app_register');
            }
    
            $this->addCapsuleToConfirmedPreviousPendingEditor(
                $user,
                $pending_editor_invitation_repository,
                $capsule_repository
            );
    
            $this->addFlash(
                'email_verified_success',
                $translator->trans('registration.email_verified_success')
            );
    
            return $this->redirectToRoute('app_login');
        }
    
        /**
         * @Route("/register_mail_sent", name="app_register_mail_sent")
         */
        public function mailSentMessage(UserRepository $userRepository): Response
        {
            $userid = $this->requestStack->getSession()->get('userid');
            $user = $userRepository->find($userid);
    
            return $this->render(
                'registration/register_mail_sent.html.twig',
                ['user' =>  $user]
            );
        }
    
        private function addCapsuleToConfirmedPreviousPendingEditor(
            User $user,
            PendingEditorInvitationRepository $pending_editor_invitation_repository,
            CapsuleRepository $capsule_repository
        ): void {
            $pending_editor_invitations = $pending_editor_invitation_repository->findBy(['email' => $user->getEmail()]);
    
            if ($pending_editor_invitations == null) {
                return;
            }
    
            $capsules_ids = $this->removeInvitations($pending_editor_invitations);
            $this->addEditorToCapsules($capsules_ids, $user, $capsule_repository);
        }
    
        /**
         * @param array<PendingEditorInvitation> $pending_editor_invitations
         * @return array<int>
         */
        private function removeInvitations(array $pending_editor_invitations): array
        {
            $capsules_ids = [];
    
            foreach ($pending_editor_invitations as $invitation) {
                if (! $invitation instanceof PendingEditorInvitation) {
                    return $capsules_ids;
                }
                $capsules_ids[] = $invitation->getCapsuleId();
                $this->entity_manager->remove($invitation);
            }
    
            return $capsules_ids;
        }
    
        /**
         * @param array<int> $capsules_ids
         */
        private function addEditorToCapsules(
            array $capsules_ids,
            User $user,
            CapsuleRepository $capsule_repository
        ): void {
            $capsules = $capsule_repository->findBy(['id' => $capsules_ids]);
    
            foreach ($capsules as $capsule) {
                if (! $capsule instanceof Capsule) {
                    return;
                }
                $capsule->addEditor($user);
                $this->entity_manager->persist($capsule);
            }
            $this->entity_manager->flush();
        }
    }