User::getChangePasswordForm()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
3
namespace LmcUser\Service;
4
5
use Interop\Container\ContainerInterface;
6
use Laminas\Authentication\AuthenticationService;
7
use Laminas\Form\Form;
8
use Laminas\ServiceManager\ServiceManager;
9
use Laminas\Crypt\Password\Bcrypt;
10
use Laminas\Hydrator;
11
use LmcUser\EventManager\EventProvider;
12
use LmcUser\Mapper\UserInterface as UserMapperInterface;
13
use LmcUser\Options\UserServiceOptionsInterface;
14
15
class User extends EventProvider
16
{
17
18
    /**
19
     * @var UserMapperInterface
20
     */
21
    protected $userMapper;
22
23
    /**
24
     * @var AuthenticationService
25
     */
26
    protected $authService;
27
28
    /**
29
     * @var Form
30
     */
31
    protected $loginForm;
32
33
    /**
34
     * @var Form
35
     */
36
    protected $registerForm;
37
38
    /**
39
     * @var Form
40
     */
41
    protected $changePasswordForm;
42
43
    /**
44
     * @var ServiceManager
45
     */
46
    protected $serviceManager;
47
48
    /**
49
     * @var UserServiceOptionsInterface
50
     */
51
    protected $options;
52
53
    /**
54
     * @var Hydrator\ClassMethods
55
     */
56
    protected $formHydrator;
57
58
    /**
59
     * createFromForm
60
     *
61
     * @param  array $data
62
     * @return \LmcUser\Entity\UserInterface
63
     * @throws Exception\InvalidArgumentException
64
     */
65
    public function register(array $data)
66
    {
67
        $class = $this->getOptions()->getUserEntityClass();
68
        $user  = new $class;
69
        $form  = $this->getRegisterForm();
70
        $form->setHydrator($this->getFormHydrator());
71
        $form->bind($user);
72
        $form->setData($data);
73
        if (!$form->isValid()) {
74
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by LmcUser\Service\User::register of type LmcUser\Entity\UserInterface.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
75
        }
76
77
        $user = $form->getData();
78
        /* @var $user \LmcUser\Entity\UserInterface */
79
80
        $bcrypt = new Bcrypt;
81
        $bcrypt->setCost($this->getOptions()->getPasswordCost());
82
        $user->setPassword($bcrypt->create($user->getPassword()));
83
84
        if ($this->getOptions()->getEnableUsername()) {
85
            $user->setUsername($data['username']);
86
        }
87
        if ($this->getOptions()->getEnableDisplayName()) {
88
            $user->setDisplayName($data['display_name']);
89
        }
90
91
        // If user state is enabled, set the default state value
92
        if ($this->getOptions()->getEnableUserState()) {
93
            $user->setState($this->getOptions()->getDefaultUserState());
94
        }
95
        $this->getEventManager()->trigger(__FUNCTION__, $this, array('user' => $user, 'form' => $form));
96
        $this->getUserMapper()->insert($user);
97
        $this->getEventManager()->trigger(__FUNCTION__.'.post', $this, array('user' => $user, 'form' => $form));
98
        return $user;
99
    }
100
101
    /**
102
     * change the current users password
103
     *
104
     * @param  array $data
105
     * @return boolean
106
     */
107
    public function changePassword(array $data)
108
    {
109
        $currentUser = $this->getAuthService()->getIdentity();
110
111
        $oldPass = $data['credential'];
112
        $newPass = $data['newCredential'];
113
114
        $bcrypt = new Bcrypt;
115
        $bcrypt->setCost($this->getOptions()->getPasswordCost());
116
117
        if (!$bcrypt->verify($oldPass, $currentUser->getPassword())) {
118
            return false;
119
        }
120
121
        $pass = $bcrypt->create($newPass);
122
        $currentUser->setPassword($pass);
123
124
        $this->getEventManager()->trigger(__FUNCTION__, $this, array('user' => $currentUser, 'data' => $data));
125
        $this->getUserMapper()->update($currentUser);
126
        $this->getEventManager()->trigger(__FUNCTION__.'.post', $this, array('user' => $currentUser, 'data' => $data));
127
128
        return true;
129
    }
130
131
    public function changeEmail(array $data)
132
    {
133
        $currentUser = $this->getAuthService()->getIdentity();
134
135
        $bcrypt = new Bcrypt;
136
        $bcrypt->setCost($this->getOptions()->getPasswordCost());
137
138
        if (!$bcrypt->verify($data['credential'], $currentUser->getPassword())) {
139
            return false;
140
        }
141
142
        $currentUser->setEmail($data['newIdentity']);
143
144
        $this->getEventManager()->trigger(__FUNCTION__, $this, array('user' => $currentUser, 'data' => $data));
145
        $this->getUserMapper()->update($currentUser);
146
        $this->getEventManager()->trigger(__FUNCTION__.'.post', $this, array('user' => $currentUser, 'data' => $data));
147
148
        return true;
149
    }
150
151
    /**
152
     * getUserMapper
153
     *
154
     * @return UserMapperInterface
155
     */
156
    public function getUserMapper()
157
    {
158
        if (null === $this->userMapper) {
159
            $this->userMapper = $this->getServiceManager()->get('lmcuser_user_mapper');
160
        }
161
        return $this->userMapper;
162
    }
163
164
    /**
165
     * setUserMapper
166
     *
167
     * @param  UserMapperInterface $userMapper
168
     * @return User
169
     */
170
    public function setUserMapper(UserMapperInterface $userMapper)
171
    {
172
        $this->userMapper = $userMapper;
173
        return $this;
174
    }
175
176
    /**
177
     * getAuthService
178
     *
179
     * @return AuthenticationService
180
     */
181
    public function getAuthService()
182
    {
183
        if (null === $this->authService) {
184
            $this->authService = $this->getServiceManager()->get('lmcuser_auth_service');
185
        }
186
        return $this->authService;
187
    }
188
189
    /**
190
     * setAuthenticationService
191
     *
192
     * @param  AuthenticationService $authService
193
     * @return User
194
     */
195
    public function setAuthService(AuthenticationService $authService)
196
    {
197
        $this->authService = $authService;
198
        return $this;
199
    }
200
201
    /**
202
     * @return Form
203
     */
204
    public function getRegisterForm()
205
    {
206
        if (null === $this->registerForm) {
207
            $this->registerForm = $this->getServiceManager()->get('lmcuser_register_form');
208
        }
209
        return $this->registerForm;
210
    }
211
212
    /**
213
     * @param  Form $registerForm
214
     * @return User
215
     */
216
    public function setRegisterForm(Form $registerForm)
217
    {
218
        $this->registerForm = $registerForm;
219
        return $this;
220
    }
221
222
    /**
223
     * @return Form
224
     */
225
    public function getChangePasswordForm()
226
    {
227
        if (null === $this->changePasswordForm) {
228
            $this->changePasswordForm = $this->getServiceManager()->get('lmcuser_change_password_form');
229
        }
230
        return $this->changePasswordForm;
231
    }
232
233
    /**
234
     * @param  Form $changePasswordForm
235
     * @return User
236
     */
237
    public function setChangePasswordForm(Form $changePasswordForm)
238
    {
239
        $this->changePasswordForm = $changePasswordForm;
240
        return $this;
241
    }
242
243
    /**
244
     * get service options
245
     *
246
     * @return UserServiceOptionsInterface
247
     */
248
    public function getOptions()
249
    {
250
        if (!$this->options instanceof UserServiceOptionsInterface) {
251
            $this->setOptions($this->getServiceManager()->get('lmcuser_module_options'));
252
        }
253
        return $this->options;
254
    }
255
256
    /**
257
     * set service options
258
     *
259
     * @param UserServiceOptionsInterface $options
260
     */
261
    public function setOptions(UserServiceOptionsInterface $options)
262
    {
263
        $this->options = $options;
264
    }
265
266
    /**
267
     * Retrieve service manager instance
268
     *
269
     * @return ServiceManager
270
     */
271
    public function getServiceManager()
272
    {
273
        return $this->serviceManager;
274
    }
275
276
    /**
277
     * Set service manager instance
278
     *
279
     * @param  ContainerInterface $serviceManager
280
     * @return User
281
     */
282
    public function setServiceManager(ContainerInterface $serviceManager)
283
    {
284
        $this->serviceManager = $serviceManager;
0 ignored issues
show
Documentation Bug introduced by
$serviceManager is of type object<Interop\Container\ContainerInterface>, but the property $serviceManager was declared to be of type object<Laminas\ServiceManager\ServiceManager>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof 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 given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
285
        return $this;
286
    }
287
288
    /**
289
     * Return the Form Hydrator
290
     *
291
     * @return \Laminas\Hydrator\HydratorInterface
292
     */
293
    public function getFormHydrator()
294
    {
295
        if (!$this->formHydrator instanceof Hydrator\HydratorInterface) {
296
            $this->setFormHydrator($this->getServiceManager()->get('lmcuser_register_form_hydrator'));
297
        }
298
299
        return $this->formHydrator;
300
    }
301
302
    /**
303
     * Set the Form Hydrator to use
304
     *
305
     * @param  Hydrator\HydratorInterface $formHydrator
306
     * @return User
307
     */
308
    public function setFormHydrator(Hydrator\HydratorInterface $formHydrator)
309
    {
310
        $this->formHydrator = $formHydrator;
0 ignored issues
show
Documentation Bug introduced by
$formHydrator is of type object<Laminas\Hydrator\HydratorInterface>, but the property $formHydrator was declared to be of type object<Laminas\Hydrator\ClassMethods>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof 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 given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
311
        return $this;
312
    }
313
}
314