Completed
Pull Request — 2.0 (#159)
by
unknown
03:01
created

GatewayController   B

Complexity

Total Complexity 31

Size/Duplication

Total Lines 281
Duplicated Lines 15.66 %

Coupling/Cohesion

Components 1
Dependencies 15

Importance

Changes 2
Bugs 2 Features 0
Metric Value
c 2
b 2
f 0
dl 44
loc 281
rs 8.9833
wmc 31
lcom 1
cbo 15

9 Methods

Rating   Name   Duplication   Size   Complexity  
B forgot() 10 24 4
A cancelRequest() 0 16 2
B cancel() 10 31 6
B register() 7 25 3
B activationEmail() 7 30 3
B activate() 0 30 4
A unauthorized() 0 14 3
A me() 10 21 3
A profile() 0 17 3

How to fix   Duplicated Code   

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:

1
<?php
2
/**
3
 * Licensed under The GPL-3.0 License
4
 * For full copyright and license information, please see the LICENSE.txt
5
 * Redistributions of files must retain the above copyright notice.
6
 *
7
 * @since    2.0.0
8
 * @author   Christopher Castro <[email protected]>
9
 * @link     http://www.quickappscms.org
10
 * @license  http://opensource.org/licenses/gpl-3.0.html GPL-3.0 License
11
 */
12
namespace User\Controller;
13
14
use Locale\Utility\LocaleToolbox;
15
use User\Controller\AppController;
16
use User\Controller\UserSignTrait;
17
use User\Notification\NotificationManager;
18
19
/**
20
 * Gateway controller.
21
 *
22
 * Provides login and logout methods.
23
 *
24
 * @property \User\Model\Table\UsersTable $Users
25
 * @method bool touch(\Cake\ORM\Entity $entity, string $eventName)
26
 * @method void unbindFieldable()
27
 */
28
class GatewayController extends AppController
29
{
30
31
    use UserSignTrait;
32
33
    /**
34
     * Starts the password recovery process.
35
     *
36
     * @return void
37
     */
38
    public function forgot()
39
    {
40
        if (!empty($this->request->data['username'])) {
41
            $this->loadModel('User.Users');
42
            $user = $this->Users
43
                ->find()
44
                ->where(['Users.username' => $this->request->data['username']])
45
                ->orWhere(['Users.email' => $this->request->data['username']])
46
                ->first();
47
48 View Code Duplication
            if ($user) {
49
                $emailSent = NotificationManager::passwordRequest($user)->send();
50
                if ($emailSent) {
51
                    $this->Flash->success(__d('user', 'Further instructions have been sent to your e-mail address.'));
52
                } else {
53
                    $this->Flash->warning(__d('user', 'Instructions could not been sent to your e-mail address, please try again later.'));
54
                }
55
            } else {
56
                $this->Flash->danger(__d('user', 'Sorry, "{0}" is not recognized as a user name or an e-mail address.', $this->request->data['username']));
57
            }
58
        }
59
60
        $this->title(__d('user', 'Password Recovery'));
61
    }
62
63
    /**
64
     * Here is where users can request to remove their accounts.
65
     *
66
     * Only non-administrator users can be canceled this way. User may request to
67
     * cancel their accounts by using the form rendered by this action, an e-mail
68
     * will be send with a especial link which will remove the account.
69
     *
70
     * @return void Redirects to previous page
71
     */
72
    public function cancelRequest()
73
    {
74
        $user = user();
75
76
        $this->loadModel('User.Users');
77
        $user = $this->Users->get($user->id);
78
        $emailSent = NotificationManager::cancelRequest($user)->send();
79
        if ($emailSent) {
80
            $this->Flash->success(__d('user', 'Further instructions have been sent to your e-mail address.'));
81
        } else {
82
            $this->Flash->warning(__d('user', 'Instructions could not been sent to your e-mail address, please try again later.'));
83
        }
84
85
        $this->title(__d('user', 'Account Cancellation'));
86
        $this->redirect($this->referer());
87
    }
88
89
    /**
90
     * Here is where user's account is actually removed.
91
     *
92
     * @param int $userId The ID of the user whose account is being canceled
93
     * @param string $code Cancellation code, code is a MD5 hash of user's encrypted
94
     *  password + site's salt
95
     * @return void Redirects to previous page
96
     */
97
    public function cancel($userId, $code)
98
    {
99
        $this->loadModel('User.Users');
100
        $user = $this->Users
101
            ->find()
102
            ->where(['id' => $userId])
103
            ->contain(['Roles'])
104
            ->limit(1)
105
            ->first();
106
107
        if (in_array(ROLE_ID_ADMINISTRATOR, $user->role_ids) &&
108
            $this->Users->countAdministrators() === 1
109
        ) {
110
            $this->Flash->warning(__d('user', 'You are the last administrator in the system, your account cannot be canceled.'));
111
            $this->redirect($this->referer());
112
        }
113
114 View Code Duplication
        if ($user && $code == $user->cancel_code) {
115
            if ($this->Users->delete($user)) {
116
                NotificationManager::canceled($user)->send();
117
                $this->Flash->success(__d('user', 'Account successfully canceled'));
118
            } else {
119
                $this->Flash->danger(__d('user', 'Account could not be canceled due to an internal error, please try again later.'));
120
            }
121
        } else {
122
            $this->Flash->warning(__d('user', 'Not user was found, invalid cancellation URL.'));
123
        }
124
125
        $this->title(__d('user', 'Account Cancellation'));
126
        $this->redirect($this->referer());
127
    }
128
129
    /**
130
     * Registers a new user.
131
     *
132
     * @return void
133
     */
134
    public function register()
135
    {
136
        $this->loadModel('User.Users');
137
        $this->Users->unbindFieldable();
138
        $user = $this->Users->newEntity();
139
        $registered = false;
140
        $languages = LocaleToolbox::languagesList();
141
142
        if ($this->request->data()) {
143
            $user->set('status', 0);
144
            $user->accessible(['id', 'token', 'status', 'last_login', 'created', 'roles'], false);
145
            $user = $this->Users->patchEntity($user, $this->request->data);
146
147 View Code Duplication
            if ($this->Users->save($user)) {
148
                NotificationManager::welcome($user)->send();
149
                $this->Flash->success(__d('user', 'Account successfully created, further instructions have been sent to your e-mail address.', ['key' => 'register']));
150
                $registered = true;
151
            } else {
152
                $this->Flash->danger(__d('user', 'Account could not be created, please check your information.'), ['key' => 'register']);
153
            }
154
        }
155
156
        $this->title(__d('user', 'Registration'));
157
        $this->set(compact('registered', 'user', 'languages'));
158
    }
159
160
    /**
161
     * Users can request to re-send activation instructions to their email address.
162
     *
163
     * @return void
164
     */
165
    public function activationEmail()
166
    {
167
        $this->loadModel('User.Users');
168
        $sent = false;
169
170
        if (!empty($this->request->data['username'])) {
171
            $user = $this->Users
172
                ->find()
173
                ->where([
174
                    'OR' => [
175
                        'username' => $this->request->data['username'],
176
                        'email' => $this->request->data['username'],
177
                    ],
178
                    'status' => 0
179
                ])
180
                ->limit(1)
181
                ->first();
182
183 View Code Duplication
            if ($user) {
184
                NotificationManager::welcome($user)->send();
185
                $this->Flash->success(__d('user', 'Instructions have been sent to your e-mail address.'), ['key' => 'activation_email']);
186
                $sent = true;
187
            } else {
188
                $this->Flash->danger(__d('user', 'No account was found matching the given username/email.'), ['key' => 'activation_email']);
189
            }
190
        }
191
192
        $this->title(__d('user', 'Activation Request'));
193
        $this->set(compact('sent'));
194
    }
195
196
    /**
197
     * Activates a registered user.
198
     *
199
     * @param string $token A valid user token
200
     * @return void
201
     */
202
    public function activate($token = null)
203
    {
204
        $activated = false;
205
        if ($token === null) {
206
            $this->redirect('/');
207
        }
208
209
        $this->loadModel('User.Users');
210
        $user = $this->Users
211
            ->find()
212
            ->select(['id', 'name', 'token'])
213
            ->where(['status' => 0, 'token' => $token])
214
            ->limit(1)
215
            ->first();
216
217
        if ($user) {
218
            if ($this->Users->updateAll(['status' => 1], ['id' => $user->id])) {
219
                NotificationManager::activated($user)->send();
220
                $activated = true;
221
                $this->Flash->success(__d('user', 'Account successfully activated.'), ['key' => 'activate']);
222
            } else {
223
                $this->Flash->danger(__d('user', 'Account could not be activated, please try again later.'), ['key' => 'activate']);
224
            }
225
        } else {
226
            $this->Flash->warning(__d('user', 'Account not found or is already active.'), ['key' => 'activate']);
227
        }
228
229
        $this->title(__d('user', 'Account Activation'));
230
        $this->set(compact('activated', 'token'));
231
    }
232
233
    /**
234
     * Renders the "unauthorized" screen, when an user attempts to access
235
     * to a restricted area.
236
     *
237
     * @return \Cake\Network\Response|null
238
     */
239
    public function unauthorized()
240
    {
241
        $this->loadModel('User.Users');
242
        if ($this->request->is('post')) {
243
            $user = $this->Auth->identify();
244
            if ($user) {
245
                $this->Auth->setUser($user);
0 ignored issues
show
Bug introduced by
It seems like $user defined by $this->Auth->identify() on line 243 can also be of type boolean; however, Cake\Controller\Component\AuthComponent::setUser() does only seem to accept array|object<ArrayAccess>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
246
247
                return $this->redirect($this->Auth->redirectUrl());
248
            } else {
249
                $this->Flash->danger(__d('user', 'Username or password is incorrect'));
250
            }
251
        }
252
    }
253
254
    /**
255
     * Renders user's "my profile" form.
256
     *
257
     * Here is where user can change their information.
258
     *
259
     * @return void
260
     */
261
    public function me()
262
    {
263
        $this->loadModel('User.Users');
264
        $user = $this->Users->get(user()->id, ['conditions' => ['status' => 1]]);
265
        $languages = LocaleToolbox::languagesList();
266
267 View Code Duplication
        if ($this->request->data()) {
268
            $user->accessible(['id', 'username', 'roles', 'status'], false);
269
            $user = $this->Users->patchEntity($user, $this->request->data);
270
            if ($this->Users->save($user)) {
271
                $this->Flash->success(__d('user', 'User information successfully updated!'), ['key' => 'user_profile']);
272
                $this->redirect($this->referer());
273
            } else {
274
                $this->Flash->danger(__d('user', 'User information could not be saved, please check your information.'), ['key' => 'user_profile']);
275
            }
276
        }
277
278
        $this->title(__d('user', 'Account'));
279
        $this->set(compact('user', 'languages'));
280
        $this->viewMode('full');
281
    }
282
283
    /**
284
     * Shows profile information for the given user.
285
     *
286
     * @param int $id User's ID
287
     * @return void
288
     * @throws \Cake\ORM\Exception\RecordNotFoundException When user not found, or
289
     *  users has marked profile as private
290
     */
291
    public function profile($id)
292
    {
293
        $this->loadModel('User.Users');	
294
	if(!$id){
295
            $id = user()->id;
296
        }
297
        $conditions = [];
298
        if ($id != user()->id) {
299
            $conditions = ['status' => 1, 'public_profile' => true];
300
        }
301
302
        $user = $this->Users->get($id, ['conditions' => $conditions]);
303
304
        $this->title(__d('user', 'User’s Profile'));
305
        $this->viewMode('full');
306
        $this->set(compact('user'));
307
    }
308
}
309