2amigos /
yii2-usuario
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | /* |
||
| 4 | * This file is part of the 2amigos/yii2-usuario project. |
||
| 5 | * |
||
| 6 | * (c) 2amigOS! <http://2amigos.us/> |
||
| 7 | * |
||
| 8 | * For the full copyright and license information, please view |
||
| 9 | * the LICENSE file that was distributed with this source code. |
||
| 10 | */ |
||
| 11 | |||
| 12 | namespace Da\User\Controller; |
||
| 13 | |||
| 14 | use Da\User\Contracts\MailChangeStrategyInterface; |
||
| 15 | use Da\User\Event\GdprEvent; |
||
| 16 | use Da\User\Event\ProfileEvent; |
||
| 17 | use Da\User\Event\SocialNetworkConnectEvent; |
||
| 18 | use Da\User\Event\UserEvent; |
||
| 19 | use Da\User\Form\GdprDeleteForm; |
||
| 20 | use Da\User\Form\SettingsForm; |
||
| 21 | use Da\User\Helper\SecurityHelper; |
||
| 22 | use Da\User\Model\Profile; |
||
| 23 | use Da\User\Model\SocialNetworkAccount; |
||
| 24 | use Da\User\Model\User; |
||
| 25 | use Da\User\Module; |
||
| 26 | use Da\User\Query\ProfileQuery; |
||
| 27 | use Da\User\Query\SocialNetworkAccountQuery; |
||
| 28 | use Da\User\Query\UserQuery; |
||
| 29 | use Da\User\Service\EmailChangeService; |
||
| 30 | use Da\User\Service\TwoFactorQrCodeUriGeneratorService; |
||
| 31 | use Da\User\Traits\ContainerAwareTrait; |
||
| 32 | use Da\User\Traits\ModuleAwareTrait; |
||
| 33 | use Da\User\Validator\AjaxRequestModelValidator; |
||
| 34 | use Da\User\Validator\TwoFactorCodeValidator; |
||
| 35 | use Yii; |
||
| 36 | use yii\base\DynamicModel; |
||
| 37 | use yii\filters\AccessControl; |
||
| 38 | use yii\filters\VerbFilter; |
||
| 39 | use yii\helpers\ArrayHelper; |
||
| 40 | use yii\web\Controller; |
||
| 41 | use yii\web\ForbiddenHttpException; |
||
| 42 | use yii\web\NotFoundHttpException; |
||
| 43 | use yii\web\Response; |
||
| 44 | |||
| 45 | class SettingsController extends Controller |
||
| 46 | { |
||
| 47 | use ContainerAwareTrait; |
||
| 48 | use ModuleAwareTrait; |
||
| 49 | |||
| 50 | /** |
||
| 51 | * {@inheritdoc} |
||
| 52 | */ |
||
| 53 | public $defaultAction = 'profile'; |
||
| 54 | |||
| 55 | protected $profileQuery; |
||
| 56 | protected $userQuery; |
||
| 57 | protected $socialNetworkAccountQuery; |
||
| 58 | |||
| 59 | /** |
||
| 60 | * SettingsController constructor. |
||
| 61 | * |
||
| 62 | * @param string $id |
||
| 63 | * @param Module $module |
||
| 64 | * @param ProfileQuery $profileQuery |
||
| 65 | * @param UserQuery $userQuery |
||
| 66 | * @param SocialNetworkAccountQuery $socialNetworkAccountQuery |
||
| 67 | * @param array $config |
||
| 68 | */ |
||
| 69 | 4 | public function __construct( |
|
| 70 | $id, |
||
| 71 | Module $module, |
||
| 72 | ProfileQuery $profileQuery, |
||
| 73 | UserQuery $userQuery, |
||
| 74 | SocialNetworkAccountQuery $socialNetworkAccountQuery, |
||
| 75 | array $config = [] |
||
| 76 | ) { |
||
| 77 | 4 | $this->profileQuery = $profileQuery; |
|
| 78 | 4 | $this->userQuery = $userQuery; |
|
| 79 | 4 | $this->socialNetworkAccountQuery = $socialNetworkAccountQuery; |
|
| 80 | 4 | parent::__construct($id, $module, $config); |
|
| 81 | 4 | } |
|
| 82 | |||
| 83 | /** |
||
| 84 | * {@inheritdoc} |
||
| 85 | */ |
||
| 86 | 4 | public function behaviors() |
|
| 87 | { |
||
| 88 | return [ |
||
| 89 | 4 | 'verbs' => [ |
|
| 90 | 'class' => VerbFilter::class, |
||
| 91 | 'actions' => [ |
||
| 92 | 'disconnect' => ['post'], |
||
| 93 | 'delete' => ['post'], |
||
| 94 | 'two-factor-disable' => ['post'] |
||
| 95 | ], |
||
| 96 | ], |
||
| 97 | 'access' => [ |
||
| 98 | 'class' => AccessControl::class, |
||
| 99 | 'rules' => [ |
||
| 100 | [ |
||
| 101 | 'allow' => true, |
||
| 102 | 'actions' => [ |
||
| 103 | 'profile', |
||
| 104 | 'account', |
||
| 105 | 'export', |
||
| 106 | 'networks', |
||
| 107 | 'privacy', |
||
| 108 | 'gdpr-consent', |
||
| 109 | 'gdpr-delete', |
||
| 110 | 'disconnect', |
||
| 111 | 'delete', |
||
| 112 | 'two-factor', |
||
| 113 | 'two-factor-enable', |
||
| 114 | 'two-factor-disable' |
||
| 115 | ], |
||
| 116 | 'roles' => ['@'], |
||
| 117 | ], |
||
| 118 | [ |
||
| 119 | 'allow' => true, |
||
| 120 | 'actions' => ['confirm'], |
||
| 121 | 'roles' => ['?', '@'], |
||
| 122 | ], |
||
| 123 | ], |
||
| 124 | ], |
||
| 125 | ]; |
||
| 126 | } |
||
| 127 | |||
| 128 | /** |
||
| 129 | * @throws \yii\base\InvalidConfigException |
||
| 130 | * @return string|Response |
||
| 131 | */ |
||
| 132 | 1 | public function actionProfile() |
|
| 133 | { |
||
| 134 | 1 | $profile = $this->profileQuery->whereUserId(Yii::$app->user->identity->getId())->one(); |
|
| 135 | |||
| 136 | 1 | if ($profile === null) { |
|
| 137 | $profile = $this->make(Profile::class); |
||
| 138 | $profile->link('user', Yii::$app->user->identity); |
||
| 139 | } |
||
| 140 | |||
| 141 | /** @var ProfileEvent $event */ |
||
| 142 | 1 | $event = $this->make(ProfileEvent::class, [$profile]); |
|
| 143 | |||
| 144 | 1 | $this->make(AjaxRequestModelValidator::class, [$profile])->validate(); |
|
| 145 | |||
| 146 | 1 | if ($profile->load(Yii::$app->request->post())) { |
|
| 147 | $this->trigger(UserEvent::EVENT_BEFORE_PROFILE_UPDATE, $event); |
||
| 148 | if ($profile->save()) { |
||
| 149 | Yii::$app->getSession()->setFlash('success', Yii::t('usuario', 'Your profile has been updated')); |
||
|
0 ignored issues
–
show
|
|||
| 150 | $this->trigger(UserEvent::EVENT_AFTER_PROFILE_UPDATE, $event); |
||
| 151 | |||
| 152 | return $this->refresh(); |
||
| 153 | } |
||
| 154 | } |
||
| 155 | |||
| 156 | 1 | return $this->render( |
|
| 157 | 1 | 'profile', |
|
| 158 | [ |
||
| 159 | 1 | 'model' => $profile, |
|
| 160 | ] |
||
| 161 | ); |
||
| 162 | } |
||
| 163 | |||
| 164 | /** |
||
| 165 | * @throws NotFoundHttpException |
||
| 166 | * @return string |
||
| 167 | */ |
||
| 168 | 2 | public function actionPrivacy() |
|
| 169 | { |
||
| 170 | 2 | if (!$this->module->enableGdprCompliance) { |
|
| 171 | 1 | throw new NotFoundHttpException(); |
|
| 172 | } |
||
| 173 | 1 | return $this->render('privacy', [ |
|
| 174 | 1 | 'module' => $this->module |
|
| 175 | ]); |
||
| 176 | } |
||
| 177 | |||
| 178 | /** |
||
| 179 | * @throws NotFoundHttpException |
||
| 180 | * @throws \Throwable |
||
| 181 | * @throws \yii\base\Exception |
||
| 182 | * @throws \yii\base\InvalidConfigException |
||
| 183 | * @throws \yii\db\StaleObjectException |
||
| 184 | * @throws ForbiddenHttpException |
||
| 185 | * @return string|Response |
||
| 186 | */ |
||
| 187 | 1 | public function actionGdprDelete() |
|
| 188 | { |
||
| 189 | 1 | if (!$this->module->enableGdprCompliance) { |
|
| 190 | throw new NotFoundHttpException(); |
||
| 191 | } |
||
| 192 | /** @var GdprDeleteForm $form */ |
||
| 193 | 1 | $form = $this->make(GdprDeleteForm::class); |
|
| 194 | |||
| 195 | 1 | $user = $form->getUser(); |
|
| 196 | /* @var $event GdprEvent */ |
||
| 197 | 1 | $event = $this->make(GdprEvent::class, [$user]); |
|
| 198 | |||
| 199 | 1 | if ($form->load(Yii::$app->request->post()) && $form->validate()) { |
|
| 200 | 1 | $this->trigger(GdprEvent::EVENT_BEFORE_DELETE, $event); |
|
| 201 | |||
| 202 | 1 | if ($event->isValid) { |
|
| 203 | 1 | Yii::$app->user->logout(); |
|
| 204 | //Disconnect social networks |
||
| 205 | 1 | $networks = $this->socialNetworkAccountQuery->where(['user_id' => $user->id])->all(); |
|
|
0 ignored issues
–
show
Accessing
id on the interface yii\web\IdentityInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
If you access a property on an interface, you most likely code against a concrete implementation of the interface. Available Fixes
Loading history...
|
|||
| 206 | 1 | foreach ($networks as $network) { |
|
| 207 | $this->disconnectSocialNetwork($network->id); |
||
| 208 | } |
||
| 209 | |||
| 210 | /* @var $security SecurityHelper */ |
||
| 211 | 1 | $security = $this->make(SecurityHelper::class); |
|
| 212 | 1 | $anonymReplacement = $this->module->gdprAnonymizePrefix . $user->id; |
|
|
0 ignored issues
–
show
Accessing
id on the interface yii\web\IdentityInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
If you access a property on an interface, you most likely code against a concrete implementation of the interface. Available Fixes
Loading history...
|
|||
| 213 | |||
| 214 | 1 | $user->updateAttributes([ |
|
| 215 | 1 | 'email' => $anonymReplacement . "@example.com", |
|
| 216 | 1 | 'username' => $anonymReplacement, |
|
| 217 | 1 | 'gdpr_deleted' => 1, |
|
| 218 | 1 | 'blocked_at' => time(), |
|
| 219 | 1 | 'auth_key' => $security->generateRandomString() |
|
| 220 | ]); |
||
| 221 | 1 | $user->profile->updateAttributes([ |
|
|
0 ignored issues
–
show
Accessing
profile on the interface yii\web\IdentityInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
If you access a property on an interface, you most likely code against a concrete implementation of the interface. Available Fixes
Loading history...
|
|||
| 222 | 1 | 'public_email' => $anonymReplacement . "@example.com", |
|
| 223 | 1 | 'name' => $anonymReplacement, |
|
| 224 | 1 | 'gravatar_email' => $anonymReplacement . "@example.com", |
|
| 225 | 1 | 'location' => $anonymReplacement, |
|
| 226 | 1 | 'website' => $anonymReplacement . ".tld", |
|
| 227 | 1 | 'bio' => Yii::t('usuario', 'Deleted by GDPR request') |
|
| 228 | ]); |
||
| 229 | } |
||
| 230 | 1 | $this->trigger(GdprEvent::EVENT_AFTER_DELETE, $event); |
|
| 231 | |||
| 232 | 1 | Yii::$app->session->setFlash('info', Yii::t('usuario', 'Your personal information has been removed')); |
|
| 233 | |||
| 234 | 1 | return $this->goHome(); |
|
| 235 | } |
||
| 236 | |||
| 237 | 1 | return $this->render('gdpr-delete', [ |
|
| 238 | 1 | 'model' => $form, |
|
| 239 | ]); |
||
| 240 | } |
||
| 241 | |||
| 242 | 1 | public function actionGdprConsent() |
|
| 243 | { |
||
| 244 | /** @var User $user */ |
||
| 245 | 1 | $user = Yii::$app->user->identity; |
|
| 246 | 1 | if ($user->gdpr_consent) { |
|
| 247 | return $this->redirect(['profile']); |
||
| 248 | } |
||
| 249 | 1 | $model = new DynamicModel(['gdpr_consent']); |
|
| 250 | 1 | $model->addRule('gdpr_consent', 'boolean'); |
|
| 251 | 1 | $model->addRule('gdpr_consent', 'default', ['value' => 0, 'skipOnEmpty' => false]); |
|
| 252 | 1 | $model->addRule('gdpr_consent', 'compare', [ |
|
| 253 | 1 | 'compareValue' => true, |
|
| 254 | 1 | 'message' => Yii::t('usuario', 'Your consent is required to work with this site'), |
|
| 255 | 'when' => function () { |
||
| 256 | 1 | return $this->module->enableGdprCompliance; |
|
| 257 | 1 | }, |
|
| 258 | ]); |
||
| 259 | 1 | if ($model->load(Yii::$app->request->post()) && $model->validate()) { |
|
| 260 | 1 | $user->updateAttributes([ |
|
| 261 | 1 | 'gdpr_consent' => 1, |
|
| 262 | 1 | 'gdpr_consent_date' => time(), |
|
| 263 | ]); |
||
| 264 | 1 | return $this->redirect(['profile']); |
|
| 265 | } |
||
| 266 | |||
| 267 | 1 | return $this->render('gdpr-consent', [ |
|
| 268 | 1 | 'model' => $model, |
|
| 269 | 1 | 'gdpr_consent_hint' => $this->module->getConsentMessage(), |
|
| 270 | ]); |
||
| 271 | } |
||
| 272 | |||
| 273 | /** |
||
| 274 | * Exports the data from the current user in a mechanical readable format (csv). Properties exported can be defined |
||
| 275 | * in the module configuration. |
||
| 276 | * @throws NotFoundHttpException if gdpr compliance is not enabled |
||
| 277 | * @throws \Exception |
||
| 278 | * @throws \Throwable |
||
| 279 | */ |
||
| 280 | public function actionExport() |
||
| 281 | { |
||
| 282 | if (!$this->module->enableGdprCompliance) { |
||
| 283 | throw new NotFoundHttpException(); |
||
| 284 | } |
||
| 285 | try { |
||
| 286 | $properties = $this->module->gdprExportProperties; |
||
| 287 | $user = Yii::$app->user->identity; |
||
| 288 | $data = [$properties, []]; |
||
| 289 | |||
| 290 | $formatter = Yii::$app->formatter; |
||
| 291 | // override the default html-specific format for nulls |
||
| 292 | $formatter->nullDisplay = ""; |
||
| 293 | |||
| 294 | foreach ($properties as $property) { |
||
| 295 | $data[1][] = $formatter->asText(ArrayHelper::getValue($user, $property)); |
||
| 296 | } |
||
| 297 | |||
| 298 | array_walk($data[0], function (&$value, $key) { |
||
|
0 ignored issues
–
show
|
|||
| 299 | $splitted = explode('.', $value); |
||
| 300 | $value = array_pop($splitted); |
||
| 301 | }); |
||
| 302 | |||
| 303 | Yii::$app->response->headers->removeAll(); |
||
| 304 | Yii::$app->response->headers->add('Content-type', 'text/csv'); |
||
| 305 | Yii::$app->response->headers->add('Content-Disposition', 'attachment;filename=gdpr-data.csv'); |
||
| 306 | Yii::$app->response->send(); |
||
| 307 | $f = fopen('php://output', 'w'); |
||
| 308 | foreach ($data as $line) { |
||
| 309 | fputcsv($f, $line); |
||
| 310 | } |
||
| 311 | } catch (\Exception $e) { |
||
| 312 | throw $e; |
||
| 313 | } catch (\Throwable $e) { |
||
| 314 | throw $e; |
||
| 315 | } |
||
| 316 | } |
||
| 317 | |||
| 318 | 1 | public function actionAccount() |
|
| 319 | { |
||
| 320 | /** @var SettingsForm $form */ |
||
| 321 | 1 | $form = $this->make(SettingsForm::class); |
|
| 322 | 1 | $event = $this->make(UserEvent::class, [$form->getUser()]); |
|
| 323 | |||
| 324 | 1 | $this->make(AjaxRequestModelValidator::class, [$form])->validate(); |
|
| 325 | |||
| 326 | 1 | if ($form->load(Yii::$app->request->post())) { |
|
| 327 | 1 | $this->trigger(UserEvent::EVENT_BEFORE_ACCOUNT_UPDATE, $event); |
|
| 328 | |||
| 329 | 1 | if ($form->save()) { |
|
| 330 | 1 | Yii::$app->getSession()->setFlash( |
|
|
0 ignored issues
–
show
The method
getSession 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
Loading history...
|
|||
| 331 | 1 | 'success', |
|
| 332 | 1 | Yii::t('usuario', 'Your account details have been updated') |
|
| 333 | ); |
||
| 334 | 1 | $this->trigger(UserEvent::EVENT_AFTER_ACCOUNT_UPDATE, $event); |
|
| 335 | |||
| 336 | 1 | return $this->refresh(); |
|
| 337 | } |
||
| 338 | } |
||
| 339 | |||
| 340 | 1 | return $this->render( |
|
| 341 | 1 | 'account', |
|
| 342 | [ |
||
| 343 | 1 | 'model' => $form, |
|
| 344 | ] |
||
| 345 | ); |
||
| 346 | } |
||
| 347 | |||
| 348 | public function actionConfirm($id, $code) |
||
| 349 | { |
||
| 350 | $user = $this->userQuery->whereId($id)->one(); |
||
| 351 | |||
| 352 | if ($user === null || MailChangeStrategyInterface::TYPE_INSECURE === $this->module->emailChangeStrategy) { |
||
| 353 | throw new NotFoundHttpException(); |
||
| 354 | } |
||
| 355 | $event = $this->make(UserEvent::class, [$user]); |
||
| 356 | |||
| 357 | $this->trigger(UserEvent::EVENT_BEFORE_CONFIRMATION, $event); |
||
| 358 | if ($this->make(EmailChangeService::class, [$code, $user])->run()) { |
||
| 359 | $this->trigger(UserEvent::EVENT_AFTER_CONFIRMATION, $event); |
||
| 360 | } |
||
| 361 | |||
| 362 | return $this->redirect(['account']); |
||
| 363 | } |
||
| 364 | |||
| 365 | public function actionNetworks() |
||
| 366 | { |
||
| 367 | return $this->render( |
||
| 368 | 'networks', |
||
| 369 | [ |
||
| 370 | 'user' => Yii::$app->user->identity, |
||
| 371 | ] |
||
| 372 | ); |
||
| 373 | } |
||
| 374 | |||
| 375 | public function actionDisconnect($id) |
||
| 376 | { |
||
| 377 | $this->disconnectSocialNetwork($id); |
||
| 378 | return $this->redirect(['networks']); |
||
| 379 | } |
||
| 380 | |||
| 381 | public function actionDelete() |
||
| 382 | { |
||
| 383 | if (!$this->module->allowAccountDelete) { |
||
| 384 | throw new NotFoundHttpException(Yii::t('usuario', 'Not found')); |
||
| 385 | } |
||
| 386 | |||
| 387 | /** @var User $user */ |
||
| 388 | $user = Yii::$app->user->identity; |
||
| 389 | $event = $this->make(UserEvent::class, [$user]); |
||
| 390 | Yii::$app->user->logout(); |
||
| 391 | |||
| 392 | $this->trigger(UserEvent::EVENT_BEFORE_DELETE, $event); |
||
| 393 | $user->delete(); |
||
| 394 | $this->trigger(UserEvent::EVENT_AFTER_DELETE, $event); |
||
| 395 | |||
| 396 | Yii::$app->session->setFlash('info', Yii::t('usuario', 'Your account has been completely deleted')); |
||
| 397 | |||
| 398 | return $this->goHome(); |
||
| 399 | } |
||
| 400 | |||
| 401 | public function actionTwoFactor($id) |
||
| 402 | { |
||
| 403 | /** @var User $user */ |
||
| 404 | $user = $this->userQuery->whereId($id)->one(); |
||
| 405 | |||
| 406 | if (null === $user) { |
||
| 407 | throw new NotFoundHttpException(); |
||
| 408 | } |
||
| 409 | |||
| 410 | $uri = $this->make(TwoFactorQrCodeUriGeneratorService::class, [$user])->run(); |
||
| 411 | |||
| 412 | return $this->renderAjax('two-factor', ['id' => $id, 'uri' => $uri]); |
||
| 413 | } |
||
| 414 | |||
| 415 | public function actionTwoFactorEnable($id) |
||
| 416 | { |
||
| 417 | Yii::$app->response->format = Response::FORMAT_JSON; |
||
| 418 | |||
| 419 | /** @var User $user */ |
||
| 420 | $user = $this->userQuery->whereId($id)->one(); |
||
| 421 | |||
| 422 | if (null === $user) { |
||
| 423 | return [ |
||
| 424 | 'success' => false, |
||
| 425 | 'message' => Yii::t('usuario', 'User not found.') |
||
| 426 | ]; |
||
| 427 | } |
||
| 428 | $code = Yii::$app->request->get('code'); |
||
| 429 | |||
| 430 | $success = $this |
||
| 431 | ->make(TwoFactorCodeValidator::class, [$user, $code, $this->module->twoFactorAuthenticationCycles]) |
||
| 432 | ->validate(); |
||
| 433 | |||
| 434 | $success = $success && $user->updateAttributes(['auth_tf_enabled' => '1']); |
||
| 435 | |||
| 436 | return [ |
||
| 437 | 'success' => $success, |
||
| 438 | 'message' => $success |
||
| 439 | ? Yii::t('usuario', 'Two factor authentication successfully enabled.') |
||
| 440 | : Yii::t('usuario', 'Verification failed. Please, enter new code.') |
||
| 441 | ]; |
||
| 442 | } |
||
| 443 | |||
| 444 | public function actionTwoFactorDisable($id) |
||
| 445 | { |
||
| 446 | /** @var User $user */ |
||
| 447 | $user = $this->userQuery->whereId($id)->one(); |
||
| 448 | |||
| 449 | if (null === $user) { |
||
| 450 | throw new NotFoundHttpException(); |
||
| 451 | } |
||
| 452 | |||
| 453 | if ($user->updateAttributes(['auth_tf_enabled' => '0'])) { |
||
| 454 | Yii::$app |
||
|
0 ignored issues
–
show
The method
getSession 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
Loading history...
|
|||
| 455 | ->getSession() |
||
| 456 | ->setFlash('success', Yii::t('usuario', 'Two factor authentication has been disabled.')); |
||
| 457 | } else { |
||
| 458 | Yii::$app |
||
| 459 | ->getSession() |
||
| 460 | ->setFlash('danger', Yii::t('usuario', 'Unable to disable Two factor authentication.')); |
||
| 461 | } |
||
| 462 | |||
| 463 | $this->redirect(['account']); |
||
| 464 | } |
||
| 465 | |||
| 466 | /** |
||
| 467 | * @param $id |
||
| 468 | * @throws ForbiddenHttpException |
||
| 469 | * @throws NotFoundHttpException |
||
| 470 | * @throws \Exception |
||
| 471 | * @throws \Throwable |
||
| 472 | * @throws \yii\db\StaleObjectException |
||
| 473 | */ |
||
| 474 | protected function disconnectSocialNetwork($id) |
||
| 475 | { |
||
| 476 | /** @var SocialNetworkAccount $account */ |
||
| 477 | $account = $this->socialNetworkAccountQuery->whereId($id)->one(); |
||
| 478 | |||
| 479 | if ($account === null) { |
||
| 480 | throw new NotFoundHttpException(); |
||
| 481 | } |
||
| 482 | if ($account->user_id !== Yii::$app->user->id) { |
||
| 483 | throw new ForbiddenHttpException(); |
||
| 484 | } |
||
| 485 | $event = $this->make(SocialNetworkConnectEvent::class, [Yii::$app->user->identity, $account]); |
||
| 486 | |||
| 487 | $this->trigger(SocialNetworkConnectEvent::EVENT_BEFORE_DISCONNECT, $event); |
||
| 488 | $account->delete(); |
||
| 489 | $this->trigger(SocialNetworkConnectEvent::EVENT_AFTER_DISCONNECT, $event); |
||
| 490 | } |
||
| 491 | } |
||
| 492 |
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:
Available Fixes
Add an additional type-check:
Only allow a single type to be passed if the variable comes from a parameter: