Completed
Pull Request — master (#164)
by Corey
07:25 queued 02:59
created

ProfileController::actions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
c 0
b 0
f 0
rs 9.4285
cc 1
eloc 5
nc 1
nop 0
1
<?php
2
namespace site\controllers;
3
4
5
use Yii;
6
use common\models\Question;
7
use yii\web\Controller;
8
use yii\filters\VerbFilter;
9
use common\components\AccessControl;
10
use League\Csv\Writer;
0 ignored issues
show
Bug introduced by
The type League\Csv\Writer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use yii\web\BadRequestHttpException;
12
13
/**
14
 * Profile controller
15
 */
16
class ProfileController extends Controller {
17
  /**
18
   * @inheritdoc
19
   */
20
  public function behaviors() {
21
    return [
22
      'access' => [
23
        'class' => AccessControl::class,
24
        'rules' => [
25
          [
26
            'actions' => ['index', 'error', 'delete-account', 'change-password', 'request-change-email', 'export'],
27
            'allow'   => true,
28
            'roles'   => ['@'],
29
          ], [
30
            'actions' => [ 'change-email', ],
31
            'allow'   => true,
32
          ],
33
        ],
34
      ],
35
      'verbs' => [
36
        'class' => VerbFilter::class,
37
        'actions' => [
38
          'deleteAccount' => ['post'],
39
          'changePassword' => ['post'],
40
        ],
41
      ],
42
    ];
43
  }
44
45
  /**
46
   * @inheritdoc
47
   */
48
  public function actions()
49
  {
50
    return [
51
      'error' => [
52
        'class' => 'yii\web\ErrorAction',
53
      ],
54
      'captcha' => [
55
        'class' => 'yii\captcha\CaptchaAction',
56
      ],
57
    ];
58
  }
59
60
  public function actionIndex() {
61
    $editProfileForm    = Yii::$container->get(\site\models\EditProfileForm::class, [Yii::$app->user->identity]);
62
    $changePasswordForm = Yii::$container->get(\site\models\ChangePasswordForm::class, [Yii::$app->user->identity]);
63
    $changeEmailForm = Yii::$container->get(\site\models\ChangeEmailForm::class, [Yii::$app->user->identity]);
64
    $deleteAccountForm  = Yii::$container->get(\site\models\DeleteAccountForm::class, [Yii::$app->user->identity]);
65
    $graph              = Yii::$container->get(\common\components\Graph::class, [Yii::$app->user->identity]);
66
67
    if (Yii::$app->request->isAjax && $editProfileForm->load($_POST)) {
68
      Yii::$app->response->format = 'json';
69
      return \yii\widgets\ActiveForm::validate($editProfileForm);
70
    }
71
    $editProfileForm->loadUser();
72
73
    if ($editProfileForm->load(Yii::$app->request->post())) {
74
      $saved_user = $editProfileForm->saveProfile();
75
      if($saved_user) {
76
        Yii::$app->getSession()->setFlash('success', 'New profile data saved!');
77
      }
78
    }
79
80
    return $this->render('index', [
81
      'profile'         => $editProfileForm,
82
      'change_password' => $changePasswordForm,
83
      'change_email'    => $changeEmailForm,
84
      'delete'          => $deleteAccountForm,
85
      'graph_url'       => $graph->getUrl(Yii::$app->user->identity->getIdHash()),
0 ignored issues
show
Bug introduced by
The method getIdHash() 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

85
      'graph_url'       => $graph->getUrl(Yii::$app->user->identity->/** @scrutinizer ignore-call */ getIdHash()),

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 getIdHash() does not exist on yii\web\IdentityInterface. Did you maybe mean getId()? ( Ignorable by Annotation )

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

85
      'graph_url'       => $graph->getUrl(Yii::$app->user->identity->/** @scrutinizer ignore-call */ getIdHash()),

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...
86
    ]);
87
  }
88
89
  public function actionDeleteAccount() {
90
    $model = Yii::$container->get(\site\models\DeleteAccountForm::class, [Yii::$app->user->identity]);
91
92
    if ($model->load(Yii::$app->request->post()) && $model->validate()) {
93
      if($model->deleteAccount()) {
94
        $this->redirect(['site/index']);
95
      } else {
96
        Yii::$app->getSession()->setFlash('error', 'Wrong password!');
97
      }
98
    }
99
100
    $this->redirect(Yii::$app->request->getReferrer());
101
  }
102
103
  public function actionChangePassword() {
104
    $model = Yii::$container->get(\site\models\ChangePasswordForm::class, [Yii::$app->user->identity]);
105
106
    if ($model->load(Yii::$app->request->post())) {
107
      if($model->validate() && $model->changePassword()) {
108
        Yii::$app->getSession()->setFlash('success', 'Password successfully changed');
109
      } else {
110
        Yii::$app->getSession()->setFlash('error', 'Wrong password!');
111
      }
112
    }
113
114
    $this->redirect(['profile/index']);
115
  }
116
117
  public function actionRequestChangeEmail() {
118
    $model = Yii::$container->get(\site\models\ChangeEmailForm::class, [Yii::$app->user->identity]);
119
120
    if ($model->load(Yii::$app->request->post()) && $model->validate()) {
121
      if($model->changeEmail()) {
122
        Yii::$app->getSession()->setFlash('success', "We've sent an email to your requested email address to confirm. Please click on the verification link to continue.");
123
      } else {
124
        Yii::$app->getSession()->setFlash('error', 'Something went wrong!');
125
      }
126
    }
127
128
    $this->redirect(['profile/index']);
129
  }
130
131
  public function actionChangeEmail(string $token) {
132
    $user = \common\models\User::findByChangeEmailToken($token);
0 ignored issues
show
Bug Best Practice introduced by
The method common\models\User::findByChangeEmailToken() is not static, but was called statically. ( Ignorable by Annotation )

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

132
    /** @scrutinizer ignore-call */ 
133
    $user = \common\models\User::findByChangeEmailToken($token);
Loading history...
133
    if($user) {
134
      $validator = new \yii\validators\EmailValidator();
135
      if($validator->validate($user->desired_email, $error)) {
136
        $user->removeChangeEmailToken();
137
        $user->email = $user->desired_email;
138
        $user->desired_email = null;
139
        $user->save();
140
        if(!Yii::$app->user->isGuest) {
141
          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

141
          Yii::$app->user->/** @scrutinizer ignore-call */ 
142
                           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...
142
          Yii::$app->session->setFlash('success', 'Your email address was successfully changed. For security, we\'ve logged you out.');
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

142
          Yii::$app->session->/** @scrutinizer ignore-call */ 
143
                              setFlash('success', 'Your email address was successfully changed. For security, we\'ve logged you out.');

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...
143
        } else {
144
          Yii::$app->session->setFlash('success', 'Your email address was successfully changed.');
145
        }
146
        return $this->goHome();
147
      } else {
148
        // desired_email failed validation. Something sneaky might be happening here
149
        // log here
150
        throw new \Exception($error);
151
      }
152
    } else {
153
      // no user was found with that token
154
      throw new BadRequestHttpException("Wrong or expired change email token. If you aren't sure why this error occurs perhaps you've already confirmed your new email address change. Please try logging in with it.");
155
    }
156
  }
157
158
  public function actionExport() {
159
    header("Content-Type: text/csv");
160
    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...
161
162
    $reader = Yii::$app->user->identity->getExportData();
0 ignored issues
show
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

162
    /** @scrutinizer ignore-call */ 
163
    $reader = Yii::$app->user->identity->getExportData();
Loading history...
163
    $fp = fopen('php://output', 'w');
164
165
    $header = [
166
      'Date',
167
      'Behavior',
168
      'Category',
169
      Question::$QUESTIONS[1],
170
      Question::$QUESTIONS[2],
171
      Question::$QUESTIONS[3],
172
    ];
173
174
    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

174
    fputcsv(/** @scrutinizer ignore-type */ $fp, $header);
Loading history...
175
    $user_behavior = Yii::$container->get(\common\interfaces\UserBehaviorInterface::class);
176
    while($row = $reader->read()) {
177
      $row = $user_behavior::decorateWithCategory([$row]);
178
      $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

178
      /** @scrutinizer ignore-call */ 
179
      $row = Yii::$app->user->identity->cleanExportData($row);
Loading history...
179
      fputcsv($fp, $row[0]);
180
    }
181
    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

181
    fclose(/** @scrutinizer ignore-type */ $fp);
Loading history...
182
183
    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...
184
  }
185
}
186