Completed
Push — master ( 7e20fc...28c56b )
by Igor
03:33
created

IndexController   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 295
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 12

Test Coverage

Coverage 68.57%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 45
c 4
b 0
f 0
lcom 1
cbo 12
dl 0
loc 295
ccs 96
cts 140
cp 0.6857
rs 8.3673

14 Methods

Rating   Name   Duplication   Size   Complexity  
A actions() 0 13 1
A successCallback() 0 4 1
B behaviors() 0 42 1
A goHome() 0 5 1
A actionIndex() 0 4 1
A actionLogin() 0 14 4
B actionSignup() 0 33 4
C actionSignupProvider() 0 51 14
A actionConfirmRequest() 0 22 3
A actionConfirmEmail() 0 20 3
B actionRequestPasswordReset() 0 23 4
B actionResetPassword() 0 27 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 yii\web\ForbiddenHttpException;
9
use yii\web\NotFoundHttpException;
10
use app\services\SocialAuth;
11
use app\models\forms\LoginForm;
12
use app\models\forms\SignupForm;
13
use app\models\forms\SignupProviderForm;
14
use app\models\forms\PasswordResetRequestForm;
15
use app\models\forms\ResetPasswordForm;
16
use app\models\forms\ConfirmEmailForm;
17
18
class IndexController extends \yii\web\Controller
19
{
20
    /**
21
     * @inheritdoc
22
     */
23 60
    public function behaviors()
24
    {
25
        return [
26 60
            'access' => [
27
                'class' => AccessControl::class,
28
                'only' => [
29
                    'auth',
30
                    'logout',
31
                    'signup',
32
                    'signup-provider',
33
                    'confirm-request',
34
                    'request-password-reset',
35
                ],
36
                'rules' => [
37
                    [
38
                        'actions' => [
39
                            'auth',
40
                            'signup',
41
                            'signup-provider',
42
                            'request-password-reset',
43
                        ],
44
                        'allow' => true,
45
                        'roles' => ['?'],
46
                    ],
47
                    [
48
                        'actions' => [
49
                            'logout',
50
                            'confirm-request'
51
                        ],
52
                        'allow' => true,
53
                        'roles' => ['@'],
54
                    ],
55
                ],
56
            ],
57
            'verbs' => [
58
                'class' => VerbFilter::class,
59
                'actions' => [
60
                    'logout' => ['post'],
61
                ],
62
            ],
63
        ];
64
    }
65
66
    /**
67
     * @inheritdoc
68
     */
69 60
    public function actions()
70
    {
71
        return [
72 60
            'error' => [
73
                'class' => 'yii\web\ErrorAction',
74
            ],
75
            'auth' => [
76 60
                'class' => 'yii\authclient\AuthAction',
77 60
                'successCallback' => [$this, 'successCallback'],
78 60
                'successUrl' => 'signup-provider'
79
            ],
80
        ];
81
    }
82
83 8
    public function successCallback($client)
84
    {
85 8
        Yii::$app->session['authClient'] = $client;
86 8
    }
87
88 19
    public function goHome()
89
    {
90 19
        Yii::$app->session['authClient'] = null;
91 19
        return Yii::$app->getResponse()->redirect(Yii::$app->getHomeUrl());
0 ignored issues
show
Bug introduced by
The method getHomeUrl does only exist in yii\web\Application, but not in yii\console\Application.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
92
    }
93
94 27
    public function actionIndex()
95
    {
96 27
        return $this->render('index');
97
    }
98
99 18
    public function actionLogin()
100
    {
101 18
        if (!Yii::$app->user->isGuest) {
102
            return $this->goHome();
103
        }
104
105 18
        $model = new LoginForm();
106 18
        if ($model->load(Yii::$app->request->post()) && $model->login()) {
107 3
            return $this->goBack();
108
        }
109 18
        return $this->render('login', [
110 18
            'model' => $model,
111
        ]);
112
    }
113
114 15
    public function actionSignup()
115
    {
116 15
        $model = new SignupForm();
117 15
        if ($model->load(Yii::$app->request->post()) && $model->signup()) {
118 3
            if ($model->sendEmail()) {
119 1
                Yii::$app->session->setFlash(
120 1
                    'success',
121 1
                    Yii::t(
122 1
                        'app.messages',
123 1
                        'Please activate your account'
124 1
                    ) . '. ' .
125 1
                    Yii::t(
126 1
                        'app.messages',
127 1
                        'A letter for activation was sent to {email}',
128 1
                        ['email' => $model->email]
129
                    )
130
                );
131 1
                return $this->goHome();
132
            }
133 2
            Yii::$app->session->setFlash(
134 2
                'error',
135 2
                Yii::t(
136 2
                    'app.messages',
137 2
                    'An error occurred while sending a message to activate account'
138
                )
139
            );
140 2
            return $this->goHome();
141
        }
142
143 15
        return $this->render('signup', [
144 15
            'model' => $model,
145
        ]);
146
    }
147
148 9
    public function actionSignupProvider()
149
    {
150 9
        $session = Yii::$app->session;
151 9
        if ($session['authClient'] === null) {
152 9
            return $this->goHome();
153
        }
154
155
        $socialAuth = (new SocialAuth($session['authClient']))->execute();
156
        $user = $socialAuth->user();
157
158
        if ($user === null) {
159
            return $this->goHome();
160
        }
161
162
        $model = new SignupProviderForm($user, $socialAuth->email());
163
164
        if ($socialAuth->isExist() && $user->isActive() === false) {
165
            $session->setFlash('error', $user->getStatusDescription());
166
            return $this->goHome();
167
        }
168
169
        if ($socialAuth->isExist() && $user->isActive() && $model->login()) {
170
            return $this->goHome();
171
        }
172
173
        if ($socialAuth->isVerified() && $model->saveUser() && $model->login()) {
174
            return $this->goHome();
175
        }
176
177
        if ($model->load(Yii::$app->request->post()) && $model->signup()) {
178
            $model->login();
179
180
            if ($model->sendEmail()) {
181
                $session->setFlash(
182
                    'success',
183
                    Yii::t('app.messages', 'Please activate your account') . '. ' .
184
                    Yii::t('app.messages', 'A letter for activation was sent to {email}', ['email' => $model->email])
185
                );
186
                return $this->goHome();
187
            }
188
            $session->setFlash(
189
                'error',
190
                Yii::t('app.messages', 'An error occurred while sending a message to activate account')
191
            );
192
            return $this->goHome();
193
        }
194
195
        return $this->render('signupProvider', [
196
            'model' => $model
197
        ]);
198
    }
199
200
    public function actionConfirmRequest()
201
    {
202
        $user = Yii::$app->user->identity;
203
        if ($user->isConfirmed()) {
204
            throw new ForbiddenHttpException(Yii::t('app', 'Access Denied'));
205
        } // @codeCoverageIgnore
206
207
        $model = new ConfirmEmailForm();
208
209
        if ($model->sendEmail($user)) {
210
            Yii::$app->session->setFlash(
211
                'success',
212
                Yii::t('app.messages', 'A letter for activation was sent to {email}', ['email' => $user->email])
213
            );
214
            return $this->goHome();
215
        }
216
        Yii::$app->session->setFlash(
217
            'error',
218
            Yii::t('app.messages', 'An error occurred while sending a message to activate account')
219
        );
220
        return $this->goHome();
221
    }
222
223 3
    public function actionConfirmEmail($token)
224
    {
225 3
        $model = new ConfirmEmailForm();
226
227 3
        if (!$model->validateToken($token)) {
228 2
            Yii::$app->session->setFlash(
229 2
                'error',
230 2
                Yii::t('app.messages', 'Invalid link for activate account')
231
            );
232 2
            return $this->goHome();
233
        }
234
235 1
        if ($model->confirmEmail()) {
236 1
            Yii::$app->session->setFlash(
237 1
                'success',
238 1
                Yii::t('app.messages', 'Your account is successfully activated')
239
            );
240
        }
241 1
        return $this->goHome();
242
    }
243
244 8
    public function actionRequestPasswordReset()
245
    {
246 8
        $model = new PasswordResetRequestForm();
247
248 8
        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
249 2
            if ($model->sendEmail()) {
250 1
                Yii::$app->session->setFlash(
251 1
                    'success',
252 1
                    Yii::t('app.messages', 'We\'ve sent you an email with instructions to reset your password')
253
                );
254 1
                return $this->goHome();
255
            }
256 1
            Yii::$app->session->setFlash(
257 1
                'error',
258 1
                Yii::t('app.messages', 'An error occurred while sending a message to reset your password')
259
            );
260 1
            return $this->goHome();
261
        }
262
263 8
        return $this->render('requestPasswordResetToken', [
264 8
            'model' => $model,
265
        ]);
266
    }
267
268 6
    public function actionResetPassword($token)
269
    {
270 6
        $model = new ResetPasswordForm();
271
272 6
        if (!$model->validateToken($token)) {
273 2
            Yii::$app->session->setFlash(
274 2
                'error',
275 2
                Yii::t('app.messages', 'Invalid link for reset password')
276
            );
277 2
            return $this->goHome();
278
        }
279
280 6
        if ($model->load(Yii::$app->request->post()) &&
281 3
            $model->validate() &&
282 1
            $model->resetPassword()
283
        ) {
284 1
            Yii::$app->session->setFlash(
285 1
                'success',
286 1
                Yii::t('app', 'New password was saved')
287
            );
288 1
            return $this->goHome();
289
        }
290
291 6
        return $this->render('resetPassword', [
292 6
            'model' => $model,
293
        ]);
294
    }
295
296
    public function actionLogout()
297
    {
298
        Yii::$app->user->logout();
299
        return $this->goHome();
300
    }
301
302
    /** @see commands/MaintenanceController **/
303 2
    public function actionMaintenance()
304
    {
305 2
        if (!Yii::$app->catchAll) {
306 1
            throw new NotFoundHttpException(Yii::t('app', 'Page not found'));
307
        } // @codeCoverageIgnore
308
309 1
        $this->layout = 'maintenance';
310 1
        return $this->render('maintenance');
311
    }
312
}
313