Completed
Push — master ( 5e7707...6e3d76 )
by Igor
03:56
created

IndexController   B

Complexity

Total Complexity 46

Size/Duplication

Total Lines 303
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 12

Test Coverage

Coverage 23.61%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 46
lcom 1
cbo 12
dl 0
loc 303
ccs 34
cts 144
cp 0.2361
rs 8.3999
c 4
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A actionMaintenance() 0 9 2
A __construct() 0 5 1
B behaviors() 0 42 1
A actions() 0 13 1
A successCallback() 0 4 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

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
    private $socialAuth;
21
22 39
    public function __construct($id, $module, SocialAuth $socialAuth, $config = [])
23
    {
24 39
        $this->socialAuth = $socialAuth;
25 39
        parent::__construct($id, $module, $config);
26 39
    }
27
28
    /**
29
     * @inheritdoc
30
     */
31 39
    public function behaviors()
32
    {
33
        return [
34 39
            'access' => [
35
                'class' => AccessControl::class,
36
                'only' => [
37
                    'auth',
38
                    'logout',
39
                    'signup',
40
                    'signup-provider',
41
                    'confirm-request',
42
                    'request-password-reset',
43
                ],
44
                'rules' => [
45
                    [
46
                        'actions' => [
47
                            'auth',
48
                            'signup',
49
                            'signup-provider',
50
                            'request-password-reset',
51
                        ],
52
                        'allow' => true,
53
                        'roles' => ['?'],
54
                    ],
55
                    [
56
                        'actions' => [
57
                            'logout',
58
                            'confirm-request'
59
                        ],
60
                        'allow' => true,
61
                        'roles' => ['@'],
62
                    ],
63
                ],
64
            ],
65
            'verbs' => [
66
                'class' => VerbFilter::class,
67
                'actions' => [
68
                    'logout' => ['post'],
69
                ],
70
            ],
71
        ];
72
    }
73
74
    /**
75
     * @inheritdoc
76
     */
77 39
    public function actions()
78
    {
79
        return [
80 39
            'error' => [
81
                'class' => 'yii\web\ErrorAction',
82
            ],
83
            'auth' => [
84 39
                'class' => 'yii\authclient\AuthAction',
85 39
                'successCallback' => [$this, 'successCallback'],
86 39
                'successUrl' => 'signup-provider'
87
            ],
88
        ];
89
    }
90
91
    public function successCallback($client)
92
    {
93
        Yii::$app->session['authClient'] = $client;
94
    }
95
96
    public function goHome()
97
    {
98
        Yii::$app->session['authClient'] = null;
99
        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...
100
    }
101
102 1
    public function actionIndex()
103
    {
104 1
        return $this->render('index');
105
    }
106
107 16
    public function actionLogin()
108
    {
109 16
        if (!Yii::$app->user->isGuest) {
110
            return $this->goHome();
111
        }
112
113 16
        $model = new LoginForm();
114 16
        if ($model->load(Yii::$app->request->post()) && $model->login()) {
115
            return $this->goBack();
116
        }
117 16
        return $this->render('login', [
118 16
            'model' => $model,
119
        ]);
120
    }
121
122 13
    public function actionSignup()
123
    {
124 13
        $model = new SignupForm();
125 13
        if ($model->load(Yii::$app->request->post()) && $model->signup()) {
126
            if ($model->sendEmail()) {
127
                Yii::$app->session->setFlash(
128
                    'success',
129
                    Yii::t(
130
                        'app.messages',
131
                        'Please activate your account'
132
                    ) . '. ' .
133
                    Yii::t(
134
                        'app.messages',
135
                        'A letter for activation was sent to {email}',
136
                        ['email' => $model->email]
137
                    )
138
                );
139
                return $this->goHome();
140
            }
141
            Yii::$app->session->setFlash(
142
                'error',
143
                Yii::t(
144
                    'app.messages',
145
                    'An error occurred while sending a message to activate account'
146
                )
147
            );
148
            return $this->goHome();
149
        }
150
151 13
        return $this->render('signup', [
152 13
            'model' => $model,
153
        ]);
154
    }
155
156
    public function actionSignupProvider()
157
    {
158
        $session = Yii::$app->session;
159
        if ($session['authClient'] === null) {
160
            return $this->goHome();
161
        }
162
163
        $this->socialAuth->execute($session['authClient']);
164
        $user = $this->socialAuth->user();
165
166
        if ($user === null) {
167
            return $this->goHome();
168
        }
169
170
        $model = new SignupProviderForm($user, $this->socialAuth->email());
171
172
        if ($this->socialAuth->isExist() && $user->isActive() === false) {
173
            $session->setFlash('error', $user->getStatusDescription());
174
            return $this->goHome();
175
        }
176
177
        if ($this->socialAuth->isExist() && $user->isActive() && $model->login()) {
178
            return $this->goHome();
179
        }
180
181
        if ($this->socialAuth->isVerified() && $model->saveUser() && $model->login()) {
182
            return $this->goHome();
183
        }
184
185
        if ($model->load(Yii::$app->request->post()) && $model->signup()) {
186
            $model->login();
187
188
            if ($model->sendEmail()) {
189
                $session->setFlash(
190
                    'success',
191
                    Yii::t('app.messages', 'Please activate your account') . '. ' .
192
                    Yii::t('app.messages', 'A letter for activation was sent to {email}', ['email' => $model->email])
193
                );
194
                return $this->goHome();
195
            }
196
            $session->setFlash(
197
                'error',
198
                Yii::t('app.messages', 'An error occurred while sending a message to activate account')
199
            );
200
            return $this->goHome();
201
        }
202
203
        return $this->render('signupProvider', [
204
            'model' => $model
205
        ]);
206
    }
207
208
    public function actionConfirmRequest()
209
    {
210
        $user = Yii::$app->user->identity;
211
        if ($user->isConfirmed()) {
212
            throw new ForbiddenHttpException(Yii::t('app', 'Access Denied'));
213
        } // @codeCoverageIgnore
214
215
        $model = new ConfirmEmailForm();
216
217
        if ($model->sendEmail($user)) {
218
            Yii::$app->session->setFlash(
219
                'success',
220
                Yii::t('app.messages', 'A letter for activation was sent to {email}', ['email' => $user->email])
221
            );
222
            return $this->goHome();
223
        }
224
        Yii::$app->session->setFlash(
225
            'error',
226
            Yii::t('app.messages', 'An error occurred while sending a message to activate account')
227
        );
228
        return $this->goHome();
229
    }
230
231
    public function actionConfirmEmail($token)
232
    {
233
        $model = new ConfirmEmailForm();
234
235
        if (!$model->validateToken($token)) {
236
            Yii::$app->session->setFlash(
237
                'error',
238
                Yii::t('app.messages', 'Invalid link for activate account')
239
            );
240
            return $this->goHome();
241
        }
242
243
        if ($model->confirmEmail()) {
244
            Yii::$app->session->setFlash(
245
                'success',
246
                Yii::t('app.messages', 'Your account is successfully activated')
247
            );
248
        }
249
        return $this->goHome();
250
    }
251
252 7
    public function actionRequestPasswordReset()
253
    {
254 7
        $model = new PasswordResetRequestForm();
255
256 7
        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
257
            if ($model->sendEmail()) {
258
                Yii::$app->session->setFlash(
259
                    'success',
260
                    Yii::t('app.messages', 'We\'ve sent you an email with instructions to reset your password')
261
                );
262
                return $this->goHome();
263
            }
264
            Yii::$app->session->setFlash(
265
                'error',
266
                Yii::t('app.messages', 'An error occurred while sending a message to reset your password')
267
            );
268
            return $this->goHome();
269
        }
270
271 7
        return $this->render('requestPasswordResetToken', [
272 7
            'model' => $model,
273
        ]);
274
    }
275
276
    public function actionResetPassword($token)
277
    {
278
        $model = new ResetPasswordForm();
279
280
        if (!$model->validateToken($token)) {
281
            Yii::$app->session->setFlash(
282
                'error',
283
                Yii::t('app.messages', 'Invalid link for reset password')
284
            );
285
            return $this->goHome();
286
        }
287
288
        if ($model->load(Yii::$app->request->post()) &&
289
            $model->validate() &&
290
            $model->resetPassword()
291
        ) {
292
            Yii::$app->session->setFlash(
293
                'success',
294
                Yii::t('app', 'New password was saved')
295
            );
296
            return $this->goHome();
297
        }
298
299
        return $this->render('resetPassword', [
300
            'model' => $model,
301
        ]);
302
    }
303
304
    public function actionLogout()
305
    {
306
        Yii::$app->user->logout();
307
        return $this->goHome();
308
    }
309
310
    /** @see commands/MaintenanceController **/
311 2
    public function actionMaintenance()
312
    {
313 2
        if (!Yii::$app->catchAll) {
314 1
            throw new NotFoundHttpException(Yii::t('app', 'Page not found'));
315
        } // @codeCoverageIgnore
316
317 1
        $this->layout = 'maintenance';
318 1
        return $this->render('maintenance');
319
    }
320
}
321