Completed
Push — master ( af0e0d...dc2a9c )
by Florian
28s queued 11s
created

IndexController::notifyNeedToConfirmEMail()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
c 0
b 0
f 0
dl 0
loc 10
rs 10
cc 1
nc 1
nop 4
1
<?php
2
3
/*
4
 * This file is part of the TheAlternativeZurich/events project.
5
 *
6
 * (c) Florian Moser <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace App\Controller;
13
14
use App\Controller\Base\BaseDoctrineController;
15
use App\Entity\Event;
16
use App\Entity\Registration;
17
use App\Entity\User;
18
use App\Form\Registration\EditType;
19
use App\Security\UserToken;
20
use App\Service\Interfaces\EmailServiceInterface;
21
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
22
use Symfony\Component\Form\FormInterface;
23
use Symfony\Component\HttpFoundation\Request;
24
use Symfony\Component\HttpFoundation\Response;
25
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
26
use Symfony\Component\Routing\Annotation\Route;
27
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
28
use Symfony\Contracts\Translation\TranslatorInterface;
29
30
/**
31
 * @Route("/")
32
 */
33
class IndexController extends BaseDoctrineController
34
{
35
    /**
36
     * @Route("", name="index")
37
     *
38
     * @return Response
39
     */
40
    public function indexAction()
41
    {
42
        $registrations = $this->getUser()->getRegistrations();
43
44
        /** @var Registration[] $upcomingRegistrations */
45
        $upcomingRegistrations = [];
46
        /** @var Registration[] $pastRegistrations */
47
        $pastRegistrations = [];
48
        foreach ($registrations as $registration) {
49
            $event = $registration->getEvent();
50
51
            $key = $event->getStartDate()->format('c').'_'.$event->getId();
52
            if (null === $event->getClosedDate()) {
53
                $upcomingRegistrations[$key] = $registration;
54
            } else {
55
                $pastRegistrations[$key] = $registration;
56
            }
57
        }
58
59
        krsort($upcomingRegistrations);
60
        krsort($pastRegistrations);
61
62
        return $this->render('index.html.twig', ['upcoming_registrations' => $upcomingRegistrations, 'past_registrations' => $pastRegistrations]);
63
    }
64
65
    /**
66
     * @Route("e/{identifier}", name="register", priority="-10")
67
     *
68
     * @return Response
69
     */
70
    public function registerAction(string $identifier, Request $request, GuardAuthenticatorHandler $guardHandler, EmailServiceInterface $emailService, TranslatorInterface $translator)
71
    {
72
        /** @var Event $event */
73
        $event = $this->getDoctrine()->getRepository(Event::class)->findOneBy(['identifier' => $identifier]);
74
        if (null === $event) {
75
            throw new NotFoundHttpException();
76
        }
77
78
        $user = $this->getUser();
79
80
        /** @var Registration|null $existingRegistration */
81
        $existingRegistration = null;
82
        if ($user) {
83
            $existingRegistration = $user->getRegistrationFor($event);
84
        }
85
86
        $organizerSecretValid = $request->query->has('organizer-secret') &&
87
            $request->query->get('organizer-secret') === $event->getOrganizerSecret();
88
89
        /** @var FormInterface/null $form */
90
        $form = null;
91
        if (!$existingRegistration && ($event->isRegistrationPossible() || $organizerSecretValid)) {
92
            $registration = new Registration();
93
            if ($user = $this->getUser()) {
94
                $registration = Registration::createFromUser($event, $user);
95
            }
96
97
            if ($organizerSecretValid) {
98
                $registration->setIsOrganizer(true);
99
            }
100
101
            $form = $this->createForm(EditType::class, $registration)
102
                ->add('submit', SubmitType::class, ['translation_domain' => 'index', 'label' => 'register.submit']);
103
            $form->handleRequest($request);
104
            if ($form->isSubmitted() && $form->isValid()) {
105
                if ($this->saveRegistration($user, $registration, $request, $emailService, $translator, $guardHandler, $event)) {
106
                    // update for view
107
                    $existingRegistration = $registration;
108
                    $form = null;
109
                }
110
            }
111
        }
112
113
        return $this->render('register.html.twig', [
114
                'existing_registration' => $existingRegistration,
115
                'event' => $event,
116
                'form' => $form ? $form->createView() : null,
117
                'user' => $user,
118
            ]
119
        );
120
    }
121
122
    private function saveRegistration(?User $user, Registration $registration, Request $request, EmailServiceInterface $emailService, TranslatorInterface $translator, GuardAuthenticatorHandler $guardHandler, Event $event): bool
123
    {
124
        // create user if not exists & login
125
        if (!$user) {
126
            $existingUser = $this->getDoctrine()->getRepository(User::class)->findOneBy(['email' => $registration->getEmail()]);
127
            if (null !== $existingUser) {
128
                $this->notifyUserAlreadyRegistered($request, $existingUser, $emailService, $translator);
129
130
                return false;
131
            }
132
133
            $user = $this->createUserAndAuthenticate($registration, $guardHandler, $request);
134
135
            $registration->setRelations($event, $user);
136
        } else {
137
            $user->updateFromRegistration($registration);
138
            $this->fastSave($user);
139
        }
140
141
        if ($registration->getIsOrganizer() && !$user->getIsEmailConfirmed()) {
142
            $this->notifyNeedToConfirmEMail($request, $user, $emailService, $translator);
143
144
            return false;
145
        }
146
147
        $registrationRepo = $this->getDoctrine()->getRepository(Registration::class);
148
        $registrationRepo->save($registration);
149
150
        return true;
151
    }
152
153
    private function notifyUserAlreadyRegistered(Request $request, User $user, EmailServiceInterface $emailService, TranslatorInterface $translator): void
154
    {
155
        $message = $translator->trans('create.error.already_registered', [], 'security');
156
        $this->displayError($message);
157
158
        // save event url to redirect after login
159
        $redirectPathKey = '_security.main.target_path';
160
        $request->getSession()->set($redirectPathKey, $request->getUri());
161
162
        $emailService->sendAuthenticateLink($user);
163
    }
164
165
    private function notifyNeedToConfirmEMail(Request $request, User $user, EmailServiceInterface $emailService, TranslatorInterface $translator): void
166
    {
167
        $message = $translator->trans('create.error.organizers_need_confirmed_email', [], 'security');
168
        $this->displayError($message);
169
170
        // save event url to redirect after login
171
        $redirectPathKey = '_security.main.target_path';
172
        $request->getSession()->set($redirectPathKey, $request->getUri());
173
174
        $emailService->sendAuthenticateLink($user);
175
    }
176
177
    private function createUserAndAuthenticate(Registration $registration, GuardAuthenticatorHandler $guardHandler, Request $request): User
178
    {
179
        $user = User::createFromRegistration($registration);
180
        $this->fastSave($user);
181
182
        $userToken = new UserToken($user);
183
        $guardHandler->authenticateWithToken($userToken, $request, 'main');
184
185
        return $user;
186
    }
187
}
188