Completed
Push — master ( eb4993...5ea51c )
by Igor
03:27
created

IndexController   B

Complexity

Total Complexity 41

Size/Duplication

Total Lines 279
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 13

Importance

Changes 10
Bugs 2 Features 3
Metric Value
wmc 41
c 10
b 2
f 3
lcom 1
cbo 13
dl 0
loc 279
rs 8.2769

13 Methods

Rating   Name   Duplication   Size   Complexity  
B behaviors() 0 27 1
A actions() 0 13 1
B successCallback() 0 26 3
A actionIndex() 0 4 1
A actionLogin() 0 15 4
B actionSignup() 0 23 4
D actionSignupProvider() 0 39 9
B actionConfirmRequest() 0 24 3
B actionConfirmEmail() 0 25 3
B actionRequestPasswordReset() 0 23 4
B actionResetPassword() 0 24 5
A actionLogout() 0 5 1
A actionMaintenance() 0 9 2

How to fix   Complexity   

Complex Class

Complex classes like IndexController 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 IndexController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace app\controllers;
4
5
use Yii;
6
use yii\filters\VerbFilter;
7
use yii\filters\AccessControl;
8
use app\components\BaseController;
9
use app\helpers\Http;
10
use app\models\User;
11
use app\models\UserProvider;
12
use app\models\forms\LoginForm;
13
use app\models\forms\SignupForm;
14
use app\models\forms\SignupProviderForm;
15
use app\models\forms\PasswordResetRequestForm;
16
use app\models\forms\ResetPasswordForm;
17
use app\models\forms\ConfirmEmailForm;
18
19
class IndexController extends BaseController
20
{
21
    /**
22
     * @inheritdoc
23
     */
24
    public function behaviors()
25
    {
26
        return [
27
            'access' => [
28
                'class' => AccessControl::className(),
29
                'only' => ['logout', 'signup', 'auth'],
30
                'rules' => [
31
                    [
32
                        'actions' => ['signup', 'auth'],
33
                        'allow' => true,
34
                        'roles' => ['?'],
35
                    ],
36
                    [
37
                        'actions' => ['logout', 'confirm-request'],
38
                        'allow' => true,
39
                        'roles' => ['@'],
40
                    ],
41
                ],
42
            ],
43
            'verbs' => [
44
                'class' => VerbFilter::className(),
45
                'actions' => [
46
                    'logout' => ['post'],
47
                ],
48
            ],
49
        ];
50
    }
51
52
    /**
53
     * @inheritdoc
54
     */
55
    public function actions()
56
    {
57
        return [
58
            'error' => [
59
                'class' => 'yii\web\ErrorAction',
60
            ],
61
            'auth' => [
62
                'class' => 'yii\authclient\AuthAction',
63
                'successCallback' => [$this, 'successCallback'],
64
                'successUrl' => 'signup-provider'
65
            ],
66
        ];
67
    }
68
69
    public function successCallback($provider)
70
    {
71
        Yii::$app->session['provider'] = null;
72
        Yii::$app->session['blocked'] = false;
73
74
        $type = UserProvider::getTypeByName($provider->id);
75
        $profile = $provider->getUserAttributes();
76
        $token = $provider->getAccessToken()->getParams();
77
        $data = [
78
            'type' => $type,
79
            'profile' => $profile,
80
            'token' => $token
81
        ];
82
83
        if ($user = User::findByProvider($type, $profile['id'])) {
84
            if ($user->isActive()) {
85
                $user->updateProvider(UserProvider::parseProvider($type, $data));
86
                $user->authorize(true);
87
            } else {
88
                Yii::$app->session['blocked'] = true;
89
                Yii::$app->session['message'] = $user->getStatusDescription();
0 ignored issues
show
Bug introduced by
The method getStatusDescription cannot be called on $user (of type array|boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
90
            }
91
        } else {
92
            Yii::$app->session['provider'] = $data;
93
        }
94
    }
95
96
    public function actionIndex()
97
    {
98
        return $this->render('index');
99
    }
100
101
    public function actionLogin()
102
    {
103
        if (!Yii::$app->user->isGuest) {
104
            return $this->goHome();
105
        }
106
107
        $model = new LoginForm();
108
        if ($model->load(Yii::$app->request->post()) && $model->login()) {
109
            return $this->goBack();
110
        } else {
111
            return $this->render('login', [
112
                'model' => $model,
113
            ]);
114
        }
115
    }
116
117
    public function actionSignup()
118
    {
119
        $model = new SignupForm();
120
        if ($model->load(Yii::$app->request->post()) && $model->signup()) {
121
            if ($model->sendEmail()) {
122
                Yii::$app->session->setFlash(
123
                    'success',
124
                    Yii::t('app.messages', 'Please activate your account') . '. ' .
125
                    Yii::t('app.messages', 'A letter for activation was sent to {email}', ['email' => $model->email])
126
                );
127
            } else {
128
                Yii::$app->session->setFlash(
129
                    'error',
130
                    Yii::t('app.messages', 'An error occurred while sending a message to activate account')
131
                );
132
            }
133
            return $this->goHome();
134
        }
135
136
        return $this->render('signup', [
137
            'model' => $model,
138
        ]);
139
    }
140
141
    public function actionSignupProvider()
142
    {
143
        if (Yii::$app->session['blocked']) {
144
            Yii::$app->session->setFlash('error', Yii::$app->session['message']);
145
            return $this->goHome();
146
        }
147
148
        if (!Yii::$app->user->isGuest || Yii::$app->session['provider'] === null) {
149
            return $this->goHome();
150
        }
151
152
        $model = new SignupProviderForm(Yii::$app->session['provider']);
153
154
        if ($model->isVerified() && $model->signup(false)) {
155
            Yii::$app->session['provider'] = null;
156
            return $this->goHome();
157
        }
158
159
        if ($model->load(Yii::$app->request->post()) && $model->signup()) {
160
            Yii::$app->session['provider'] = null;
161
            if ($model->sendEmail()) {
162
                Yii::$app->session->setFlash(
0 ignored issues
show
Bug introduced by
The method setFlash cannot be called on \Yii::$app->session (of type array<string,null,{"provider":"null"}>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
163
                    'success',
164
                    Yii::t('app.messages', 'Please activate your account') . '. ' .
165
                    Yii::t('app.messages', 'A letter for activation was sent to {email}', ['email' => $model->email])
166
                );
167
            } else {
168
                Yii::$app->session->setFlash(
0 ignored issues
show
Bug introduced by
The method setFlash cannot be called on \Yii::$app->session (of type array<string,null,{"provider":"null"}>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
169
                    'error',
170
                    Yii::t('app.messages', 'An error occurred while sending a message to activate account')
171
                );
172
            }
173
            return $this->goHome();
174
        }
175
176
        return $this->render('signupProvider', [
177
            'model' => $model
178
        ]);
179
    }
180
181
    public function actionConfirmRequest()
182
    {
183
        $user = Yii::$app->user->identity;
184
        if ($user->isConfirmed()) {
185
            Http::exception(403);
186
        } // @codeCoverageIgnore
187
188
        $model = new ConfirmEmailForm();
189
190
        if ($model->sendEmail($user)) {
191
            Yii::$app->session->setFlash(
192
                'success',
193
                Yii::t('app.messages', 'A letter for activation was sent to {email}', [
194
                    'email' => $user->email
195
                ])
196
            );
197
        } else {
198
            Yii::$app->session->setFlash(
199
                'error',
200
                Yii::t('app.messages', 'An error occurred while sending a message to activate account')
201
            );
202
        }
203
        return $this->goHome();
204
    }
205
206
    public function actionConfirmEmail($token)
207
    {
208
        $model = new ConfirmEmailForm();
209
210
        if (!$model->validateToken($token)) {
211
            Yii::$app->session->setFlash(
212
                'error',
213
                Yii::t('app.messages', 'Invalid link for activate account')
214
            );
215
            return $this->goHome();
216
        }
217
218
        if ($model->confirmEmail()) {
219
            Yii::$app->session->setFlash(
220
                'success',
221
                Yii::t('app.messages', 'Your account is successfully activated')
222
            );
223
        } else {
224
            Yii::$app->session->setFlash(
225
                'error',
226
                Yii::t('app.messages', 'An error occurred while activating account')
227
            );
228
        }
229
        return $this->goHome();
230
    }
231
232
    public function actionRequestPasswordReset()
233
    {
234
        $model = new PasswordResetRequestForm();
235
236
        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
237
            if ($model->sendEmail()) {
238
                Yii::$app->session->setFlash(
239
                    'success',
240
                    Yii::t('app.messages', 'We\'ve sent you an email with instructions to reset your password')
241
                );
242
            } else {
243
                Yii::$app->session->setFlash(
244
                    'error',
245
                    Yii::t('app.messages', 'An error occurred while sending a message to reset your password')
246
                );
247
            }
248
            return $this->goHome();
249
        }
250
251
        return $this->render('requestPasswordResetToken', [
252
            'model' => $model,
253
        ]);
254
    }
255
256
    public function actionResetPassword($token)
257
    {
258
        $model = new ResetPasswordForm();
259
260
        if (!$model->validateToken($token)) {
261
            Yii::$app->session->setFlash(
262
                'error',
263
                Yii::t('app.messages', 'Invalid link for reset password')
264
            );
265
            return $this->goHome();
266
        }
267
268
        if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) {
269
            Yii::$app->session->setFlash(
270
                'success',
271
                Yii::t('app', 'New password was saved')
272
            );
273
            return $this->goHome();
274
        }
275
276
        return $this->render('resetPassword', [
277
            'model' => $model,
278
        ]);
279
    }
280
281
    public function actionLogout()
282
    {
283
        Yii::$app->user->logout();
284
        return $this->goHome();
285
    }
286
287
    /** @see commands/MaintenanceController **/
288
    public function actionMaintenance()
289
    {
290
        if (!Yii::$app->catchAll) {
291
            Http::exception(404);
292
        } // @codeCoverageIgnore
293
294
        $this->layout = 'maintenance';
295
        return $this->render('maintenance');
296
    }
297
}
298