Completed
Pull Request — 1.x (#627)
by Dylan
08:40
created

UserController::indexAction()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

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