Completed
Pull Request — master (#317)
by Guilherme
04:03
created

VerificationController::editPhoneAction()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 30
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 17
nc 2
nop 2
dl 0
loc 30
rs 9.7
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the login-cidadao project or it's bundles.
4
 *
5
 * (c) Guilherme Donato <guilhermednt on github>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace LoginCidadao\PhoneVerificationBundle\Controller;
12
13
use FOS\UserBundle\Event\FilterUserResponseEvent;
14
use FOS\UserBundle\Event\FormEvent;
15
use FOS\UserBundle\Event\GetResponseUserEvent;
16
use FOS\UserBundle\FOSUserEvents;
17
use FOS\UserBundle\Model\UserManagerInterface;
18
use LoginCidadao\CoreBundle\Model\PersonInterface;
19
use LoginCidadao\CoreBundle\Security\User\Manager\UserManager;
20
use LoginCidadao\PhoneVerificationBundle\Exception\VerificationNotSentException;
21
use LoginCidadao\PhoneVerificationBundle\Form\PhoneNumberFormType;
22
use LoginCidadao\PhoneVerificationBundle\Form\PhoneVerificationType;
23
use LoginCidadao\PhoneVerificationBundle\Model\PhoneVerificationInterface;
24
use LoginCidadao\PhoneVerificationBundle\Service\PhoneVerificationServiceInterface;
25
use LoginCidadao\TaskStackBundle\Service\TaskStackManagerInterface;
26
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
27
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
28
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
29
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
30
use Symfony\Component\Form\FormError;
31
use Symfony\Component\HttpFoundation\Request;
32
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
33
use Symfony\Component\Translation\TranslatorInterface;
34
35
/**
36
 * @codeCoverageIgnore
37
 */
38
class VerificationController extends Controller
39
{
40
    /**
41
     * @Route("/task/verify-phone/{id}", name="lc_verify_phone")
42
     * @Template()
43
     */
44
    public function verifyAction(Request $request, $id)
45
    {
46
        /** @var PhoneVerificationServiceInterface $phoneVerificationService */
47
        $phoneVerificationService = $this->get('phone_verification');
48
49
        /** @var PhoneVerificationInterface $pendingVerifications */
50
        $verification = $phoneVerificationService->getPendingPhoneVerificationById($id, $this->getUser());
51
52
        if (!$verification) {
0 ignored issues
show
introduced by
$verification is of type LoginCidadao\PhoneVerifi...neVerificationInterface, thus it always evaluated to true.
Loading history...
53
            return $this->noVerificationOrVerified($request);
54
        }
55
56
        $editPhoneForm = $this->createForm(PhoneNumberFormType::class, $verification->getPerson(), [
57
            'action' => $this->generateUrl('lc_phone_verification_edit_phone', ['verificationId' => $id]),
58
        ]);
59
        $form = $this->createForm(PhoneVerificationType::class);
60
        $form->handleRequest($request);
61
        $verified = false;
62
63
        if ($form->isValid()) {
64
            $code = $form->getData()['verificationCode'];
65
            $verified = $phoneVerificationService->verify($verification, $code);
66
            if (!$verified) {
67
                $form->get('verificationCode')->addError(new FormError(
68
                    $this->get('translator')->trans('tasks.verify_phone.form.errors.verificationCode.invalid_code')
69
                ));
70
            }
71
        }
72
73
        if (!$verification || $verified) {
0 ignored issues
show
introduced by
$verification is of type LoginCidadao\PhoneVerifi...neVerificationInterface, thus it always evaluated to true.
Loading history...
74
            return $this->noVerificationOrVerified($request);
75
        }
76
77
        $nextResend = $this->getNextResendDate($verification);
78
        $mandatory = $phoneVerificationService->isVerificationMandatory($verification);
79
80
        return [
81
            'verification' => $verification,
82
            'nextResend' => $nextResend,
83
            'mandatory' => $mandatory,
84
            'form' => $form->createView(),
85
            'editPhoneForm' => $editPhoneForm->createView(),
86
        ];
87
    }
88
89
    /**
90
     * @Route("/task/verify-phone/{id}/success", name="lc_phone_verification_success")
91
     * @Template("LoginCidadaoPhoneVerificationBundle:Verification:response.html.twig")
92
     */
93
    public function successAction(Request $request, $id)
0 ignored issues
show
Unused Code introduced by
The parameter $id is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

93
    public function successAction(Request $request, /** @scrutinizer ignore-unused */ $id)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

93
    public function successAction(/** @scrutinizer ignore-unused */ Request $request, $id)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
94
    {
95
        /** @var TranslatorInterface $translator */
96
        $translator = $this->get('translator');
97
98
        return [
99
            'message' => $translator->trans('tasks.verify_phone.success'),
100
            'target' => $this->generateUrl('lc_dashboard'),
101
        ];
102
    }
103
104
    /**
105
     * @Route("/task/verify-phone/{id}/resend", name="lc_phone_verification_code_resend")
106
     * @Template()
107
     */
108
    public function resendAction(Request $request, $id)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

108
    public function resendAction(/** @scrutinizer ignore-unused */ Request $request, $id)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
109
    {
110
        /** @var PhoneVerificationServiceInterface $phoneVerificationService */
111
        $phoneVerificationService = $this->get('phone_verification');
112
113
        $verification = $phoneVerificationService->getPendingPhoneVerificationById($id, $this->getUser());
114
        if (!$verification instanceof PhoneVerificationInterface) {
0 ignored issues
show
introduced by
$verification is always a sub-type of LoginCidadao\PhoneVerifi...neVerificationInterface.
Loading history...
115
            throw $this->createNotFoundException();
116
        }
117
118
        try {
119
            $phoneVerificationService->sendVerificationCode($verification);
120
121
            $result = ['type' => 'success', 'message' => 'tasks.verify_phone.resend.success'];
122
        } catch (TooManyRequestsHttpException $e) {
123
            $result = ['type' => 'danger', 'message' => 'tasks.verify_phone.resend.errors.too_many_requests'];
124
        } catch (VerificationNotSentException $e) {
125
            $result = ['type' => 'danger', 'message' => 'tasks.verify_phone.resend.errors.unavailable'];
126
        }
127
128
        /** @var TranslatorInterface $translator */
129
        $translator = $this->get('translator');
130
        $this->addFlash($result['type'], $translator->trans($result['message']));
131
132
        return $this->redirectToRoute('lc_verify_phone', ['id' => $id]);
133
    }
134
135
    /**
136
     * @Route("/task/verify-phone/{verificationId}/edit-phone", name="lc_phone_verification_edit_phone")
137
     */
138
    public function editPhoneAction(Request $request, $verificationId)
139
    {
140
        /** @var PersonInterface $person */
141
        $person = $this->getUser();
142
        $response = $this->redirectToRoute('lc_verify_phone', ['id' => $verificationId]);
143
144
        /** @var EventDispatcherInterface $dispatcher */
145
        $dispatcher = $this->get('event_dispatcher');
146
        $event = new GetResponseUserEvent($person, $request);
147
        $dispatcher->dispatch(FOSUserEvents::PROFILE_EDIT_INITIALIZE, $event);
148
149
        $editPhoneForm = $this->createForm(PhoneNumberFormType::class, $person, [
150
            'action' => $this->generateUrl('lc_phone_verification_edit_phone', ['verificationId' => $verificationId]),
151
        ]);
152
        $editPhoneForm->handleRequest($request);
153
        if ($editPhoneForm->isValid()) {
154
            /** @var $userManager UserManager */
155
            $userManager = $this->get('lc.user_manager');
156
157
            $event = new FormEvent($editPhoneForm, $request);
158
            $dispatcher->dispatch(FOSUserEvents::PROFILE_EDIT_SUCCESS, $event);
159
160
            $userManager->updateUser($person);
161
162
            $event = new FilterUserResponseEvent($person, $request, $response);
163
            $dispatcher->dispatch(FOSUserEvents::PROFILE_EDIT_COMPLETED, $event);
164
            $response = $event->getResponse();
165
        }
166
167
        return $response;
168
    }
169
170
    /**
171
     * @Route("/task/verify-phone/{id}/skip", name="lc_phone_verification_skip")
172
     * @Template()
173
     */
174
    public function skipAction(Request $request, $id)
0 ignored issues
show
Unused Code introduced by
The parameter $id is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

174
    public function skipAction(Request $request, /** @scrutinizer ignore-unused */ $id)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
175
    {
176
        /** @var TaskStackManagerInterface $taskStackManager */
177
        $taskStackManager = $this->get('task_stack.manager');
178
179
        $task = $taskStackManager->getCurrentTask();
180
        if ($task) {
181
            $taskStackManager->setTaskSkipped($task);
182
        }
183
184
        return $taskStackManager->processRequest($request, $this->redirectToRoute('lc_dashboard'));
185
    }
186
187
    /**
188
     * This route is used to verify the phone using a Verification Token.
189
     *
190
     * The objective is that the user can simply click a link received via SMS and the phone would be verified
191
     *
192
     * @Route("/v/{id}/{token}", name="lc_phone_verification_verify_link")
193
     * @Template()
194
     */
195
    public function clickToVerifyAction(Request $request, $id, $token)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

195
    public function clickToVerifyAction(/** @scrutinizer ignore-unused */ Request $request, $id, $token)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
196
    {
197
        /** @var PhoneVerificationServiceInterface $phoneVerificationService */
198
        $phoneVerificationService = $this->get('phone_verification');
199
200
        $verification = $phoneVerificationService->getPhoneVerificationById($id);
201
202
        if (!$verification || false === $phoneVerificationService->verifyToken($verification, $token)) {
0 ignored issues
show
introduced by
$verification is of type LoginCidadao\PhoneVerifi...neVerificationInterface, thus it always evaluated to true.
Loading history...
203
            /** @var TranslatorInterface $translator */
204
            $translator = $this->get('translator');
205
206
            return $this->render(
207
                'LoginCidadaoPhoneVerificationBundle:Verification:response.html.twig',
208
                [
209
                    'message' => $translator->trans('tasks.verify_phone.failure'),
210
                    'target' => $this->generateUrl('lc_dashboard'),
211
                ]
212
            );
213
        }
214
215
        return $this->redirectToRoute('lc_phone_verification_success', ['id' => $verification->getId()]);
216
    }
217
218
    private function noVerificationOrVerified(Request $request)
219
    {
220
        /** @var TaskStackManagerInterface $taskStackManager */
221
        $taskStackManager = $this->get('task_stack.manager');
222
        $task = $taskStackManager->getCurrentTask();
223
        if ($task) {
224
            $taskStackManager->setTaskSkipped($task);
225
        }
226
227
        return $taskStackManager->processRequest($request, $this->redirectToRoute('lc_dashboard'));
228
    }
229
230
    private function getNextResendDate(PhoneVerificationInterface $verification)
231
    {
232
        /** @var PhoneVerificationServiceInterface $phoneVerificationService */
233
        $phoneVerificationService = $this->get('phone_verification');
234
235
        $nextResend = $phoneVerificationService->getNextResendDate($verification);
236
        if ($nextResend <= new \DateTime()) {
237
            $nextResend = false;
238
        }
239
240
        return $nextResend;
241
    }
242
}
243