Completed
Push — master ( a7788f...d3b416 )
by Antonio
02:45
created

AdminController::actionSwitchIdentity()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 14
ccs 0
cts 7
cp 0
rs 9.4285
cc 2
eloc 7
nc 2
nop 1
crap 6
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\Event\UserEvent;
15
use Da\User\Factory\MailFactory;
16
use Da\User\Filter\AccessRuleFilter;
17
use Da\User\Model\Profile;
18
use Da\User\Model\User;
19
use Da\User\Query\UserQuery;
20
use Da\User\Search\UserSearch;
21
use Da\User\Service\SwitchIdentityService;
22
use Da\User\Service\UserBlockService;
23
use Da\User\Service\UserConfirmationService;
24
use Da\User\Service\UserCreateService;
25
use Da\User\Traits\ContainerAwareTrait;
26
use Da\User\Validator\AjaxRequestModelValidator;
27
use Yii;
28
use yii\base\Module;
29
use yii\db\ActiveRecord;
30
use yii\filters\AccessControl;
31
use yii\filters\VerbFilter;
32
use yii\helpers\Url;
33
use yii\web\Controller;
34
35
class AdminController extends Controller
36
{
37
    use ContainerAwareTrait;
38
39
    /**
40
     * @var UserQuery
41
     */
42
    protected $userQuery;
43
44
    /**
45
     * AdminController constructor.
46
     *
47
     * @param string    $id
48
     * @param Module    $module
49
     * @param UserQuery $userQuery
50
     * @param array     $config
51
     */
52 2
    public function __construct($id, Module $module, UserQuery $userQuery, array $config = [])
53
    {
54 2
        $this->userQuery = $userQuery;
55 2
        parent::__construct($id, $module, $config);
56 2
    }
57
58
    /**
59
     * @param \yii\base\Action $action
60
     *
61
     * @return bool
62
     */
63 2
    public function beforeAction($action)
64
    {
65 2
        if (in_array($action->id, ['index', 'update', 'update-profile', 'info', 'assignments'], true)) {
66 2
            Url::remember('', 'actions-redirect');
67
        }
68
69 2
        return parent::beforeAction($action);
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75 2
    public function behaviors()
76
    {
77
        return [
78 2
            'verbs' => [
79
                'class' => VerbFilter::class,
80
                'actions' => [
81
                    'delete' => ['post'],
82
                    'confirm' => ['post'],
83
                    'block' => ['post'],
84
                    'switch-identity' => ['post']
85
                ],
86
            ],
87
            'access' => [
88
                'class' => AccessControl::class,
89
                'ruleConfig' => [
90
                    'class' => AccessRuleFilter::class,
91
                ],
92
                'rules' => [
93
                    [
94
                        'allow' => true,
95
                        'roles' => ['admin'],
96
                    ],
97
                ],
98
            ],
99
        ];
100
    }
101
102
    public function actionIndex()
103
    {
104
        $searchModel = $this->make(UserSearch::class);
105
        $dataProvider = $searchModel->search(Yii::$app->request->get());
106
107
        return $this->render(
108
            'index',
109
            [
110
                'dataProvider' => $dataProvider,
111
                'searchModel' => $searchModel,
112
            ]
113
        );
114
    }
115
116 1
    public function actionCreate()
117
    {
118
        /** @var User $user */
119 1
        $user = $this->make(User::class, [], ['scenario' => 'create']);
120
121
        /** @var UserEvent $event */
122 1
        $event = $this->make(UserEvent::class, [$user]);
123
124 1
        $this->make(AjaxRequestModelValidator::class, [$user])->validate();
125
126 1
        if ($user->load(Yii::$app->request->post())) {
127 1
            $this->trigger(UserEvent::EVENT_BEFORE_CREATE, $event);
128
129 1
            $mailService = MailFactory::makeWelcomeMailerService($user);
130
131 1
            if ($this->make(UserCreateService::class, [$user, $mailService])->run()) {
132 1
                Yii::$app->getSession()->setFlash('success', Yii::t('usuario', 'User has been created'));
0 ignored issues
show
Bug introduced by
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

  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...
133 1
                $this->trigger(UserEvent::EVENT_AFTER_CREATE, $event);
134
135 1
                return $this->redirect(['update', 'id' => $user->id]);
136
            }
137
        }
138
139 1
        return $this->render('create', ['user' => $user]);
140
    }
141
142 2
    public function actionUpdate($id)
143
    {
144 2
        $user = $this->userQuery->where(['id' => $id])->one();
145 2
        $user->setScenario('update');
146
        /** @var UserEvent $event */
147 2
        $event = $this->make(UserEvent::class, [$user]);
148
149 2
        $this->make(AjaxRequestModelValidator::class, [$user])->validate();
150
151 2
        if ($user->load(Yii::$app->request->post())) {
152 1
            $this->trigger(ActiveRecord::EVENT_BEFORE_UPDATE, $event);
153
154 1
            if ($user->save()) {
155 1
                Yii::$app->getSession()->setFlash('success', Yii::t('usuario', 'Account details have been updated'));
0 ignored issues
show
Bug introduced by
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

  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...
156 1
                $this->trigger(ActiveRecord::EVENT_AFTER_UPDATE, $event);
157
158 1
                return $this->refresh();
159
            }
160
        }
161
162 2
        return $this->render('_account', ['user' => $user]);
163
    }
164
165
    public function actionUpdateProfile($id)
166
    {
167
        /** @var User $user */
168
        $user = $this->userQuery->where(['id' => $id])->one();
169
        /** @var Profile $profile */
170
        $profile = $user->profile;
171
        if ($profile === null) {
172
            $profile = $this->make(Profile::class);
173
            $profile->link('user', $user);
174
        }
175
        /** @var UserEvent $event */
176
        $event = $this->make(UserEvent::class, [$user]);
177
178
        $this->make(AjaxRequestModelValidator::class, [$user])->validate();
179
180
        if ($profile->load(Yii::$app->request->post())) {
181
            if ($profile->save()) {
182
                $this->trigger(UserEvent::EVENT_BEFORE_PROFILE_UPDATE, $event);
183
                Yii::$app->getSession()->setFlash('success', Yii::t('usuario', 'Profile details have been updated'));
0 ignored issues
show
Bug introduced by
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

  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...
184
                $this->trigger(UserEvent::EVENT_AFTER_PROFILE_UPDATE, $event);
185
186
                return $this->refresh();
187
            }
188
        }
189
190
        return $this->render(
191
            '_profile',
192
            [
193
                'user' => $user,
194
                'profile' => $profile,
195
            ]
196
        );
197
    }
198
199
    public function actionInfo($id)
200
    {
201
        /** @var User $user */
202
        $user = $this->userQuery->where(['id' => $id])->one();
203
204
        return $this->render(
205
            '_info',
206
            [
207
                'user' => $user,
208
            ]
209
        );
210
    }
211
212
    public function actionAssignments($id)
213
    {
214
        /** @var User $user */
215
        $user = $this->userQuery->where(['id' => $id])->one();
216
217
        return $this->render(
218
            '_assignments',
219
            [
220
                'user' => $user,
221
                'params' => Yii::$app->request->post(),
222
            ]
223
        );
224
    }
225
226
    public function actionConfirm($id)
227
    {
228
        /** @var User $user */
229
        $user = $this->userQuery->where(['id' => $id])->one();
230
        /** @var UserEvent $event */
231
        $event = $this->make(UserEvent::class, [$user]);
232
233
        $this->trigger(UserEvent::EVENT_BEFORE_CONFIRMATION, $event);
234
235
        if ($this->make(UserConfirmationService::class, [$user])->run()) {
236
            Yii::$app->getSession()->setFlash('success', Yii::t('usuario', 'User has been confirmed'));
0 ignored issues
show
Bug introduced by
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

  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...
237
            $this->trigger(UserEvent::EVENT_AFTER_CONFIRMATION, $event);
238
        } else {
239
            Yii::$app->getSession()->setFlash(
240
                'warning',
241
                Yii::t('usuario', 'Unable to confirm user. Please, try again.')
242
            );
243
        }
244
245
        return $this->redirect(Url::previous('actions-redirect'));
246
    }
247
248
    public function actionDelete($id)
249
    {
250
        if ((int)$id === Yii::$app->user->getId()) {
251
            Yii::$app->getSession()->setFlash('danger', Yii::t('usuario', 'You cannot remove your own account'));
0 ignored issues
show
Bug introduced by
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

  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...
252
        } else {
253
            /** @var User $user */
254
            $user = $this->userQuery->where(['id' => $id])->one();
255
            /** @var UserEvent $event */
256
            $event = $this->make(UserEvent::class, [$user]);
257
            $this->trigger(ActiveRecord::EVENT_BEFORE_DELETE, $event);
258
259
            if ($user->delete()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $user->delete() of type false|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
260
                Yii::$app->getSession()->setFlash('success', Yii::t('usuario', 'User has been deleted'));
261
                $this->trigger(ActiveRecord::EVENT_AFTER_DELETE, $event);
262
            } else {
263
                Yii::$app->getSession()->setFlash(
264
                    'warning',
265
                    Yii::t('usuario', 'Unable to delete user. Please, try again later.')
266
                );
267
            }
268
        }
269
270
        return $this->redirect(['index']);
271
    }
272
273
    public function actionBlock($id)
274
    {
275
        if ((int)$id === Yii::$app->user->getId()) {
276
            Yii::$app->getSession()->setFlash('danger', Yii::t('usuario', 'You cannot remove your own account'));
0 ignored issues
show
Bug introduced by
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

  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...
277
        } else {
278
            /** @var User $user */
279
            $user = $this->userQuery->where(['id' => $id])->one();
280
            /** @var UserEvent $event */
281
            $event = $this->make(UserEvent::class, [$user]);
282
283
            if ($this->make(UserBlockService::class, [$user, $event, $this])->run()) {
284
                Yii::$app->getSession()->setFlash('success', Yii::t('usuario', 'User block status has been updated.'));
285
            } else {
286
                Yii::$app->getSession()->setFlash('danger', Yii::t('usuario', 'Unable to update block status.'));
287
            }
288
        }
289
290
        return $this->redirect(Url::previous('actions-redirect'));
291
    }
292
293
    public function actionSwitchIdentity($id = null)
294
    {
295
        /** @var \Da\User\Module $module */
296
        $module = $this->module;
297
        if (false === $module->enableSwitchIdentities) {
298
            Yii::$app->getSession()->setFlash('danger', Yii::t('usuario', 'Switch identities is disabled.'));
0 ignored issues
show
Bug introduced by
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

  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...
299
300
            return $this->redirect(['index']);
301
        }
302
303
        $this->make(SwitchIdentityService::class, [$this, 'userId' => $id])->run();
304
305
        return $this->goHome();
306
    }
307
}
308