processPasswordAndEmailChanges()   B
last analyzed

Complexity

Conditions 5
Paths 12

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 15
rs 8.8571
cc 5
eloc 8
nc 12
nop 3
1
<?php
2
/*
3
  ÁTICA - Aplicación web para la gestión documental de centros educativos
4
5
  Copyright (C) 2015-2017: Luis Ramón López López
6
7
  This program is free software: you can redistribute it and/or modify
8
  it under the terms of the GNU Affero General Public License as published by
9
  the Free Software Foundation, either version 3 of the License, or
10
  (at your option) any later version.
11
12
  This program is distributed in the hope that it will be useful,
13
  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
  GNU Affero General Public License for more details.
16
17
  You should have received a copy of the GNU Affero General Public License
18
  along with this program.  If not, see [http://www.gnu.org/licenses/].
19
*/
20
21
namespace AppBundle\Controller;
22
23
use AppBundle\Entity\User;
24
use AppBundle\Form\Type\UserType;
25
use AppBundle\Service\MailerService;
26
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
27
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
28
use Symfony\Component\Config\Definition\Exception\Exception;
29
use Symfony\Component\Form\Form;
30
use Symfony\Component\Form\SubmitButton;
31
use Symfony\Component\HttpFoundation\Request;
32
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
33
34
class PersonalDataController extends Controller
35
{
36
    /**
37
     * @Route("/datos", name="personal_data", methods={"GET", "POST"})
38
     */
39
    public function userProfileFormAction(Request $request)
40
    {
41
        /** @var User $user */
42
        $user = $this->getUser();
43
44
        $form = $this->createForm(UserType::class, $user, [
45
            'own' => true,
46
            'admin' => $user->isGlobalAdministrator()
47
        ]);
48
49
        $oldEmail = $user->getEmailAddress();
50
51
        $form->handleRequest($request);
52
53
        if ($form->isSubmitted() && $form->isValid()) {
54
            $translator = $this->get('translator');
55
56
            $passwordSubmitted = $this->processPasswordAndEmailChanges($form, $user, $oldEmail);
0 ignored issues
show
Compatibility introduced by
$form of type object<Symfony\Component\Form\FormInterface> is not a sub-type of object<Symfony\Component\Form\Form>. It seems like you assume a concrete implementation of the interface Symfony\Component\Form\FormInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
57
            $message = $this->get('translator')->trans($passwordSubmitted ? 'message.password_changed' : 'message.saved', [], 'user');
58
59
            try {
60
                $this->getDoctrine()->getManager()->flush();
61
                $this->addFlash('success', $message);
62
                return $this->redirectToRoute('frontpage');
63
            } catch (Exception $e) {
64
                $this->addFlash('error', $translator->trans('message.error', [], 'user'));
65
            }
66
        }
67
68
        return $this->render('user/personal_data_form.html.twig', [
69
            'menu_path' => 'frontpage',
70
            'breadcrumb' => [
71
                ['caption' => 'menu.personal_data']
72
            ],
73
            'title' => $this->get('translator')->trans('user.data', [], 'layout'),
74
            'form' => $form->createView(),
75
            'user' => $user
76
        ]);
77
    }
78
79
    /**
80
     * Requests an email address change confirmation
81
     *
82
     * @param User $user
83
     * @param string $oldEmail
84
     */
85
    private function requestEmailAddressChange(User $user, $oldEmail)
86
    {
87
        $newEmail = $user->getEmailAddress();
88
89
        if ($newEmail === '') {
90
            $newEmail = null;
91
        }
92
93
        if ($user->isGlobalAdministrator() || null === $newEmail) {
94
            $user->setEmailAddress($newEmail);
95
        } else {
96
            $user->setTokenType($newEmail);
97
            // generar un nuevo token
98
            $token = bin2hex(random_bytes(16));
99
            $user->setToken($token);
100
101
            // obtener tiempo de expiración del token
102
            $expire = (int) $this->getParameter('password_reset.expire');
103
104
            // calcular fecha de expiración del token
105
            $validity = new \DateTime();
106
            $validity->add(new \DateInterval('PT'.$expire.'M'));
107
            $user->setTokenExpiration($validity);
108
109
            $user->setEmailAddress($newEmail);
110
111
            // enviar correo
112
            if (0 === $this->get(MailerService::class)->sendEmail([$user],
113
                    ['id' => 'form.change_email.email.subject', 'parameters' => []],
114
                    [
115
                        'id' => 'form.change_email.email.body',
116
                        'parameters' => [
117
                            '%name%' => $user->getFirstName(),
118
                            '%link%' => $this->generateUrl('email_reset_do',
119
                                ['userId' => $user->getId(), 'token' => $token],
120
                                UrlGeneratorInterface::ABSOLUTE_URL),
121
                            '%expiry%' => $expire
122
                        ]
123
                    ], 'security')
124
            ) {
125
                $this->addFlash('error', $this->get('translator')->trans('message.email_change.error', [], 'user'));
126
            } else {
127
                $this->addFlash('info',
128
                    $this->get('translator')->trans('message.email_change.info', ['%email%' => $newEmail], 'user'));
129
            }
130
131
            $user->setEmailAddress($oldEmail);
132
        }
133
    }
134
135
    /**
136
     * Checks if a password/email change has been requested and process it
137
     * @param Form $form
138
     * @param User $user
139
     * @param string $oldEmail
140
     * @return bool
141
     */
142
    private function processPasswordAndEmailChanges(Form $form, User $user, $oldEmail)
143
    {
144
        // comprobar si ha cambiado el correo electrónico
145
        if ($user->getEmailAddress() !== $oldEmail) {
146
            $this->requestEmailAddressChange($user, $oldEmail);
147
        }
148
149
        // Si es solicitado, cambiar la contraseña
150
        $passwordSubmitted = ($form->has('changePassword') && $form->get('changePassword') instanceof SubmitButton) && $form->get('changePassword')->isClicked();
151
        if ($passwordSubmitted) {
152
            $user->setPassword($this->get('security.password_encoder')
153
                ->encodePassword($user, $form->get('newPassword')->get('first')->getData()));
154
        }
155
        return $passwordSubmitted;
156
    }
157
}
158