Completed
Pull Request — master (#164)
by Corey
03:20
created

SiteController::behaviors()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 26
c 0
b 0
f 0
rs 8.8571
cc 1
eloc 16
nc 1
nop 0
1
<?php
2
3
namespace site\controllers;
4
5
use Yii;
6
use common\models\LoginForm;
7
use common\models\Question;
8
use site\models\PasswordResetRequestForm;
9
use site\models\ResetPasswordForm;
10
use site\models\ContactForm;
11
use yii\base\InvalidParamException;
12
use yii\web\BadRequestHttpException;
13
use yii\web\Controller;
14
use yii\filters\VerbFilter;
15
use common\components\AccessControl;
16
17
/**
18
 * Site controller
19
 */
20
class SiteController extends Controller
21
{
22
  /**
23
   * @inheritdoc
24
   */
25
  public function behaviors()
26
  {
27
    return [
28
      'access' => [
29
        'class' => AccessControl::class,
30
        'rules' => [
31
          [
32
            'actions' => ['index', 'error', 'privacy', 'terms', 'about', 'captcha', 'contact', 'faq', 'change-email'],
33
            'allow' => true,
34
          ],
35
          [
36
            'actions' => ['login', 'signup', 'reset-password', 'request-password-reset', 'verify-email'],
37
            'allow' => true,
38
            'roles' => ['?'],
39
          ],
40
          [
41
            'actions' => ['logout', 'welcome'],
42
            'allow' => true,
43
            'roles' => ['@'],
44
          ],
45
        ],
46
      ],
47
      'verbs' => [
48
        'class' => VerbFilter::class,
49
        'actions' => [
50
          'logout' => ['post'],
51
        ],
52
      ],
53
    ];
54
  }
55
56
  /**
57
   * @inheritdoc
58
   */
59
  public function actions()
60
  {
61
    return [
62
      'error' => [
63
        'class' => 'yii\web\ErrorAction',
64
      ],
65
      'captcha' => [
66
        'class' => 'yii\captcha\CaptchaAction',
67
      ],
68
    ];
69
  }
70
71
  public function actionIndex()
72
  {
73
    $time = Yii::$container->get(\common\interfaces\TimeInterface::class); 
74
    $key = "index_blog_".$time->getLocalDate('UTC');
75
    $posts = Yii::$app->cache->get($key);
76
    if($posts === false) {
77
      $posts = \Yii::$app->getModule('blog')
78
                            ->fetch()
79
                            ->parse()
80
                            ->results;
81
    }
82
    Yii::$app->cache->set($key, $posts, 60*60*24);
83
84
    return $this->render('index', ['posts'=>$posts]);
85
  }
86
87
  public function actionLogin()
88
  {
89
    $model = Yii::$container->get(\common\models\LoginForm::class);
90
    if ($model->load(Yii::$app->request->post()) && $model->login()) {
91
      return $this->goBack();
92
    } else {
93
      return $this->render('login', [
94
        'model' => $model,
95
      ]);
96
    }
97
  }
98
99
  public function actionLogout()
100
  {
101
    Yii::$app->user->logout();
0 ignored issues
show
Bug introduced by
The method logout() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

101
    Yii::$app->user->/** @scrutinizer ignore-call */ 
102
                     logout();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
102
    return $this->goHome();
103
  }
104
105
  public function actionContact()
106
  {
107
    $model = new ContactForm();
108
    if ($model->load(Yii::$app->request->post()) && $model->validate()) {
109
      if($model->sendEmail(Yii::$app->params['adminEmail'])) {
110
        Yii::$app->session->setFlash('success', 'Thank you for contacting us. We will respond to you as soon as possible.');
0 ignored issues
show
Bug introduced by
The method setFlash() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

110
        Yii::$app->session->/** @scrutinizer ignore-call */ 
111
                            setFlash('success', 'Thank you for contacting us. We will respond to you as soon as possible.');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
111
      } else {
112
        Yii::$app->session->setFlash('error', 'There was an error sending email.');
113
      }
114
115
      return $this->refresh();
116
    } else {
117
      return $this->render('contact', [
118
        'model' => $model,
119
      ]);
120
    }
121
  }
122
123
  public function actionAbout()
124
  {
125
    return $this->render('about');
126
  }
127
128
  public function actionFaq()
129
  {
130
    return $this->render('faq');
131
  }
132
133
  public function actionWelcome()
134
  {
135
    return $this->render('welcome');
136
  }
137
138
  public function actionSignup()
139
  {
140
    $model = Yii::$container->get(\site\models\SignupForm::class);
141
    if($model->load(Yii::$app->request->post()) && $model->validate()) {
142
      $model->signup();
143
      Yii::$app->getSession()->setFlash('success', 'We have sent a verification email to the email address you provided. Please check your inbox and follow the instructions to verify your account.');
144
      return $this->redirect('/',302);
145
    }
146
147
    return $this->render('signup', [
148
      'model' => $model,
149
    ]);
150
  }
151
152
  public function actionRequestPasswordReset()
153
  {
154
    $model = Yii::$container->get(\site\models\PasswordResetRequestForm::class);
155
    if($model->load(Yii::$app->request->post()) && $model->validate()) {
156
      if(!$model->sendEmail()) {
157
        $ip = Yii::$app->getRequest()->getUserIP() ?: "UNKNOWN";
158
        Yii::warning("$ip has tried to reset the password for ".$model->email);
159
      }
160
161
      Yii::$app->getSession()->setFlash('success', 'If there is an account with the submitted email address you will receive further instructions in your email inbox.');
162
      return $this->goHome();
163
    }
164
165
    return $this->render('requestPasswordResetToken', [
166
      'model' => $model,
167
    ]);
168
  }
169
170
  public function actionResetPassword($token)
171
  {
172
    try {
173
      $model = Yii::$container->get(\site\models\ResetPasswordForm::class, [$token]);
174
    } catch (InvalidParamException $e) {
175
      throw new BadRequestHttpException($e->getMessage());
176
    }
177
178
    if ($model->load(Yii::$app->request->post())
179
        && $model->validate()
180
        && $model->resetPassword()) {
181
      Yii::$app->getSession()->setFlash('success', 'New password was saved.');
182
      return $this->goHome();
183
    }
184
185
    return $this->render('resetPassword', [
186
      'model' => $model,
187
    ]);
188
  }
189
190
  public function actionVerifyEmail($token)
191
  {
192
    if (empty($token) || !is_string($token)) {
193
      throw new BadRequestHttpException('Email verification token cannot be blank.');
194
    }
195
196
    $user = Yii::$container->get(\common\interfaces\UserInterface::class)->findByVerifyEmailToken($token);
197
    if (!$user) {
198
      throw new BadRequestHttpException("Wrong or expired email verification token. If you aren't sure why this error occurs perhaps you've already verified your account. Please try logging in.");
199
    }
200
201
    if($user->isTokenConfirmed($user->verify_email_token)) {
202
      Yii::$app->getSession()->setFlash('success', 'Your account has already been verified. Please log in.');
203
      return $this->redirect('/login',302);
204
    } else if (Yii::$app->getUser()->login($user)) {
205
      $user->confirmVerifyEmailToken();
206
      $user->save();
207
      Yii::$app->getSession()->setFlash('success', 'Your account has been verified. Please continue with your check-in.');
208
      return $this->redirect('/welcome',302);
209
    }
210
  }
211
212
  public function actionChangeEmail($token)
213
  {
214
    if (empty($token) || !is_string($token)) {
215
      throw new BadRequestHttpException('The email change token cannot be blank.');
216
    }
217
218
    $user = Yii::$container->get(\common\interfaces\UserInterface::class)->findByChangeEmailToken($token);
219
    var_dump( $user);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($user) looks like debug code. Are you sure you do not want to remove it?
Loading history...
220
    exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
221
    if (!$user) {
0 ignored issues
show
Unused Code introduced by
IfNode is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
222
      throw new BadRequestHttpException("Wrong or expired email change token. If you aren't sure why this error occurs perhaps you've already confirmed your change of email. Please try logging in.");
223
    }
224
225
    $user->email = $user->desired_email;
226
    $user->save();
227
    // log out the user (if they're logged in)
228
229
    Yii::$app->getSession()->setFlash('success', 'Your email address has been successfully changed. Please log in.');
230
    return $this->redirect('/login',302);
231
  }
232
233
  public function actionPrivacy()
234
  {
235
    return $this->render('privacy');
236
  }
237
238
  public function actionTerms()
239
  {
240
    return $this->render('terms');
241
  }
242
243
  public function actionExport()
244
  {
245
    header("Content-Type: text/csv");
246
    header("Content-Disposition: attachment; filename=fsa-data-export-".Yii::$app->user->identity->email."-".date('Ymd').".csv");
0 ignored issues
show
Bug introduced by
Accessing email on the interface yii\web\IdentityInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
247
248
    $reader = Yii::$app->user->identity->getExportData();
0 ignored issues
show
Bug introduced by
The method getExportData() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

248
    /** @scrutinizer ignore-call */ 
249
    $reader = Yii::$app->user->identity->getExportData();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method getExportData() does not exist on yii\web\IdentityInterface. It seems like you code against a sub-type of said class. However, the method does not exist in site\tests\_support\MockUser. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

248
    /** @scrutinizer ignore-call */ 
249
    $reader = Yii::$app->user->identity->getExportData();
Loading history...
249
    $fp = fopen('php://output', 'w');
250
251
    $header = [
252
      'Date',
253
      'Behavior',
254
      'Category',
255
      Question::$QUESTIONS[1],
256
      Question::$QUESTIONS[2],
257
      Question::$QUESTIONS[3],
258
    ];
259
260
    fputcsv($fp, $header);
0 ignored issues
show
Bug introduced by
It seems like $fp can also be of type false; however, parameter $handle of fputcsv() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

260
    fputcsv(/** @scrutinizer ignore-type */ $fp, $header);
Loading history...
261
    $user_behavior = Yii::$container->get(\common\interfaces\UserBehaviorInterface::class);
262
    while($row = $reader->read()) {
263
      $row = $user_behavior::decorateWithCategory([$row]);
264
      $row = Yii::$app->user->identity->cleanExportData($row);
0 ignored issues
show
Bug introduced by
The method cleanExportData() does not exist on yii\web\IdentityInterface. It seems like you code against a sub-type of said class. However, the method does not exist in site\tests\_support\MockUser. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

264
      /** @scrutinizer ignore-call */ 
265
      $row = Yii::$app->user->identity->cleanExportData($row);
Loading history...
265
      fputcsv($fp, $row[0]);
266
    }
267
    fclose($fp);
0 ignored issues
show
Bug introduced by
It seems like $fp can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

267
    fclose(/** @scrutinizer ignore-type */ $fp);
Loading history...
268
269
    die;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
270
  }
271
}
272