Completed
Pull Request — 1.x (#641)
by
unknown
15:00
created

UserController::registerAction()   C

Complexity

Conditions 14
Paths 50

Size

Total Lines 64
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 64
rs 6.0222
c 0
b 0
f 0
cc 14
eloc 40
nc 50
nop 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace ZfcUser\Controller;
4
5
use Zend\Form\FormInterface;
6
use Zend\Mvc\Controller\AbstractActionController;
7
use Zend\ServiceManager\ServiceLocatorInterface;
8
use Zend\Stdlib\ResponseInterface as Response;
9
use Zend\Stdlib\Parameters;
10
use Zend\View\Model\ViewModel;
11
use ZfcUser\Service\User as UserService;
12
use ZfcUser\Options\UserControllerOptionsInterface;
13
14
class UserController extends AbstractActionController
15
{
16
    const ROUTE_CHANGEPASSWD = 'zfcuser/changepassword';
17
    const ROUTE_LOGIN        = 'zfcuser/login';
18
    const ROUTE_REGISTER     = 'zfcuser/register';
19
    const ROUTE_CHANGEEMAIL  = 'zfcuser/changeemail';
20
21
    const CONTROLLER_NAME    = 'zfcuser';
22
23
    /**
24
     * @var UserService
25
     */
26
    protected $userService;
27
28
    /**
29
     * @var FormInterface
30
     */
31
    protected $loginForm;
32
33
    /**
34
     * @var FormInterface
35
     */
36
    protected $registerForm;
37
38
    /**
39
     * @var FormInterface
40
     */
41
    protected $changePasswordForm;
42
43
    /**
44
     * @var FormInterface
45
     */
46
    protected $changeEmailForm;
47
48
    /**
49
     * @todo Make this dynamic / translation-friendly
50
     * @var string
51
     */
52
    protected $failedLoginMessage = 'Authentication failed. Please try again.';
53
54
    /**
55
     * @var UserControllerOptionsInterface
56
     */
57
    protected $options;
58
59
    /**
60
     * @var callable $redirectCallback
61
     */
62
    protected $redirectCallback;
63
64
    /**
65
     * @var ServiceLocatorInterface
66
     */
67
    protected $serviceLocator;
68
69
    /**
70
     * @param callable $redirectCallback
71
     */
72
    public function __construct($redirectCallback)
73
    {
74
        if (!is_callable($redirectCallback)) {
75
            throw new \InvalidArgumentException('You must supply a callable redirectCallback');
76
        }
77
        $this->redirectCallback = $redirectCallback;
78
    }
79
80
    /**
81
     * User page
82
     */
83
    public function indexAction()
84
    {
85
        if (!$this->zfcUserAuthentication()->hasIdentity()) {
86
            return $this->redirect()->toRoute(static::ROUTE_LOGIN);
87
        }
88
        return new ViewModel();
89
    }
90
91
    /**
92
     * Login form
93
     */
94
    public function loginAction()
95
    {
96
        if ($this->zfcUserAuthentication()->hasIdentity()) {
97
            return $this->redirect()->toRoute($this->getOptions()->getLoginRedirectRoute());
98
        }
99
100
        $request = $this->getRequest();
101
        $form    = $this->getLoginForm();
102
103
        if ($this->getOptions()->getUseRedirectParameterIfPresent() && $request->getQuery()->get('redirect')) {
104
            $redirect = $request->getQuery()->get('redirect');
105
        } else {
106
            $redirect = false;
107
        }
108
109
        if (!$request->isPost()) {
110
            return array(
111
                'loginForm' => $form,
112
                'redirect'  => $redirect,
113
                'enableRegistration' => $this->getOptions()->getEnableRegistration(),
114
            );
115
        }
116
117
        $form->setData($request->getPost());
118
119
        if (!$form->isValid()) {
120
            $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage($this->failedLoginMessage);
121
            return $this->redirect()->toUrl($this->url()->fromRoute(static::ROUTE_LOGIN).($redirect ? '?redirect='. rawurlencode($redirect) : ''));
122
        }
123
124
        // clear adapters
125
        $this->zfcUserAuthentication()->getAuthAdapter()->resetAdapters();
126
        $this->zfcUserAuthentication()->getAuthService()->clearIdentity();
127
128
        return $this->forward()->dispatch(static::CONTROLLER_NAME, array('action' => 'authenticate'));
129
    }
130
131
    /**
132
     * Logout and clear the identity
133
     */
134
    public function logoutAction()
135
    {
136
        $this->zfcUserAuthentication()->getAuthAdapter()->resetAdapters();
137
        $this->zfcUserAuthentication()->getAuthAdapter()->logoutAdapters();
138
        $this->zfcUserAuthentication()->getAuthService()->clearIdentity();
139
140
        $redirect = $this->redirectCallback;
141
142
        return $redirect();
143
    }
144
145
    /**
146
     * General-purpose authentication action
147
     */
148
    public function authenticateAction()
149
    {
150
        if ($this->zfcUserAuthentication()->hasIdentity()) {
151
            return $this->redirect()->toRoute($this->getOptions()->getLoginRedirectRoute());
152
        }
153
154
        $adapter = $this->zfcUserAuthentication()->getAuthAdapter();
155
        $redirect = $this->params()->fromPost('redirect', $this->params()->fromQuery('redirect', false));
156
157
        $result = $adapter->prepareForAuthentication($this->getRequest());
158
159
        // Return early if an adapter returned a response
160
        if ($result instanceof Response) {
161
            return $result;
162
        }
163
164
        $auth = $this->zfcUserAuthentication()->getAuthService()->authenticate($adapter);
165
166
        if (!$auth->isValid()) {
167
            $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage($this->failedLoginMessage);
168
            $adapter->resetAdapters();
169
            return $this->redirect()->toUrl(
170
                $this->url()->fromRoute(static::ROUTE_LOGIN) .
171
                ($redirect ? '?redirect='. rawurlencode($redirect) : '')
172
            );
173
        }
174
175
        $redirect = $this->redirectCallback;
176
177
        return $redirect();
178
    }
179
180
    /**
181
     * Register new user
182
     */
183
    public function registerAction()
184
    {
185
        // if the user is logged in, we don't need to register
186
        if ($this->zfcUserAuthentication()->hasIdentity()) {
187
            // redirect to the login redirect route
188
            return $this->redirect()->toRoute($this->getOptions()->getLoginRedirectRoute());
189
        }
190
        // if registration is disabled
191
        if (!$this->getOptions()->getEnableRegistration()) {
192
            return array('enableRegistration' => false);
193
        }
194
195
        $request = $this->getRequest();
196
        $service = $this->getUserService();
197
        $form = $this->getRegisterForm();
198
199
        if ($this->getOptions()->getUseRedirectParameterIfPresent() && $request->getQuery()->get('redirect')) {
200
            $redirect = $request->getQuery()->get('redirect');
201
        } else {
202
            $redirect = false;
203
        }
204
205
        $redirectUrl = $this->url()->fromRoute(static::ROUTE_REGISTER)
206
            . ($redirect ? '?redirect=' . rawurlencode($redirect) : '');
207
        $prg = $this->prg($redirectUrl, true);
208
209
        if ($prg instanceof Response) {
210
            return $prg;
211
        } elseif ($prg === false) {
212
            return array(
213
                'registerForm' => $form,
214
                'enableRegistration' => $this->getOptions()->getEnableRegistration(),
215
                'redirect' => $redirect,
216
            );
217
        }
218
219
        $post = $prg;
220
        $user = $service->register($post);
221
222
        $redirect = isset($prg['redirect']) ? $prg['redirect'] : null;
223
224
        if (!$user) {
225
            return array(
226
                'registerForm' => $form,
227
                'enableRegistration' => $this->getOptions()->getEnableRegistration(),
228
                'redirect' => $redirect,
229
            );
230
        }
231
232
        if ($service->getOptions()->getLoginAfterRegistration()) {
233
            $identityFields = $service->getOptions()->getAuthIdentityFields();
234
            if (in_array('email', $identityFields)) {
235
                $post['identity'] = $user->getEmail();
236
            } elseif (in_array('username', $identityFields)) {
237
                $post['identity'] = $user->getUsername();
238
            }
239
            $post['credential'] = $post['password'];
240
            $request->setPost(new Parameters($post));
241
            return $this->forward()->dispatch(static::CONTROLLER_NAME, array('action' => 'authenticate'));
242
        }
243
244
        // TODO: Add the redirect parameter here...
245
        return $this->redirect()->toUrl($this->url()->fromRoute(static::ROUTE_LOGIN) . ($redirect ? '?redirect='. rawurlencode($redirect) : ''));
246
    }
247
248
    /**
249
     * Change the users password
250
     */
251
    public function changepasswordAction()
252
    {
253
        // if the user isn't logged in, we can't change password
254
        if (!$this->zfcUserAuthentication()->hasIdentity()) {
255
            // redirect to the login redirect route
256
            return $this->redirect()->toRoute($this->getOptions()->getLoginRedirectRoute());
257
        }
258
259
        $form = $this->getChangePasswordForm();
260
        $prg = $this->prg(static::ROUTE_CHANGEPASSWD);
261
262
        $fm = $this->flashMessenger()->setNamespace('change-password')->getMessages();
263
        if (isset($fm[0])) {
264
            $status = $fm[0];
265
        } else {
266
            $status = null;
267
        }
268
269
        if ($prg instanceof Response) {
270
            return $prg;
271
        } elseif ($prg === false) {
272
            return array(
273
                'status' => $status,
274
                'changePasswordForm' => $form,
275
            );
276
        }
277
278
        $form->setData($prg);
279
280
        if (!$form->isValid()) {
281
            return array(
282
                'status' => false,
283
                'changePasswordForm' => $form,
284
            );
285
        }
286
287
        if (!$this->getUserService()->changePassword($form->getData())) {
288
            return array(
289
                'status' => false,
290
                'changePasswordForm' => $form,
291
            );
292
        }
293
294
        $this->flashMessenger()->setNamespace('change-password')->addMessage(true);
295
        return $this->redirect()->toRoute(static::ROUTE_CHANGEPASSWD);
296
    }
297
298
    public function changeEmailAction()
299
    {
300
        // if the user isn't logged in, we can't change email
301
        if (!$this->zfcUserAuthentication()->hasIdentity()) {
302
            // redirect to the login redirect route
303
            return $this->redirect()->toRoute($this->getOptions()->getLoginRedirectRoute());
304
        }
305
306
        $form = $this->getChangeEmailForm();
307
        $request = $this->getRequest();
308
        $request->getPost()->set('identity', $this->getUserService()->getAuthService()->getIdentity()->getEmail());
309
310
        $fm = $this->flashMessenger()->setNamespace('change-email')->getMessages();
311
        if (isset($fm[0])) {
312
            $status = $fm[0];
313
        } else {
314
            $status = null;
315
        }
316
317
        $prg = $this->prg(static::ROUTE_CHANGEEMAIL);
318
        if ($prg instanceof Response) {
319
            return $prg;
320
        } elseif ($prg === false) {
321
            return array(
322
                'status' => $status,
323
                'changeEmailForm' => $form,
324
            );
325
        }
326
327
        $form->setData($prg);
328
329
        if (!$form->isValid()) {
330
            return array(
331
                'status' => false,
332
                'changeEmailForm' => $form,
333
            );
334
        }
335
336
        $change = $this->getUserService()->changeEmail($prg);
337
338
        if (!$change) {
339
            $this->flashMessenger()->setNamespace('change-email')->addMessage(false);
340
            return array(
341
                'status' => false,
342
                'changeEmailForm' => $form,
343
            );
344
        }
345
346
        $this->flashMessenger()->setNamespace('change-email')->addMessage(true);
347
        return $this->redirect()->toRoute(static::ROUTE_CHANGEEMAIL);
348
    }
349
350
    /**
351
     * Getters/setters for DI stuff
352
     */
353
354
    public function getUserService()
355
    {
356
        if (!$this->userService) {
357
            $this->userService = $this->serviceLocator->get('zfcuser_user_service');
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->serviceLocator->g...'zfcuser_user_service') can also be of type array. However, the property $userService is declared as type object<ZfcUser\Service\User>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
358
        }
359
        return $this->userService;
360
    }
361
362
    public function setUserService(UserService $userService)
363
    {
364
        $this->userService = $userService;
365
        return $this;
366
    }
367
368
    public function getRegisterForm()
369
    {
370
        if (!$this->registerForm) {
371
            $this->setRegisterForm($this->serviceLocator->get('zfcuser_register_form'));
0 ignored issues
show
Documentation introduced by
$this->serviceLocator->g...zfcuser_register_form') is of type object|array, but the function expects a object<Zend\Form\FormInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
372
        }
373
        return $this->registerForm;
374
    }
375
376
    public function setRegisterForm(FormInterface$registerForm)
377
    {
378
        $this->registerForm = $registerForm;
379
    }
380
381
    public function getLoginForm()
382
    {
383
        if (!$this->loginForm) {
384
            $this->setLoginForm($this->serviceLocator->get('zfcuser_login_form'));
0 ignored issues
show
Documentation introduced by
$this->serviceLocator->get('zfcuser_login_form') is of type object|array, but the function expects a object<Zend\Form\FormInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
385
        }
386
        return $this->loginForm;
387
    }
388
389
    public function setLoginForm(FormInterface $loginForm)
390
    {
391
        $this->loginForm = $loginForm;
392
        $fm = $this->flashMessenger()->setNamespace('zfcuser-login-form')->getMessages();
393
        if (isset($fm[0])) {
394
            $this->loginForm->setMessages(
395
                array('identity' => array($fm[0]))
396
            );
397
        }
398
        return $this;
399
    }
400
401
    public function getChangePasswordForm()
402
    {
403
        if (!$this->changePasswordForm) {
404
            $this->setChangePasswordForm($this->serviceLocator->get('zfcuser_change_password_form'));
0 ignored issues
show
Documentation introduced by
$this->serviceLocator->g..._change_password_form') is of type object|array, but the function expects a object<Zend\Form\FormInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
405
        }
406
        return $this->changePasswordForm;
407
    }
408
409
    public function setChangePasswordForm(FormInterface $changePasswordForm)
410
    {
411
        $this->changePasswordForm = $changePasswordForm;
412
        return $this;
413
    }
414
415
    /**
416
     * set options
417
     *
418
     * @param UserControllerOptionsInterface $options
419
     * @return UserController
420
     */
421
    public function setOptions(UserControllerOptionsInterface $options)
422
    {
423
        $this->options = $options;
424
        return $this;
425
    }
426
427
    /**
428
     * get options
429
     *
430
     * @return UserControllerOptionsInterface
431
     */
432
    public function getOptions()
433
    {
434
        if (!$this->options instanceof UserControllerOptionsInterface) {
435
            $this->setOptions($this->serviceLocator->get('zfcuser_module_options'));
0 ignored issues
show
Documentation introduced by
$this->serviceLocator->g...fcuser_module_options') is of type object|array, but the function expects a object<ZfcUser\Options\U...rollerOptionsInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
436
        }
437
        return $this->options;
438
    }
439
440
    /**
441
     * Get changeEmailForm.
442
     * @return ChangeEmailForm
443
     */
444
    public function getChangeEmailForm()
445
    {
446
        if (!$this->changeEmailForm) {
447
            $this->setChangeEmailForm($this->serviceLocator->get('zfcuser_change_email_form'));
448
        }
449
        return $this->changeEmailForm;
450
    }
451
452
    /**
453
     * Set changeEmailForm.
454
     *
455
     * @param $changeEmailForm - the value to set.
456
     * @return $this
457
     */
458
    public function setChangeEmailForm($changeEmailForm)
459
    {
460
        $this->changeEmailForm = $changeEmailForm;
461
        return $this;
462
    }
463
}
464