Passed
Push — master ( 700b0f...aafb0a )
by Björn
18:25 queued 10s
created

ZfcuserController   C

Complexity

Total Complexity 54

Size/Duplication

Total Lines 758
Duplicated Lines 11.35 %

Coupling/Cohesion

Components 1
Dependencies 24

Test Coverage

Coverage 35.08%

Importance

Changes 0
Metric Value
wmc 54
lcom 1
cbo 24
dl 86
loc 758
ccs 87
cts 248
cp 0.3508
rs 6.322
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A getOptions() 0 4 1
A defineActionTitles() 0 21 1
A defineToolbarItems() 0 51 1
A onDispatch() 0 26 3
A userprofileAction() 0 18 2
A indexAction() 0 10 2
C requestpasswordresetAction() 11 89 11
D resetpasswordAction() 29 127 15
A userdataAction() 0 10 2
B edituserdataAction() 24 80 5
B edituserprofileAction() 0 70 5
A getUserTable() 11 11 3
A getAclroleTable() 11 11 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like ZfcuserController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ZfcuserController, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * BB's Zend Framework 2 Components
4
 * 
5
 * AdminModule
6
 *
7
 * @package   [MyApplication]
8
 * @package   BB's Zend Framework 2 Components
9
 * @package   AdminModule
10
 * @author    Björn Bartels <[email protected]>
11
 * @link      https://gitlab.bjoernbartels.earth/groups/zf2
12
 * @license   http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
13
 * @copyright copyright (c) 2016 Björn Bartels <[email protected]>
14
 */
15
16
17
namespace Admin\Controller;
18
19
use Application\Controller\Traits\ControllerTranslatorTrait;
20
use Application\Controller\Traits\ControllerActiontitlesTrait;
21
use Application\Controller\Traits\ControllerToolbarTrait;
22
23
use Admin\Module as AdminModule;
24
use Admin\Form\RequestPasswordResetForm;
25
use Admin\Form\ResetPasswordForm;
26
use Admin\Form\User;
27
use Admin\Form\UserData;
28
use Admin\Form\UserDataForm;
29
use Admin\Form\UserProfileForm;
30
use Admin\Model\UserProfile;
31
32
use Zend\Crypt\Password\Bcrypt;
33
use Zend\Stdlib\ResponseInterface as Response;
34
35
use Zend\View\Model\ViewModel;
36
use Zend\Mvc\MvcEvent;
37
use Zend\ServiceManager\ServiceLocatorInterface;
38
39
use ZfcUser\Controller\UserController;
40
use ZfcUser\Controller\Plugin\ZfcUserAuthentication;
41
42
/**
43
 * overrides to ZFC-User's own 'user'-controller
44
 * 
45
 * @method \ZfcUserAuthentication zfcUserAuthentication()
46
 */
47
class ZfcuserController extends UserController
48
{
49
	use ControllerTranslatorTrait;
50
	use ControllerActiontitlesTrait;
51
	use ControllerToolbarTrait;
52
	
53
    /**
54
     * 
55
     * @var array|\Admin\Model\AclroleTable
56
     */
57
    protected $aclroleTable;
58
    
59
    /**
60
     * 
61
     * @var array|\Admin\Model\UserTable
62
     */
63
    protected $userTable;
64
    
65
    /**
66
     * @param callable $redirectCallback
0 ignored issues
show
Bug introduced by
There is no parameter named $redirectCallback. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
67
     * @param callable $redirectCallback
0 ignored issues
show
Bug introduced by
There is no parameter named $redirectCallback. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
68
     * /
69
    //public function __construct(ServiceLocatorInterface $serviceLocator, $redirectCallback)
70
    public function __construct($userService, $options, $registerForm, $loginForm)
71
    {
72
        $this->userService = $userService;
73
        $this->options = $options;
74
        $this->registerForm = $registerForm;
75
        $this->loginForm = $loginForm;
76
        
77
        /*if ( $serviceLocator ) {
78
    		$this->setServiceLocator($serviceLocator);
79
    	}
80
    	if (!is_callable($redirectCallback)) {
81
            throw new \InvalidArgumentException('You must supply a callable redirectCallback');
82
        }
83
        $this->redirectCallback = $redirectCallback; * /
84
        
85
    }
86
87
    /**
88
     * set current action titles
89
     * @return self
90
     */
91
    public function defineActionTitles() 
92
    {
93
        $this->setActionTitles(
94
            array(
95
                'login'                 => $this->translate("login"),
96
                'authenticate'          => $this->translate("login"),
97
                'logout'                => $this->translate("logout"),
98
                'register'              => $this->translate("register user"),
99
                'requestpasswordreset'  => $this->translate("reset password"),
100
                'changeemail'           => $this->translate("change email"),
101
                'changepassword'        => $this->translate("change password"),
102
                'resetpassword'         => $this->translate("reset password"),
103
                'userdata'              => $this->translate("userdata"),
104
                'edituserdata'          => $this->translate("edit userdata"),
105
                'userprofile'           => $this->translate("user profile"),
106
                'index'                 => $this->translate("user profile"),
107
                'edituserprofile'       => $this->translate("edit profile"),
108
            )
109
        );
110
        return $this;
111
    }
112
113
    /**
114
     * set current toolbar items
115
     * @return self
116
     */
117
    public function defineToolbarItems() 
118
    {
119
        $this->setToolbarItems(
120
            array(
121
                "index" => array(
122
            array(
123
                'label'            => 'edit profile',
124
                'icon'            => 'edit',
125
                'class'            => 'button btn btn-default small btn-sm btn-cta-xhr cta-xhr-modal',
126
                'route'            => 'zfcuser/edituserprofile',
127
                'resource'        => 'mvc:user',
128
            ),
129
            array(
130
                'label'            => 'edit userdata',
131
                'icon'            => 'user',
132
                'class'            => 'button btn btn-default small btn-sm btn-cta-xhr cta-xhr-modal',
133
                'route'            => 'zfcuser/edituserdata',
134
                'resource'        => 'mvc:user',
135
            ),
136
            array(
137
                'label'         => 'change email',
138
                'icon'            => 'envelope',
139
                'class'            => 'button btn btn-default small btn-sm btn-cta-xhr cta-xhr-modal',
140
                'route'            => 'zfcuser/changeemail',
141
                'resource'        => 'mvc:user',
142
            ),
143
            array(
144
                'label'         => 'change password',
145
                'icon'            => 'lock',
146
                'class'            => 'button btn btn-default small btn-sm btn-cta-xhr cta-xhr-modal',
147
                'route'            => 'zfcuser/changepassword',
148
                'resource'        => 'mvc:user',
149
            ),
150
            array(
151
                'label'            => "",
152
                'class'            => 'btn btn-none small btn-sm',
153
                'uri'            => "#",
154
                'active'        => false,
155
            ),
156
            array(
157
                'label'         => 'logout',
158
                'icon'            => 'power-off',
159
                'class'            => 'button btn btn-default small btn-sm',
160
                'route'            => 'zfcuser/logout',
161
                'resource'        => 'mvc:user',
162
            ),
163
            ),
164
            )
165
        );
166
        return $this;
167
    }
168
169
    /**
170
     * initialize titles and toolbar items
171
     * 
172
     * {@inheritDoc}
173
     * @see \Zend\Mvc\Controller\AbstractActionController::onDispatch()
174
     */
175
    public function onDispatch(MvcEvent $e)
176
    {
177
        $oEvent = $this->applyToolbarOnDispatch($e);
0 ignored issues
show
Unused Code introduced by
$oEvent is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
178
        
179
        $routeMatch = $e->getRouteMatch();
180
        if (!$routeMatch) {
181
            /**
182
             * @todo Determine requirements for when route match is missing.
183
             *       Potentially allow pulling directly from request metadata?
184
             */
185
            throw new Exception\DomainException('Missing route matches; unsure how to retrieve action');
186
        }
187
188
        $action = $routeMatch->getParam('action', 'not-found');
189
        $method = static::getMethodFromAction($action);
190
191
        if (!method_exists($this, $method)) {
192
            $method = 'notFoundAction';
193
        }
194
195
        $actionResponse = $this->$method();
196
197
        $e->setResult($actionResponse);
198
199
        return $actionResponse;
200
    }
201
    
202
    /**
203
     * view user's profile data
204
     * @return mixed|\Zend\Http\Response|\Zend\View\Model\ViewModel
205
     */
206 1
    public function userprofileAction()
207
    {
208
        // if the user is logged in...
209 1
        if (!$this->zfcUserAuthentication()->hasIdentity()) {
210
            // ...redirect to the login redirect route
211
            return $this->redirect()->toRoute('zfcuser/login'); //$this->getOptions()->getLoginRedirectRoute());
212
        }
213 1
    	$oIdentity = $this->zfcUserAuthentication()->getIdentity();
214 1
        $oProfile = new \Admin\Model\UserProfile();
215 1
        $oProfile->load($oIdentity->getId());
216
        
217 1
        return new ViewModel(
218
            array(
219 1
                "userProfile" => $oProfile,
220 1
                "toolbarItems" => $this->getToolbarItems(),
221
            )
222
        );
223
    }
224
    
225
    /**
226
     * User page
227
     * @return mixed|\Zend\Http\Response|\Zend\View\Model\ViewModel
228
     */
229 1
    public function indexAction()
230
    {
231
        // if the user is logged in...
232 1
        if (!$this->zfcUserAuthentication()->hasIdentity()) {
233
            // ...redirect to the login redirect route
234
            //return $this->redirect()->toRoute('zfcuser/login'); //$this->getOptions()->getLoginRedirectRoute());
235
        }
236 1
        return $this->userprofileAction();
237
        
238
    }
239
240
    /**
241
     * General-purpose authentication action
242
     * /
243
    public function authenticateAction()
244
    {
245
        if ($this->zfcUserAuthentication()->hasIdentity()) {
246
            return $this->redirect()->toRoute($this->getOptions()->getLoginRedirectRoute());
247
        }
248
249
        $adapter = $this->zfcUserAuthentication()->getAuthAdapter();
250
        $redirect = $this->params()->fromPost('redirect', $this->params()->fromQuery('redirect', false));
251
252
        $result = $adapter->prepareForAuthentication($this->getRequest());
253
254
        // Return early if an adapter returned a response
255
        if ($result instanceof Response) {
256
            return $result;
257
        }
258
259
        $auth = $this->zfcUserAuthentication()->getAuthService()->authenticate($adapter);
260
261
        if (!$auth->isValid()) {
262
            $this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage($this->failedLoginMessage);
263
            $adapter->resetAdapters();
264
            return $this->redirect()->toUrl(
265
                $this->url()->fromRoute(static::ROUTE_LOGIN) .
266
                ($redirect ? '?redirect='. rawurlencode($redirect) : '')
267
            );
268
        }
269
270
        $redirect = $this->redirectCallback;
271
272
        return $redirect();
273
    }
274
    
275
    /**
276
     * Logout and clear the identity
277
     * /
278
    public function logoutAction()
279
    {
280
        $this->zfcUserAuthentication()->getAuthAdapter()->resetAdapters();
281
        $this->zfcUserAuthentication()->getAuthAdapter()->logoutAdapters();
282
        $this->zfcUserAuthentication()->getAuthService()->clearIdentity();
283
284
        //$redirect = $this->redirectCallback;
285
286
        //return $redirect();
287
    }
288
289
    
290
    /**
291
     * call parent object's authenticate... 
292
     * @return mixed|\Zend\Http\Response|\Zend\View\Model\ViewModel
293
     * /
294
    public function authenticateAction()
295
    {
296
    	return parent::authenticateAction();
297
    }
298
299
    /**
300
     * call parent object's logout... 
301
     * @return mixed|\Zend\Http\Response|\Zend\View\Model\ViewModel
302
     * /
303
    public function logoutAction()
304
    {
305
    	return parent::logoutAction();
306
    }
307
308
    /**
309
     * Register new user
310
     * @return mixed|\Zend\Http\Response|\Zend\View\Model\ViewModel
311
     * /
312
    public function registerAction()
313
    {
314
        // if the user is logged in, we don't need to register
315
        if ($this->zfcUserAuthentication()->hasIdentity()) {
316
            // redirect to the login redirect route
317
            return $this->redirect()->toRoute($this->getOptions()->getLoginRedirectRoute());
318
        }
319
        // if registration is disabled
320
        if (!$this->getOptions()->getEnableRegistration()) {
321
            return array('enableRegistration' => false);
322
        }
323
        
324
        $service = $this->getUserService();
325
        $config = $this->getServiceLocator()->get('Config');
326
        $translator    = $this->getTranslator();
327
        $oModule = new AdminModule();
328
        $oModule->setAppConfig($config);
329
        
330
        /** @var \Zend\Http\Response $registrationResponse * /
331
        $registrationResponse = parent::registerAction();
332
        
333
        if ($registrationResponse instanceof Response) {
334
        	$statusCode = $registrationResponse->getStatusCode();
335
        	if ($statusCode != 303) {
336
        		$this->flashMessenger()->addSuccessMessage($translator->translate("registration succeeded"));
337
		        if ($config['zfcuser_user_must_confirm']) {
338
		            $this->flashMessenger()->addInfoMessage($translator->translate("you have been sent an email with further instructions to follow"));
339
		        }
340
		        if ($config['zfcuser_admin_must_activate']) {
341
		        	$this->flashMessenger()->addInfoMessage($translator->translate("admin has been notified for activation"));
342
		        }
343
		        if ($service->getOptions()->getLoginAfterRegistration()) {
344
	            	//$oModule->sendActivationNotificationMail($user);
345
	            	$this->flashMessenger()->addSuccessMessage($translator->translate("registration and activation succeeded"));
346
		        }
347
        	}
348
	    }
349
        return $registrationResponse;
350
    }
351
352
    /**
353
     * request a user's password reset link
354
     * @return mixed|\Zend\Http\Response|\Zend\View\Model\ViewModel
355
     */
356 1
    public function requestpasswordresetAction()
357
    {
358
        // if the user is logged in, we don't need to 'reset' the password
359 1
        if ($this->zfcUserAuthentication()->hasIdentity()) {
360
            // redirect to the login redirect route
361
            return $this->redirect()->toRoute($this->getOptions()->getLoginRedirectRoute());
362
        }
363
        // \Application\Module::getService
364
        //$config     = $this->getServiceLocator()->get('Config');
365
        //$options    = $this->getServiceLocator()->get('zfcuser_module_options');
366
/*        
367
        $userService  = $serviceLocator->get('zfcuser_user_service');
368
        $registerForm = $serviceLocator->get('zfcuser_register_form');
369
        $loginForm    = $serviceLocator->get('zfcuser_login_form');
370
        $options      = $serviceLocator->get('zfcuser_module_options');
371
*/
372 1
        $config     = \Application\Module::getService('Config');
373 1
        $options    = \Application\Module::getService('zfcuser_module_options');
374
        /**
375
         * @var \Zend\Http\PhpEnvironment\Request|\Zend\Http\Request $request
376
         */
377 1
        $request    = $this->getRequest();
378
        //$service    = $this->getUserService();
379 1
        $service    = \Application\Module::getService('zfcuser_user_service');
380 1
        $form        = new RequestPasswordResetForm(null, $options);
381 1
        $translator    = $this->getTranslator();
382
        
383
        // if password reset is disabled
384 1
        if (!$config['zfcuser']['enable_passwordreset']) {
385
            return array('enableRegistration' => false);
386
        }
387
        
388 1 View Code Duplication
        if ($options->getUseRedirectParameterIfPresent() && $request->getQuery()->get('redirect')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
389
            $redirect = $request->getQuery()->get('redirect');
390
        } else {
391 1
            $redirect = false;
392
        }
393
394 1
        $redirectUrl = $this->url()->fromRoute('userrequestpasswordreset') . ($redirect ? '?redirect=' . rawurlencode($redirect) : '');
395
        
396 1
        if (!$request->isPost()) {
397
            return array(
398 1
            'requestPasswordResetForm' => $form,
399 1
            'enablePasswordReset' => !!$config['zfcuser']['enable_passwordreset'], // $this->getOptions()->getEnablePasswordreset(),
400 1
            'redirect' => $redirect,
401
            );
402
        }
403
        
404
        $oModule = new AdminModule();
405
        $oModule->setAppConfig($config);
406
        $identity = $this->params()->fromPost('identity');
407
408
        /** @var \Admin\Entity\User $user */
409
        $user = false;
410
        
411
            /** @var \Admin\Model\UserTable $userTable */
412
            $userTable = \Application\Module::getService('\Admin\Model\UserTable');
413
            /** @var \Admin\Entity\User $selectedUser */
414
            $selectedUser = $userTable->getUserByEmailOrUsername($identity);
415
            if ($selectedUser) {
416
                /** @var \ZfcUser\Mapper\User $userMapper */
417
                $userMapper = \Application\Module::getService('zfcuser_user_mapper');
418
                $user = $userMapper->findByUsername($selectedUser->username);
0 ignored issues
show
Bug introduced by
The property username cannot be accessed from this context as it is declared protected in class ZfcUser\Entity\User.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
419
                if (!$user) {
420
                    $user = $userMapper->findByEmail($selectedUser->email);
0 ignored issues
show
Bug introduced by
The property email cannot be accessed from this context as it is declared protected in class ZfcUser\Entity\User.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
421
                }
422
            }
423
        
424 View Code Duplication
        if (!$user) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
425
            $this->flashMessenger()->addWarningMessage(
426
                sprintf($translator->translate("user '%s' not found"), $identity)
427
            );
428
            return $this->redirect()->toUrl($redirectUrl);
429
        }
430
431
        // user found, create token and send link via email
432
        
433
        $user->setToken($oModule->createUserToken($user));
434
        $service->getUserMapper()->update($user);
435
        
436
        
437
        $oModule->sendPasswordResetMail($user);
438
        $this->flashMessenger()->addSuccessMessage(
439
            sprintf($translator->translate("password reset email has been sent to user '%s'"), $identity)
440
        );
441
        
442
        return $this->redirect()->toUrl($this->url()->fromRoute($config["zfcuser_registration_redirect_route"]) . ($redirect ? '?redirect='. rawurlencode($redirect) : ''));
443
            
444
    }
445
446
    /**
447
     * reset a user's password
448
     * @return mixed|\Zend\Http\Response|\Zend\View\Model\ViewModel
449
     */
450 4
    public function resetpasswordAction()
451
    {
452
        // if the user is logged in, we don't need to 'reset' the password
453 4
        if ($this->zfcUserAuthentication()->hasIdentity()) {
454
            // redirect to the login redirect route
455 1
            return $this->redirect()->toRoute($this->getOptions()->getLoginRedirectRoute());
456
        }
457
458
        //$config     = $this->getServiceLocator()->get('Config');
459
        //$options    = $this->getServiceLocator()->get('zfcuser_module_options');
460 3
        $config     = \Application\Module::getService('Config');
461 3
        $options    = \Application\Module::getService('zfcuser_module_options');
462
        /**
463
         * @var \Zend\Http\PhpEnvironment\Request|\Zend\Http\Request $request
464
         */
465 3
        $request    = $this->getRequest();
466
        //$service    = $this->getUserService();
467 3
        $service    = \Application\Module::getService('zfcuser_user_service');
468 3
        $form        = new ResetPasswordForm(null, $options);
0 ignored issues
show
Unused Code introduced by
The call to ResetPasswordForm::__construct() has too many arguments starting with $options.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
469 3
        $translator    = $this->getTranslator();
470
        
471
        // if password reset is disabled
472 3
        if (!$config['zfcuser']['enable_passwordreset']) {
473
            return array('enableRegistration' => false);
474
        }
475
        
476 3 View Code Duplication
        if ($options->getUseRedirectParameterIfPresent() && $request->getQuery()->get('redirect')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
477
            $redirect = $request->getQuery()->get('redirect');
478
        } else {
479 3
            $redirect = false;
480
        }
481
482 3
        $redirectUrl = $this->url()->fromRoute(static::ROUTE_LOGIN) . ($redirect ? '?redirect=' . rawurlencode($redirect) : '');
483
        
484 3
        if (!$request->isPost() ) {
485
            
486 3
            $user = false;
0 ignored issues
show
Unused Code introduced by
$user is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
487 3
            $userId = (int) $this->params()->fromRoute('user_id');
488 3
            $resetToken = $this->params()->fromRoute('resettoken');
489
            
490 3
            $userTable = \Application\Module::getService('zfcuser_user_mapper');
491 3
            $user = $userTable->findById($userId);
492
            
493 3 View Code Duplication
            if (!$user ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
494 2
                $this->flashMessenger()->addWarningMessage(
495 2
                    sprintf($translator->translate("invalid request"), '')
496
                );
497 2
                return $this->redirect()->toUrl($redirectUrl);
498
            }
499
            
500 1 View Code Duplication
            if (empty($resetToken) || ($resetToken != $user->getToken()) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
501 1
                $this->flashMessenger()->addWarningMessage(
502 1
                    sprintf($translator->translate("invalid request"), '')
503
                );
504 1
                return $this->redirect()->toUrl($redirectUrl);
505
            }
506
            
507
            return array(
508
                'user' => $user,
509
                'userId' => $userId,
510
                'resetToken' => $resetToken,
511
                'resetPasswordForm' => $form,
512
                'enablePasswordReset' => !!$config['zfcuser']['enable_passwordreset'],
513
                'redirect' => $redirect,
514
            );
515
            
516
        }
517
            
518
        $user = false;
0 ignored issues
show
Unused Code introduced by
$user is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
519
        $userId = $this->params()->fromPost('identity');
520
        $resetToken = $this->params()->fromPost('token');
521
        
522
        $oModule = new AdminModule();
523
        $oModule->setAppConfig($config);
524
        $user = false;
0 ignored issues
show
Unused Code introduced by
$user is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
525
        
526
        $userTable = \Application\Module::getService('zfcuser_user_mapper');
527
        $user = $userTable->findByEmail($userId);
528
            
529 View Code Duplication
        if (!$user ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
530
            $this->flashMessenger()->addWarningMessage(
531
                sprintf($translator->translate("invalid request"), $userId)
532
            );
533
            return $this->redirect()->toUrl($redirectUrl);
534
        }
535
        
536 View Code Duplication
        if (empty($resetToken) || ($resetToken != $user->getToken()) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
537
            $this->flashMessenger()->addWarningMessage(
538
                sprintf($translator->translate("invalid request"), $resetToken)
539
            );
540
            return $this->redirect()->toUrl($redirectUrl);
541
        }
542
        
543
        $form->setData((array)$this->params()->fromPost());
544
        
545
        if (!$form->isValid() ) {
546
            
547
            return array(
548
            'user' => $user,
549
            'userId' => $userId,
550
            'resetToken' => $resetToken,
551
            'resetPasswordForm' => $form,
552
            'enablePasswordReset' => !!$config['zfcuser']['enable_passwordreset'], // $this->getOptions()->getEnablePasswordreset(),
553
            'redirect' => $redirect,
554
            );
555
            
556
        } else {
557
        
558
            $newCredential = $this->params()->fromPost('newCredential');
559
            
560
            $bcrypt        = new Bcrypt;
561
            $bcrypt->setCost($options->getPasswordCost());
562
            $user->setPassword($bcrypt->create($newCredential));
563
            $user->setToken('');
564
            $service->getUserMapper()->update($user);
565
        
566
            $this->flashMessenger()->addSuccessMessage(
567
                sprintf($translator->translate("password has been set"), $resetToken)
568
            );
569
            return $this->redirect()->toUrl(
570
                $this->url()->fromRoute($config["zfcuser_registration_redirect_route"]) 
571
                . ($redirect ? '?redirect='. rawurlencode($redirect) : '')
572
            );
573
            
574
        }
575
        
576
    }
577
578
    /**
579
     * view user's basic data
580
     * @return mixed|\Zend\Http\Response|\Zend\View\Model\ViewModel
581
     */
582 1
    public function userdataAction()
583
    {
584
        // if the user is logged in...
585 1
        if (!$this->zfcUserAuthentication()->hasIdentity()) {
586
            // ...redirect to the login redirect route
587
            return $this->redirect()->toRoute($this->getOptions()->getLoginRedirectRoute());
588
        }
589
        
590 1
        return $this->redirect()->toRoute("zfcuser");
591
    }
592
    
593
    /**
594
     * edit user's basic data
595
     * @return mixed|\Zend\Http\Response|\Zend\View\Model\ViewModel
596
     */
597 1
    public function edituserdataAction()
598
    {
599
        
600
        // if the user is not logged in...
601 1
        if (!$this->zfcUserAuthentication()->hasIdentity()) {
602
            // ...redirect to the login redirect route
603
            return $this->redirect()->toRoute($this->getOptions()->getLoginRedirectRoute());
604
        }
605
        
606 1
        $form        = new UserDataForm();
607 1
        $translator    = $this->getTranslator();
608
        
609
        /** @var \Admin\Entity\User $oIdentity */
610 1
        $oIdentity        = $this->zfcUserAuthentication()->getIdentity();
611
        /** @var \Admin\Model\UserData $oUser */
612 1
        $oUser         = new \Admin\Model\UserData();
613
        
614 1
        $oUser->exchangeArray($oIdentity->__getArrayCopy());
615 1
        $userId        = (int) $oIdentity->getId();
616
617 1
        $form->bind($oUser);
618
    
619 1 View Code Duplication
        if (!$this->getRequest()->isPost() ) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method isPost() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
620
            
621 1
            return new ViewModel(
622
                array(
623 1
                    'showForm'        => true,
624 1
                    'user'            => $oIdentity,
625 1
                    'userId'          => $userId,
626 1
                    'userdataForm'    => $form,
627
                )
628
            );
629
            
630
        }
631
        
632
        $data = (array)$this->params()->fromPost();
633
        $form->setData($data);
634
        
635
        if (!$form->isValid() ) {
636
            
637
            $this->flashMessenger()->addWarningMessage(
638
                $translator->translate("user data could not be changed")
639
            );
640
            
641
            return new ViewModel(
642
                array(
643
                'showForm'        => true,
644
                'user'            => $oIdentity,
645
                'userId'        => $userId,
646
                'userdataForm'    => $form,
647
                )
648
            );
649
                
650
        } else {
651
            
652
            $oIdentity->setDisplayName($data["display_name"]);
653
            $oUser->exchangeArray($oIdentity->__getArrayCopy());
654
            
655
            $this->getUserTable()->saveUser($oUser);
656
            
657
            $this->flashMessenger()->addSuccessMessage(
658
                $translator->translate("user data has been changed")
659
            );
660
661 View Code Duplication
            if ($this->getRequest()->isXmlHttpRequest() ) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method isXmlHttpRequest() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
662
                return new ViewModel(
663
                    array(
664
                    'showForm'      => false,
665
                    'user'            => $oIdentity,
666
                    'userId'        => $userId,
667
                    'userdataForm'    => $form,
668
                    )
669
                );
670
            } else {
671
                return $this->redirect()->toRoute('zfcuser');
672
            }
673
    
674
        }
675
676
    }
677
    
678
    /**
679
     * edit user's profile data
680
     * @return mixed|\Zend\Http\Response|\Zend\View\Model\ViewModel
681
     */
682 1
    public function edituserprofileAction()
683
    {
684
        
685
        // if the user is not logged in...
686 1
        if (!$this->zfcUserAuthentication()->hasIdentity()) {
687
            // ...redirect to the login redirect route
688
            return $this->redirect()->toRoute($this->getOptions()->getLoginRedirectRoute());
689
        }
690
        
691 1
        $form        = new UserProfileForm();
692 1
        $translator    = $this->getTranslator();
693
        /**
694
         * @var \Zend\Http\PhpEnvironment\Request|\Zend\Http\Request $request
695
         */
696 1
        $request    = $this->getRequest();
697 1
        $user        = $this->zfcUserAuthentication()->getIdentity();
698 1
        $userId        = (int) $user->getId();
699 1
        $profile    = new UserProfile;
700 1
        $profile->load($userId);
701 1
        $form->bind($profile);
702
        
703 1
        if (!$this->getRequest()->isPost() ) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\RequestInterface as the method isPost() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Request, Zend\Http\Request.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
704
            
705
            return array(
706 1
                'showForm'        => true,
707 1
                'user'            => $user,
708 1
                'userId'          => $userId,
709 1
                'userprofileForm' => $form,
710
            );
711
            
712
        }
713
        
714
        $data = (array)$this->params()->fromPost();
715
        $form->setData($data);
716
        
717
        if (!$form->isValid() ) {
718
            
719
            $this->flashMessenger()->addWarningMessage(
720
                $translator->translate("user profile data could not be changed")
721
            );
722
            return array(
723
                'showForm'        => true,
724
                'user'            => $user,
725
                'userId'          => $userId,
726
                'userprofileForm' => $form,
727
            );
728
                
729
        } else {
730
        
731
            $profile->exchangeArray($data);
732
            $profile->save();
733
734
            $this->flashMessenger()->addSuccessMessage(
735
                $translator->translate("user profile data has been changed")
736
            );
737
            
738
            if ($request->isXmlHttpRequest() ) {
739
                $response = array(
0 ignored issues
show
Unused Code introduced by
$response is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
740
                    'showForm'          => false,
741
                    'user'                => $user,
742
                    'userId'            => $userId,
743
                    'userprofileForm'    => $form,
744
                );
745
            } else {
746
                return $this->redirect()->toRoute('zfcuser');
747
            }
748
                
749
        }
750
        
751
    }
752
    
753
754
    // // db mappers
755
756
    
757
    /**
758
     * retrieve user table mapper
759
     *
760
     * @return array|\Admin\Model\UserTable
761
     * @throws \Exception
762
     */
763 View Code Duplication
    public function getUserTable()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
764
    {
765
        if (!$this->userTable) {
766
            $sm = $this->getServiceLocator();
767
            $this->userTable = $sm->get('Admin\Model\UserTable');
768
            if (!$this->userTable instanceof \Admin\Model\UserTable) {
769
            	throw new \Exception("invalid user table object: ".gettype($this->userTable));
770
            }
771
        }
772
        return $this->userTable;
773
    }
774
    
775
    /**
776
     * retrieve ACL roles table mapper
777
     *
778
     * @return array|\Admin\Model\AclroleTable
779
     * @throws \Exception
780
     */
781 View Code Duplication
    public function getAclroleTable()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
782
    {
783
        if (!$this->aclroleTable) {
784
            $sm = $this->getServiceLocator();
785
            $this->aclroleTable = $sm->get('Admin\Model\AclroleTable');
786
            if (!$this->aclroleTable instanceof \Admin\Model\AclroleTable) {
787
            	throw new \Exception("invalid ACL role table object: ".gettype($this->aclroleTable));
788
            }
789
        }
790
        return $this->aclroleTable;
791
    }
792
    
793
    /**
794
     * retrieve ZfcUser\ModuleOptions
795
     *
796
     * @return array|\ZfcUser\ModuleOptions
797
     * @throws \Exception
798
     */
799
    public function getOptions()
800
    {
801
    	return \Application\Module::getService('zfcuser_module_options');
802
    } 
803
    
804
}
805