UserController::signupAction()   B
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 38
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 11
Bugs 1 Features 2
Metric Value
c 11
b 1
f 2
dl 0
loc 38
rs 8.439
cc 5
eloc 23
nc 4
nop 1
1
<?php
2
3
namespace AppBundle\Controller;
4
5
use AppBundle\Entity\User;
6
use AppBundle\Form\Type\User\SignupType;
7
use AppBundle\Form\Type\User\ConfirmType;
8
use AppBundle\Form\Type\User\ProfileType;
9
use AppBundle\Form\Type\User\ResetType;
10
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
11
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
12
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
13
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
14
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
15
use Symfony\Component\Form\FormError;
16
use Symfony\Component\HttpFoundation\Request;
17
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
18
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
19
use Symfony\Component\Security\Core\Exception\DisabledException;
20
21
class UserController extends Controller
22
{
23
    use DoctrineController;
24
25
    /**
26
     * @Route("/login")
27
     * @Method("GET")
28
     * @Template
29
     */
30
    public function loginAction()
31
    {
32
        $authenticationUtils = $this->get('security.authentication_utils');
33
        $error = $authenticationUtils->getLastAuthenticationError();
34
        $lastUsername = $authenticationUtils->getLastUsername();
35
36
        if ($error) {
37
            if ($error instanceof DisabledException) {
38
                $error = $this->get('translator')->trans('user.login.account_disabled');
39
            } elseif ($error instanceof BadCredentialsException) {
40
                $error = $this->get('translator')->trans('user.login.incorrect_credentials');
41
            }
42
        }
43
        return compact('lastUsername', 'error');
44
    }
45
46
    /**
47
     * @Route("/signup")
48
     * @Method({"GET", "POST"})
49
     * @Template
50
     */
51
    public function signupAction(Request $request)
52
    {
53
        $form = $this->createForm(new SignupType(), $user = new User());
54
55
        $form->handleRequest($request);
56
        if (!$form->isValid()) {
57
            return ['form' => $form->createView()];
58
        }
59
60
        $same = $this->repo('AppBundle:User')->findOneBy(['email' => $user->getEmail()]);
61
        if (null !== $same and $same->isConfirmed()) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
62
            $form->get('email')->addError(new FormError(
63
                $this->get('translator')->trans('user.signup.already_confirmed', ['%email%' => $user->getEmail()])
64
            ));
65
            return ['form' => $form->createView()];
66
        }
67
68
        if (null !== $same) {
69
            $this->get('mail')->user($same, 'activate_email', [
70
                'link' => $this->generateUrl('app_user_confirm', ['token' => $same->getConfirmationToken()], true),
71
            ]);
72
            $this->addFlash('info', $this->get('translator')->trans('user.reset.confirmation_sent', [
73
                '%email%' => $same->getEmail()]
74
            ));
75
            return ['form' => $form->createView()];
76
        }
77
78
        $user->regenerateConfirmationToken();
79
        $this->persist($user);
80
        $this->flush();
81
82
        $this->get('mail')->user($user, 'activate_email', [
83
            'link' => $this->generateUrl('app_user_confirm', ['token' => $user->getConfirmationToken()], true),
84
        ]);
85
86
        $this->addFlash('success', $this->get('translator')->trans('user.reset.flash.email_sent'));
87
        return $this->redirect($this->generateUrl('app_user_login'));
88
    }
89
90
    /**
91
     * @Route("/confirm/{token}")
92
     * @Method({"GET", "POST"})
93
     * @ParamConverter("user", class="AppBundle:User", options={"mapping": {"token": "confirmationToken"}})
94
     * @Template
95
     */
96
    public function confirmAction(Request $request, User $user)
97
    {
98
        $form = $this->createForm(new ConfirmType(), $user);
99
        $form->handleRequest($request);
100
        if (!$form->isValid()) {
101
            return ['form' => $form->createView(), 'token' => $user->getConfirmationToken()];
102
        }
103
104
        $encoder = $this->container->get('security.encoder_factory')->getEncoder($user);
105
        $user->setPassword($encoder->encodePassword($user->getPlainPassword(), $user->getSalt()));
106
        $user->confirm();
107
        $this->persist($user);
108
        $this->flush();
109
110
        $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
111
        $this->get('security.token_storage')->setToken($token);
112
113
        $this->addFlash('success', $this->get('translator')->trans('user.flash.confirmed', ['%user%' => $user]));
114
        return $this->redirect($this->generateUrl('app_user_profile'));
115
    }
116
117
    /**
118
     * @Route("/profile")
119
     * @Method({"GET", "POST"})
120
     * @Template
121
     */
122
    public function profileAction(Request $request)
123
    {
124
        $user = clone $this->getUser(); // prevent user change in session
125
        $form = $this->createForm(new ProfileType(), $user);
126
        $form->handleRequest($request);
127
        if (!$form->isValid()) {
128
            return ['form' => $form->createView()];
129
        }
130
131
        $em = $this->getDoctrine()->getManager();
132
        if ($user->getPlainPassword()) {
133
            $encoder = $this->container->get('security.encoder_factory')->getEncoder($user);
134
            $user->setPassword($encoder->encodePassword($user->getPlainPassword(), $user->getSalt()));
135
        }
136
        $this->persist($em->merge($user));
137
        $this->flush();
138
139
        $this->addFlash('success', $this->get('translator')->trans('user.profile.flash.updated'));
140
        return $this->redirect($this->generateUrl('app_user_profile'));
141
    }
142
143
    /**
144
     * @Route("/reset")
145
     * @Method({"GET", "POST"})
146
     * @Template
147
     */
148
    public function resetAction(Request $request)
149
    {
150
        $form = $this->createForm(new ResetType());
151
        $form->handleRequest($request);
152
        if (!$form->isValid()) {
153
            return ['form' => $form->createView()];
154
        }
155
156
        $email = $form->get('email')->getData();
157
        $user = $this->repo('AppBundle:User')->findOneByEmail($email);
158
159
        if (!$user) {
160
            $form->get('email')->addError(new FormError($this->get('translator')->trans('user.reset.user_not_found')));
161
            return ['form' => $form->createView()];
162
        }
163
164
        // @TODO: expiration date may be useful
165
        $user->regenerateConfirmationToken();
166
        $this->persist($user);
167
        $this->flush();
168
169
        // @TODO: captcha after 3 failed attempts
170
        $this->get('mail')->user($user, 'activate_email', [
171
            'link' => $this->generateUrl('app_user_confirm', ['token' => $user->getConfirmationToken()], true),
172
        ]);
173
174
        $this->addFlash('success', $this->get('translator')->trans('user.reset.flash.password_sent', [
175
            '%email%' => $user->getEmail()
176
        ]));
177
178
        return $this->redirect($this->generateUrl('app_user_login'));
179
    }
180
}
181