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
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.